ripper_ruby_parser 1.7.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +4 -4
- data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +24 -12
- data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +33 -54
- data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +17 -19
- data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +34 -1
- data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +1 -1
- data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +12 -15
- data/lib/ripper_ruby_parser/sexp_handlers/string_literals.rb +21 -15
- data/lib/ripper_ruby_parser/sexp_processor.rb +4 -17
- data/lib/ripper_ruby_parser/unescape.rb +36 -12
- data/lib/ripper_ruby_parser/version.rb +1 -1
- metadata +110 -78
- data/Rakefile +0 -33
- data/test/end_to_end/comments_test.rb +0 -59
- data/test/end_to_end/comparison_test.rb +0 -104
- data/test/end_to_end/lib_comparison_test.rb +0 -18
- data/test/end_to_end/line_numbering_test.rb +0 -31
- data/test/end_to_end/samples_comparison_test.rb +0 -13
- data/test/end_to_end/test_comparison_test.rb +0 -18
- data/test/pt_testcase/pt_test.rb +0 -44
- data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +0 -200
- data/test/ripper_ruby_parser/parser_test.rb +0 -576
- data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +0 -597
- data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +0 -717
- data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +0 -536
- data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +0 -165
- data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +0 -209
- data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +0 -237
- data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +0 -429
- data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +0 -405
- data/test/ripper_ruby_parser/sexp_handlers/string_literals_test.rb +0 -973
- data/test/ripper_ruby_parser/sexp_processor_test.rb +0 -327
- data/test/ripper_ruby_parser/version_test.rb +0 -7
- data/test/samples/assignment.rb +0 -22
- data/test/samples/comments.rb +0 -13
- data/test/samples/conditionals.rb +0 -23
- data/test/samples/lambdas.rb +0 -5
- data/test/samples/loops.rb +0 -36
- data/test/samples/misc.rb +0 -285
- data/test/samples/number.rb +0 -9
- data/test/samples/operators.rb +0 -18
- data/test/samples/strings.rb +0 -147
- data/test/test_helper.rb +0 -111
@@ -1,576 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
|
4
|
-
|
5
|
-
describe RipperRubyParser::Parser do
|
6
|
-
let(:parser) { RipperRubyParser::Parser.new }
|
7
|
-
describe "#parse" do
|
8
|
-
it "returns an s-expression" do
|
9
|
-
result = parser.parse "foo"
|
10
|
-
_(result).must_be_instance_of Sexp
|
11
|
-
end
|
12
|
-
|
13
|
-
describe "for an empty program" do
|
14
|
-
it "returns nil" do
|
15
|
-
_("").must_be_parsed_as nil
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
describe "for a class declaration" do
|
20
|
-
it "works with a namespaced class name" do
|
21
|
-
_("class Foo::Bar; end")
|
22
|
-
.must_be_parsed_as s(:class,
|
23
|
-
s(:colon2, s(:const, :Foo), :Bar),
|
24
|
-
nil)
|
25
|
-
end
|
26
|
-
|
27
|
-
it "works for singleton classes" do
|
28
|
-
_("class << self; end").must_be_parsed_as s(:sclass, s(:self))
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "for a module declaration" do
|
33
|
-
it "works with a simple module name" do
|
34
|
-
_("module Foo; end")
|
35
|
-
.must_be_parsed_as s(:module, :Foo)
|
36
|
-
end
|
37
|
-
|
38
|
-
it "works with a namespaced module name" do
|
39
|
-
_("module Foo::Bar; end")
|
40
|
-
.must_be_parsed_as s(:module,
|
41
|
-
s(:colon2, s(:const, :Foo), :Bar))
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe "for empty parentheses" do
|
46
|
-
it "works with lone ()" do
|
47
|
-
_("()").must_be_parsed_as s(:nil)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe "for a begin..end block" do
|
52
|
-
it "works with no statements" do
|
53
|
-
_("begin; end")
|
54
|
-
.must_be_parsed_as s(:nil)
|
55
|
-
end
|
56
|
-
|
57
|
-
it "works with one statement" do
|
58
|
-
_("begin; foo; end")
|
59
|
-
.must_be_parsed_as s(:call, nil, :foo)
|
60
|
-
end
|
61
|
-
|
62
|
-
it "works with multiple statements" do
|
63
|
-
_("begin; foo; bar; end")
|
64
|
-
.must_be_parsed_as s(:block,
|
65
|
-
s(:call, nil, :foo),
|
66
|
-
s(:call, nil, :bar))
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe "for arguments" do
|
71
|
-
it "works for a simple case with splat" do
|
72
|
-
_("foo *bar")
|
73
|
-
.must_be_parsed_as s(:call,
|
74
|
-
nil,
|
75
|
-
:foo,
|
76
|
-
s(:splat, s(:call, nil, :bar)))
|
77
|
-
end
|
78
|
-
|
79
|
-
it "works for a multi-argument case with splat" do
|
80
|
-
_("foo bar, *baz")
|
81
|
-
.must_be_parsed_as s(:call,
|
82
|
-
nil,
|
83
|
-
:foo,
|
84
|
-
s(:call, nil, :bar),
|
85
|
-
s(:splat, s(:call, nil, :baz)))
|
86
|
-
end
|
87
|
-
|
88
|
-
it "works for a simple case passing a block" do
|
89
|
-
_("foo &bar")
|
90
|
-
.must_be_parsed_as s(:call, nil, :foo,
|
91
|
-
s(:block_pass,
|
92
|
-
s(:call, nil, :bar)))
|
93
|
-
end
|
94
|
-
|
95
|
-
it "works for a bare hash" do
|
96
|
-
_("foo bar => baz")
|
97
|
-
.must_be_parsed_as s(:call, nil, :foo,
|
98
|
-
s(:hash,
|
99
|
-
s(:call, nil, :bar),
|
100
|
-
s(:call, nil, :baz)))
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
describe "for the __ENCODING__ keyword" do
|
105
|
-
it "evaluates to the equivalent of Encoding::UTF_8" do
|
106
|
-
_("__ENCODING__")
|
107
|
-
.must_be_parsed_as s(:colon2, s(:const, :Encoding), :UTF_8)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
describe "for the __FILE__ keyword" do
|
112
|
-
describe "when not passing a file name" do
|
113
|
-
it "creates a string sexp with value '(string)'" do
|
114
|
-
_("__FILE__")
|
115
|
-
.must_be_parsed_as s(:str, "(string)")
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
describe "when passing a file name" do
|
120
|
-
it "creates a string sexp with the file name" do
|
121
|
-
result = parser.parse "__FILE__", "foo"
|
122
|
-
_(result).must_equal s(:str, "foo")
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
describe "for the __LINE__ keyword" do
|
128
|
-
it "creates a literal sexp with value of the line number" do
|
129
|
-
_("__LINE__")
|
130
|
-
.must_be_parsed_as s(:lit, 1)
|
131
|
-
_("\n__LINE__")
|
132
|
-
.must_be_parsed_as s(:lit, 2)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
describe "for the END keyword" do
|
137
|
-
it "converts to a :postexe iterator" do
|
138
|
-
_("END { foo }")
|
139
|
-
.must_be_parsed_as s(:iter, s(:postexe), 0, s(:call, nil, :foo))
|
140
|
-
end
|
141
|
-
|
142
|
-
it "works with an empty block" do
|
143
|
-
_("END { }")
|
144
|
-
.must_be_parsed_as s(:iter, s(:postexe), 0)
|
145
|
-
end
|
146
|
-
|
147
|
-
it "assigns correct line numbers" do
|
148
|
-
_("END {\nfoo\n}")
|
149
|
-
.must_be_parsed_as s(:iter,
|
150
|
-
s(:postexe).line(1), 0,
|
151
|
-
s(:call, nil, :foo).line(2)).line(1),
|
152
|
-
with_line_numbers: true
|
153
|
-
end
|
154
|
-
|
155
|
-
it "assigns correct line numbers to a embedded begin block" do
|
156
|
-
_("END {\nbegin\nfoo\nend\n}")
|
157
|
-
.must_be_parsed_as s(:iter,
|
158
|
-
s(:postexe).line(1), 0,
|
159
|
-
s(:call, nil, :foo).line(3)).line(1),
|
160
|
-
with_line_numbers: true
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
describe "for the BEGIN keyword" do
|
165
|
-
it "converts to a :preexe iterator" do
|
166
|
-
_("BEGIN { foo }")
|
167
|
-
.must_be_parsed_as s(:iter, s(:preexe), 0, s(:call, nil, :foo))
|
168
|
-
end
|
169
|
-
|
170
|
-
it "works with an empty block" do
|
171
|
-
_("BEGIN { }")
|
172
|
-
.must_be_parsed_as s(:iter, s(:preexe), 0)
|
173
|
-
end
|
174
|
-
|
175
|
-
it "assigns correct line numbers" do
|
176
|
-
_("BEGIN {\nfoo\n}")
|
177
|
-
.must_be_parsed_as s(:iter,
|
178
|
-
s(:preexe).line(1), 0,
|
179
|
-
s(:call, nil, :foo).line(2)).line(1),
|
180
|
-
with_line_numbers: true
|
181
|
-
end
|
182
|
-
|
183
|
-
it "assigns correct line numbers to a embedded begin block" do
|
184
|
-
_("BEGIN {\nbegin\nfoo\nend\n}")
|
185
|
-
.must_be_parsed_as s(:iter,
|
186
|
-
s(:preexe).line(1), 0,
|
187
|
-
s(:begin,
|
188
|
-
s(:call, nil, :foo).line(3)).line(2)).line(1),
|
189
|
-
with_line_numbers: true
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
describe "for constant lookups" do
|
194
|
-
it "works when explicitely starting from the root namespace" do
|
195
|
-
_("::Foo")
|
196
|
-
.must_be_parsed_as s(:colon3, :Foo)
|
197
|
-
end
|
198
|
-
|
199
|
-
it "works with a three-level constant lookup" do
|
200
|
-
_("Foo::Bar::Baz")
|
201
|
-
.must_be_parsed_as s(:colon2,
|
202
|
-
s(:colon2, s(:const, :Foo), :Bar),
|
203
|
-
:Baz)
|
204
|
-
end
|
205
|
-
|
206
|
-
it "works looking up a constant in a non-constant" do
|
207
|
-
_("foo::Bar").must_be_parsed_as s(:colon2,
|
208
|
-
s(:call, nil, :foo),
|
209
|
-
:Bar)
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
describe "for variable references" do
|
214
|
-
it "works for self" do
|
215
|
-
_("self")
|
216
|
-
.must_be_parsed_as s(:self)
|
217
|
-
end
|
218
|
-
|
219
|
-
it "works for instance variables" do
|
220
|
-
_("@foo")
|
221
|
-
.must_be_parsed_as s(:ivar, :@foo)
|
222
|
-
end
|
223
|
-
|
224
|
-
it "works for global variables" do
|
225
|
-
_("$foo")
|
226
|
-
.must_be_parsed_as s(:gvar, :$foo)
|
227
|
-
end
|
228
|
-
|
229
|
-
it "works for regexp match references" do
|
230
|
-
_("$1")
|
231
|
-
.must_be_parsed_as s(:nth_ref, 1)
|
232
|
-
end
|
233
|
-
|
234
|
-
specify { _("$'").must_be_parsed_as s(:back_ref, :"'") }
|
235
|
-
specify { _("$&").must_be_parsed_as s(:back_ref, :"&") }
|
236
|
-
|
237
|
-
it "works for class variables" do
|
238
|
-
_("@@foo")
|
239
|
-
.must_be_parsed_as s(:cvar, :@@foo)
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
describe "for expressions" do
|
244
|
-
it "handles assignment inside binary operator expressions" do
|
245
|
-
_("foo + (bar = baz)")
|
246
|
-
.must_be_parsed_as s(:call,
|
247
|
-
s(:call, nil, :foo),
|
248
|
-
:+,
|
249
|
-
s(:lasgn,
|
250
|
-
:bar,
|
251
|
-
s(:call, nil, :baz)))
|
252
|
-
end
|
253
|
-
|
254
|
-
it "handles assignment inside unary operator expressions" do
|
255
|
-
_("+(foo = bar)")
|
256
|
-
.must_be_parsed_as s(:call,
|
257
|
-
s(:lasgn, :foo, s(:call, nil, :bar)),
|
258
|
-
:+@)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
# Note: differences in the handling of comments are not caught by Sexp's
|
263
|
-
# implementation of equality.
|
264
|
-
describe "for comments" do
|
265
|
-
it "handles method comments" do
|
266
|
-
result = parser.parse "# Foo\ndef foo; end"
|
267
|
-
_(result).must_equal s(:defn,
|
268
|
-
:foo,
|
269
|
-
s(:args), s(:nil))
|
270
|
-
_(result.comments).must_equal "# Foo\n"
|
271
|
-
end
|
272
|
-
|
273
|
-
it "handles comments for methods with explicit receiver" do
|
274
|
-
result = parser.parse "# Foo\ndef foo.bar; end"
|
275
|
-
_(result).must_equal s(:defs,
|
276
|
-
s(:call, nil, :foo),
|
277
|
-
:bar,
|
278
|
-
s(:args),
|
279
|
-
s(:nil))
|
280
|
-
_(result.comments).must_equal "# Foo\n"
|
281
|
-
end
|
282
|
-
|
283
|
-
it "matches comments to the correct entity" do
|
284
|
-
result = parser.parse "# Foo\nclass Foo\n# Bar\ndef bar\nend\nend"
|
285
|
-
_(result).must_equal s(:class, :Foo, nil,
|
286
|
-
s(:defn, :bar,
|
287
|
-
s(:args), s(:nil)))
|
288
|
-
_(result.comments).must_equal "# Foo\n"
|
289
|
-
defn = result[3]
|
290
|
-
_(defn.sexp_type).must_equal :defn
|
291
|
-
_(defn.comments).must_equal "# Bar\n"
|
292
|
-
end
|
293
|
-
|
294
|
-
it "combines multi-line comments" do
|
295
|
-
result = parser.parse "# Foo\n# Bar\ndef foo; end"
|
296
|
-
_(result).must_equal s(:defn,
|
297
|
-
:foo,
|
298
|
-
s(:args), s(:nil))
|
299
|
-
_(result.comments).must_equal "# Foo\n# Bar\n"
|
300
|
-
end
|
301
|
-
|
302
|
-
it "drops comments inside method bodies" do
|
303
|
-
result = parser.parse <<-RUBY
|
304
|
-
# Foo
|
305
|
-
class Foo
|
306
|
-
# foo
|
307
|
-
def foo
|
308
|
-
bar # this is dropped
|
309
|
-
end
|
310
|
-
|
311
|
-
# bar
|
312
|
-
def bar
|
313
|
-
baz
|
314
|
-
end
|
315
|
-
end
|
316
|
-
RUBY
|
317
|
-
_(result).must_equal s(:class,
|
318
|
-
:Foo,
|
319
|
-
nil,
|
320
|
-
s(:defn, :foo, s(:args), s(:call, nil, :bar)),
|
321
|
-
s(:defn, :bar, s(:args), s(:call, nil, :baz)))
|
322
|
-
_(result.comments).must_equal "# Foo\n"
|
323
|
-
_(result[3].comments).must_equal "# foo\n"
|
324
|
-
_(result[4].comments).must_equal "# bar\n"
|
325
|
-
end
|
326
|
-
|
327
|
-
it "handles the use of symbols that are keywords" do
|
328
|
-
result = parser.parse "# Foo\ndef bar\n:class\nend"
|
329
|
-
_(result).must_equal s(:defn,
|
330
|
-
:bar,
|
331
|
-
s(:args),
|
332
|
-
s(:lit, :class))
|
333
|
-
_(result.comments).must_equal "# Foo\n"
|
334
|
-
end
|
335
|
-
|
336
|
-
it "handles use of singleton class inside methods" do
|
337
|
-
result = parser.parse "# Foo\ndef bar\nclass << self\nbaz\nend\nend"
|
338
|
-
_(result).must_equal s(:defn,
|
339
|
-
:bar,
|
340
|
-
s(:args),
|
341
|
-
s(:sclass, s(:self),
|
342
|
-
s(:call, nil, :baz)))
|
343
|
-
_(result.comments).must_equal "# Foo\n"
|
344
|
-
end
|
345
|
-
|
346
|
-
# TODO: Prefer assigning comment to the BEGIN instead
|
347
|
-
it "assigns comments on BEGIN blocks to the following item" do
|
348
|
-
result = parser.parse "# Bar\nBEGIN { }\n# Foo\ndef foo; end"
|
349
|
-
_(result).must_equal s(:block,
|
350
|
-
s(:iter, s(:preexe), 0),
|
351
|
-
s(:defn, :foo, s(:args), s(:nil)))
|
352
|
-
_(result[2].comments).must_equal "# Bar\n# Foo\n"
|
353
|
-
end
|
354
|
-
|
355
|
-
it "assigns comments on multiple BEGIN blocks to the following item" do
|
356
|
-
result = parser.parse "# Bar\nBEGIN { }\n# Baz\nBEGIN { }\n# Foo\ndef foo; end"
|
357
|
-
_(result).must_equal s(:block,
|
358
|
-
s(:iter, s(:preexe), 0),
|
359
|
-
s(:iter, s(:preexe), 0),
|
360
|
-
s(:defn, :foo, s(:args), s(:nil)))
|
361
|
-
_(result[3].comments).must_equal "# Bar\n# Baz\n# Foo\n"
|
362
|
-
end
|
363
|
-
|
364
|
-
it "assigns comments on BEGIN blocks to the first following item" do
|
365
|
-
result = parser.parse "# Bar\nBEGIN { }\n# Foo\nclass Bar\n# foo\ndef foo; end\nend"
|
366
|
-
_(result).must_equal s(:block,
|
367
|
-
s(:iter, s(:preexe), 0),
|
368
|
-
s(:class, :Bar, nil,
|
369
|
-
s(:defn, :foo, s(:args), s(:nil))))
|
370
|
-
_(result[2].comments).must_equal "# Bar\n# Foo\n"
|
371
|
-
_(result[2][3].comments).must_equal "# foo\n"
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
# Note: differences in the handling of line numbers are not caught by
|
376
|
-
# Sexp's implementation of equality.
|
377
|
-
describe "assigning line numbers" do
|
378
|
-
it "works for a plain method call" do
|
379
|
-
result = parser.parse "foo"
|
380
|
-
_(result.line).must_equal 1
|
381
|
-
end
|
382
|
-
|
383
|
-
it "works for a method call with parentheses" do
|
384
|
-
result = parser.parse "foo()"
|
385
|
-
_(result.line).must_equal 1
|
386
|
-
end
|
387
|
-
|
388
|
-
it "works for a method call with receiver" do
|
389
|
-
result = parser.parse "foo.bar"
|
390
|
-
_(result.line).must_equal 1
|
391
|
-
end
|
392
|
-
|
393
|
-
it "works for a method call with receiver and arguments" do
|
394
|
-
result = parser.parse "foo.bar baz"
|
395
|
-
_(result.line).must_equal 1
|
396
|
-
end
|
397
|
-
|
398
|
-
it "works for a method call with arguments" do
|
399
|
-
result = parser.parse "foo bar"
|
400
|
-
_(result.line).must_equal 1
|
401
|
-
end
|
402
|
-
|
403
|
-
it "works for a block with two lines" do
|
404
|
-
result = parser.parse "foo\nbar\n"
|
405
|
-
_(result.sexp_type).must_equal :block
|
406
|
-
_(result[1].line).must_equal 1
|
407
|
-
_(result[2].line).must_equal 2
|
408
|
-
_(result.line).must_equal 1
|
409
|
-
end
|
410
|
-
|
411
|
-
it "works for a constant reference" do
|
412
|
-
result = parser.parse "Foo"
|
413
|
-
_(result.line).must_equal 1
|
414
|
-
end
|
415
|
-
|
416
|
-
it "works for an instance variable" do
|
417
|
-
result = parser.parse "@foo"
|
418
|
-
_(result.line).must_equal 1
|
419
|
-
end
|
420
|
-
|
421
|
-
it "works for a global variable" do
|
422
|
-
result = parser.parse "$foo"
|
423
|
-
_(result.line).must_equal 1
|
424
|
-
end
|
425
|
-
|
426
|
-
it "works for a class variable" do
|
427
|
-
result = parser.parse "@@foo"
|
428
|
-
_(result.line).must_equal 1
|
429
|
-
end
|
430
|
-
|
431
|
-
it "works for a local variable" do
|
432
|
-
_("foo = bar\nfoo\n")
|
433
|
-
.must_be_parsed_as s(:block,
|
434
|
-
s(:lasgn, :foo, s(:call, nil, :bar).line(1)).line(1),
|
435
|
-
s(:lvar, :foo).line(2)).line(1),
|
436
|
-
with_line_numbers: true
|
437
|
-
end
|
438
|
-
|
439
|
-
it "works for an integer literal" do
|
440
|
-
result = parser.parse "42"
|
441
|
-
_(result.line).must_equal 1
|
442
|
-
end
|
443
|
-
|
444
|
-
it "works for a float literal" do
|
445
|
-
result = parser.parse "3.14"
|
446
|
-
_(result.line).must_equal 1
|
447
|
-
end
|
448
|
-
|
449
|
-
it "works for a range literal" do
|
450
|
-
result = parser.parse "0..4"
|
451
|
-
_(result.line).must_equal 1
|
452
|
-
end
|
453
|
-
|
454
|
-
it "works for an exclusive range literal" do
|
455
|
-
result = parser.parse "0...4"
|
456
|
-
_(result.line).must_equal 1
|
457
|
-
end
|
458
|
-
|
459
|
-
it "works for a symbol literal" do
|
460
|
-
result = parser.parse ":foo"
|
461
|
-
_(result.line).must_equal 1
|
462
|
-
end
|
463
|
-
|
464
|
-
it "works for a keyword-like symbol literal" do
|
465
|
-
result = parser.parse ":and"
|
466
|
-
_(result.line).must_equal 1
|
467
|
-
end
|
468
|
-
|
469
|
-
it "works for a string literal" do
|
470
|
-
result = parser.parse '"foo"'
|
471
|
-
_(result.line).must_equal 1
|
472
|
-
end
|
473
|
-
|
474
|
-
it "works for a backtick string literal" do
|
475
|
-
result = parser.parse "`foo`"
|
476
|
-
_(result.line).must_equal 1
|
477
|
-
end
|
478
|
-
|
479
|
-
it "works for a plain regexp literal" do
|
480
|
-
result = parser.parse "/foo/"
|
481
|
-
_(result.line).must_equal 1
|
482
|
-
end
|
483
|
-
|
484
|
-
it "works for a regular expression back reference" do
|
485
|
-
result = parser.parse "$1"
|
486
|
-
_(result.line).must_equal 1
|
487
|
-
end
|
488
|
-
|
489
|
-
it "works for self" do
|
490
|
-
result = parser.parse "self"
|
491
|
-
_(result.line).must_equal 1
|
492
|
-
end
|
493
|
-
|
494
|
-
it "works for __FILE__" do
|
495
|
-
result = parser.parse "__FILE__"
|
496
|
-
_(result.line).must_equal 1
|
497
|
-
end
|
498
|
-
|
499
|
-
it "works for nil" do
|
500
|
-
result = parser.parse "nil"
|
501
|
-
_(result.line).must_equal 1
|
502
|
-
end
|
503
|
-
|
504
|
-
it "works for a symbol literal" do
|
505
|
-
result = parser.parse ":foo"
|
506
|
-
_(result.line).must_equal 1
|
507
|
-
end
|
508
|
-
|
509
|
-
it "works for a class definition" do
|
510
|
-
result = parser.parse "class Foo; end"
|
511
|
-
_(result.line).must_equal 1
|
512
|
-
end
|
513
|
-
|
514
|
-
it "works for a module definition" do
|
515
|
-
result = parser.parse "module Foo; end"
|
516
|
-
_(result.line).must_equal 1
|
517
|
-
end
|
518
|
-
|
519
|
-
it "works for a method definition" do
|
520
|
-
result = parser.parse "def foo; end"
|
521
|
-
_(result.line).must_equal 1
|
522
|
-
end
|
523
|
-
|
524
|
-
it "works for assignment of the empty hash" do
|
525
|
-
result = parser.parse "foo = {}"
|
526
|
-
_(result.line).must_equal 1
|
527
|
-
end
|
528
|
-
|
529
|
-
it "works for multiple assignment of empty hashes" do
|
530
|
-
result = parser.parse "foo, bar = {}, {}"
|
531
|
-
_(result.line).must_equal 1
|
532
|
-
end
|
533
|
-
|
534
|
-
it "assigns line numbers to nested sexps without their own line numbers" do
|
535
|
-
_("foo(bar) do\nnext baz\nend\n")
|
536
|
-
.must_be_parsed_as s(:iter,
|
537
|
-
s(:call, nil, :foo, s(:call, nil, :bar).line(1)).line(1),
|
538
|
-
0,
|
539
|
-
s(:next, s(:call, nil, :baz).line(2)).line(2)).line(1),
|
540
|
-
with_line_numbers: true
|
541
|
-
end
|
542
|
-
|
543
|
-
describe "when a line number is passed" do
|
544
|
-
it "shifts all line numbers as appropriate" do
|
545
|
-
result = parser.parse "foo\nbar\n", "(string)", 3
|
546
|
-
_(result).must_equal s(:block,
|
547
|
-
s(:call, nil, :foo),
|
548
|
-
s(:call, nil, :bar))
|
549
|
-
_(result.line).must_equal 3
|
550
|
-
_(result[1].line).must_equal 3
|
551
|
-
_(result[2].line).must_equal 4
|
552
|
-
end
|
553
|
-
end
|
554
|
-
end
|
555
|
-
end
|
556
|
-
|
557
|
-
describe "#trickle_up_line_numbers" do
|
558
|
-
it "works through several nested levels" do
|
559
|
-
inner = s(:foo)
|
560
|
-
outer = s(:bar, s(:baz, s(:qux, inner)))
|
561
|
-
outer.line = 42
|
562
|
-
parser.send :trickle_down_line_numbers, outer
|
563
|
-
_(inner.line).must_equal 42
|
564
|
-
end
|
565
|
-
end
|
566
|
-
|
567
|
-
describe "#trickle_down_line_numbers" do
|
568
|
-
it "works through several nested levels" do
|
569
|
-
inner = s(:foo)
|
570
|
-
inner.line = 42
|
571
|
-
outer = s(:bar, s(:baz, s(:qux, inner)))
|
572
|
-
parser.send :trickle_up_line_numbers, outer
|
573
|
-
_(outer.line).must_equal 42
|
574
|
-
end
|
575
|
-
end
|
576
|
-
end
|