def test_extract_format_spec__with_align_only_raises_error(self): # -- INVALID-FORMAT: Width without type. for align in Field.ALIGN_CHARS: with self.assertRaises(ValueError) as cm: Field.extract_format_spec(align) self.assertEqual("INVALID-FORMAT: %s (without type)" % align, str(cm.exception))
def test_not_equal__with_field(self): for field in self.FIELDS: other2 = Field(field.name, "XXX") self.assertNotEqual(field.format, other2.format) self.assertNotEqual(field, other2) other3 = Field("xxx", field.format) self.assertNotEqual(field.name, other3.name) self.assertNotEqual(field, other3)
def test_extract_format_spec_with_fill_and_align_only_raises_error(self): # -- INVALID-FORMAT: Width without type. fill = "_" for align in Field.ALIGN_CHARS: with self.assertRaises(ValueError) as cm: format = fill + align Field.extract_format_spec(format) self.assertEqual("INVALID-FORMAT: %s (without type)" % format, str(cm.exception))
def test_set_format_invalidates_format_spec(self): field = Field(format="Number") self.assertEqual(field.format, "Number") self.assertEqual(field.format_spec.type, "Number") self.assertEqual(field.format_spec.align, None) field.set_format("<ManyNumbers") self.assertEqual(field.format, "<ManyNumbers") self.assertEqual(field.format_spec.type, "ManyNumbers") self.assertEqual(field.format_spec.align, '<')
def test_to_string_conversion(self): test_data = [ (Field(), "{}"), (Field("name"), "{name}"), (Field(format="type"), "{:type}"), (Field("name", "type"), "{name:type}"), ] for field, expected_text in test_data: text = str(field) self.assertEqual(text, expected_text)
def test_not_equal__with_string(self): for field in self.FIELDS: other2 = Field(field.name, "XXX") other2_text = str(other2) self.assertNotEqual(field.format, other2.format) self.assertNotEqual(field, other2_text) other3 = Field("xxx", field.format) other3_text = str(other3) self.assertNotEqual(field.name, other3.name) self.assertNotEqual(field, other3_text)
def test_format_spec__is_lazy_evaluated(self): fields = [ Field(), Field("name"), Field("name", "type"), Field(format="type") ] for field in fields: self.assertIsNone(field._format_spec) if field.format: _ = field.format_spec.type self.assertIsNotNone(field.format_spec) else: self.assertIsNone(field.format_spec)
def test_extract_format_spec__with_all(self): for format, expected_spec in self.FORMAT_AND_FORMAT_SPEC_DATA: format_spec = Field.extract_format_spec(format) self.assertEqual(format_spec, expected_spec) self.assertValidFormatWidth(format_spec.width) if format_spec.align is not None: self.assertValidFormatAlign(format_spec.align)
def test_extract_format_spec__with_zero_and_type(self): formats = ["0s", "0d", "0Number", "0Number+"] for format in formats: format_spec = Field.extract_format_spec(format) expected_type = format[1:] expected_spec = make_format_spec(type=expected_type, zero=True) self.assertEqual(format_spec, expected_spec)
def test_extract_format_spec__with_width_and_type(self): formats = ["1s", "2d", "6s", "10d", "60f", "123456789s"] for format in formats: format_spec = Field.extract_format_spec(format) expected_type = format[-1] expected_width = format[:-1] expected_spec = make_format_spec(type=expected_type, width=expected_width) self.assertEqual(format_spec, expected_spec) self.assertValidFormatWidth(format_spec.width)
def test_extract_format_spec__with_align_and_type(self): # -- ALIGN_CHARS = "<>=^" formats = ["<s", ">d", "=Number", "^Number+"] for format in formats: format_spec = Field.extract_format_spec(format) expected_align = format[0] expected_type = format[1:] expected_spec = make_format_spec(type=expected_type, align=expected_align) self.assertEqual(format_spec, expected_spec) self.assertValidFormatAlign(format_spec.align)
def test_extract_format_spec__with_type(self): format_types = ["d", "w", "Number", "Number?", "Number*", "Number+"] for format_type in format_types: format_spec = Field.extract_format_spec(format_type) expected_spec = make_format_spec(format_type) self.assertEqual(format_spec.type, format_type) self.assertEqual(format_spec.width, "") self.assertEqual(format_spec.zero, False) self.assertIsNone(format_spec.align) self.assertIsNone(format_spec.fill) self.assertEqual(format_spec, expected_spec)
def test_extract_fields__with_many_fields(self): MANY_FIELDS_DATA = [ ("{}xxx{name2}", [Field(), Field("name2")]), ("{name1}yyy{:type2}", [Field("name1"), Field(format="type2")]), ("{:type1}xxx{name2}{name3:type3}", [Field(format="type1"), Field("name2"), Field("name3", "type3")]), ] prefix = "XXX ___" suffix = "XXX {{escaped_field}} {{escaped_field:xxx_type}} XXX" for field_text, expected_fields in MANY_FIELDS_DATA: fields = list(FieldParser.extract_fields(field_text)) self.assertEqual(len(fields), len(expected_fields)) self.assertSequenceEqual(fields, expected_fields) field_text2 = prefix + field_text + suffix fields2 = list(FieldParser.extract_fields(field_text2)) self.assertEqual(len(fields2), len(expected_fields)) self.assertSequenceEqual(fields2, expected_fields)
class TestFieldParser(TestCase): INVALID_FIELDS = ["", "{", "}", "xxx", "name:type", ":type"] VALID_FIELD_DATA = [("{}", Field()), ("{name}", Field("name")), ("{:type}", Field(format="type")), ("{name:type}", Field("name", "type"))] #def assertFieldEqual(self, actual, expected): # message = "FAILED: %s == %s" % (actual, expected) # self.assertIsInstance(actual, Field) # self.assertIsInstance(expected, Field) # self.assertEqual(actual, expected, message) # # self.assertEqual(actual.name, expected.name, message) # # self.assertEqual(actual.format, expected.format, message) def test_parse__raises_error_with_missing_or_partial_braces(self): for field_text in self.INVALID_FIELDS: with self.assertRaises(ValueError): FieldParser.parse(field_text) def test_parse__with_valid_fields(self): for field_text, expected_field in self.VALID_FIELD_DATA: field = FieldParser.parse(field_text) self.assertEqual(field, expected_field) def test_extract_fields__without_field(self): prefix = "XXX ___" suffix = "XXX {{escaped_field}} {{escaped_field:xxx_type}} XXX" field_texts = [prefix, suffix, prefix + suffix, suffix + prefix] for field_text in field_texts: fields = list(FieldParser.extract_fields(field_text)) self.assertEqual(len(fields), 0) def test_extract_fields__with_one_field(self): prefix = "XXX ___" suffix = "XXX {{escaped_field}} {{escaped_field:xxx_type}} XXX" for field_text, expected_field in self.VALID_FIELD_DATA: fields = list(FieldParser.extract_fields(field_text)) self.assertEqual(len(fields), 1) self.assertSequenceEqual(fields, [expected_field]) field_text2 = prefix + field_text + suffix fields2 = list(FieldParser.extract_fields(field_text2)) self.assertEqual(len(fields2), 1) self.assertSequenceEqual(fields, fields2) def test_extract_fields__with_many_fields(self): MANY_FIELDS_DATA = [ ("{}xxx{name2}", [Field(), Field("name2")]), ("{name1}yyy{:type2}", [Field("name1"), Field(format="type2")]), ("{:type1}xxx{name2}{name3:type3}", [Field(format="type1"), Field("name2"), Field("name3", "type3")]), ] prefix = "XXX ___" suffix = "XXX {{escaped_field}} {{escaped_field:xxx_type}} XXX" for field_text, expected_fields in MANY_FIELDS_DATA: fields = list(FieldParser.extract_fields(field_text)) self.assertEqual(len(fields), len(expected_fields)) self.assertSequenceEqual(fields, expected_fields) field_text2 = prefix + field_text + suffix fields2 = list(FieldParser.extract_fields(field_text2)) self.assertEqual(len(fields2), len(expected_fields)) self.assertSequenceEqual(fields2, expected_fields) def test_extract_types(self): MANY_TYPES_DATA = [ ("{}xxx{name2}", []), ("{name1}yyy{:type2}", ["type2"]), ("{:type1}xxx{name2}{name3:type3}", ["type1", "type3"]), ] for field_text, expected_types in MANY_TYPES_DATA: type_names = list(FieldParser.extract_types(field_text)) self.assertEqual(len(type_names), len(expected_types)) self.assertSequenceEqual(type_names, expected_types)
def test_make_format(self): for expected_format, format_spec in self.FORMAT_AND_FORMAT_SPEC_DATA: format = Field.make_format(format_spec) self.assertEqual(format, expected_format) format_spec2 = Field.extract_format_spec(format) self.assertEqual(format_spec2, format_spec)
def test_extract_format_spec__with_zero_only_raises_error(self): # -- INVALID-FORMAT: Width without type. with self.assertRaises(ValueError) as cm: Field.extract_format_spec("0") self.assertEqual("INVALID-FORMAT: 0 (without type)", str(cm.exception))
def test_not_equal__with_unsupported(self): UNSUPPORTED_TYPES = [None, make_format_spec(), True, False, 10] field = Field() for other in UNSUPPORTED_TYPES: with self.assertRaises(ValueError): field != other
class TestField(TestCase): EMPTY_FORMAT_FIELDS = [ Field(), #< Empty field. Field("name"), #< Named field without format. Field("name", ""), #< Named field with format=empty-string. Field(format=""), #< Field with format=empty-string. ] NONEMPTY_FORMAT_FIELDS = [ Field(format="Number"), #< Typed field without name". Field("name", "Number"), #< Named and typed field". ] INVALID_FORMAT_FIELDS = [ Field(format="<"), #< Align without type. Field(format="_<"), #< Fill and align without type. Field(format="_<10"), #< Fill, align and width without type. Field(format="_<098"), #< Fill, align, zero and width without type. ] FIELDS = EMPTY_FORMAT_FIELDS + NONEMPTY_FORMAT_FIELDS + INVALID_FORMAT_FIELDS def test_is_typed__returns_true_for_nonempty_format(self): fields = self.NONEMPTY_FORMAT_FIELDS + self.INVALID_FORMAT_FIELDS for field in fields: self.assertTrue(field.has_format, "Field: %s" % field) def test_is_typed__returns_false_for_empty_format(self): fields = self.EMPTY_FORMAT_FIELDS for field in fields: self.assertFalse(field.has_format, "Field: %s" % field) def test_format_spec__returns_none_if_format_is_empty(self): for field in self.EMPTY_FORMAT_FIELDS: self.assertIsNone(field.format_spec, "Field: %s" % field) def test_format_spec__if_format_is_nonempty_and_valid(self): for field in self.NONEMPTY_FORMAT_FIELDS: self.assertIsNotNone(field.format_spec) self.assertIsInstance(field.format_spec, FormatSpec) def test_format_spec__raises_error_if_nonempty_format_is_invalid(self): for field in self.INVALID_FORMAT_FIELDS: with self.assertRaises(ValueError): field.format_spec def test_format_spec__is_lazy_evaluated(self): fields = [ Field(), Field("name"), Field("name", "type"), Field(format="type") ] for field in fields: self.assertIsNone(field._format_spec) if field.format: _ = field.format_spec.type self.assertIsNotNone(field.format_spec) else: self.assertIsNone(field.format_spec) def test_set_format_invalidates_format_spec(self): field = Field(format="Number") self.assertEqual(field.format, "Number") self.assertEqual(field.format_spec.type, "Number") self.assertEqual(field.format_spec.align, None) field.set_format("<ManyNumbers") self.assertEqual(field.format, "<ManyNumbers") self.assertEqual(field.format_spec.type, "ManyNumbers") self.assertEqual(field.format_spec.align, '<') def test_to_string_conversion(self): test_data = [ (Field(), "{}"), (Field("name"), "{name}"), (Field(format="type"), "{:type}"), (Field("name", "type"), "{name:type}"), ] for field, expected_text in test_data: text = str(field) self.assertEqual(text, expected_text) def test_equal__with_field(self): for field in self.FIELDS: other = field self.assertEqual(field, other) def test_equal__with_string(self): for field in self.FIELDS: other = str(field) self.assertEqual(field, other) def test_equal__with_unsupported(self): UNSUPPORTED_TYPES = [None, make_format_spec(), True, False, 10] field = Field() for other in UNSUPPORTED_TYPES: with self.assertRaises(ValueError): field == other def test_not_equal__with_field(self): for field in self.FIELDS: other2 = Field(field.name, "XXX") self.assertNotEqual(field.format, other2.format) self.assertNotEqual(field, other2) other3 = Field("xxx", field.format) self.assertNotEqual(field.name, other3.name) self.assertNotEqual(field, other3) def test_not_equal__with_string(self): for field in self.FIELDS: other2 = Field(field.name, "XXX") other2_text = str(other2) self.assertNotEqual(field.format, other2.format) self.assertNotEqual(field, other2_text) other3 = Field("xxx", field.format) other3_text = str(other3) self.assertNotEqual(field.name, other3.name) self.assertNotEqual(field, other3_text) def test_not_equal__with_unsupported(self): UNSUPPORTED_TYPES = [None, make_format_spec(), True, False, 10] field = Field() for other in UNSUPPORTED_TYPES: with self.assertRaises(ValueError): field != other
def test_extract_format_spec__with_empty_string_raises_error(self): with self.assertRaises(ValueError) as cm: Field.extract_format_spec("") self.assertIn("INVALID-FORMAT", str(cm.exception))