def test_parser__can_parse_normal_fields(self): existing_types = dict(Number=parse_number) schema = "Number: {number:Number}" parser = Parser(schema, existing_types) self.assert_match(parser, "Number: 42", "number", 42) self.assert_match(parser, "Number: 123", "number", 123) self.assert_mismatch(parser, "Number: ") self.assert_mismatch(parser, "Number: XXX") self.assert_mismatch(parser, "Number: -123")
def __call__(self, step_text, step_impl): try: parser = Parser(step_impl.pattern, parsetype_registry.types) except ValueError: raise Exception("Cannot create parser") # raise StepPatternError(step_impl.pattern, func.__name__, e) match = parser.search(step_text, evaluate_result=False) if match: return self.Match(match), len(match.match.group()) return None, 0
def test_parse_step_arguments_object(parse_pattern, string, expected_args, expected_kwargs): """ Test functionality of ParseStepArguments object """ # given parser = Parser(parse_pattern) match = parser.search(string, evaluate_result=False) args = matcher.ParseStepArguments(match) # when actual_args, actual_kwargs = args.evaluate() # then assert actual_args == expected_args assert actual_kwargs == expected_kwargs
def match_step(sentence, steps): """ Tries to find a match from the given sentence with the given steps :param string sentence: the step sentence to match :param dict steps: the available registered steps :returns: the arguments and the func which were matched :rtype: tuple """ potentional_matches = [] for pattern, func in steps.items(): if isinstance(pattern, re._pattern_type): # pylint: disable=protected-access match = pattern.search(sentence) argument_match = RegexStepArguments(match) if match: longest_group = get_longest_group(match) else: longest_group = 0 else: try: parser = Parser(pattern, CustomTypeRegistry().custom_types) except ValueError as e: raise StepPatternError(pattern, func.__name__, e) match = parser.search(sentence, evaluate_result=False) argument_match = ParseStepArguments(match) if match: longest_group = get_longest_group(match.match) else: longest_group = 0 if match: step_match = StepMatch(argument_match=argument_match, func=func) if len(sentence) == longest_group: # if perfect match can be made we return it no # matter of the other potentional matches return step_match distance_to_perfect = abs(len(sentence) - longest_group) potentional_matches.append((step_match, distance_to_perfect)) if potentional_matches: # get best match return min(potentional_matches, key=lambda x: x[1])[0] return None
def test_parser__can_parse_cardinality_field_optional(self): # -- CARDINALITY: 0..1 = zero_or_one = optional existing_types = dict(Number=parse_number) self.assertFalse("Number?" in existing_types) # -- ENSURE: Missing type variant is created. schema = "OptionalNumber: {number:Number?}" parser = Parser(schema, existing_types) self.assertTrue("Number?" in existing_types) # -- ENSURE: Newly created type variant is usable. self.assert_match(parser, "OptionalNumber: 42", "number", 42) self.assert_match(parser, "OptionalNumber: 123", "number", 123) self.assert_match(parser, "OptionalNumber: ", "number", None) self.assert_mismatch(parser, "OptionalNumber:") self.assert_mismatch(parser, "OptionalNumber: XXX") self.assert_mismatch(parser, "OptionalNumber: -123")
def test_parser__can_parse_cardinality_field_many0(self): # -- CARDINALITY: 0..* = zero_or_more = many0 existing_types = dict(Number=parse_number) self.assertFalse("Number*" in existing_types) # -- ENSURE: Missing type variant is created. schema = "List0: {numbers:Number*}" parser = Parser(schema, existing_types) self.assertTrue("Number*" in existing_types) # -- ENSURE: Newly created type variant is usable. self.assert_match(parser, "List0: 42", "numbers", [42]) self.assert_match(parser, "List0: 1, 2, 3", "numbers", [1, 2, 3]) self.assert_match(parser, "List0: ", "numbers", []) self.assert_mismatch(parser, "List0:") self.assert_mismatch(parser, "List0: XXX") self.assert_mismatch(parser, "List0: -123")
def test_parser__can_parse_cardinality_field_many_with_own_type_builder( self): # -- CARDINALITY: 1..* = one_or_more = many class MyCardinalityFieldTypeBuilder(CardinalityFieldTypeBuilder): listsep = ';' type_builder = MyCardinalityFieldTypeBuilder existing_types = dict(Number=parse_number) self.assertFalse("Number+" in existing_types) # -- ENSURE: Missing type variant is created. schema = "List: {numbers:Number+}" parser = Parser(schema, existing_types, type_builder) self.assertTrue("Number+" in existing_types) # -- ENSURE: Newly created type variant is usable. # NOTE: Use other list separator. self.assert_match(parser, "List: 42", "numbers", [42]) self.assert_match(parser, "List: 1; 2; 3", "numbers", [1, 2, 3]) self.assert_match(parser, "List: 4;5;6", "numbers", [4, 5, 6]) self.assert_mismatch(parser, "List: ") self.assert_mismatch(parser, "List:") self.assert_mismatch(parser, "List: XXX") self.assert_mismatch(parser, "List: -123")