fabiokung-ruby_parser 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,466 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'test/unit'
4
+ require 'ruby_parser'
5
+
6
+ $: << File.expand_path('~/Work/p4/zss/src/ParseTree/dev/lib')
7
+ $: << File.expand_path('~/Work/p4/zss/src/ParseTree/dev/test')
8
+
9
+ require 'pt_testcase'
10
+
11
+ class RubyParser
12
+ def process input
13
+ parse input
14
+ end
15
+ end
16
+
17
+ class RubyParserTestCase < ParseTreeTestCase
18
+ def self.previous key
19
+ "Ruby"
20
+ end
21
+
22
+ def self.generate_test klass, node, data, input_name, output_name
23
+ return if node.to_s =~ /bmethod|dmethod/
24
+ return if Array === data['Ruby']
25
+
26
+ output_name = "ParseTree"
27
+
28
+ super
29
+ end
30
+ end
31
+
32
+ class TestRubyParser < RubyParserTestCase
33
+ alias :refute_nil :assert_not_nil unless defined? Mini
34
+
35
+ def setup
36
+ super
37
+
38
+ # puts self.name
39
+
40
+ @processor = RubyParser.new
41
+ end
42
+
43
+ def test_attrasgn_array_lhs
44
+ rb = '[1, 2, 3, 4][from .. to] = ["a", "b", "c"]'
45
+ pt = s(:attrasgn,
46
+ s(:array, s(:lit, 1), s(:lit, 2), s(:lit, 3), s(:lit, 4)),
47
+ :[]=,
48
+ s(:arglist,
49
+ s(:dot2,
50
+ s(:call, nil, :from, s(:arglist)),
51
+ s(:call, nil, :to, s(:arglist))),
52
+ s(:array, s(:str, "a"), s(:str, "b"), s(:str, "c"))))
53
+
54
+ result = @processor.parse(rb)
55
+
56
+ assert_equal pt, result
57
+ end
58
+
59
+ def test_block_append
60
+ head = s(:args)
61
+ tail = s(:zsuper)
62
+ expected = s(:block, s(:args), s(:zsuper))
63
+ assert_equal expected, @processor.block_append(head, tail)
64
+ end
65
+
66
+ def test_block_append_begin_begin
67
+ head = s(:begin, s(:args))
68
+ tail = s(:begin, s(:args))
69
+ expected = s(:block, s(:args), s(:begin, s(:args)))
70
+ assert_equal expected, @processor.block_append(head, tail)
71
+ end
72
+
73
+ def test_block_append_block
74
+ head = s(:block, s(:args))
75
+ tail = s(:zsuper)
76
+ expected = s(:block, s(:args), s(:zsuper))
77
+ assert_equal expected, @processor.block_append(head, tail)
78
+ end
79
+
80
+ def test_block_append_nil_head
81
+ head = nil
82
+ tail = s(:zsuper)
83
+ expected = s(:zsuper)
84
+ assert_equal expected, @processor.block_append(head, tail)
85
+ end
86
+
87
+ def test_block_append_nil_tail
88
+ head = s(:args)
89
+ tail = nil
90
+ expected = s(:args)
91
+ assert_equal expected, @processor.block_append(head, tail)
92
+ end
93
+
94
+ def test_block_append_tail_block
95
+ head = s(:call, nil, :f1, s(:arglist))
96
+ tail = s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y)))
97
+ expected = s(:block,
98
+ s(:call, nil, :f1, s(:arglist)),
99
+ s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y))))
100
+ assert_equal expected, @processor.block_append(head, tail)
101
+ end
102
+
103
+ def test_call_env
104
+ @processor.env[:a] = :lvar
105
+ expected = s(:call, s(:lvar, :a), :happy, s(:arglist))
106
+
107
+ assert_equal expected, @processor.parse('a.happy')
108
+ end
109
+
110
+ def test_dasgn_icky2
111
+ rb = "a do\n v = nil\n begin\n yield\n rescue Exception => v\n break\n end\nend"
112
+ pt = s(:iter,
113
+ s(:call, nil, :a, s(:arglist)),
114
+ nil,
115
+ s(:block,
116
+ s(:lasgn, :v, s(:nil)),
117
+ s(:rescue,
118
+ s(:yield),
119
+ s(:resbody,
120
+ s(:array, s(:const, :Exception), s(:lasgn, :v, s(:gvar, :$!))),
121
+ s(:break)))))
122
+
123
+ assert_equal pt, @processor.parse(rb)
124
+ end
125
+
126
+ def test_class_comments
127
+ rb = "# blah 1\n# blah 2\n\nclass X\n # blah 3\n def blah\n # blah 4\n end\nend"
128
+ pt = s(:class, :X, nil,
129
+ s(:scope,
130
+ s(:defn, :blah, s(:args), s(:scope, s(:block, s(:nil))))))
131
+
132
+ actual = @processor.parse(rb)
133
+ assert_equal pt, actual
134
+
135
+ assert_equal "# blah 1\n# blah 2\n\n", actual.comments
136
+ assert_equal "# blah 3\n", actual.scope.defn.comments
137
+ end
138
+
139
+ def test_module_comments
140
+ rb = "# blah 1\n \n # blah 2\n\nmodule X\n # blah 3\n def blah\n # blah 4\n end\nend"
141
+ pt = s(:module, :X,
142
+ s(:scope,
143
+ s(:defn, :blah, s(:args), s(:scope, s(:block, s(:nil))))))
144
+
145
+ actual = @processor.parse(rb)
146
+ assert_equal pt, actual
147
+ assert_equal "# blah 1\n\n# blah 2\n\n", actual.comments
148
+ assert_equal "# blah 3\n", actual.scope.defn.comments
149
+ end
150
+
151
+ def test_defn_comments
152
+ rb = "# blah 1\n# blah 2\n\ndef blah\nend"
153
+ pt = s(:defn, :blah, s(:args), s(:scope, s(:block, s(:nil))))
154
+
155
+ actual = @processor.parse(rb)
156
+ assert_equal pt, actual
157
+ assert_equal "# blah 1\n# blah 2\n\n", actual.comments
158
+ end
159
+
160
+ def test_defs_comments
161
+ rb = "# blah 1\n# blah 2\n\ndef self.blah\nend"
162
+ pt = s(:defs, s(:self), :blah, s(:args), s(:scope, s(:block)))
163
+
164
+ actual = @processor.parse(rb)
165
+ assert_equal pt, actual
166
+ assert_equal "# blah 1\n# blah 2\n\n", actual.comments
167
+ end
168
+
169
+ def test_do_bug # TODO: rename
170
+ rb = "a 1\na.b do |c|\n # do nothing\nend"
171
+ pt = s(:block,
172
+ s(:call, nil, :a, s(:arglist, s(:lit, 1))),
173
+ s(:iter,
174
+ s(:call, s(:call, nil, :a, s(:arglist)), :b, s(:arglist)),
175
+ s(:lasgn, :c)))
176
+
177
+ assert_equal pt, @processor.parse(rb)
178
+ end
179
+
180
+ def test_dstr_evstr
181
+ rb = "\"#\{'a'}#\{b}\""
182
+ pt = s(:dstr, "a", s(:evstr, s(:call, nil, :b, s(:arglist))))
183
+
184
+ assert_equal pt, @processor.parse(rb)
185
+ end
186
+
187
+ def test_dstr_str
188
+ rb = "\"#\{'a'} b\""
189
+ pt = s(:str, "a b")
190
+
191
+ assert_equal pt, @processor.parse(rb)
192
+ end
193
+
194
+ def test_empty
195
+ rb = ""
196
+ pt = nil
197
+
198
+ assert_equal pt, @processor.parse(rb)
199
+ end
200
+
201
+ def test_evstr_evstr
202
+ rb = "\"#\{a}#\{b}\""
203
+ pt = s(:dstr, "", s(:evstr, s(:call, nil, :a, s(:arglist))), s(:evstr, s(:call, nil, :b, s(:arglist))))
204
+
205
+ assert_equal pt, @processor.parse(rb)
206
+ end
207
+
208
+ def test_evstr_str
209
+ rb = "\"#\{a} b\""
210
+ pt = s(:dstr, "", s(:evstr, s(:call, nil, :a, s(:arglist))), s(:str, " b"))
211
+
212
+ assert_equal pt, @processor.parse(rb)
213
+ end
214
+
215
+ def test_lasgn_env
216
+ rb = 'a = 42'
217
+ pt = s(:lasgn, :a, s(:lit, 42))
218
+ expected_env = { :a => :lvar }
219
+
220
+ assert_equal pt, @processor.parse(rb)
221
+ assert_equal expected_env, @processor.env.all
222
+ end
223
+
224
+ def test_list_append
225
+ a = s(:lit, 1)
226
+ b = s(:lit, 2)
227
+ c = s(:lit, 3)
228
+
229
+ result = @processor.list_append(s(:array, b.dup), c.dup)
230
+
231
+ assert_equal s(:array, b, c), result
232
+
233
+ result = @processor.list_append(b.dup, c.dup)
234
+
235
+ assert_equal s(:array, b, c), result
236
+
237
+ result = @processor.list_append(result, a.dup)
238
+
239
+ assert_equal s(:array, b, c, a), result
240
+
241
+ lhs, rhs = s(:array, s(:lit, :iter)), s(:when, s(:const, :BRANCHING), nil)
242
+ expected = s(:array, s(:lit, :iter), s(:when, s(:const, :BRANCHING), nil))
243
+
244
+ assert_equal expected, @processor.list_append(lhs, rhs)
245
+ end
246
+
247
+ def test_list_prepend
248
+ a = s(:lit, 1)
249
+ b = s(:lit, 2)
250
+ c = s(:lit, 3)
251
+
252
+ result = @processor.list_prepend(b.dup, s(:array, c.dup))
253
+
254
+ assert_equal s(:array, b, c), result
255
+
256
+ result = @processor.list_prepend(b.dup, c.dup)
257
+
258
+ assert_equal s(:array, b, c), result
259
+
260
+ result = @processor.list_prepend(a.dup, result)
261
+
262
+ assert_equal s(:array, a, b, c), result
263
+ end
264
+
265
+ def test_literal_concat_dstr_dstr
266
+ lhs = s(:dstr, "Failed to download spec ",
267
+ s(:evstr, s(:call, nil, :spec_name, s(:arglist))),
268
+ s(:str, " from "),
269
+ s(:evstr, s(:call, nil, :source_uri, s(:arglist))),
270
+ s(:str, ":\n"))
271
+ rhs = s(:dstr, "\t",
272
+ s(:evstr, s(:call, s(:ivar, :@fetch_error), :message)))
273
+ expected = s(:dstr, "Failed to download spec ",
274
+ s(:evstr, s(:call, nil, :spec_name, s(:arglist))),
275
+ s(:str, " from "),
276
+ s(:evstr, s(:call, nil, :source_uri, s(:arglist))),
277
+ s(:str, ":\n"),
278
+ s(:str, "\t"),
279
+ s(:evstr, s(:call, s(:ivar, :@fetch_error), :message)))
280
+
281
+ assert_equal expected, @processor.literal_concat(lhs, rhs)
282
+ end
283
+
284
+ def test_literal_concat_dstr_evstr
285
+ lhs, rhs = s(:dstr, "a"), s(:evstr, s(:call, nil, :b, s(:arglist)))
286
+ expected = s(:dstr, "a", s(:evstr, s(:call, nil, :b, s(:arglist))))
287
+
288
+ assert_equal expected, @processor.literal_concat(lhs, rhs)
289
+ end
290
+
291
+ def test_literal_concat_evstr_evstr
292
+ lhs, rhs = s(:evstr, s(:lit, 1)), s(:evstr, s(:lit, 2))
293
+ expected = s(:dstr, "", s(:evstr, s(:lit, 1)), s(:evstr, s(:lit, 2)))
294
+
295
+ assert_equal expected, @processor.literal_concat(lhs, rhs)
296
+ end
297
+
298
+ def test_literal_concat_str_evstr
299
+ lhs, rhs = s(:str, ""), s(:evstr, s(:str, "blah"))
300
+
301
+ assert_equal s(:str, "blah"), @processor.literal_concat(lhs, rhs)
302
+ end
303
+
304
+ def test_logop_12
305
+ lhs = s(:lit, 1)
306
+ rhs = s(:lit, 2)
307
+ exp = s(:and, s(:lit, 1), s(:lit, 2))
308
+
309
+ assert_equal exp, @processor.logop(:and, lhs, rhs)
310
+ end
311
+
312
+ def test_logop_1234_5
313
+ lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:and, s(:lit, 3), s(:lit, 4))))
314
+ rhs = s(:lit, 5)
315
+ exp = s(:and,
316
+ s(:lit, 1),
317
+ s(:and,
318
+ s(:lit, 2),
319
+ s(:and,
320
+ s(:lit, 3),
321
+ s(:and,
322
+ s(:lit, 4),
323
+ s(:lit, 5)))))
324
+
325
+ assert_equal exp, @processor.logop(:and, lhs, rhs)
326
+ end
327
+
328
+ def test_logop_123_4
329
+ lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
330
+ rhs = s(:lit, 4)
331
+ exp = s(:and,
332
+ s(:lit, 1),
333
+ s(:and,
334
+ s(:lit, 2),
335
+ s(:and,
336
+ s(:lit, 3),
337
+ s(:lit, 4))))
338
+
339
+ assert_equal exp, @processor.logop(:and, lhs, rhs)
340
+ end
341
+
342
+ def test_logop_12_3
343
+ lhs = s(:and, s(:lit, 1), s(:lit, 2))
344
+ rhs = s(:lit, 3)
345
+ exp = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
346
+
347
+ assert_equal exp, @processor.logop(:and, lhs, rhs)
348
+ end
349
+
350
+ def test_logop_nested_mix
351
+ lhs = s(:or, s(:call, nil, :a, s(:arglist)), s(:call, nil, :b, s(:arglist)))
352
+ rhs = s(:and, s(:call, nil, :c, s(:arglist)), s(:call, nil, :d, s(:arglist)))
353
+ exp = s(:or,
354
+ s(:or, s(:call, nil, :a, s(:arglist)), s(:call, nil, :b, s(:arglist))),
355
+ s(:and, s(:call, nil, :c, s(:arglist)), s(:call, nil, :d, s(:arglist))))
356
+
357
+ lhs.paren = true
358
+ rhs.paren = true
359
+
360
+ assert_equal exp, @processor.logop(:or, lhs, rhs)
361
+ end
362
+
363
+ def test_str_evstr
364
+ rb = "\"a #\{b}\""
365
+ pt = s(:dstr, "a ", s(:evstr, s(:call, nil, :b, s(:arglist))))
366
+
367
+ assert_equal pt, @processor.parse(rb)
368
+ end
369
+
370
+ def test_str_pct_Q_nested
371
+ rb = "%Q[before [#\{nest}] after]"
372
+ pt = s(:dstr, "before [", s(:evstr, s(:call, nil, :nest, s(:arglist))), s(:str, "] after"))
373
+
374
+ assert_equal pt, @processor.parse(rb)
375
+ end
376
+
377
+ # def test_str_pct_nested_nested
378
+ # rb = "%{ { #\{ \"#\{1}\" } } }"
379
+ # pt = s(:dstr, " { ", s(:evstr, s(:lit, 1)), s(:str, " } "))
380
+
381
+ # assert_equal pt, @processor.parse(rb)
382
+ # end
383
+
384
+ def test_str_str
385
+ rb = "\"a #\{'b'}\""
386
+ pt = s(:str, "a b")
387
+
388
+ assert_equal pt, @processor.parse(rb)
389
+ end
390
+
391
+ def test_str_str_str
392
+ rb = "\"a #\{'b'} c\""
393
+ pt = s(:str, "a b c")
394
+
395
+ assert_equal pt, @processor.parse(rb)
396
+ end
397
+
398
+ STARTING_LINE = {
399
+ "case_nested_inner_no_expr" => 2,
400
+ "case_no_expr" => 2,
401
+ "case_splat" => 2,
402
+ "dstr_heredoc_expand" => 2,
403
+ "dstr_heredoc_windoze_sucks" => 2,
404
+ "dstr_heredoc_yet_again" => 2,
405
+ "str_heredoc" => 2,
406
+ "str_heredoc_call" => 2,
407
+ "str_heredoc_empty" => 2,
408
+ "str_heredoc_indent" => 2,
409
+ "structure_unused_literal_wwtt" => 3, # yes, 3... odd test
410
+ "undef_block_1" => 2,
411
+ "undef_block_2" => 2,
412
+ "undef_block_3" => 2,
413
+ "undef_block_wtf" => 2,
414
+ }
415
+
416
+ def after_process_hook klass, node, data, input_name, output_name
417
+ expected = STARTING_LINE[node] || 1
418
+ assert_equal expected, @result.line, "should have proper line number"
419
+ end
420
+
421
+ def test_position_info
422
+ rb = "a = 42\np a"
423
+ pt = s(:block,
424
+ s(:lasgn, :a, s(:lit, 42)),
425
+ s(:call, nil, :p, s(:arglist, s(:lvar, :a))))
426
+
427
+ result = @processor.parse(rb, "blah.rb")
428
+
429
+ assert_equal pt, result
430
+
431
+ assert_equal 1, result.line, "block should have line number"
432
+ assert_equal 1, result.lasgn.line, "lasgn should have line number"
433
+ assert_equal 2, result.call.line, "call should have line number"
434
+
435
+ expected = "blah.rb"
436
+
437
+ assert_equal expected, result.file
438
+ assert_equal expected, result.lasgn.file
439
+ assert_equal expected, result.call.file
440
+
441
+ assert_same result.file, result.lasgn.file
442
+ assert_same result.file, result.call.file
443
+ end
444
+
445
+ def test_position_info2
446
+ rb = "def x(y)\n p(y)\n y *= 2\n return y;\nend" # TODO: remove () & ;
447
+ pt = s(:defn, :x, s(:args, :y),
448
+ s(:scope,
449
+ s(:block,
450
+ s(:call, nil, :p, s(:arglist, s(:lvar, :y))),
451
+ s(:lasgn, :y,
452
+ s(:call, s(:lvar, :y), :*, s(:arglist, s(:lit, 2)))),
453
+ s(:return, s(:lvar, :y)))))
454
+
455
+ result = @processor.parse(rb)
456
+
457
+ assert_equal pt, result
458
+
459
+ body = result.scope.block
460
+
461
+ assert_equal 1, result.line, "defn should have line number"
462
+ assert_equal 2, body.call.line, "call should have line number"
463
+ assert_equal 3, body.lasgn.line, "lasgn should have line number"
464
+ assert_equal 4, body.return.line, "return should have line number"
465
+ end
466
+ end
@@ -0,0 +1,177 @@
1
+ require 'test/unit'
2
+ require 'ruby_parser_extras'
3
+
4
+ class TestStackState < Test::Unit::TestCase
5
+ def test_stack_state
6
+ s = StackState.new :test
7
+ s.push true
8
+ s.push false
9
+ s.lexpop
10
+ assert_equal [false, true], s.stack
11
+ end
12
+
13
+ def test_is_in_state
14
+ s = StackState.new :test
15
+ assert_equal false, s.is_in_state
16
+ s.push false
17
+ assert_equal false, s.is_in_state
18
+ s.push true
19
+ assert_equal true, s.is_in_state
20
+ s.push false
21
+ assert_equal false, s.is_in_state
22
+ end
23
+
24
+ def test_lexpop
25
+ s = StackState.new :test
26
+ assert_equal [false], s.stack
27
+ s.push true
28
+ s.push false
29
+ assert_equal [false, true, false], s.stack
30
+ s.lexpop
31
+ assert_equal [false, true], s.stack
32
+ end
33
+
34
+ def test_pop
35
+ s = StackState.new :test
36
+ assert_equal [false], s.stack
37
+ s.push true
38
+ assert_equal [false, true], s.stack
39
+ assert_equal true, s.pop
40
+ assert_equal [false], s.stack
41
+ end
42
+
43
+ def test_push
44
+ s = StackState.new :test
45
+ assert_equal [false], s.stack
46
+ s.push true
47
+ s.push false
48
+ assert_equal [false, true, false], s.stack
49
+ end
50
+ end
51
+
52
+ class TestEnvironment < Test::Unit::TestCase
53
+ def deny t
54
+ assert ! t
55
+ end
56
+
57
+ def setup
58
+ @env = Environment.new
59
+ @env[:blah] = 42
60
+ assert_equal 42, @env[:blah]
61
+ end
62
+
63
+ def test_use
64
+ @env.use :blah
65
+ expected = [{ :blah => true }]
66
+ assert_equal expected, @env.instance_variable_get(:"@use")
67
+ end
68
+
69
+ def test_use_scoped
70
+ @env.use :blah
71
+ @env.extend
72
+ expected = [{}, { :blah => true }]
73
+ assert_equal expected, @env.instance_variable_get(:"@use")
74
+ end
75
+
76
+ def test_used_eh
77
+ @env.extend :dynamic
78
+ @env[:x] = :dvar
79
+ @env.use :x
80
+ assert_equal true, @env.used?(:x)
81
+ end
82
+
83
+ def test_used_eh_none
84
+ assert_equal nil, @env.used?(:x)
85
+ end
86
+
87
+ def test_used_eh_scoped
88
+ self.test_used_eh
89
+ @env.extend :dynamic
90
+ assert_equal true, @env.used?(:x)
91
+ end
92
+
93
+ def test_var_scope_dynamic
94
+ @env.extend :dynamic
95
+ assert_equal 42, @env[:blah]
96
+ @env.unextend
97
+ assert_equal 42, @env[:blah]
98
+ end
99
+
100
+ def test_var_scope_static
101
+ @env.extend
102
+ assert_equal nil, @env[:blah]
103
+ @env.unextend
104
+ assert_equal 42, @env[:blah]
105
+ end
106
+
107
+ def test_dynamic
108
+ expected1 = {}
109
+ expected2 = { :x => 42 }
110
+
111
+ assert_equal expected1, @env.dynamic
112
+ begin
113
+ @env.extend :dynamic
114
+ assert_equal expected1, @env.dynamic
115
+
116
+ @env[:x] = 42
117
+ assert_equal expected2, @env.dynamic
118
+
119
+ begin
120
+ @env.extend :dynamic
121
+ assert_equal expected2, @env.dynamic
122
+ @env.unextend
123
+ end
124
+
125
+ assert_equal expected2, @env.dynamic
126
+ @env.unextend
127
+ end
128
+ assert_equal expected1, @env.dynamic
129
+ end
130
+
131
+ def test_all_dynamic
132
+ expected = { :blah => 42 }
133
+
134
+ @env.extend :dynamic
135
+ assert_equal expected, @env.all
136
+ @env.unextend
137
+ assert_equal expected, @env.all
138
+ end
139
+
140
+ def test_all_static
141
+ @env.extend
142
+ expected = { }
143
+ assert_equal expected, @env.all
144
+
145
+ @env.unextend
146
+ expected = { :blah => 42 }
147
+ assert_equal expected, @env.all
148
+ end
149
+
150
+ def test_dynamic_eh
151
+ assert_equal false, @env.dynamic?
152
+ @env.extend :dynamic
153
+ assert_equal true, @env.dynamic?
154
+ @env.extend
155
+ assert_equal false, @env.dynamic?
156
+ end
157
+
158
+ def test_all_static_deeper
159
+ expected0 = { :blah => 42 }
160
+ expected1 = { :blah => 42, :blah2 => 24 }
161
+ expected2 = { :blah => 27 }
162
+
163
+ @env.extend :dynamic
164
+ @env[:blah2] = 24
165
+ assert_equal expected1, @env.all
166
+
167
+ @env.extend
168
+ @env[:blah] = 27
169
+ assert_equal expected2, @env.all
170
+
171
+ @env.unextend
172
+ assert_equal expected1, @env.all
173
+
174
+ @env.unextend
175
+ assert_equal expected0, @env.all
176
+ end
177
+ end