def test_parse_with_many_unnamed_fields_with_variants(self): from parse_type.parse import Parser as Parser2 type_dict = build_type_dict(self.TYPE_CONVERTERS) schema = """\ Number: {:Number} YesNo: {:YesNo} Color: {:Color} Person: {:PersonChoice} Variant2: {:Color_or_PersonChoice} Variant1: {:Number_or_YesNo} """ # -- OMIT: XFAIL, due to group_index delta counting => Parser problem. parser = Parser2(schema, type_dict) text = """\ Number: 12 YesNo: yes Color: red Person: Alice Variant2: Bob Variant1: 42 """ expected = [ 12, True, Color.red, "Alice", "Bob", 42 ] result = parser.parse(text) self.assertIsNotNone(result) self.assertEqual(result.fixed, tuple(expected))
def test_parse_with_many_unnamed_fields(self): type_dict = build_type_dict(self.TYPE_CONVERTERS) schema = """\ Number: {:Number} YesNo: {:YesNo} Color: {:Color} Person: {:PersonChoice} """ # -- OMIT: XFAIL, due to group_index delta counting => Parser problem. # Variant2: {:Color_or_PersonChoice} # Variant1: {:Number_or_YesNo} parser = parse.Parser(schema, type_dict) text = """\ Number: 12 YesNo: yes Color: red Person: Alice """ # SKIP: Variant2: Bob # SKIP: Variant1: 42 expected = [ 12, True, Color.red, "Alice", ] # -- SKIP: "Bob", 42 ] result = parser.parse(text) self.assertIsNotNone(result) self.assertEqual(result.fixed, tuple(expected))
def test_parse_with_many_named_fields(self): type_dict = build_type_dict(self.TYPE_CONVERTERS) schema = """\ Number: {number:Number} YesNo: {answer:YesNo} Color: {color:Color} Person: {person:PersonChoice} Variant1: {variant1:Number_or_YesNo} Variant2: {variant2:Color_or_PersonChoice} """ parser = parse.Parser(schema, type_dict) text = """\ Number: 12 YesNo: yes Color: red Person: Alice Variant1: 42 Variant2: Bob """ expected = dict( number=12, answer=True, color=Color.red, person="Alice", variant1=42, variant2="Bob" ) result = parser.parse(text) self.assertIsNotNone(result) self.assertEqual(result.named, expected)
def test_parse_with_many_unnamed_fields_with_variants(self): from parse_type.parse import Parser as Parser2 type_dict = build_type_dict(self.TYPE_CONVERTERS) schema = """\ Number: {:Number} YesNo: {:YesNo} Color: {:Color} Person: {:PersonChoice} Variant2: {:Color_or_PersonChoice} Variant1: {:Number_or_YesNo} """ # -- OMIT: XFAIL, due to group_index delta counting => Parser problem. parser = Parser2(schema, type_dict) text = """\ Number: 12 YesNo: yes Color: red Person: Alice Variant2: Bob Variant1: 42 """ expected = [12, True, Color.red, "Alice", "Bob", 42] result = parser.parse(text) self.assertIsNotNone(result) self.assertEqual(result.fixed, tuple(expected))
def test_parse_with_many_named_fields(self): type_dict = build_type_dict(self.TYPE_CONVERTERS) schema = """\ Number: {number:Number} YesNo: {answer:YesNo} Color: {color:Color} Person: {person:PersonChoice} Variant1: {variant1:Number_or_YesNo} Variant2: {variant2:Color_or_PersonChoice} """ parser = parse.Parser(schema, type_dict) text = """\ Number: 12 YesNo: yes Color: red Person: Alice Variant1: 42 Variant2: Bob """ expected = dict(number=12, answer=True, color=Color.red, person="Alice", variant1=42, variant2="Bob") result = parser.parse(text) self.assertIsNotNone(result) self.assertEqual(result.named, expected)
def test_with_one_or_more_with_other_separator(self): parse_numbers2 = TypeBuilder.with_one_or_more(parse_number, listsep=';') parse_numbers2.name = "Numbers2" extra_types = build_type_dict([ parse_numbers2 ]) schema = "List: {numbers:Numbers2}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "List: 1", "numbers", [ 1 ]) self.assert_match(parser, "List: 1; 2", "numbers", [ 1, 2 ]) self.assert_match(parser, "List: 1; 2; 3", "numbers", [ 1, 2, 3 ])
def test_make_choice(self): parse_choice = TypeBuilder.make_choice(["one", "two", "three"]) parse_choice.name = "NumberWordChoice" extra_types = build_type_dict([ parse_choice ]) schema = "Answer: {answer:NumberWordChoice}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "Answer: one", "answer", "one") self.assert_match(parser, "Answer: two", "answer", "two") self.ensure_can_parse_all_choices(parser, parse_choice, "Answer: %s", "answer") # -- PARSE MISMATCH: self.assert_mismatch(parser, "Answer: __one__", "answer") self.assert_mismatch(parser, "Answer: one ", "answer") self.assert_mismatch(parser, "Answer: one ZZZ", "answer")
def test_make_choice(self): parse_choice = TypeBuilder.make_choice(["one", "two", "three"]) parse_choice.name = "NumberWordChoice" extra_types = build_type_dict([parse_choice]) schema = "Answer: {answer:NumberWordChoice}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "Answer: one", "answer", "one") self.assert_match(parser, "Answer: two", "answer", "two") self.ensure_can_parse_all_choices(parser, parse_choice, "Answer: %s", "answer") # -- PARSE MISMATCH: self.assert_mismatch(parser, "Answer: __one__", "answer") self.assert_mismatch(parser, "Answer: one ", "answer") self.assert_mismatch(parser, "Answer: one ZZZ", "answer")
def test_cardinality_field_with_zero_or_one(self): # -- SETUP: parse_person = TypeBuilder.make_choice(["Alice", "Bob", "Charly"]) parse_person.name = "Person" # For testing only. extra_types = build_type_dict([ parse_person ]) schema = "Optional: {person:Person?}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "Optional: ", "person", None) self.assert_match(parser, "Optional: Alice", "person", "Alice") self.assert_match(parser, "Optional: Bob", "person", "Bob") # -- PARSE MISMATCH: self.assert_mismatch(parser, "Optional: Anna", "person") # Similar1. self.assert_mismatch(parser, "Optional: Boby", "person") # Similar2. self.assert_mismatch(parser, "Optional: a", "person") # INVALID ...
def test_parse_choice_persons(self): extra_types = build_type_dict([parse_person_choice]) schema = "Answer: {answer:PersonChoice}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "Answer: Alice", "answer", "Alice") self.assert_match(parser, "Answer: Bob", "answer", "Bob") self.ensure_can_parse_all_choices(parser, parse_person_choice, "Answer: %s", "answer") # -- IGNORE-CASE: In parsing, calls type converter function !!! # SKIP-WART: self.assert_match(parser, "Answer: BOB", "answer", "BOB") # -- PARSE MISMATCH: self.assert_mismatch(parser, "Answer: __Alice__", "answer") self.assert_mismatch(parser, "Answer: Alice ", "answer") self.assert_mismatch(parser, "Answer: Alice ZZZ", "answer")
def test_without_cardinality_field(self): # -- IMPLCIT CARDINALITY: one # -- SETUP: parse_person = TypeBuilder.make_choice(["Alice", "Bob", "Charly"]) parse_person.name = "Person" # For testing only. extra_types = build_type_dict([ parse_person ]) schema = "One: {person:Person}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "One: Alice", "person", "Alice") self.assert_match(parser, "One: Bob", "person", "Bob") # -- PARSE MISMATCH: self.assert_mismatch(parser, "One: ", "person") # Missing. self.assert_mismatch(parser, "One: BAlice", "person") # Similar1. self.assert_mismatch(parser, "One: Boby", "person") # Similar2. self.assert_mismatch(parser, "One: a", "person") # INVALID ...
def test_without_cardinality_field(self): # -- IMPLCIT CARDINALITY: one # -- SETUP: parse_person = TypeBuilder.make_choice(["Alice", "Bob", "Charly"]) parse_person.name = "Person" # For testing only. extra_types = build_type_dict([parse_person]) schema = "One: {person:Person}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "One: Alice", "person", "Alice") self.assert_match(parser, "One: Bob", "person", "Bob") # -- PARSE MISMATCH: self.assert_mismatch(parser, "One: ", "person") # Missing. self.assert_mismatch(parser, "One: BAlice", "person") # Similar1. self.assert_mismatch(parser, "One: Boby", "person") # Similar2. self.assert_mismatch(parser, "One: a", "person") # INVALID ...
def test_parse_choice_persons(self): extra_types = build_type_dict([ parse_person_choice ]) schema = "Answer: {answer:PersonChoice}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "Answer: Alice", "answer", "Alice") self.assert_match(parser, "Answer: Bob", "answer", "Bob") self.ensure_can_parse_all_choices(parser, parse_person_choice, "Answer: %s", "answer") # -- IGNORE-CASE: In parsing, calls type converter function !!! # SKIP-WART: self.assert_match(parser, "Answer: BOB", "answer", "BOB") # -- PARSE MISMATCH: self.assert_mismatch(parser, "Answer: __Alice__", "answer") self.assert_mismatch(parser, "Answer: Alice ", "answer") self.assert_mismatch(parser, "Answer: Alice ZZZ", "answer")
def test_with_zero_or_more__choice(self): parse_color = TypeBuilder.make_choice(["red", "green", "blue"]) parse_colors = TypeBuilder.with_zero_or_more(parse_color) parse_colors.name = "Colors0" extra_types = build_type_dict([ parse_colors ]) schema = "List: {colors:Colors0}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "List: ", "colors", [ ]) self.assert_match(parser, "List: green", "colors", [ "green" ]) self.assert_match(parser, "List: red, green", "colors", [ "red", "green" ]) # -- PARSE MISMATCH: self.assert_mismatch(parser, "List: x", "colors") # Not a Color. self.assert_mismatch(parser, "List: black", "colors") # Unknown self.assert_mismatch(parser, "List: red,", "colors") # Trailing sep. self.assert_mismatch(parser, "List: a, b", "colors") # List of ...
def test_parse_with_optional_and_named_fields(self): parse_opt_number = TypeBuilder.with_optional(parse_number) parse_opt_number.name = "Number?" type_dict = build_type_dict([parse_opt_number, parse_number]) schema = "Numbers: {number1:Number?} {number2:Number}" parser = parse.Parser(schema, type_dict) # -- CASE: Optional number is present result = parser.parse("Numbers: 34 12") expected = dict(number1=34, number2=12) self.assertIsNotNone(result) self.assertEqual(result.named, expected) # -- CASE: Optional number is missing result = parser.parse("Numbers: 12") expected = dict(number1=None, number2=12) self.assertIsNotNone(result) self.assertEqual(result.named, expected)
def test_with_one_or_more_enum(self): parse_color = TypeBuilder.make_enum({"red": 1, "green":2, "blue": 3}) parse_colors = TypeBuilder.with_one_or_more(parse_color) parse_colors.name = "Colors" extra_types = build_type_dict([ parse_colors ]) schema = "List: {colors:Colors}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "List: green", "colors", [ 2 ]) self.assert_match(parser, "List: red, green", "colors", [ 1, 2 ]) # -- PARSE MISMATCH: self.assert_mismatch(parser, "List: ", "colors") # Zero items. self.assert_mismatch(parser, "List: x", "colors") # Not a Color. self.assert_mismatch(parser, "List: black", "colors") # Unknown self.assert_mismatch(parser, "List: red,", "colors") # Trailing sep. self.assert_mismatch(parser, "List: a, b", "colors") # List of ...
def test_cardinality_field_with_one_or_more(self): # -- SETUP: parse_person = TypeBuilder.make_choice(["Alice", "Bob", "Charly"]) parse_person.name = "Person" # For testing only. extra_types = build_type_dict([ parse_person ]) schema = "List: {persons:Person+}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "List: Alice", "persons", [ "Alice" ]) self.assert_match(parser, "List: Bob", "persons", [ "Bob" ]) self.assert_match(parser, "List: Bob, Alice", "persons", [ "Bob", "Alice" ]) # -- PARSE MISMATCH: self.assert_mismatch(parser, "List: ", "persons") # Zero items. self.assert_mismatch(parser, "List: BAlice", "persons") # Unknown1. self.assert_mismatch(parser, "List: Boby", "persons") # Unknown2. self.assert_mismatch(parser, "List: Alice,", "persons") # Trailing, self.assert_mismatch(parser, "List: a, b", "persons") # List of...
def test_cardinality_field_with_zero_or_one(self): # -- SETUP: parse_person = TypeBuilder.make_choice(["Alice", "Bob", "Charly"]) parse_person.name = "Person" # For testing only. extra_types = build_type_dict([parse_person]) schema = "Optional: {person:Person?}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "Optional: ", "person", None) self.assert_match(parser, "Optional: Alice", "person", "Alice") self.assert_match(parser, "Optional: Bob", "person", "Bob") # -- PARSE MISMATCH: self.assert_mismatch(parser, "Optional: Anna", "person") # Similar1. self.assert_mismatch(parser, "Optional: Boby", "person") # Similar2. self.assert_mismatch(parser, "Optional: a", "person") # INVALID ...
def test_make_choice2(self): # -- strict=False: Disable errors due to case mismatch. parse_choice2 = TypeBuilder.make_choice2(["zero", "one", "two"], strict=False) parse_choice2.name = "NumberWordChoice2" extra_types = build_type_dict([ parse_choice2 ]) schema = "Answer: {answer:NumberWordChoice2}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "Answer: zero", "answer", (0, "zero")) self.assert_match(parser, "Answer: one", "answer", (1, "one")) self.assert_match(parser, "Answer: two", "answer", (2, "two")) self.ensure_can_parse_all_choices2(parser, parse_choice2, "Answer: %s", "answer") # -- PARSE MISMATCH: self.assert_mismatch(parser, "Answer: __one__", "answer") self.assert_mismatch(parser, "Answer: one ", "answer") self.assert_mismatch(parser, "Answer: one ZZZ", "answer")
def test_parse_enum_yesno(self): extra_types = build_type_dict([ parse_yesno ]) schema = "Answer: {answer:YesNo}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.ensure_can_parse_all_enum_values(parser, parse_yesno, "Answer: %s", "answer") # -- VALID: self.assert_match(parser, "Answer: yes", "answer", True) self.assert_match(parser, "Answer: no", "answer", False) # -- IGNORE-CASE: In parsing, calls type converter function !!! self.assert_match(parser, "Answer: YES", "answer", True) # -- PARSE MISMATCH: self.assert_mismatch(parser, "Answer: __YES__", "answer") self.assert_mismatch(parser, "Answer: yes ", "answer") self.assert_mismatch(parser, "Answer: yes ZZZ", "answer")
def test_decorated_function_with_parser(self): # -- SETUP: @parse.with_pattern(r"\d+") def parse_number(text): return int(text) parse_number.name = "Number" #< For test automation. more_types = build_type_dict([ parse_number ]) schema = "Test: {number:Number}" parser = parse.Parser(schema, more_types) # -- PERFORM TESTS: self.assert_match(parser, "Test: 1", "number", 1) self.assert_match(parser, "Test: 42", "number", 42) self.assert_match(parser, "Test: 123", "number", 123) # -- PARSE MISMATCH: self.assert_mismatch(parser, "Test: x", "number") # Not a Number. self.assert_mismatch(parser, "Test: -1", "number") # Negative. self.assert_mismatch(parser, "Test: a, b", "number") # List of ...
def test_make_choice2(self): # -- strict=False: Disable errors due to case mismatch. parse_choice2 = TypeBuilder.make_choice2(["zero", "one", "two"], strict=False) parse_choice2.name = "NumberWordChoice2" extra_types = build_type_dict([parse_choice2]) schema = "Answer: {answer:NumberWordChoice2}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "Answer: zero", "answer", (0, "zero")) self.assert_match(parser, "Answer: one", "answer", (1, "one")) self.assert_match(parser, "Answer: two", "answer", (2, "two")) self.ensure_can_parse_all_choices2(parser, parse_choice2, "Answer: %s", "answer") # -- PARSE MISMATCH: self.assert_mismatch(parser, "Answer: __one__", "answer") self.assert_mismatch(parser, "Answer: one ", "answer") self.assert_mismatch(parser, "Answer: one ZZZ", "answer")
def test_parse_enum_yesno(self): extra_types = build_type_dict([parse_yesno]) schema = "Answer: {answer:YesNo}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.ensure_can_parse_all_enum_values(parser, parse_yesno, "Answer: %s", "answer") # -- VALID: self.assert_match(parser, "Answer: yes", "answer", True) self.assert_match(parser, "Answer: no", "answer", False) # -- IGNORE-CASE: In parsing, calls type converter function !!! self.assert_match(parser, "Answer: YES", "answer", True) # -- PARSE MISMATCH: self.assert_mismatch(parser, "Answer: __YES__", "answer") self.assert_mismatch(parser, "Answer: yes ", "answer") self.assert_mismatch(parser, "Answer: yes ZZZ", "answer")
def test_parse_with_many_and_unnamed_fields(self): # -- ENSURE: Cardinality.one_or_more.group_count is correct # REQUIRES: ParserExt := parse_type.Parser with group_count support parse_many_numbers = TypeBuilder.with_many(parse_number) parse_many_numbers.name = "Number+" type_dict = build_type_dict([parse_many_numbers, parse_number]) schema = "Numbers: {:Number+} {:Number}" parser = ParserExt(schema, type_dict) # -- CASE: result = parser.parse("Numbers: 1, 2, 3 42") expected = ([1, 2, 3], 42) self.assertIsNotNone(result) self.assertEqual(result.fixed, tuple(expected)) result = parser.parse("Numbers: 3 43") expected = ([ 3 ], 43) self.assertIsNotNone(result) self.assertEqual(result.fixed, tuple(expected))
def test_parse_with_many0_and_unnamed_fields(self): # -- ENSURE: Cardinality.zero_or_more.group_count is correct # REQUIRES: ParserExt := parse_type.Parser with group_count support parse_many0_numbers = TypeBuilder.with_many0(parse_number) parse_many0_numbers.name = "Number*" type_dict = build_type_dict([parse_many0_numbers, parse_number]) schema = "Numbers: {:Number*} {:Number}" parser = ParserExt(schema, type_dict) # -- CASE: Optional numbers are present result = parser.parse("Numbers: 1, 2, 3 42") expected = ([1, 2, 3], 42) self.assertIsNotNone(result) self.assertEqual(result.fixed, tuple(expected)) # -- CASE: Optional numbers are missing := EMPTY-LIST result = parser.parse("Numbers: 43") expected = ([ ], 43) self.assertIsNotNone(result) self.assertEqual(result.fixed, tuple(expected))
def test_parse_with_optional_and_unnamed_fields(self): # -- ENSURE: Cardinality.optional.group_count is correct # REQUIRES: ParserExt := parse_type.Parser with group_count support parse_opt_number = TypeBuilder.with_optional(parse_number) parse_opt_number.name = "Number?" type_dict = build_type_dict([parse_opt_number, parse_number]) schema = "Numbers: {:Number?} {:Number}" parser = ParserExt(schema, type_dict) # -- CASE: Optional number is present result = parser.parse("Numbers: 34 12") expected = (34, 12) self.assertIsNotNone(result) self.assertEqual(result.fixed, tuple(expected)) # -- CASE: Optional number is missing result = parser.parse("Numbers: 12") expected = (None, 12) self.assertIsNotNone(result) self.assertEqual(result.fixed, tuple(expected))
def test_cardinality_field_with_one_or_more(self): # -- SETUP: parse_person = TypeBuilder.make_choice(["Alice", "Bob", "Charly"]) parse_person.name = "Person" # For testing only. extra_types = build_type_dict([parse_person]) schema = "List: {persons:Person+}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.assert_match(parser, "List: Alice", "persons", ["Alice"]) self.assert_match(parser, "List: Bob", "persons", ["Bob"]) self.assert_match(parser, "List: Bob, Alice", "persons", ["Bob", "Alice"]) # -- PARSE MISMATCH: self.assert_mismatch(parser, "List: ", "persons") # Zero items. self.assert_mismatch(parser, "List: BAlice", "persons") # Unknown1. self.assert_mismatch(parser, "List: Boby", "persons") # Unknown2. self.assert_mismatch(parser, "List: Alice,", "persons") # Trailing, self.assert_mismatch(parser, "List: a, b", "persons") # List of...
def test_make_enum_with_dict(self): parse_nword = TypeBuilder.make_enum({"one": 1, "two": 2, "three": 3}) parse_nword.name = "NumberAsWord" extra_types = build_type_dict([ parse_nword ]) schema = "Answer: {number:NumberAsWord}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.ensure_can_parse_all_enum_values(parser, parse_nword, "Answer: %s", "number") # -- VALID: self.assert_match(parser, "Answer: one", "number", 1) self.assert_match(parser, "Answer: two", "number", 2) # -- IGNORE-CASE: In parsing, calls type converter function !!! self.assert_match(parser, "Answer: THREE", "number", 3) # -- PARSE MISMATCH: self.assert_mismatch(parser, "Answer: __one__", "number") self.assert_mismatch(parser, "Answer: one ", "number") self.assert_mismatch(parser, "Answer: one_", "number") self.assert_mismatch(parser, "Answer: one ZZZ", "number")
def test_make_enum_with_dict(self): parse_nword = TypeBuilder.make_enum({"one": 1, "two": 2, "three": 3}) parse_nword.name = "NumberAsWord" extra_types = build_type_dict([parse_nword]) schema = "Answer: {number:NumberAsWord}" parser = parse.Parser(schema, extra_types) # -- PERFORM TESTS: self.ensure_can_parse_all_enum_values(parser, parse_nword, "Answer: %s", "number") # -- VALID: self.assert_match(parser, "Answer: one", "number", 1) self.assert_match(parser, "Answer: two", "number", 2) # -- IGNORE-CASE: In parsing, calls type converter function !!! self.assert_match(parser, "Answer: THREE", "number", 3) # -- PARSE MISMATCH: self.assert_mismatch(parser, "Answer: __one__", "number") self.assert_mismatch(parser, "Answer: one ", "number") self.assert_mismatch(parser, "Answer: one_", "number") self.assert_mismatch(parser, "Answer: one ZZZ", "number")