14
sys.path.insert(0,"..")
15
sys.tracebacklimit = 0
19
def make_pymodule_path(filename):
20
path = os.path.dirname(filename)
21
file = os.path.basename(filename)
22
mod, ext = os.path.splitext(file)
24
if sys.hexversion >= 0x3020000:
25
modname = mod+"."+imp.get_tag()+ext
26
fullpath = os.path.join(path,'__pycache__',modname)
31
def pymodule_out_exists(filename):
32
return os.path.exists(make_pymodule_path(filename))
34
def pymodule_out_remove(filename):
35
os.remove(make_pymodule_path(filename))
37
def check_expected(result,expected):
38
if sys.version_info[0] >= 3:
39
if isinstance(result,str):
40
result = result.encode('ascii')
41
if isinstance(expected,str):
42
expected = expected.encode('ascii')
43
resultlines = result.splitlines()
44
expectedlines = expected.splitlines()
47
if len(resultlines) != len(expectedlines):
50
for rline,eline in zip(resultlines,expectedlines):
51
if not rline.endswith(eline):
55
def run_import(module):
56
code = "import "+module
58
del sys.modules[module]
60
# Tests related to errors and warnings when building lexers
61
class LexErrorWarningTests(unittest.TestCase):
63
sys.stderr = StringIO.StringIO()
64
sys.stdout = StringIO.StringIO()
65
if sys.hexversion >= 0x3020000:
66
warnings.filterwarnings('ignore',category=ResourceWarning)
69
sys.stderr = sys.__stderr__
70
sys.stdout = sys.__stdout__
71
def test_lex_doc1(self):
72
self.assertRaises(SyntaxError,run_import,"lex_doc1")
73
result = sys.stderr.getvalue()
74
self.assert_(check_expected(result,
75
"lex_doc1.py:18: No regular expression defined for rule 't_NUMBER'\n"))
76
def test_lex_dup1(self):
77
self.assertRaises(SyntaxError,run_import,"lex_dup1")
78
result = sys.stderr.getvalue()
79
self.assert_(check_expected(result,
80
"lex_dup1.py:20: Rule t_NUMBER redefined. Previously defined on line 18\n" ))
82
def test_lex_dup2(self):
83
self.assertRaises(SyntaxError,run_import,"lex_dup2")
84
result = sys.stderr.getvalue()
85
self.assert_(check_expected(result,
86
"lex_dup2.py:22: Rule t_NUMBER redefined. Previously defined on line 18\n" ))
88
def test_lex_dup3(self):
89
self.assertRaises(SyntaxError,run_import,"lex_dup3")
90
result = sys.stderr.getvalue()
91
self.assert_(check_expected(result,
92
"lex_dup3.py:20: Rule t_NUMBER redefined. Previously defined on line 18\n" ))
94
def test_lex_empty(self):
95
self.assertRaises(SyntaxError,run_import,"lex_empty")
96
result = sys.stderr.getvalue()
97
self.assert_(check_expected(result,
98
"No rules of the form t_rulename are defined\n"
99
"No rules defined for state 'INITIAL'\n"))
101
def test_lex_error1(self):
102
run_import("lex_error1")
103
result = sys.stderr.getvalue()
104
self.assert_(check_expected(result,
105
"No t_error rule is defined\n"))
107
def test_lex_error2(self):
108
self.assertRaises(SyntaxError,run_import,"lex_error2")
109
result = sys.stderr.getvalue()
110
self.assert_(check_expected(result,
111
"Rule 't_error' must be defined as a function\n")
114
def test_lex_error3(self):
115
self.assertRaises(SyntaxError,run_import,"lex_error3")
116
result = sys.stderr.getvalue()
117
self.assert_(check_expected(result,
118
"lex_error3.py:20: Rule 't_error' requires an argument\n"))
120
def test_lex_error4(self):
121
self.assertRaises(SyntaxError,run_import,"lex_error4")
122
result = sys.stderr.getvalue()
123
self.assert_(check_expected(result,
124
"lex_error4.py:20: Rule 't_error' has too many arguments\n"))
126
def test_lex_ignore(self):
127
self.assertRaises(SyntaxError,run_import,"lex_ignore")
128
result = sys.stderr.getvalue()
129
self.assert_(check_expected(result,
130
"lex_ignore.py:20: Rule 't_ignore' must be defined as a string\n"))
132
def test_lex_ignore2(self):
133
run_import("lex_ignore2")
134
result = sys.stderr.getvalue()
135
self.assert_(check_expected(result,
136
"t_ignore contains a literal backslash '\\'\n"))
139
def test_lex_re1(self):
140
self.assertRaises(SyntaxError,run_import,"lex_re1")
141
result = sys.stderr.getvalue()
142
self.assert_(check_expected(result,
143
"Invalid regular expression for rule 't_NUMBER'. unbalanced parenthesis\n"))
145
def test_lex_re2(self):
146
self.assertRaises(SyntaxError,run_import,"lex_re2")
147
result = sys.stderr.getvalue()
148
self.assert_(check_expected(result,
149
"Regular expression for rule 't_PLUS' matches empty string\n"))
151
def test_lex_re3(self):
152
self.assertRaises(SyntaxError,run_import,"lex_re3")
153
result = sys.stderr.getvalue()
154
self.assert_(check_expected(result,
155
"Invalid regular expression for rule 't_POUND'. unbalanced parenthesis\n"
156
"Make sure '#' in rule 't_POUND' is escaped with '\\#'\n"))
158
def test_lex_rule1(self):
159
self.assertRaises(SyntaxError,run_import,"lex_rule1")
160
result = sys.stderr.getvalue()
161
self.assert_(check_expected(result,
162
"t_NUMBER not defined as a function or string\n"))
164
def test_lex_rule2(self):
165
self.assertRaises(SyntaxError,run_import,"lex_rule2")
166
result = sys.stderr.getvalue()
167
self.assert_(check_expected(result,
168
"lex_rule2.py:18: Rule 't_NUMBER' requires an argument\n"))
170
def test_lex_rule3(self):
171
self.assertRaises(SyntaxError,run_import,"lex_rule3")
172
result = sys.stderr.getvalue()
173
self.assert_(check_expected(result,
174
"lex_rule3.py:18: Rule 't_NUMBER' has too many arguments\n"))
177
def test_lex_state1(self):
178
self.assertRaises(SyntaxError,run_import,"lex_state1")
179
result = sys.stderr.getvalue()
180
self.assert_(check_expected(result,
181
"states must be defined as a tuple or list\n"))
183
def test_lex_state2(self):
184
self.assertRaises(SyntaxError,run_import,"lex_state2")
185
result = sys.stderr.getvalue()
186
self.assert_(check_expected(result,
187
"Invalid state specifier 'comment'. Must be a tuple (statename,'exclusive|inclusive')\n"
188
"Invalid state specifier 'example'. Must be a tuple (statename,'exclusive|inclusive')\n"))
190
def test_lex_state3(self):
191
self.assertRaises(SyntaxError,run_import,"lex_state3")
192
result = sys.stderr.getvalue()
193
self.assert_(check_expected(result,
194
"State name 1 must be a string\n"
195
"No rules defined for state 'example'\n"))
197
def test_lex_state4(self):
198
self.assertRaises(SyntaxError,run_import,"lex_state4")
199
result = sys.stderr.getvalue()
200
self.assert_(check_expected(result,
201
"State type for state comment must be 'inclusive' or 'exclusive'\n"))
204
def test_lex_state5(self):
205
self.assertRaises(SyntaxError,run_import,"lex_state5")
206
result = sys.stderr.getvalue()
207
self.assert_(check_expected(result,
208
"State 'comment' already defined\n"))
210
def test_lex_state_noerror(self):
211
run_import("lex_state_noerror")
212
result = sys.stderr.getvalue()
213
self.assert_(check_expected(result,
214
"No error rule is defined for exclusive state 'comment'\n"))
216
def test_lex_state_norule(self):
217
self.assertRaises(SyntaxError,run_import,"lex_state_norule")
218
result = sys.stderr.getvalue()
219
self.assert_(check_expected(result,
220
"No rules defined for state 'example'\n"))
222
def test_lex_token1(self):
223
self.assertRaises(SyntaxError,run_import,"lex_token1")
224
result = sys.stderr.getvalue()
225
self.assert_(check_expected(result,
226
"No token list is defined\n"
227
"Rule 't_NUMBER' defined for an unspecified token NUMBER\n"
228
"Rule 't_PLUS' defined for an unspecified token PLUS\n"
229
"Rule 't_MINUS' defined for an unspecified token MINUS\n"
232
def test_lex_token2(self):
233
self.assertRaises(SyntaxError,run_import,"lex_token2")
234
result = sys.stderr.getvalue()
235
self.assert_(check_expected(result,
236
"tokens must be a list or tuple\n"
237
"Rule 't_NUMBER' defined for an unspecified token NUMBER\n"
238
"Rule 't_PLUS' defined for an unspecified token PLUS\n"
239
"Rule 't_MINUS' defined for an unspecified token MINUS\n"
242
def test_lex_token3(self):
243
self.assertRaises(SyntaxError,run_import,"lex_token3")
244
result = sys.stderr.getvalue()
245
self.assert_(check_expected(result,
246
"Rule 't_MINUS' defined for an unspecified token MINUS\n"))
249
def test_lex_token4(self):
250
self.assertRaises(SyntaxError,run_import,"lex_token4")
251
result = sys.stderr.getvalue()
252
self.assert_(check_expected(result,
253
"Bad token name '-'\n"))
256
def test_lex_token5(self):
258
run_import("lex_token5")
259
except ply.lex.LexError:
260
e = sys.exc_info()[1]
261
self.assert_(check_expected(str(e),"lex_token5.py:19: Rule 't_NUMBER' returned an unknown token type 'NUM'"))
263
def test_lex_token_dup(self):
264
run_import("lex_token_dup")
265
result = sys.stderr.getvalue()
266
self.assert_(check_expected(result,
267
"Token 'MINUS' multiply defined\n"))
270
def test_lex_literal1(self):
271
self.assertRaises(SyntaxError,run_import,"lex_literal1")
272
result = sys.stderr.getvalue()
273
self.assert_(check_expected(result,
274
"Invalid literal '**'. Must be a single character\n"))
276
def test_lex_literal2(self):
277
self.assertRaises(SyntaxError,run_import,"lex_literal2")
278
result = sys.stderr.getvalue()
279
self.assert_(check_expected(result,
280
"Invalid literals specification. literals must be a sequence of characters\n"))
286
# Tests related to various build options associated with lexers
287
class LexBuildOptionTests(unittest.TestCase):
289
sys.stderr = StringIO.StringIO()
290
sys.stdout = StringIO.StringIO()
292
sys.stderr = sys.__stderr__
293
sys.stdout = sys.__stdout__
295
shutil.rmtree("lexdir")
299
def test_lex_module(self):
300
run_import("lex_module")
301
result = sys.stdout.getvalue()
302
self.assert_(check_expected(result,
307
def test_lex_object(self):
308
run_import("lex_object")
309
result = sys.stdout.getvalue()
310
self.assert_(check_expected(result,
315
def test_lex_closure(self):
316
run_import("lex_closure")
317
result = sys.stdout.getvalue()
318
self.assert_(check_expected(result,
322
def test_lex_optimize(self):
324
os.remove("lextab.py")
328
os.remove("lextab.pyc")
332
os.remove("lextab.pyo")
335
run_import("lex_optimize")
337
result = sys.stdout.getvalue()
338
self.assert_(check_expected(result,
342
self.assert_(os.path.exists("lextab.py"))
345
p = subprocess.Popen([sys.executable,'-O','lex_optimize.py'],
346
stdout=subprocess.PIPE)
347
result = p.stdout.read()
349
self.assert_(check_expected(result,
353
self.assert_(pymodule_out_exists("lextab.pyo"))
355
pymodule_out_remove("lextab.pyo")
356
p = subprocess.Popen([sys.executable,'-OO','lex_optimize.py'],
357
stdout=subprocess.PIPE)
358
result = p.stdout.read()
359
self.assert_(check_expected(result,
363
self.assert_(pymodule_out_exists("lextab.pyo"))
365
os.remove("lextab.py")
369
pymodule_out_remove("lextab.pyc")
373
pymodule_out_remove("lextab.pyo")
377
def test_lex_optimize2(self):
379
os.remove("opt2tab.py")
383
os.remove("opt2tab.pyc")
387
os.remove("opt2tab.pyo")
390
run_import("lex_optimize2")
391
result = sys.stdout.getvalue()
392
self.assert_(check_expected(result,
396
self.assert_(os.path.exists("opt2tab.py"))
398
p = subprocess.Popen([sys.executable,'-O','lex_optimize2.py'],
399
stdout=subprocess.PIPE)
400
result = p.stdout.read()
401
self.assert_(check_expected(result,
405
self.assert_(pymodule_out_exists("opt2tab.pyo"))
406
pymodule_out_remove("opt2tab.pyo")
407
p = subprocess.Popen([sys.executable,'-OO','lex_optimize2.py'],
408
stdout=subprocess.PIPE)
409
result = p.stdout.read()
410
self.assert_(check_expected(result,
414
self.assert_(pymodule_out_exists("opt2tab.pyo"))
416
os.remove("opt2tab.py")
420
pymodule_out_remove("opt2tab.pyc")
424
pymodule_out_remove("opt2tab.pyo")
428
def test_lex_optimize3(self):
430
shutil.rmtree("lexdir")
435
os.mkdir("lexdir/sub")
436
open("lexdir/__init__.py","w").write("")
437
open("lexdir/sub/__init__.py","w").write("")
438
run_import("lex_optimize3")
439
result = sys.stdout.getvalue()
440
self.assert_(check_expected(result,
444
self.assert_(os.path.exists("lexdir/sub/calctab.py"))
446
p = subprocess.Popen([sys.executable,'-O','lex_optimize3.py'],
447
stdout=subprocess.PIPE)
448
result = p.stdout.read()
449
self.assert_(check_expected(result,
453
self.assert_(pymodule_out_exists("lexdir/sub/calctab.pyo"))
454
pymodule_out_remove("lexdir/sub/calctab.pyo")
455
p = subprocess.Popen([sys.executable,'-OO','lex_optimize3.py'],
456
stdout=subprocess.PIPE)
457
result = p.stdout.read()
458
self.assert_(check_expected(result,
462
self.assert_(pymodule_out_exists("lexdir/sub/calctab.pyo"))
464
shutil.rmtree("lexdir")
468
def test_lex_opt_alias(self):
470
os.remove("aliastab.py")
474
os.remove("aliastab.pyc")
478
os.remove("aliastab.pyo")
481
run_import("lex_opt_alias")
482
result = sys.stdout.getvalue()
483
self.assert_(check_expected(result,
487
self.assert_(os.path.exists("aliastab.py"))
489
p = subprocess.Popen([sys.executable,'-O','lex_opt_alias.py'],
490
stdout=subprocess.PIPE)
491
result = p.stdout.read()
492
self.assert_(check_expected(result,
496
self.assert_(pymodule_out_exists("aliastab.pyo"))
497
pymodule_out_remove("aliastab.pyo")
498
p = subprocess.Popen([sys.executable,'-OO','lex_opt_alias.py'],
499
stdout=subprocess.PIPE)
500
result = p.stdout.read()
501
self.assert_(check_expected(result,
505
self.assert_(pymodule_out_exists("aliastab.pyo"))
507
os.remove("aliastab.py")
511
pymodule_out_remove("aliastab.pyc")
515
pymodule_out_remove("aliastab.pyo")
519
def test_lex_many_tokens(self):
521
os.remove("manytab.py")
525
os.remove("manytab.pyc")
529
os.remove("manytab.pyo")
532
run_import("lex_many_tokens")
533
result = sys.stdout.getvalue()
534
self.assert_(check_expected(result,
535
"(TOK34,'TOK34:',1,0)\n"
536
"(TOK143,'TOK143:',1,7)\n"
537
"(TOK269,'TOK269:',1,15)\n"
538
"(TOK372,'TOK372:',1,23)\n"
539
"(TOK452,'TOK452:',1,31)\n"
540
"(TOK561,'TOK561:',1,39)\n"
541
"(TOK999,'TOK999:',1,47)\n"
544
self.assert_(os.path.exists("manytab.py"))
546
p = subprocess.Popen([sys.executable,'-O','lex_many_tokens.py'],
547
stdout=subprocess.PIPE)
548
result = p.stdout.read()
549
self.assert_(check_expected(result,
550
"(TOK34,'TOK34:',1,0)\n"
551
"(TOK143,'TOK143:',1,7)\n"
552
"(TOK269,'TOK269:',1,15)\n"
553
"(TOK372,'TOK372:',1,23)\n"
554
"(TOK452,'TOK452:',1,31)\n"
555
"(TOK561,'TOK561:',1,39)\n"
556
"(TOK999,'TOK999:',1,47)\n"
559
self.assert_(pymodule_out_exists("manytab.pyo"))
560
pymodule_out_remove("manytab.pyo")
562
os.remove("manytab.py")
566
os.remove("manytab.pyc")
570
os.remove("manytab.pyo")
574
# Tests related to run-time behavior of lexers
575
class LexRunTests(unittest.TestCase):
577
sys.stderr = StringIO.StringIO()
578
sys.stdout = StringIO.StringIO()
580
sys.stderr = sys.__stderr__
581
sys.stdout = sys.__stdout__
583
def test_lex_hedit(self):
584
run_import("lex_hedit")
585
result = sys.stdout.getvalue()
586
self.assert_(check_expected(result,
587
"(H_EDIT_DESCRIPTOR,'abc',1,0)\n"
588
"(H_EDIT_DESCRIPTOR,'abcdefghij',1,6)\n"
589
"(H_EDIT_DESCRIPTOR,'xy',1,20)\n"))
591
def test_lex_state_try(self):
592
run_import("lex_state_try")
593
result = sys.stdout.getvalue()
594
self.assert_(check_expected(result,
598
"Entering comment state\n"
599
"comment body LexToken(body_part,'This is a comment */',1,9)\n"
601
"(NUMBER,'10',1,32)\n"