import unittest, pprint
from simpleparse.parser import Parser
from simpleparse.stt.TextTools import TextTools
from genericvalues import NullResult,AnyInt
class ParserGenerationTests(unittest.TestCase):
def doBasicTest(self, definition, parserName, testValue, expected, ):
result = Parser( definition).parse( testValue, parserName )
assert result == expected, '''\nexpected:%s\n got:%s\n'''%( expected, result )
def testGenNegRange1( self ):
self.doBasicTest(
'''s := - something *
<something> := [ab]''',
's',
'mmmab',
(1,[],3)
)
def testGenNegRange2( self ):
self.doBasicTest(
'''s := - something
<something> := [ab]''',
's',
'mmmab',
(1,[],1)
)
def testGenNegLit1( self ):
self.doBasicTest(
'''s := - something *
<something> := "a"''',
's',
'mmmab',
(1,[],3)
)
def testGenPosReptOpt1( self ):
self.doBasicTest(
'''s := something *
something := "a" ''',
's',
'aammmab',
(1,[("something",0,1,NullResult),("something",1,2,NullResult)],2)
)
def testGenPosReptOpt2( self ):
self.doBasicTest(
'''s := something *
something := "a" ''',
's',
'mmmab',
(1,[],0)
)
def testGenPosRept1( self ):
self.doBasicTest(
'''s := something +
something := "a" ''',
's',
'mmmab',
(0,[],AnyInt)
)
def testLookaheadPositive( self ):
self.doBasicTest(
'''s := ?"b"
''',
's',
'bbbba',
(1,[
],0)
)
def testLookaheadNeg( self ):
self.doBasicTest(
'''s := ?-"b"
''',
's',
'bbbba',
(0,[
],AnyInt)
)
def testLookaheadNeg2( self ):
self.doBasicTest(
'''s := ?-"b"?
''',
's',
'bbbba',
(1,[
],0)
)
def testLookaheadNeg3( self ):
self.doBasicTest(
'''s := "b", ?-"a"
''',
's',
'bbbba',
(1,[
],1)
)
def testLookaheadNeg4( self ):
self.doBasicTest(
'''s := "b", ?-"a", "ba"
''',
's',
'bba',
(1,[
],3)
)
def testLookaheadNeg5( self ):
self.doBasicTest(
'''s := ?-t, "ba"
t := "bad"
''',
's',
'bac',
(1,[
],2)
)
def testLookaheadNeg6( self ):
self.doBasicTest(
'''s := ?-t, "ba"
t := "bad"
''',
's',
'bad',
(0,[
],AnyInt)
)
def testLookahead2( self ):
"""Test lookahead on literals (more complex)"""
self.doBasicTest(
'''s := something+, "ba"
something := "b",?-"a"
''',
's',
'bbbba',
(1,[
("something",0,1,NullResult),
("something",1,2,NullResult),
("something",2,3,NullResult),
],5)
)
def testLookahead3( self ):
"""Test lookahead on reported positive productions"""
self.doBasicTest(
'''s := ?trailer
trailer := "bad"
''',
's',
'badba',
(1,[
("trailer",0,3,NullResult),
],0)
)
def testLookahead4( self ):
self.doBasicTest(
'''s := ?-trailer?
trailer := "bad"
''',
's',
'badba',
(1,[
],0)
)
def testLookahead5( self ):
self.doBasicTest(
'''s := ?-trailer, 'ba'
trailer := "bad"
''',
's',
'babba',
(1,[
],2)
)
def testLookahead6( self ):
self.doBasicTest(
'''s := ?-trailer, 'ba'
trailer := "bad"
''',
's',
'badba',
(0,[
],AnyInt)
)
def testGenPos1( self ):
self.doBasicTest(
'''s := something
something := "a" ''',
's',
'mmmab',
(0,[],AnyInt)
)
def testGenPos2( self ):
self.doBasicTest(
'''s := something
something := "a" ''',
's',
'ammmab',
(1,[('something',0,1,NullResult),],1)
)
def testOptionalGroupHitEOF( self ):
"""Test optional group hitting an EOF during success run"""
self.doBasicTest(
'''s := something*
something := ("a"/"b") ''',
's',
'aa',
(1,[
('something',0,1,NullResult),
('something',1,2,NullResult),
],2)
)
def testMultiLineDef( self ):
"""Test multi-line definitions"""
self.doBasicTest(
'''s :=
something*
something := (
"a"/
"b"
) ''',
's',
'aa',
(1,[
('something',0,1,NullResult),
('something',1,2,NullResult),
],2)
)
## def testRepeatOptionalFail( self ):
## """Explicit test of the optional-repeating-child of repeating object
## """
## self.doBasicTest(
## r'''
## controlword := '\\',('*','\\')?,[-a-zA-Z0-9]+
## contents := -[\012}\\]*
## file := (controlword/contents)+
## ''',
## "file",
## "\\*\\test sdf ff f f sdfff\\",
## (1, [
## ("controlword", 0,7,[]),
## ("contents",7,24),
## ],24),
## )
def testGenCILiteral1( self ):
self.doBasicTest(
'''s := c"this"''',
's',
'this',
(1,[],4)
)
def testGenCILiteral2( self ):
self.doBasicTest(
'''s := c"this"''',
's',
'This',
(1,[],4)
)
def testGenCILiteral3( self ):
self.doBasicTest(
'''s := c"this"''',
's',
'THIS',
(1,[],4)
)
def testGenCILiteral4( self ):
self.doBasicTest(
'''s := -c"this"''',
's',
' THIS',
(1,[],1)
)
def testGenCILiteral5( self ):
self.doBasicTest(
'''s := -c"this"''',
's',
' thi',
(1,[],1)
)
def testGenCILiteral6( self ):
self.doBasicTest(
'''s := -c"this"*''',
's',
' thi',
(1,[],4)
)
class NameTests(unittest.TestCase):
def doBasicTest(self, definition, parserName, testValue, expected, ):
result = Parser( definition).parse( testValue, production=parserName )
assert result == expected, '''\nexpected:%s\n got:%s\n'''%( expected, result )
def test_p( self ):
self.doBasicTest(
'''s := something
something := "a" ''',
's',
'ammmab',
(1,[('something',0,1,NullResult),],1)
)
def test_po( self ):
self.doBasicTest(
'''s := something?
something := "a" ''',
's',
'ammmab',
(1,[('something',0,1,NullResult),],1)
)
def test_por( self ):
self.doBasicTest(
'''s := something*
something := "a" ''',
's',
'ammmab',
(1,[('something',0,1,NullResult),],1)
)
def test_pr( self ):
self.doBasicTest(
'''s := something+
something := "a" ''',
's',
'ammmab',
(1,[('something',0,1,NullResult),],1)
)
def test_n( self ):
self.doBasicTest(
'''s := - something
<something> := [ab]''',
's',
'mmmab',
(1,[],1)
)
def test_no( self ):
self.doBasicTest(
'''s := - something?
<something> := [ab]''',
's',
'mmmab',
(1,[],1)
)
def test_nor( self ):
self.doBasicTest(
'''s := - something*
<something> := [ab]''',
's',
'mmmab',
(1,[],3)
)
def test_nr( self ):
self.doBasicTest(
'''s := - something+
<something> := [ab]''',
's',
'mmmab',
(1,[],3)
)
def test_n_f( self ):
self.doBasicTest(
'''s := - something
<something> := [ab]''',
's',
'ammmab',
(0,[],AnyInt)
)
def test_no_f( self ):
self.doBasicTest(
'''s := - something?
<something> := [ab]''',
's',
'ammmab',
(1,[],0)
)
def test_nor_f( self ):
self.doBasicTest(
'''s := - something*
<something> := [ab]''',
's',
'ammmab',
(1,[],0)
)
def test_nr_f( self ):
self.doBasicTest(
'''s := - something +
<something> := [ab]''',
's',
'ammmab',
(0,[],AnyInt)
)
## def test_por_big( self ):
## """This test creates 1,000,000 result tuples (very inefficiently, I might add)...
## on my machine that takes a long time, so I do not bother with the test
## (note that with a recursive mx.TextTools, this should actually blow up
## long before you get into memory problems :) ).
## """
## self.doBasicTest(
## '''s := something*
## something := "a" ''',
## 's',
## 'a'*1000000,
## (1,[
## ],1000000)
## )
def test_expanded_name( self ):
"""Non-reporting (expanded) name test
Tests new feature, a name whose children
are reported, but which is not itself reported,
basically this lets you create anonymous
groups which can be referenced from other
productions.
"""
self.doBasicTest(
'''s := something +
>something< := r
r := [ab]
v := [c]
''',
's',
'abammmab',
(1,[
('r',0,1, NullResult),
('r',1,2, NullResult),
('r',2,3, NullResult),
],3)
)
def test_expanded_SingleNameChild( self ):
"""Expanded group with single child which is a Name itself
This originally failed when the Name object's report value
was changed to 0 (redundant information for the "expanded" code),
resulting in the child production not getting reported.
"""
self.doBasicTest(
'''s := something +
something := r
r := [ab]''',
'something',
'abammmab',
(1,[
('r',0,1, NullResult),
],1)
)
class BasicMethodSource:
def __init__( self ):
self.results = []
def _m_a( self, taglist,text,l,r,subtags ):
self.results.append( ('a',text[l:r]))
def _m_b( self, taglist, text, l,r,subtags):
self.results.append( ('b',l,r) )
_m_c = TextTools.AppendMatch
_m_d = TextTools.AppendTagobj
_o_d = "hello world"
class AppendToTagobjMethodSource:
def __init__( self ):
self._o_d = []
_m_d = TextTools.AppendToTagobj
class CallTests(unittest.TestCase):
"""Tests semantics of calling objects from a method source during parsing"""
def parse( self, definition, parserName, testValue, source):
result = Parser(
definition,
).parse(testValue, production=parserName, processor = source)
return result
def test_basic_call( self ):
"""Test basic ability to call a method instead of regular functioning"""
source = BasicMethodSource()
self.parse( """
x := (a/b)*
a := "a"
b := "b"
""", 'x', 'abba', source)
assert source.results == [ ('a','a'),('b',1,2),('b',2,3),('a','a'),], """Method source methods were not called, or called improperly:\n%s"""%(source.results,)
def test_AppendMatch( self ):
"""Test ability to append the text-string match to the results list"""
source = BasicMethodSource()
result = self.parse( """
x := c*
c := 'c'
""", 'x', 'ccc', source)
assert result == (1,[
'c','c','c',
],3), """Result was %s"""%( result, )
def test_AppendTagObj( self ):
"""Test appending the tagobject to the results list"""
source = BasicMethodSource()
result = self.parse( """
x := d*
d := 'd'
""", 'x', 'ddd', source)
assert result == (1,[
"hello world","hello world","hello world",
],3)
def test_AppendToTagObj( self ):
"""Test basic ability to call a method instead of regular functioning"""
source = AppendToTagobjMethodSource()
result = self.parse( """
x := d*
d := 'd'
""", 'x', 'ddd', source)
assert source._o_d == [ (None,0,1,NullResult),(None,1,2,NullResult),(None,2,3,NullResult)], """Method source methods were not called, or called improperly:\n%s"""%(source._o_d,)
import test_grammarparser
import test_erroronfail
def getSuite():
return unittest.TestSuite((
test_grammarparser.getSuite(),
test_erroronfail.getSuite(),
unittest.makeSuite(ParserGenerationTests, 'test'),
unittest.makeSuite(NameTests, 'test'),
unittest.makeSuite(CallTests, 'test'),
))
if __name__ == "__main__":
unittest.main(defaultTest="getSuite")
|