1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 '''
31 Tests for a bug reported for 3.2, 3.2.1
32 '''
33
34
35
36
37
38
39
40 from unittest import TestCase
41 from difflib import Differ
42
43 from lepl import *
44 from lepl.support.graph import ConstructorWalker
45 from lepl.matchers.matcher import Matcher, canonical_matcher_type,\
46 MatcherTypeException, is_child
47 from lepl.matchers.memo import _LMemo, _RMemo, LMemo, RMemo
48 from lepl.matchers.transform import Transform, TransformationWrapper
49 from lepl.core.rewriters import NodeStats, Flatten, \
50 ComposeTransforms, AutoMemoize, clone_matcher, RightMemoize, LeftMemoize
51
52
54 '''
55 Based on the original bug report.
56 '''
57
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
123 '''
124 Test various clone functions.
125 '''
126
128 '''
129 Use a description of the graph to check against changes.
130 '''
131
132
133 name = Word(Letter()) > 'name'
134
135 expression = Delayed()
136 variable = Delayed()
137
138 function = (expression / '()') > 'function'
139 expression += (variable | function) > 'expression'
140 variable += (name | expression / '.' / name)
141
142 dotted_name = function & Eos()
143 base = dotted_name.tree()
144
145 desc0 = NodeStats(dotted_name)
146 print(desc0)
147 assert desc0.total == 18, desc0
148 self.assert_count(desc0, And, 5)
149 self.assert_count(desc0, Or, 2)
150 self.assert_count(desc0, Delayed, 2)
151
152 clone0 = clone_matcher(dotted_name)
153
154 diff = Differ()
155 diff_text = '\n'.join(diff.compare(base.split('\n'), clone0.tree().split('\n')))
156
157 descx = NodeStats(clone0)
158 print(descx)
159 assert descx == desc0
160
161 clone1 = Flatten()(dotted_name)
162 print(clone1.tree())
163 desc1 = NodeStats(clone1)
164 print(desc1)
165
166 assert desc1.total == 17, desc1
167 self.assert_count(desc1, And, 4)
168 self.assert_count(desc1, Or, 2)
169 self.assert_count(desc1, Delayed, 2)
170 self.assert_count(desc1, Transform, 7)
171 self.assert_count(desc1, TransformationWrapper, 7)
172
173 clone2 = ComposeTransforms()(clone1)
174 desc2 = NodeStats(clone2)
175
176
177 assert desc2.total == 17, desc2
178 self.assert_count(desc2, And, 4)
179 self.assert_count(desc2, Or, 2)
180 self.assert_count(desc2, Delayed, 2)
181 self.assert_count(desc2, Transform, 6)
182 self.assert_count(desc2, TransformationWrapper, 6)
183
184 clone3 = RightMemoize()(clone2)
185 desc3 = NodeStats(clone3)
186
187 assert desc3.total == 17, desc3
188 self.assert_count(desc3, _RMemo, 17)
189 self.assert_count(desc3, Delayed, 2)
190
191 clone4 = LeftMemoize()(clone2)
192 desc4 = NodeStats(clone4)
193
194 assert desc4.total == 17, desc4
195 self.assert_count(desc4, _LMemo, 20)
196
197 self.assert_count(desc4, Delayed, 3)
198
199 clone5 = AutoMemoize(left=LMemo, right=RMemo)(clone2)
200 desc5 = NodeStats(clone5)
201
202 assert desc5.total == 17, desc5
203 self.assert_count(desc5, _RMemo, 5)
204 self.assert_count(desc5, _LMemo, 15)
205
206 self.assert_count(desc5, Delayed, 3)
207
208 try:
209 clone3.config.clear()
210 clone3.parse_string('1join()')
211 assert False, 'Expected error'
212 except MemoException as error:
213 assert 'Left recursion was detected' in str(error), str(error)
214
215 clone4.config.clear()
216 clone4.parse_string('1join()')
217 clone5.config.clear()
218 clone5.parse_string('1join()')
219
221 '''
222 Check the count for a given type.
223 '''
224 try:
225 type_ = canonical_matcher_type(type_)
226 except MatcherTypeException:
227 pass
228 assert type_ in desc.types and len(desc.types[type_]) == count, \
229 len(desc.types[type_]) if type_ in desc.types else type_
230