def test_many_disjunctions_form_one_object(self): rule = easyparse.PatternRule('0') | \ easyparse.PatternRule('1') | \ easyparse.PatternRule('2') | \ easyparse.PatternRule('3') self.assertEqual(4, len(rule.rules)) self.assertEqual((True, '2'), rule.parse('2'))
def test_many_conjunctions_form_one_object(self): rule = easyparse.PatternRule('0') + \ easyparse.PatternRule('1') + \ easyparse.PatternRule('2') + \ easyparse.PatternRule('3') self.assertEqual(4, len(rule.rules)) self.assertEqual((True, ['0', '1', '2', '3']), rule.parse('0123'))
def test_join(self): rule = easyparse.join(easyparse.PatternRule('a'), easyparse.PatternRule('q', ignore_output=True)) self.assertEqual((True, easyparse.Ignored), rule.parse('')) self.assertEqual((True, ['a']), rule.parse('a')) self.assertEqual((True, ['a', 'a']), rule.parse('aqa')) self.assertEqual((True, ['a']), rule.parse('aa'))
def test_repeat_range(self): rule = easyparse.repeat(easyparse.PatternRule('ab'), 1, 2) + easyparse.PatternRule('c') self.assertEqual((True, ['ab', 'c']), rule.parse('abc')) self.assertEqual((True, ['ab', 'ab', 'c']), rule.parse('ababc')) self.assertEqual(False, rule.parse('c')[0]) self.assertEqual(False, rule.parse('abababc')[0])
def test_disjunction_rule_failure(self): rule = easyparse.DisjunctionRule(easyparse.PatternRule('a'), easyparse.PatternRule('b')) ok, backtrace = rule.parse('c') a_backtrace = ('', 'Pattern', 'a') b_backtrace = ('', 'Pattern', 'b') inner_backtraces = [a_backtrace, b_backtrace] self.assertFalse(ok) self.assertEqual(('', 'Disjunction', inner_backtraces), backtrace)
def test_print_backtrace_conjunction(self): rule = easyparse.ConjunctionRule(easyparse.PatternRule('a'), easyparse.PatternRule('0')) ok, backtrace = rule.parse('a1') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = '\n'.join([ "<Unnamed>: Conjunction: Failed", " <Unnamed>: Pattern: Matched 'a'", " <Unnamed>: Pattern: Failed to match '0'\n" ]) self.assertEqual(exp_backtrace_string, backtrace_string)
def test_conjunction_rule_failure(self): rule = easyparse.ConjunctionRule(easyparse.PatternRule('a'), easyparse.PatternRule('b')) ok, backtrace = rule.parse('aa') self.assertFalse(ok) self.assertEqual(('', 'Conjunction', ([('', 'Pattern', 'a')], ('', 'Pattern', 'b'))), backtrace) ok, backtrace = rule.parse('ba') self.assertFalse(ok) self.assertEqual(('', 'Conjunction', ([], ('', 'Pattern', 'a'))), backtrace)
def test_many_allow_whitespace(self): rule = easyparse.many_ws(easyparse.PatternRule('a')) self.assertEqual((True, easyparse.Ignored), rule.parse('')) for i in range(1, 5): self.assertEqual((True, ['a'] * i), rule.parse('a' * i)) for i in range(1, 5): self.assertEqual((True, ['a'] * i), rule.parse('a ' * i))
def test_print_backtrace_pattern(self): rule = easyparse.PatternRule('a') ok, backtrace = rule.parse('b') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = \ """<Unnamed>: Pattern: Failed to match 'a'\n""" self.assertEqual(exp_backtrace_string, backtrace_string)
def test_rule_decorator(self): @easyparse.parse_rule def mock_rule(r): return r + r rule0 = easyparse.PatternRule('9') rule1 = mock_rule(rule0) self.assertEqual((True, ['9', '9']), rule1.parse('99'))
def test_named_rule_backtrace(self): """Test that the generic rule name is replaced by a specific one when the rule is part of a Grammar object.""" g = easyparse.Grammar() g.ident = easyparse.PatternRule('a') ok, backtrace = g.ident.parse('b') self.assertFalse(ok) self.assertEqual(('ident', 'Pattern', 'a'), backtrace)
def test_print_backtrace_named_transformation(self): g = easyparse.Grammar() g.num = easyparse.PatternRule('a') > int ok, backtrace = g.num.parse('a') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = \ "num: Transformation: Failed to transform 'a'\n" self.assertEqual(exp_backtrace_string, backtrace_string)
def test_print_backtrace_named_pattern(self): g = easyparse.Grammar() g.ident = easyparse.PatternRule('a') ok, backtrace = g.ident.parse('b') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = \ """ident: Pattern: Failed to match 'a'\n""" self.assertEqual(exp_backtrace_string, backtrace_string)
def test_print_backtrace_transformation(self): """Test the backtrace for when the transformation itself fails.""" rule = easyparse.TransformationRule(easyparse.PatternRule('a'), int) ok, backtrace = rule.parse('a') self.assertFalse(ok) backtrace_string = self._print_backtrace_to_string(backtrace) exp_backtrace_string = \ "<Unnamed>: Transformation: Failed to transform 'a'\n" self.assertEqual(exp_backtrace_string, backtrace_string)
def test_two_conjunctions_not_ignoring_whitespace(self): # Use parens to test different groupings rule0 = easyparse.PatternRule('a') ^ (easyparse.PatternRule('b') ^ easyparse.PatternRule('c')) rule1 = (easyparse.PatternRule('a') ^ easyparse.PatternRule('b')) ^ easyparse.PatternRule('c') self.assertEqual((True, ['a', 'b', 'c']), rule0.parse('abc')) self.assertEqual((True, ['a', 'b', 'c']), rule1.parse('abc')) for bad_pattern in ['a bc', 'ab c', 'a b c']: self.assertEqual(False, rule0.parse(bad_pattern)[0]) self.assertEqual(False, rule1.parse(bad_pattern)[0])
def test_two_conjunctions_first_ignoring_whitespace(self): rule0 = easyparse.PatternRule('a') ^ (easyparse.PatternRule('b') + easyparse.PatternRule('c')) rule1 = (easyparse.PatternRule('a') ^ easyparse.PatternRule('b')) + easyparse.PatternRule('c') for good_pattern in ['abc', 'ab c']: self.assertEqual((True, ['a', 'b', 'c']), rule0.parse(good_pattern), msg=good_pattern) self.assertEqual((True, ['a', 'b', 'c']), rule1.parse(good_pattern), msg=good_pattern) for bad_pattern in ['a bc', 'a b c']: self.assertEqual(False, rule0.parse(bad_pattern)[0]) self.assertEqual(False, rule1.parse(bad_pattern)[0])
def test_match_conjunctions_and_disjunctions(self): rule = easyparse.PatternRule('0') + easyparse.PatternRule('1') | \ easyparse.PatternRule('1') self.assertEqual((True, ['0', '1']), rule.parse('01')) self.assertEqual((True, '1'), rule.parse('1')) self.assertFalse(rule.parse('00')[0])
def test_optional(self): rule = easyparse.optional(easyparse.PatternRule('0')) self.assertEqual((True, '0'), rule.parse('0')) self.assertEqual((True, easyparse.Ignored), rule.parse(''))
def test_match_ignores_preceding_whitespace_but_matches_pattern_space( self): rule = easyparse.PatternRule(' ') self.assertEqual((True, ' '), rule.parse('\t ', allow_whitespace=True))
def test_conjunction_not_ignoring_whitespace(self): rule = easyparse.PatternRule('a') ^ \ easyparse.PatternRule('b') self.assertEqual((True, ['a', 'b']), rule.parse('ab')) self.assertEqual(False, rule.parse('a b')[0])
def test_whitespace_matches_itself(self): rule = easyparse.PatternRule('\t') itr = '\t00' self.assertEqual((True, '\t'), rule.parse(itr))
def test_many_disjunctions_are_right_branching(self): rule = easyparse.PatternRule('0') | \ (easyparse.PatternRule('1') | easyparse.PatternRule('2')) self.assertEqual(3, len(rule.rules)) self.assertEqual((True, '1'), rule.parse('1'))
def test_match_shorter_than_pattern(self): rule = easyparse.PatternRule('000') self.assertFalse(rule.parse('0')[0])
def test_match_with_significant_whitespace(self): rule = easyparse.PatternRule('0') self.assertEqual(False, rule.parse(' 0')[0])
def test_match_disjunction_rule(self): rule = easyparse.PatternRule('0') | easyparse.PatternRule('1') self.assertEqual((True, '0'), rule.parse('0')) self.assertEqual((True, '1'), rule.parse('1')) self.assertFalse(rule.parse('2')[0])
def test_match_wrong_rule_with_whitespace(self): rule = easyparse.PatternRule('0') self.assertEqual(False, rule.parse(' 1')[0])
def test_match_with_same_whitespace_preceding(self): rule = easyparse.PatternRule(' 0') self.assertEqual((True, ' 0'), rule.parse(' 0', allow_whitespace=True))
def test_match_with_injected_whitespace(self): rule = easyparse.PatternRule('01') self.assertEqual(False, rule.parse('0 1')[0])
def test_match_multiple_conjunction_rules(self): rule = easyparse.PatternRule('0') + easyparse.PatternRule('1') +\ easyparse.PatternRule('2') self.assertEqual((True, ['0', '1', '2']), rule.parse('012')) self.assertFalse(rule.parse('0012')[0])
def test_transformation_function(self): rule = easyparse.PatternRule('0') > int self.assertEqual((True, 0), rule.parse('0')) self.assertNotEqual((True, '0'), rule.parse('0'))