erikrose / parsimonious

The fastest pure-Python PEG parser I can muster
MIT License
1.81k stars 127 forks source link

Document grammar testing strategy #138

Closed MswPaulDSmith closed 6 years ago

MswPaulDSmith commented 6 years ago

Grammars can get quite complex and some guidance on how to test them would be useful.

My initial thoughts are that perhaps grammars could be combined such that the actual Grammar is

complete = elementA / elementB...

but then we define some test nodes such as

test_elementA = elementA / xxx

(A second element, xxx, seems to be needed to cause visitation). Then the idea would be to create a visit_test_elementA() visitor node to allow us to catch and validate the elementA part of a test parse.

erikrose commented 6 years ago

Grammars are dict-like, so you can easily take them apart and test individual rules. In fact, that's what I do in Parsimonious itself! For example, in test_grammar.py...

    def test_regex(self):
        text = '~"[a-zA-Z_][a-zA-Z_0-9]*"LI'
        regex = rule_grammar['regex']
        eq_(rule_grammar['regex'].parse(text),
            Node(regex, text, 0, len(text), children=[
                 Node(Literal('~'), text, 0, 1),
                 Node(rule_grammar['spaceless_literal'], text, 1, 25, children=[
                     Node(rule_grammar['spaceless_literal'].members[0], text, 1, 25)]),
                 Node(regex.members[2], text, 25, 27),
                 Node(rule_grammar['_'], text, 27, 27)]))

Let me know if that doesn't answer your question.

MswPaulDSmith commented 6 years ago

Thanks - this sounds exactly like I want.