def test_with_many(self): # -- ALIAS FOR: one_or_more parse_numbers = TypeBuilder.with_many(parse_number) parse_numbers.name = "Numbers" extra_types = self.build_type_dict([ parse_numbers ]) schema = "List: {numbers:Numbers}" 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 ]) # -- PARSE MISMATCH: self.assert_mismatch(parser, "List: ", "numbers") # Zero items.
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_with_many(self): # -- ALIAS FOR: one_or_more parse_numbers = TypeBuilder.with_many(parse_number) self.check_parse_number_with_many(parse_numbers)
find_largest_prime_factor, is_palindromic, find_largest_palindrome, find_factors, find_largest_multiple, \ least_common_multiple, sum_of_squares_for_range, square_of_sums_for_range, difference_of_squares @parse.with_pattern(r'\d+') def parse_number(text): """ turns text into an int to help make feature files nicer to read :param text: str text to parse into an int :return: int parsed text """ return int(text.strip()) parse_numbers = TypeBuilder.with_many(parse_number, listsep=',') register_type(ListInts=parse_numbers) true_false_mapper = { 'True': True, 'False': False } parse_bool = TypeBuilder.make_enum(true_false_mapper) register_type(Boolean=parse_bool) use_step_matcher('parse') @when("I find the multiples of 3 and 5 under {limit:d}") def i_find_multiples_of_3_and_5_under(context, limit):
# @mark.user_defined_types # ------------------------------------------------------------------------ # USER-DEFINED TYPES: # ------------------------------------------------------------------------ from behave import matchers from parse_type import TypeBuilder company_persons = [ "Alice", "Bob", "Charly", "Dodo" ] parse_person = TypeBuilder.make_choice(company_persons) matchers.register_type(Person=parse_person) # -- MANY-TYPE: Persons := list<Person> with list-separator = "and" # parse_persons = TypeBuilder.with_one_or_more(parse_person, listsep="and") parse_persons = TypeBuilder.with_many(parse_person, listsep="and") matchers.register_type(PersonAndMore=parse_persons) # @mark.steps # ---------------------------------------------------------------------------- # STEPS: # ---------------------------------------------------------------------------- from behave import given, when, then # -- MANY-VARIANT 1: Use Cardinality field in parse expression (comma-separated) @when('I meet {persons:Person+}') def step_when_I_meet_persons(context, persons): for person in persons: context.meeting.persons.add(person)
# @mark.user_defined_types # ------------------------------------------------------------------------ # USER-DEFINED TYPES: # ------------------------------------------------------------------------ from behave import matchers from parse_type import TypeBuilder company_persons = ["Alice", "Bob", "Charly", "Dodo"] parse_person = TypeBuilder.make_choice(company_persons) matchers.register_type(Person=parse_person) # -- MANY-TYPE: Persons := list<Person> with list-separator = "and" # parse_persons = TypeBuilder.with_one_or_more(parse_person, listsep="and") parse_persons = TypeBuilder.with_many(parse_person, listsep="and") matchers.register_type(PersonAndMore=parse_persons) # @mark.steps # ---------------------------------------------------------------------------- # STEPS: # ---------------------------------------------------------------------------- from behave import given, when, then # -- MANY-VARIANT 1: Use Cardinality field in parse expression (comma-separated) @when('I meet {persons:Person+}') def step_when_I_meet_persons(context, persons): for person in persons: context.meeting.persons.add(person)
"""New syntax test file""" import re from typing import List, Optional from parse_type import TypeBuilder def parse_string(text) -> str: return str(text) list_str_commas = TypeBuilder.with_many(parse_string, listsep=",") list_str_newlines = TypeBuilder.with_many(parse_string, listsep="\n") def list_from_string(text: str, sep: Optional[str] = None) -> List[str]: return text.split(sep=sep) def clean_escape_sequences(string: str) -> str: reaesc = re.compile(r'\x1b[^m]*m') return reaesc.sub('', string) def remove_prefix(text: str, prefix: str) -> str: if text.startswith(prefix): return text[len(prefix):] return text
isEval = re.match(r'^[`{].*?[`}]$', text) is not None # strip of trailing ` if re.match(r'^`.*?`$', text): text = text[1:-1] # first substitute any {Variable} with context.Variable result = re.sub(r'{(?P<var>\w+)}', r'context.\g<var>', text) if isEval: result = eval(result) return result parse_numbers = TypeBuilder.with_many(parse_number, listsep=",") parse_words = TypeBuilder.with_many(parse_word, listsep=",") parse_hexs = TypeBuilder.with_many(parse_hex, listsep=",") parse_one_hex = TypeBuilder.with_zero_or_one(parse_hex) parse_is_is_not = TypeBuilder.make_choice(["is", "is NOT"]) parse_have_not_have = TypeBuilder.make_choice(["have", "NOT have"]) parse_has_does_not_have = TypeBuilder.make_choice(["has", "does NOT have"]) parse_one_context_variables = TypeBuilder.with_zero_or_one( parse_context_variable) type_dict = { 'd+': parse_numbers, 'w+': parse_words, 'h': parse_one_hex, 'h+': parse_hexs, 'is': parse_is_is_not, 'have': parse_have_not_have,