source: trunk/tests/TestPullParser.py @ 78

Revision 78, 3.2 KB checked in by tim, 9 years ago (diff)

moved tests to tests folder

  • Property svn:executable set to *
Line 
1import YamlTest
2from here import flushLeft
3from test import assertEquals
4from TestPushDumper import mockEvents
5from yaml import load
6
7"""
8This is experimental code.  I am moving toward a rewrite of the YAML
9parser so that it uses a pull interface.  I am using a mock object
10to emulate the parser, so that I can experiment with the interface a bit,
11and also to sketch out some ideas for schema-driven parsing.
12"""
13
14class MockParser:
15    def __init__(self, events):
16        self.events = events
17        self.index = 0
18
19    def __getattr__(self, name):
20        (nextName, value) = self.events[self.index]
21        if name != nextName:
22            raise "Improper mocking for event %d (%s vs. %s)" % \
23                (self.index, name, nextName)
24        self.index += 1
25        return lambda: value
26
27class Loader:
28    def __init__(self, parser):
29        self.parser = parser
30
31    def load(self, data):
32        typ = self.parser.getType()
33        return self._load(typ)
34
35    def _load(self, typ):
36        if typ == 'seq':
37            return self._loadSeq()
38        elif typ == 'map':
39            return self._loadMap()
40        else:
41            return self._loadScalar()
42
43    def _loadSeq(self):
44        results = []
45        def itemFunc(self, results, typ):
46            results.append(self._load(typ))
47        return self.iterateItems(results, itemFunc)
48
49    def _loadMap(self):
50        results = {}
51        def itemFunc(self, results, typ):
52            key = self._load(typ)
53            valTyp = self.parser.getType()
54            value = self._load(typ)
55            results[key] = value
56        return self.iterateItems(results, itemFunc)
57
58    def iterateItems(self, results, func):
59        while 1:
60            typ = self.parser.getType()
61            if typ is None:
62                return results
63            else:
64                func(self, results, typ)
65
66    def _loadScalar(self):
67        return self.parser.getScalar()
68
69def mockParser(data):
70    events = mockEvents(data)
71    return MockParser(events)
72
73def mockLoad(data):
74    loader = Loader(mockParser(data))
75    return loader.load(None) # None for data cause events are all mocked
76
77def testRoundTrip(data):
78    obj = mockLoad(data)
79    assertEquals(obj, data)
80
81class Test(YamlTest.YamlTest):
82
83    def testMock(self):
84        parser = MockParser( [
85            ('getScalar', 'foo'),
86            ('getArray', [1,2,3]),
87            ('getScalar', None),
88        ])
89        assertEquals(parser.getScalar(), 'foo')
90        assertEquals(parser.getArray(), [1,2,3])
91        assertEquals(parser.getScalar(), None)
92
93    def testList(self):
94        testRoundTrip([1,2,3])
95
96    def testDict(self):
97        testRoundTrip({'foo': 'bar'})
98
99    def testListDict(self):
100        testRoundTrip( [ [1,2,3], {'foo': 'bar'} ] )
101
102    def testComplexStructure(self):
103        data = load(flushLeft(
104            """
105            list:
106                - {foo: bar}
107                - [1, 2, 3]
108            dict:
109                name: steve
110                games: [hoops, pool]
111            """))
112        testRoundTrip(data)
113
114if __name__ == '__main__':
115    import unittest
116    unittest.main()
Note: See TracBrowser for help on using the repository browser.