Commit dd0c4d2a authored by Igor Dejanovic's avatar Igor Dejanovic

Migrating tests to pytest

parent 5a959c36
...@@ -8,37 +8,33 @@ ...@@ -8,37 +8,33 @@
# Copyright: (c) 2014 Igor R. Dejanović <igor DOT dejanovic AT gmail DOT com> # Copyright: (c) 2014 Igor R. Dejanović <igor DOT dejanovic AT gmail DOT com>
# License: MIT License # License: MIT License
####################################################################### #######################################################################
from unittest import TestCase import pytest
from arpeggio import ParserPython, ZeroOrMore, OneOrMore, NonTerminal, Terminal, NoMatch, Combine from arpeggio import ParserPython, ZeroOrMore, OneOrMore, NonTerminal, Terminal, NoMatch, Combine
from arpeggio.peg import ParserPEG from arpeggio.peg import ParserPEG
class TestDecoratorCombine(TestCase): def test_combine_python():
def test_combine_python(self): # This will result in NonTerminal node
def root(): return my_rule(), "."
# This will result in Terminal node
def my_rule(): return Combine(ZeroOrMore("a"), OneOrMore("b"))
# This will result in NonTerminal node parser = ParserPython(root)
def root(): return my_rule(), "."
# This will result in Terminal node
def my_rule(): return Combine(ZeroOrMore("a"), OneOrMore("b"))
parser = ParserPython(root) input1 = "abbb."
input1 = "abbb." # Whitespaces are preserved in lexical rules so the following input
# should not be recognized.
input2 = "a b bb."
# Whitespaces are preserved in lexical rules so the following input ptree1 = parser.parse(input1)
# should not be recognized.
input2 = "a b bb."
ptree1 = parser.parse(input1) with pytest.raises(NoMatch):
ptree2 = parser.parse(input2)
def fail_nm(): assert isinstance(ptree1, NonTerminal)
ptree2 = parser.parse(input2) assert isinstance(ptree1[0], Terminal)
assert ptree1[0].value == "abbb"
self.assertRaises(NoMatch, fail_nm)
self.assertIsInstance(ptree1, NonTerminal)
self.assertIsInstance(ptree1[0], Terminal)
self.assertEqual(ptree1[0].value, "abbb")
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
# License: MIT License # License: MIT License
####################################################################### #######################################################################
import pytest
import os import os
from unittest import TestCase
from arpeggio.export import PMDOTExporter, PTDOTExporter from arpeggio.export import PMDOTExporter, PTDOTExporter
# Grammar # Grammar
...@@ -24,32 +24,30 @@ def expression(): return term, ZeroOrMore(["+", "-"], term) ...@@ -24,32 +24,30 @@ def expression(): return term, ZeroOrMore(["+", "-"], term)
def calc(): return OneOrMore(expression), EOF def calc(): return OneOrMore(expression), EOF
class TestPythonParser(TestCase): @pytest.fixture
def parser():
return ParserPython(calc)
def setUp(self):
"""
Create parser
"""
self.parser = ParserPython(calc)
def test_export_parser_model(self): def test_export_parser_model(parser):
""" """
Testing parser model export Testing parser model export
""" """
PMDOTExporter().exportFile(self.parser.parser_model, PMDOTExporter().exportFile(parser.parser_model,
"test_exporter_parser_model.dot") "test_exporter_parser_model.dot")
self.assertTrue(os.path.exists("test_exporter_parser_model.dot")) assert os.path.exists("test_exporter_parser_model.dot")
def test_export_parse_tree(self): def test_export_parse_tree(parser):
""" """
Testing parse tree export. Testing parse tree export.
""" """
parse_tree = self.parser.parse("-(4-1)*5+(2+4.67)+5.89/(.2+7)") parse_tree = parser.parse("-(4-1)*5+(2+4.67)+5.89/(.2+7)")
PTDOTExporter().exportFile(parse_tree, PTDOTExporter().exportFile(parse_tree,
"test_exporter_parse_tree.dot") "test_exporter_parse_tree.dot")
assert os.path.exists("test_exporter_parse_tree.dot")
self.assertTrue(os.path.exists("test_exporter_parse_tree.dot"))
...@@ -7,123 +7,138 @@ ...@@ -7,123 +7,138 @@
# License: MIT License # License: MIT License
####################################################################### #######################################################################
from unittest import TestCase import pytest
from arpeggio import ParserPython, ZeroOrMore, OneOrMore, NoMatch, EOF, Optional, And, Not from arpeggio import ParserPython, ZeroOrMore, OneOrMore, NoMatch, EOF, Optional, And, Not
from arpeggio import RegExMatch as _ from arpeggio import RegExMatch as _
class TestParsingExpression(TestCase): def test_sequence():
def test_sequence(self): def grammar(): return ("a", "b", "c")
def grammar(): return ("a", "b", "c") parser = ParserPython(grammar)
parser = ParserPython(grammar) parsed = parser.parse("a b c")
parsed = parser.parse("a b c") assert str(parsed) == "a | b | c"
assert repr(parsed) == "[ 'a' [0], 'b' [2], 'c' [4] ]"
self.assertEqual(str(parsed), "a | b | c") def test_ordered_choice():
self.assertEqual(repr(parsed), "[ 'a' [0], 'b' [2], 'c' [4] ]")
def test_ordered_choice(self): def grammar(): return ["a", "b", "c"], EOF
def grammar(): return ["a", "b", "c"], EOF parser = ParserPython(grammar)
parser = ParserPython(grammar) parsed = parser.parse("b")
parsed = parser.parse("b") assert str(parsed) == "b | "
assert repr(parsed) == "[ 'b' [0], EOF [1] ]"
self.assertEqual(str(parsed), "b | ") parsed = parser.parse("c")
self.assertEqual(repr(parsed), "[ 'b' [0], EOF [1] ]") assert str(parsed) == "c | "
assert repr(parsed) == "[ 'c' [0], EOF [1] ]"
parsed = parser.parse("c") with pytest.raises(NoMatch):
self.assertEqual(str(parsed), "c | ") parser.parse("ab")
self.assertEqual(repr(parsed), "[ 'c' [0], EOF [1] ]")
self.assertRaises(NoMatch, lambda: parser.parse("ab")) with pytest.raises(NoMatch):
self.assertRaises(NoMatch, lambda: parser.parse("bb")) parser.parse("bb")
def test_zero_or_more(self): def test_zero_or_more():
def grammar(): return ZeroOrMore("a"), EOF def grammar(): return ZeroOrMore("a"), EOF
parser = ParserPython(grammar) parser = ParserPython(grammar)
parsed = parser.parse("aaaaaaa") parsed = parser.parse("aaaaaaa")
self.assertEqual(str(parsed), "a | a | a | a | a | a | a | ") assert str(parsed) == "a | a | a | a | a | a | a | "
self.assertEqual(repr(parsed), "[ 'a' [0], 'a' [1], 'a' [2], 'a' [3], 'a' [4], 'a' [5], 'a' [6], EOF [7] ]") assert repr(parsed) == "[ 'a' [0], 'a' [1], 'a' [2], 'a' [3], 'a' [4], 'a' [5], 'a' [6], EOF [7] ]"
parsed = parser.parse("") parsed = parser.parse("")
self.assertEqual(str(parsed), "") assert str(parsed) == ""
self.assertEqual(repr(parsed), "[ EOF [0] ]") assert repr(parsed) == "[ EOF [0] ]"
self.assertRaises(NoMatch, lambda: parser.parse("bbb")) with pytest.raises(NoMatch):
parser.parse("bbb")
def test_one_or_more(self): def test_one_or_more():
def grammar(): return OneOrMore("a") def grammar(): return OneOrMore("a")
parser = ParserPython(grammar) parser = ParserPython(grammar)
parsed = parser.parse("aaaaaaa") parsed = parser.parse("aaaaaaa")
self.assertEqual(str(parsed), "a | a | a | a | a | a | a") assert str(parsed) == "a | a | a | a | a | a | a"
self.assertEqual(repr(parsed), "[ 'a' [0], 'a' [1], 'a' [2], 'a' [3], 'a' [4], 'a' [5], 'a' [6] ]") assert repr(parsed) == "[ 'a' [0], 'a' [1], 'a' [2], 'a' [3], 'a' [4], 'a' [5], 'a' [6] ]"
self.assertRaises(NoMatch, lambda: parser.parse(""))
self.assertRaises(NoMatch, lambda: parser.parse("bbb"))
def test_optional(self): with pytest.raises(NoMatch):
parser.parse("")
def grammar(): return Optional("a"), "b", EOF with pytest.raises(NoMatch):
parser.parse("bbb")
parser = ParserPython(grammar) def test_optional():
parsed = parser.parse("ab") def grammar(): return Optional("a"), "b", EOF
self.assertEqual(str(parsed), "a | b | ") parser = ParserPython(grammar)
self.assertEqual(repr(parsed), "[ 'a' [0], 'b' [1], EOF [2] ]")
parsed = parser.parse("b") parsed = parser.parse("ab")
self.assertEqual(str(parsed), "b | ") assert str(parsed) == "a | b | "
self.assertEqual(repr(parsed), "[ 'b' [0], EOF [1] ]") assert repr(parsed) == "[ 'a' [0], 'b' [1], EOF [2] ]"
self.assertRaises(NoMatch, lambda: parser.parse("aab")) parsed = parser.parse("b")
self.assertRaises(NoMatch, lambda: parser.parse(""))
assert str(parsed) == "b | "
assert repr(parsed) == "[ 'b' [0], EOF [1] ]"
# Syntax predicates with pytest.raises(NoMatch):
parser.parse("aab")
def test_and(self): with pytest.raises(NoMatch):
parser.parse("")
def grammar(): return "a", And("b"), ["c", "b"], EOF
parser = ParserPython(grammar) # Syntax predicates
parsed = parser.parse("ab") def test_and():
self.assertEqual(str(parsed), "a | b | ")
self.assertEqual(repr(parsed), "[ 'a' [0], 'b' [1], EOF [2] ]")
# 'And' will try to match 'b' and fail so 'c' will never get matched def grammar(): return "a", And("b"), ["c", "b"], EOF
self.assertRaises(NoMatch, lambda: parser.parse("ac"))
# 'And' will not consume 'b' from the input so second 'b' will never match
self.assertRaises(NoMatch, lambda: parser.parse("abb"))
def test_not(self): parser = ParserPython(grammar)
def grammar(): return "a", Not("b"), ["b", "c"], EOF parsed = parser.parse("ab")
assert str(parsed) == "a | b | "
assert repr(parsed) == "[ 'a' [0], 'b' [1], EOF [2] ]"
parser = ParserPython(grammar) # 'And' will try to match 'b' and fail so 'c' will never get matched
with pytest.raises(NoMatch):
parser.parse("ac")
parsed = parser.parse("ac") # 'And' will not consume 'b' from the input so second 'b' will never match
with pytest.raises(NoMatch):
parser.parse("abb")
self.assertEqual(str(parsed), "a | c | ") def test_not():
self.assertEqual(repr(parsed), "[ 'a' [0], 'c' [1], EOF [2] ]")
# Not will will fail on 'b' def grammar(): return "a", Not("b"), ["b", "c"], EOF
self.assertRaises(NoMatch, lambda: parser.parse("ab"))
# And will not consume 'c' from the input so 'b' will never match parser = ParserPython(grammar)
self.assertRaises(NoMatch, lambda: parser.parse("acb"))
parsed = parser.parse("ac")
assert str(parsed) == "a | c | "
assert repr(parsed) == "[ 'a' [0], 'c' [1], EOF [2] ]"
# Not will will fail on 'b'
with pytest.raises(NoMatch):
parser.parse("ab")
# And will not consume 'c' from the input so 'b' will never match
with pytest.raises(NoMatch):
parser.parse("acb")
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# License: MIT License # License: MIT License
####################################################################### #######################################################################
from unittest import TestCase import pytest
from arpeggio import Sequence, NonTerminal from arpeggio import Sequence, NonTerminal
from arpeggio.peg import ParserPEG from arpeggio.peg import ParserPEG
...@@ -20,33 +20,32 @@ grammar = ''' ...@@ -20,33 +20,32 @@ grammar = '''
calc <- expression+ EOF; calc <- expression+ EOF;
''' '''
class TestPEGParser(TestCase): def test_construct_parser():
def test_construct_parser(self): parser = ParserPEG(grammar, 'calc')
parser = ParserPEG(grammar, 'calc') assert parser.parser_model.rule == 'calc'
assert isinstance(parser.parser_model, Sequence)
assert parser.parser_model.nodes[0].name == 'OneOrMore'
self.assertEqual(parser.parser_model.rule ,'calc') def test_parse_input():
self.assertTrue(isinstance(parser.parser_model, Sequence))
self.assertEqual(parser.parser_model.nodes[0].name ,'OneOrMore')
def test_parse_input(self): parser = ParserPEG(grammar, 'calc')
input = "4+5*7/3.45*-45*(2.56+32)/-56*(2-1.34)"
result = parser.parse(input)
parser = ParserPEG(grammar, 'calc') assert isinstance(result, NonTerminal)
input = "4+5*7/3.45*-45*(2.56+32)/-56*(2-1.34)" assert str(result) == "4 | + | 5 | * | 7 | / | 3.45 | * | - | 45 | * | ( | 2.56 | + | 32 | ) | / | - | 56 | * | ( | 2 | - | 1.34 | ) | "
result = parser.parse(input) assert repr(result) == "[ [ [ [ number '4' [0] ] ], '+' [1], [ [ number '5' [2] ], '*' [3], [ number '7' [4] ], '/' [5], [ number '3.45' [6] ], '*' [10], [ '-' [11], number '45' [12] ], '*' [14], [ '(' [15], [ [ [ number '2.56' [16] ] ], '+' [20], [ [ number '32' [21] ] ] ], ')' [23] ], '/' [24], [ '-' [25], number '56' [26] ], '*' [28], [ '(' [29], [ [ [ number '2' [30] ] ], '-' [31], [ [ number '1.34' [32] ] ] ], ')' [36] ] ] ], EOF [37] ]"
self.assertTrue(isinstance(result, NonTerminal)) def test_reduce_tree():
self.assertEqual(str(result), "4 | + | 5 | * | 7 | / | 3.45 | * | - | 45 | * | ( | 2.56 | + | 32 | ) | / | - | 56 | * | ( | 2 | - | 1.34 | ) | ")
self.assertEqual(repr(result),"[ [ [ [ number '4' [0] ] ], '+' [1], [ [ number '5' [2] ], '*' [3], [ number '7' [4] ], '/' [5], [ number '3.45' [6] ], '*' [10], [ '-' [11], number '45' [12] ], '*' [14], [ '(' [15], [ [ [ number '2.56' [16] ] ], '+' [20], [ [ number '32' [21] ] ] ], ')' [23] ], '/' [24], [ '-' [25], number '56' [26] ], '*' [28], [ '(' [29], [ [ [ number '2' [30] ] ], '-' [31], [ [ number '1.34' [32] ] ] ], ')' [36] ] ] ], EOF [37] ]")
def test_reduce_tree(self): parser = ParserPEG(grammar, 'calc', reduce_tree=True)
input = "4+5*7/3.45*-45*(2.56+32)/-56*(2-1.34)"
result = parser.parse(input)
parser = ParserPEG(grammar, 'calc', reduce_tree=True) assert isinstance(result, NonTerminal)
input = "4+5*7/3.45*-45*(2.56+32)/-56*(2-1.34)"
result = parser.parse(input)
self.assertTrue(isinstance(result, NonTerminal)) assert str(result) == "4 | + | 5 | * | 7 | / | 3.45 | * | - | 45 | * | ( | 2.56 | + | 32 | ) | / | - | 56 | * | ( | 2 | - | 1.34 | ) | "
assert repr(result) == "[ [ number '4' [0], '+' [1], [ number '5' [2], '*' [3], number '7' [4], '/' [5], number '3.45' [6], '*' [10], [ '-' [11], number '45' [12] ], '*' [14], [ '(' [15], [ number '2.56' [16], '+' [20], number '32' [21] ], ')' [23] ], '/' [24], [ '-' [25], number '56' [26] ], '*' [28], [ '(' [29], [ number '2' [30], '-' [31], number '1.34' [32] ], ')' [36] ] ] ], EOF [37] ]"
self.assertEqual(str(result),"4 | + | 5 | * | 7 | / | 3.45 | * | - | 45 | * | ( | 2.56 | + | 32 | ) | / | - | 56 | * | ( | 2 | - | 1.34 | ) | ")
self.assertEqual(repr(result), "[ [ number '4' [0], '+' [1], [ number '5' [2], '*' [3], number '7' [4], '/' [5], number '3.45' [6], '*' [10], [ '-' [11], number '45' [12] ], '*' [14], [ '(' [15], [ number '2.56' [16], '+' [20], number '32' [21] ], ')' [23] ], '/' [24], [ '-' [25], number '56' [26] ], '*' [28], [ '(' [29], [ number '2' [30], '-' [31], number '1.34' [32] ], ')' [36] ] ] ], EOF [37] ]")
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# License: MIT License # License: MIT License
####################################################################### #######################################################################
from unittest import TestCase import pytest
# Grammar # Grammar
from arpeggio import Optional, ZeroOrMore, OneOrMore, EOF, ParserPython,\ from arpeggio import Optional, ZeroOrMore, OneOrMore, EOF, ParserPython,\
...@@ -23,36 +23,34 @@ def expression(): return term, ZeroOrMore(["+", "-"], term) ...@@ -23,36 +23,34 @@ def expression(): return term, ZeroOrMore(["+", "-"], term)
def calc(): return OneOrMore(expression), EOF def calc(): return OneOrMore(expression), EOF
class TestPythonParser(TestCase): def test_pp_construction():
'''
Tests parser construction from python internal DSL description.
'''
parser = ParserPython(calc)
def test_pp_construction(self): assert parser.parser_model.rule == 'calc'
''' assert isinstance(parser.parser_model, Sequence)
Tests parser construction from python internal DSL description. assert parser.parser_model.nodes[0].desc == 'OneOrMore'
'''
parser = ParserPython(calc)
self.assertEqual(parser.parser_model.rule ,'calc') def test_parse_input():
self.assertTrue(isinstance(parser.parser_model, Sequence))
self.assertEqual(parser.parser_model.nodes[0].desc ,'OneOrMore')
def test_parse_input(self): parser = ParserPython(calc)
input = "4+5*7/3.45*-45*(2.56+32)/-56*(2-1.34)"
result = parser.parse(input)
parser = ParserPython(calc) assert isinstance(result, NonTerminal)
input = "4+5*7/3.45*-45*(2.56+32)/-56*(2-1.34)" assert str(result) == "4 | + | 5 | * | 7 | / | 3.45 | * | - | 45 | * | ( | 2.56 | + | 32 | ) | / | - | 56 | * | ( | 2 | - | 1.34 | ) | "
result = parser.parse(input) assert repr(result) == "[ [ [ [ number '4' [0] ] ], '+' [1], [ [ number '5' [2] ], '*' [3], [ number '7' [4] ], '/' [5], [ number '3.45' [6] ], '*' [10], [ '-' [11], number '45' [12] ], '*' [14], [ '(' [15], [ [ [ number '2.56' [16] ] ], '+' [20], [ [ number '32' [21] ] ] ], ')' [23] ], '/' [24], [ '-' [25], number '56' [26] ], '*' [28], [ '(' [29], [ [ [ number '2' [30] ] ], '-' [31], [ [ number '1.34' [32] ] ] ], ')' [36] ] ] ], EOF [37] ]"
self.assertTrue(isinstance(result, NonTerminal)) def test_reduce_tree():
self.assertEqual(str(result), "4 | + | 5 | * | 7 | / | 3.45 | * | - | 45 | * | ( | 2.56 | + | 32 | ) | / | - | 56 | * | ( | 2 | - | 1.34 | ) | ")
self.assertEqual(repr(result), "[ [ [ [ number '4' [0] ] ], '+' [1], [ [ number '5' [2] ], '*' [3], [ number '7' [4] ], '/' [5], [ number '3.45' [6] ], '*' [10], [ '-' [11], number '45' [12] ], '*' [14], [ '(' [15], [ [ [ number '2.56' [16] ] ], '+' [20], [ [ number '32' [21] ] ] ], ')' [23] ], '/' [24], [ '-' [25], number '56' [26] ], '*' [28], [ '(' [29], [ [ [ number '2' [30] ] ], '-' [31], [ [ number '1.34' [32] ] ] ], ')' [36] ] ] ], EOF [37] ]")
def test_reduce_tree(self): parser = ParserPython(calc, reduce_tree=True)
input = "4+5*7/3.45*-45*(2.56+32)/-56*(2-1.34)"
result = parser.parse(input)
parser = ParserPython(calc, reduce_tree=True) assert isinstance(result, NonTerminal)
input = "4+5*7/3.45*-45*(2.56+32)/-56*(2-1.34)"
result = parser.parse(input)
self.assertTrue(isinstance(result, NonTerminal)) assert str(result) == "4 | + | 5 | * | 7 | / | 3.45 | * | - | 45 | * | ( | 2.56 | + | 32 | ) | / | - | 56 | * | ( | 2 | - | 1.34 | ) | "
assert repr(result) == "[ [ number '4' [0], '+' [1], [ number '5' [2], '*' [3], number '7' [4], '/' [5], number '3.45' [6], '*' [10], [ '-' [11], number '45' [12] ], '*' [14], [ '(' [15], [ number '2.56' [16], '+' [20], number '32' [21] ], ')' [23] ], '/' [24], [ '-' [25], number '56' [26] ], '*' [28], [ '(' [29], [ number '2' [30], '-' [31], number '1.34' [32] ], ')' [36] ] ] ], EOF [37] ]"
self.assertEqual(str(result),"4 | + | 5 | * | 7 | / | 3.45 | * | - | 45 | * | ( | 2.56 | + | 32 | ) | / | - | 56 | * | ( | 2 | - | 1.34 | ) | ")
self.assertEqual(repr(result), "[ [ number '4' [0], '+' [1], [ number '5' [2], '*' [3], number '7' [4], '/' [5], number '3.45' [6], '*' [10], [ '-' [11], number '45' [12] ], '*' [14], [ '(' [15], [ number '2.56' [16], '+' [20], number '32' [21] ], ')' [23] ], '/' [24], [ '-' [25], number '56' [26] ], '*' [28], [ '(' [29], [ number '2' [30], '-' [31], number '1.34' [32] ], ')' [36] ] ] ], EOF [37] ]")
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# License: MIT License # License: MIT License
####################################################################### #######################################################################
from unittest import TestCase import pytest
# Grammar # Grammar
from arpeggio import ParserPython, ZeroOrMore from arpeggio import ParserPython, ZeroOrMore
...@@ -18,16 +18,13 @@ def bar(): return "c" ...@@ -18,16 +18,13 @@ def bar(): return "c"
def baz(): return "d" def baz(): return "d"
def test_lookup_single():
class TestPEGParser(TestCase): parser = ParserPython(foo)
def test_lookup_single(self): result = parser.parse("a c b d")
parser = ParserPython(foo) assert hasattr(result, "bar")
assert hasattr(result, "baz")
result = parser.parse("a c b d") assert not hasattr(result, "unexisting")
self.assertTrue(hasattr(result, "bar"))
self.assertTrue(hasattr(result, "baz"))
self.assertTrue(not hasattr(result, "unexisting"))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment