ripper_ruby_parser 1.6.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +8 -25
  4. data/lib/ripper_ruby_parser.rb +2 -2
  5. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +54 -23
  6. data/lib/ripper_ruby_parser/parser.rb +3 -3
  7. data/lib/ripper_ruby_parser/sexp_handlers.rb +11 -9
  8. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +10 -11
  9. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +48 -63
  10. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +17 -19
  11. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +35 -2
  12. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +15 -242
  13. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +4 -2
  14. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +1 -1
  15. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +24 -24
  16. data/lib/ripper_ruby_parser/sexp_handlers/string_literals.rb +266 -0
  17. data/lib/ripper_ruby_parser/sexp_processor.rb +47 -78
  18. data/lib/ripper_ruby_parser/unescape.rb +79 -50
  19. data/lib/ripper_ruby_parser/version.rb +1 -1
  20. metadata +115 -78
  21. data/Rakefile +0 -33
  22. data/test/end_to_end/comments_test.rb +0 -59
  23. data/test/end_to_end/comparison_test.rb +0 -104
  24. data/test/end_to_end/lib_comparison_test.rb +0 -29
  25. data/test/end_to_end/line_numbering_test.rb +0 -64
  26. data/test/end_to_end/samples_comparison_test.rb +0 -13
  27. data/test/end_to_end/test_comparison_test.rb +0 -32
  28. data/test/pt_testcase/pt_test.rb +0 -44
  29. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +0 -190
  30. data/test/ripper_ruby_parser/parser_test.rb +0 -469
  31. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +0 -649
  32. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +0 -661
  33. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +0 -536
  34. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +0 -1117
  35. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +0 -209
  36. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +0 -267
  37. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +0 -427
  38. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +0 -399
  39. data/test/ripper_ruby_parser/sexp_processor_test.rb +0 -303
  40. data/test/ripper_ruby_parser/version_test.rb +0 -7
  41. data/test/samples/assignment.rb +0 -17
  42. data/test/samples/comments.rb +0 -13
  43. data/test/samples/conditionals.rb +0 -23
  44. data/test/samples/loops.rb +0 -36
  45. data/test/samples/misc.rb +0 -278
  46. data/test/samples/number.rb +0 -7
  47. data/test/samples/operators.rb +0 -18
  48. data/test/samples/strings.rb +0 -140
  49. data/test/test_helper.rb +0 -79
@@ -1,1117 +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
-
8
- describe '#parse' do
9
- describe 'for regexp literals' do
10
- it 'works for a simple regex literal' do
11
- '/foo/'.
12
- must_be_parsed_as s(:lit, /foo/)
13
- end
14
-
15
- it 'works for regex literals with escaped right parenthesis' do
16
- '/\\)/'.
17
- must_be_parsed_as s(:lit, /\)/)
18
- end
19
-
20
- it 'works for regex literals with escape sequences' do
21
- '/\\)\\n\\\\/'.
22
- must_be_parsed_as s(:lit, /\)\n\\/)
23
- end
24
-
25
- it 'does not fix encoding' do
26
- '/2\302\275/'.
27
- must_be_parsed_as s(:lit, /2\302\275/)
28
- end
29
-
30
- it 'works for a regex literal with the multiline flag' do
31
- '/foo/m'.
32
- must_be_parsed_as s(:lit, /foo/m)
33
- end
34
-
35
- it 'works for a regex literal with the extended flag' do
36
- '/foo/x'.
37
- must_be_parsed_as s(:lit, /foo/x)
38
- end
39
-
40
- it 'works for a regex literal with the ignorecase flag' do
41
- '/foo/i'.
42
- must_be_parsed_as s(:lit, /foo/i)
43
- end
44
-
45
- it 'works for a regex literal with a combination of flags' do
46
- '/foo/ixmn'.
47
- must_be_parsed_as s(:lit, /foo/mixn)
48
- end
49
-
50
- it 'works with the no-encoding flag' do
51
- '/foo/n'.
52
- must_be_parsed_as s(:lit, /foo/n)
53
- end
54
-
55
- it 'works with line continuation' do
56
- "/foo\\\nbar/".
57
- must_be_parsed_as s(:lit, /foobar/)
58
- end
59
-
60
- describe 'for a %r-delimited regex literal' do
61
- it 'works for the simple case with escape sequences' do
62
- '%r[foo\nbar]'.
63
- must_be_parsed_as s(:lit, /foo\nbar/)
64
- end
65
-
66
- it 'works with odd delimiters and escape sequences' do
67
- '%r_foo\nbar_'.
68
- must_be_parsed_as s(:lit, /foo\nbar/)
69
- end
70
- end
71
-
72
- describe 'with interpolations' do
73
- it 'works for a simple interpolation' do
74
- '/foo#{bar}baz/'.
75
- must_be_parsed_as s(:dregx,
76
- 'foo',
77
- s(:evstr, s(:call, nil, :bar)),
78
- s(:str, 'baz'))
79
- end
80
-
81
- it 'works for a regex literal with flags and interpolation' do
82
- '/foo#{bar}/ixm'.
83
- must_be_parsed_as s(:dregx,
84
- 'foo',
85
- s(:evstr, s(:call, nil, :bar)),
86
- 7)
87
- end
88
-
89
- it 'works with the no-encoding flag' do
90
- '/foo#{bar}/n'.
91
- must_be_parsed_as s(:dregx,
92
- 'foo',
93
- s(:evstr,
94
- s(:call, nil, :bar)), 32)
95
- end
96
-
97
- it 'works with the unicode-encoding flag' do
98
- '/foo#{bar}/u'.
99
- must_be_parsed_as s(:dregx,
100
- 'foo',
101
- s(:evstr,
102
- s(:call, nil, :bar)), 16)
103
- end
104
-
105
- it 'works with unicode flag plus other flag' do
106
- '/foo#{bar}/un'.
107
- must_be_parsed_as s(:dregx,
108
- 'foo',
109
- s(:evstr,
110
- s(:call, nil, :bar)), 48)
111
- end
112
-
113
- it 'works with the euc-encoding flag' do
114
- '/foo#{bar}/e'.
115
- must_be_parsed_as s(:dregx,
116
- 'foo',
117
- s(:evstr,
118
- s(:call, nil, :bar)), 16)
119
- end
120
-
121
- it 'works with the sjis-encoding flag' do
122
- '/foo#{bar}/s'.
123
- must_be_parsed_as s(:dregx,
124
- 'foo',
125
- s(:evstr,
126
- s(:call, nil, :bar)), 16)
127
- end
128
-
129
- it 'works for a regex literal with interpolate-once flag' do
130
- '/foo#{bar}/o'.
131
- must_be_parsed_as s(:dregx_once,
132
- 'foo',
133
- s(:evstr, s(:call, nil, :bar)))
134
- end
135
-
136
- it 'works with an empty interpolation' do
137
- '/foo#{}bar/'.
138
- must_be_parsed_as s(:dregx,
139
- 'foo',
140
- s(:evstr),
141
- s(:str, 'bar'))
142
- end
143
-
144
- describe 'containing just a literal string' do
145
- it 'performs the interpolation when it is at the end' do
146
- '/foo#{"bar"}/'.must_be_parsed_as s(:lit, /foobar/)
147
- end
148
-
149
- it 'performs the interpolation when it is in the middle' do
150
- '/foo#{"bar"}baz/'.must_be_parsed_as s(:lit, /foobarbaz/)
151
- end
152
-
153
- it 'performs the interpolation when it is at the start' do
154
- '/#{"foo"}bar/'.must_be_parsed_as s(:lit, /foobar/)
155
- end
156
- end
157
- end
158
- end
159
-
160
- describe 'for string literals' do
161
- it 'works for empty strings' do
162
- "''".
163
- must_be_parsed_as s(:str, '')
164
- end
165
-
166
- it 'sets the encoding for literal strings to utf8 even if ascii would do' do
167
- parser = RipperRubyParser::Parser.new
168
- result = parser.parse '"foo"'
169
- result.must_equal s(:str, 'foo')
170
- result[1].encoding.to_s.must_equal 'UTF-8'
171
- end
172
-
173
- it 'handles line breaks within double-quoted strings' do
174
- "\"foo\nbar\"".
175
- must_be_parsed_as s(:str, "foo\nbar")
176
- end
177
-
178
- it 'handles line continuation with double-quoted strings' do
179
- "\"foo\\\nbar\"".
180
- must_be_parsed_as s(:str, 'foobar')
181
- end
182
-
183
- it 'escapes line continuation with double-quoted strings' do
184
- "\"foo\\\\\nbar\"".
185
- must_be_parsed_as s(:str, "foo\\\nbar")
186
- end
187
-
188
- describe 'with double-quoted strings with escape sequences' do
189
- it 'works for strings with escape sequences' do
190
- '"\\n"'.
191
- must_be_parsed_as s(:str, "\n")
192
- end
193
-
194
- it 'works for strings with useless escape sequences' do
195
- '"F\\OO"'.
196
- must_be_parsed_as s(:str, 'FOO')
197
- end
198
-
199
- it 'works for strings with escaped backslashes' do
200
- '"\\\\n"'.
201
- must_be_parsed_as s(:str, '\\n')
202
- end
203
-
204
- it 'works for a representation of a regex literal with escaped right parenthesis' do
205
- '"/\\\\)/"'.
206
- must_be_parsed_as s(:str, '/\\)/')
207
- end
208
-
209
- it 'works for a uselessly escaped right parenthesis' do
210
- '"/\\)/"'.
211
- must_be_parsed_as s(:str, '/)/')
212
- end
213
-
214
- it 'works for a string containing escaped quotes' do
215
- '"\\""'.
216
- must_be_parsed_as s(:str, '"')
217
- end
218
-
219
- it 'works with hex escapes' do
220
- '"\\x36"'.must_be_parsed_as s(:str, '6')
221
- '"\\x4a"'.must_be_parsed_as s(:str, 'J')
222
- '"\\x4A"'.must_be_parsed_as s(:str, 'J')
223
- '"\\x3Z"'.must_be_parsed_as s(:str, "\x03Z")
224
- end
225
-
226
- it 'works with single-letter escapes' do
227
- '"foo\\abar"'.must_be_parsed_as s(:str, "foo\abar")
228
- '"foo\\bbar"'.must_be_parsed_as s(:str, "foo\bbar")
229
- '"foo\\ebar"'.must_be_parsed_as s(:str, "foo\ebar")
230
- '"foo\\fbar"'.must_be_parsed_as s(:str, "foo\fbar")
231
- '"foo\\nbar"'.must_be_parsed_as s(:str, "foo\nbar")
232
- '"foo\\rbar"'.must_be_parsed_as s(:str, "foo\rbar")
233
- '"foo\\sbar"'.must_be_parsed_as s(:str, "foo\sbar")
234
- '"foo\\tbar"'.must_be_parsed_as s(:str, "foo\tbar")
235
- '"foo\\vbar"'.must_be_parsed_as s(:str, "foo\vbar")
236
- end
237
-
238
- it 'works with octal number escapes' do
239
- '"foo\\123bar"'.must_be_parsed_as s(:str, "foo\123bar")
240
- '"foo\\23bar"'.must_be_parsed_as s(:str, "foo\023bar")
241
- '"foo\\3bar"'.must_be_parsed_as s(:str, "foo\003bar")
242
-
243
- '"foo\\118bar"'.must_be_parsed_as s(:str, "foo\0118bar")
244
- '"foo\\18bar"'.must_be_parsed_as s(:str, "foo\0018bar")
245
- end
246
-
247
- it 'works with simple short hand control sequence escapes' do
248
- '"foo\\cabar"'.must_be_parsed_as s(:str, "foo\cabar")
249
- '"foo\\cZbar"'.must_be_parsed_as s(:str, "foo\cZbar")
250
- end
251
-
252
- it 'works with simple regular control sequence escapes' do
253
- '"foo\\C-abar"'.must_be_parsed_as s(:str, "foo\C-abar")
254
- '"foo\\C-Zbar"'.must_be_parsed_as s(:str, "foo\C-Zbar")
255
- end
256
-
257
- it 'works with unicode escapes' do
258
- '"foo\\u273bbar"'.must_be_parsed_as s(:str, 'foo✻bar')
259
- end
260
-
261
- it 'works with unicode escapes with braces' do
262
- '"foo\\u{273b}bar"'.must_be_parsed_as s(:str, 'foo✻bar')
263
- end
264
-
265
- it 'converts to unicode if possible' do
266
- '"2\302\275"'.must_be_parsed_as s(:str, '2½')
267
- end
268
-
269
- it 'does not convert to unicode if result is not valid' do
270
- '"2\x82\302\275"'.
271
- must_be_parsed_as s(:str,
272
- (+"2\x82\xC2\xBD").force_encoding('ascii-8bit'))
273
- end
274
- end
275
-
276
- describe 'with interpolations containing just a literal string' do
277
- it 'performs the interpolation when it is at the end' do
278
- '"foo#{"bar"}"'.must_be_parsed_as s(:str, 'foobar')
279
- end
280
-
281
- it 'performs the interpolation when it is in the middle' do
282
- '"foo#{"bar"}baz"'.must_be_parsed_as s(:str, 'foobarbaz')
283
- end
284
-
285
- it 'performs the interpolation when it is at the start' do
286
- '"#{"foo"}bar"'.must_be_parsed_as s(:str, 'foobar')
287
- end
288
- end
289
-
290
- describe 'with interpolations without braces' do
291
- it 'works for ivars' do
292
- "\"foo\#@bar\"".must_be_parsed_as s(:dstr,
293
- 'foo',
294
- s(:evstr, s(:ivar, :@bar)))
295
- end
296
-
297
- it 'works for gvars' do
298
- "\"foo\#$bar\"".must_be_parsed_as s(:dstr,
299
- 'foo',
300
- s(:evstr, s(:gvar, :$bar)))
301
- end
302
-
303
- it 'works for cvars' do
304
- "\"foo\#@@bar\"".must_be_parsed_as s(:dstr,
305
- 'foo',
306
- s(:evstr, s(:cvar, :@@bar)))
307
- end
308
- end
309
-
310
- describe 'with interpolations with braces' do
311
- it 'works for trivial interpolated strings' do
312
- '"#{foo}"'.
313
- must_be_parsed_as s(:dstr,
314
- '',
315
- s(:evstr,
316
- s(:call, nil, :foo)))
317
- end
318
-
319
- it 'works for basic interpolated strings' do
320
- '"foo#{bar}"'.
321
- must_be_parsed_as s(:dstr,
322
- 'foo',
323
- s(:evstr,
324
- s(:call, nil, :bar)))
325
- end
326
-
327
- it 'works for strings with several interpolations' do
328
- '"foo#{bar}baz#{qux}"'.
329
- must_be_parsed_as s(:dstr,
330
- 'foo',
331
- s(:evstr, s(:call, nil, :bar)),
332
- s(:str, 'baz'),
333
- s(:evstr, s(:call, nil, :qux)))
334
- end
335
-
336
- it 'correctly handles two interpolations in a row' do
337
- "\"\#{bar}\#{qux}\"".
338
- must_be_parsed_as s(:dstr,
339
- '',
340
- s(:evstr, s(:call, nil, :bar)),
341
- s(:evstr, s(:call, nil, :qux)))
342
- end
343
-
344
- it 'works with an empty interpolation' do
345
- "\"foo\#{}bar\"".
346
- must_be_parsed_as s(:dstr,
347
- 'foo',
348
- s(:evstr),
349
- s(:str, 'bar'))
350
- end
351
-
352
- it 'correctly handles interpolation with __FILE__ before another interpolation' do
353
- "\"foo\#{__FILE__}\#{bar}\"".
354
- must_be_parsed_as s(:dstr,
355
- 'foo(string)',
356
- s(:evstr, s(:call, nil, :bar)))
357
- end
358
-
359
- it 'correctly handles interpolation with __FILE__ after another interpolation' do
360
- "\"\#{bar}foo\#{__FILE__}\"".
361
- must_be_parsed_as s(:dstr,
362
- '',
363
- s(:evstr, s(:call, nil, :bar)),
364
- s(:str, 'foo'),
365
- s(:str, '(string)'))
366
- end
367
-
368
- it 'correctly handles nested interpolation' do
369
- '"foo#{"bar#{baz}"}"'.
370
- must_be_parsed_as s(:dstr,
371
- 'foobar',
372
- s(:evstr, s(:call, nil, :baz)))
373
- end
374
-
375
- it 'correctly handles consecutive nested interpolation' do
376
- '"foo#{"bar#{baz}"}foo#{"bar#{baz}"}"'.
377
- must_be_parsed_as s(:dstr,
378
- 'foobar',
379
- s(:evstr, s(:call, nil, :baz)),
380
- s(:str, 'foo'),
381
- s(:str, 'bar'),
382
- s(:evstr, s(:call, nil, :baz)))
383
- end
384
- end
385
-
386
- describe 'with interpolations and escape sequences' do
387
- it 'works when interpolations are followed by escape sequences' do
388
- '"#{foo}\\n"'.
389
- must_be_parsed_as s(:dstr,
390
- '',
391
- s(:evstr, s(:call, nil, :foo)),
392
- s(:str, "\n"))
393
- end
394
-
395
- it 'works when interpolations contain a mix of other string-like literals' do
396
- '"#{[:foo, \'bar\']}\\n"'.
397
- must_be_parsed_as s(:dstr,
398
- '',
399
- s(:evstr, s(:array, s(:lit, :foo), s(:str, 'bar'))),
400
- s(:str, "\n"))
401
- end
402
-
403
- it 'converts to unicode after interpolation' do
404
- '"#{foo}2\302\275"'.
405
- must_be_parsed_as s(:dstr,
406
- '',
407
- s(:evstr, s(:call, nil, :foo)),
408
- s(:str, '2½'))
409
- end
410
-
411
- it 'convert single null byte to unicode after interpolation' do
412
- '"#{foo}\0"'.
413
- must_be_parsed_as s(:dstr,
414
- '',
415
- s(:evstr, s(:call, nil, :foo)),
416
- s(:str, "\u0000"))
417
- end
418
-
419
- it 'converts string with null to unicode after interpolation' do
420
- '"#{foo}bar\0"'.
421
- must_be_parsed_as s(:dstr,
422
- '',
423
- s(:evstr, s(:call, nil, :foo)),
424
- s(:str, "bar\x00"))
425
- end
426
- end
427
-
428
- describe 'with single quoted strings' do
429
- it 'works with escaped single quotes' do
430
- "'foo\\'bar'".
431
- must_be_parsed_as s(:str, "foo'bar")
432
- end
433
-
434
- it 'works with embedded backslashes' do
435
- "'foo\\abar'".
436
- must_be_parsed_as s(:str, 'foo\abar')
437
- end
438
-
439
- it 'works with escaped embedded backslashes' do
440
- "'foo\\\\abar'".
441
- must_be_parsed_as s(:str, 'foo\abar')
442
- end
443
-
444
- it 'works with sequences of backslashes' do
445
- "'foo\\\\\\abar'".
446
- must_be_parsed_as s(:str, 'foo\\\\abar')
447
- end
448
-
449
- it 'does not process line continuation' do
450
- "'foo\\\nbar'".
451
- must_be_parsed_as s(:str, "foo\\\nbar")
452
- end
453
- end
454
-
455
- describe 'with %Q-delimited strings' do
456
- it 'works for the simple case' do
457
- '%Q[bar]'.
458
- must_be_parsed_as s(:str, 'bar')
459
- end
460
-
461
- it 'works for escape sequences' do
462
- '%Q[foo\\nbar]'.
463
- must_be_parsed_as s(:str, "foo\nbar")
464
- end
465
-
466
- it 'works for multi-line strings' do
467
- "%Q[foo\nbar]".
468
- must_be_parsed_as s(:str, "foo\nbar")
469
- end
470
-
471
- it 'handles line continuation' do
472
- "%Q[foo\\\nbar]".
473
- must_be_parsed_as s(:str, 'foobar')
474
- end
475
- end
476
-
477
- describe 'with %q-delimited strings' do
478
- it 'works for the simple case' do
479
- '%q[bar]'.
480
- must_be_parsed_as s(:str, 'bar')
481
- end
482
-
483
- it 'does not handle for escape sequences' do
484
- '%q[foo\\nbar]'.
485
- must_be_parsed_as s(:str, 'foo\nbar')
486
- end
487
-
488
- it 'works for multi-line strings' do
489
- "%q[foo\nbar]".
490
- must_be_parsed_as s(:str, "foo\nbar")
491
- end
492
-
493
- it 'handles line continuation' do
494
- "%q[foo\\\nbar]".
495
- must_be_parsed_as s(:str, "foo\\\nbar")
496
- end
497
- end
498
-
499
- describe 'with %-delimited strings' do
500
- it 'works for the simple case' do
501
- '%(bar)'.
502
- must_be_parsed_as s(:str, 'bar')
503
- end
504
-
505
- it 'works for escape sequences' do
506
- '%(foo\nbar)'.
507
- must_be_parsed_as s(:str, "foo\nbar")
508
- end
509
-
510
- it 'works for multiple lines' do
511
- "%(foo\nbar)".
512
- must_be_parsed_as s(:str, "foo\nbar")
513
- end
514
-
515
- it 'works with line continuations' do
516
- "%(foo\\\nbar)".
517
- must_be_parsed_as s(:str, 'foobar')
518
- end
519
-
520
- it 'works for odd delimiters' do
521
- '%!foo\nbar!'.
522
- must_be_parsed_as s(:str, "foo\nbar")
523
- end
524
- end
525
-
526
- describe 'with string concatenation' do
527
- it 'performs the concatenation in the case of two simple literal strings' do
528
- '"foo" "bar"'.must_be_parsed_as s(:str, 'foobar')
529
- end
530
-
531
- it 'performs the concatenation when the right string has interpolations' do
532
- "\"foo\" \"bar\#{baz}\"".
533
- must_be_parsed_as s(:dstr,
534
- 'foobar',
535
- s(:evstr, s(:call, nil, :baz)))
536
- end
537
-
538
- describe 'when the left string has interpolations' do
539
- it 'performs the concatenation' do
540
- "\"foo\#{bar}\" \"baz\"".
541
- must_be_parsed_as s(:dstr,
542
- 'foo',
543
- s(:evstr, s(:call, nil, :bar)),
544
- s(:str, 'baz'))
545
- end
546
-
547
- it 'performs the concatenation with an empty string' do
548
- "\"foo\#{bar}\" \"\"".
549
- must_be_parsed_as s(:dstr,
550
- 'foo',
551
- s(:evstr, s(:call, nil, :bar)),
552
- s(:str, ''))
553
- end
554
- end
555
-
556
- describe 'when both strings have interpolations' do
557
- it 'performs the concatenation' do
558
- "\"foo\#{bar}\" \"baz\#{qux}\"".
559
- must_be_parsed_as s(:dstr,
560
- 'foo',
561
- s(:evstr, s(:call, nil, :bar)),
562
- s(:str, 'baz'),
563
- s(:evstr, s(:call, nil, :qux)))
564
- end
565
-
566
- it 'removes empty substrings from the concatenation' do
567
- "\"foo\#{bar}\" \"\#{qux}\"".
568
- must_be_parsed_as s(:dstr,
569
- 'foo',
570
- s(:evstr, s(:call, nil, :bar)),
571
- s(:evstr, s(:call, nil, :qux)))
572
- end
573
- end
574
- end
575
-
576
- describe 'for heredocs' do
577
- it 'works for the simple case' do
578
- "<<FOO\nbar\nFOO".
579
- must_be_parsed_as s(:str, "bar\n")
580
- end
581
-
582
- it 'works with multiple lines' do
583
- "<<FOO\nbar\nbaz\nFOO".
584
- must_be_parsed_as s(:str, "bar\nbaz\n")
585
- end
586
-
587
- it 'works for the indentable case' do
588
- "<<-FOO\n bar\n FOO".
589
- must_be_parsed_as s(:str, " bar\n")
590
- end
591
-
592
- it 'works for the automatically outdenting case' do
593
- " <<~FOO\n bar\n FOO".
594
- must_be_parsed_as s(:str, "bar\n")
595
- end
596
-
597
- it 'works for escape sequences' do
598
- "<<FOO\nbar\\tbaz\nFOO".
599
- must_be_parsed_as s(:str, "bar\tbaz\n")
600
- end
601
-
602
- it 'converts \r to carriage returns' do
603
- "<<FOO\nbar\\rbaz\\r\nFOO".
604
- must_be_parsed_as s(:str, "bar\rbaz\r\n")
605
- end
606
-
607
- it 'does not unescape with single quoted version' do
608
- "<<'FOO'\nbar\\tbaz\nFOO".
609
- must_be_parsed_as s(:str, "bar\\tbaz\n")
610
- end
611
-
612
- it 'works with multiple lines with the single quoted version' do
613
- "<<'FOO'\nbar\nbaz\nFOO".
614
- must_be_parsed_as s(:str, "bar\nbaz\n")
615
- end
616
-
617
- it 'does not unescape with indentable single quoted version' do
618
- "<<-'FOO'\n bar\\tbaz\n FOO".
619
- must_be_parsed_as s(:str, " bar\\tbaz\n")
620
- end
621
-
622
- it 'does not unescape the automatically outdenting single quoted version' do
623
- "<<~'FOO'\n bar\\tbaz\n FOO".
624
- must_be_parsed_as s(:str, "bar\\tbaz\n")
625
- end
626
-
627
- it 'handles line continuation' do
628
- "<<FOO\nbar\\\nbaz\nFOO".
629
- must_be_parsed_as s(:str, "barbaz\n")
630
- end
631
-
632
- it 'escapes line continuation' do
633
- "<<FOO\nbar\\\\\nbaz\nFOO".
634
- must_be_parsed_as s(:str, "bar\\\nbaz\n")
635
- end
636
-
637
- it 'converts to unicode' do
638
- "<<FOO\n2\\302\\275\nFOO".
639
- must_be_parsed_as s(:str, "2½\n")
640
- end
641
-
642
- it 'handles interpolation' do
643
- "<<FOO\n\#{bar}\nFOO".
644
- must_be_parsed_as s(:dstr, '',
645
- s(:evstr, s(:call, nil, :bar)),
646
- s(:str, "\n"))
647
- end
648
-
649
- it 'handles line continuation after interpolation' do
650
- "<<FOO\n\#{bar}\nbaz\\\nqux\nFOO".
651
- must_be_parsed_as s(:dstr, '',
652
- s(:evstr, s(:call, nil, :bar)),
653
- s(:str, "\nbazqux\n"))
654
- end
655
-
656
- it 'handles line continuation after interpolation for the indentable case' do
657
- "<<-FOO\n\#{bar}\nbaz\\\nqux\nFOO".
658
- must_be_parsed_as s(:dstr, '',
659
- s(:evstr, s(:call, nil, :bar)),
660
- s(:str, "\nbazqux\n"))
661
- end
662
- end
663
- end
664
-
665
- describe 'for word list literals with %w delimiter' do
666
- it 'works for the simple case' do
667
- '%w(foo bar)'.
668
- must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar'))
669
- end
670
-
671
- it 'does not perform interpolation' do
672
- '%w(foo\\nbar baz)'.
673
- must_be_parsed_as s(:array, s(:str, 'foo\\nbar'), s(:str, 'baz'))
674
- end
675
-
676
- it 'handles line continuation' do
677
- "%w(foo\\\nbar baz)".
678
- must_be_parsed_as s(:array, s(:str, "foo\nbar"), s(:str, 'baz'))
679
- end
680
-
681
- it 'handles escaped spaces' do
682
- '%w(foo bar\ baz)'.
683
- must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar baz'))
684
- end
685
- end
686
-
687
- describe 'for word list literals with %W delimiter' do
688
- it 'works for the simple case' do
689
- '%W(foo bar)'.
690
- must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar'))
691
- end
692
-
693
- it 'handles escaped spaces' do
694
- '%W(foo bar\ baz)'.
695
- must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar baz'))
696
- end
697
-
698
- it 'correctly handles interpolation' do
699
- "%W(foo \#{bar} baz)".
700
- must_be_parsed_as s(:array,
701
- s(:str, 'foo'),
702
- s(:dstr, '', s(:evstr, s(:call, nil, :bar))),
703
- s(:str, 'baz'))
704
- end
705
-
706
- it 'correctly handles braceless interpolation' do
707
- "%W(foo \#@bar baz)".
708
- must_be_parsed_as s(:array,
709
- s(:str, 'foo'),
710
- s(:dstr, '', s(:evstr, s(:ivar, :@bar))),
711
- s(:str, 'baz'))
712
- end
713
-
714
- it 'correctly handles in-word interpolation' do
715
- "%W(foo \#{bar}baz)".
716
- must_be_parsed_as s(:array,
717
- s(:str, 'foo'),
718
- s(:dstr,
719
- '',
720
- s(:evstr, s(:call, nil, :bar)),
721
- s(:str, 'baz')))
722
- end
723
-
724
- it 'correctly handles escape sequences' do
725
- '%W(foo\nbar baz)'.
726
- must_be_parsed_as s(:array,
727
- s(:str, "foo\nbar"),
728
- s(:str, 'baz'))
729
- end
730
-
731
- it 'converts to unicode if possible' do
732
- '%W(2\302\275)'.must_be_parsed_as s(:array, s(:str, '2½'))
733
- end
734
-
735
- it 'correctly handles line continuation' do
736
- "%W(foo\\\nbar baz)".
737
- must_be_parsed_as s(:array,
738
- s(:str, "foo\nbar"),
739
- s(:str, 'baz'))
740
- end
741
-
742
- it 'correctly handles multiple lines' do
743
- "%W(foo\nbar baz)".
744
- must_be_parsed_as s(:array,
745
- s(:str, 'foo'),
746
- s(:str, 'bar'),
747
- s(:str, 'baz'))
748
- end
749
- end
750
-
751
- describe 'for symbol list literals with %i delimiter' do
752
- it 'works for the simple case' do
753
- '%i(foo bar)'.
754
- must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
755
- end
756
-
757
- it 'does not perform interpolation' do
758
- '%i(foo\\nbar baz)'.
759
- must_be_parsed_as s(:array, s(:lit, :"foo\\nbar"), s(:lit, :baz))
760
- end
761
-
762
- it 'handles line continuation' do
763
- "%i(foo\\\nbar baz)".
764
- must_be_parsed_as s(:array, s(:lit, :"foo\nbar"), s(:lit, :baz))
765
- end
766
- end
767
-
768
- describe 'for symbol list literals with %I delimiter' do
769
- it 'works for the simple case' do
770
- '%I(foo bar)'.
771
- must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
772
- end
773
-
774
- it 'correctly handles escape sequences' do
775
- '%I(foo\nbar baz)'.
776
- must_be_parsed_as s(:array,
777
- s(:lit, :"foo\nbar"),
778
- s(:lit, :baz))
779
- end
780
-
781
- it 'correctly handles interpolation' do
782
- "%I(foo \#{bar} baz)".
783
- must_be_parsed_as s(:array,
784
- s(:lit, :foo),
785
- s(:dsym, '', s(:evstr, s(:call, nil, :bar))),
786
- s(:lit, :baz))
787
- end
788
-
789
- it 'correctly handles in-word interpolation' do
790
- "%I(foo \#{bar}baz)".
791
- must_be_parsed_as s(:array,
792
- s(:lit, :foo),
793
- s(:dsym,
794
- '',
795
- s(:evstr, s(:call, nil, :bar)),
796
- s(:str, 'baz')))
797
- end
798
-
799
- it 'correctly handles line continuation' do
800
- "%I(foo\\\nbar baz)".
801
- must_be_parsed_as s(:array,
802
- s(:lit, :"foo\nbar"),
803
- s(:lit, :baz))
804
- end
805
-
806
- it 'correctly handles multiple lines' do
807
- "%I(foo\nbar baz)".
808
- must_be_parsed_as s(:array,
809
- s(:lit, :foo),
810
- s(:lit, :bar),
811
- s(:lit, :baz))
812
- end
813
- end
814
-
815
- describe 'for character literals' do
816
- it 'works for simple character literals' do
817
- '?a'.
818
- must_be_parsed_as s(:str, 'a')
819
- end
820
-
821
- it 'works for escaped character literals' do
822
- '?\\n'.
823
- must_be_parsed_as s(:str, "\n")
824
- end
825
-
826
- it 'works for escaped character literals with ctrl' do
827
- '?\\C-a'.
828
- must_be_parsed_as s(:str, "\u0001")
829
- end
830
-
831
- it 'works for escaped character literals with meta' do
832
- '?\\M-a'.
833
- must_be_parsed_as s(:str, (+"\xE1").force_encoding('ascii-8bit'))
834
- end
835
-
836
- it 'works for escaped character literals with meta plus shorthand ctrl' do
837
- '?\\M-\\ca'.
838
- must_be_parsed_as s(:str, (+"\x81").force_encoding('ascii-8bit'))
839
- end
840
-
841
- it 'works for escaped character literals with shorthand ctrl plus meta' do
842
- '?\\c\\M-a'.
843
- must_be_parsed_as s(:str, (+"\x81").force_encoding('ascii-8bit'))
844
- end
845
-
846
- it 'works for escaped character literals with meta plus ctrl' do
847
- '?\\M-\\C-a'.
848
- must_be_parsed_as s(:str, (+"\x81").force_encoding('ascii-8bit'))
849
- end
850
-
851
- it 'works for escaped character literals with ctrl plus meta' do
852
- '?\\C-\\M-a'.
853
- must_be_parsed_as s(:str, (+"\x81").force_encoding('ascii-8bit'))
854
- end
855
- end
856
-
857
- describe 'for symbol literals' do
858
- it 'works for simple symbols' do
859
- ':foo'.
860
- must_be_parsed_as s(:lit, :foo)
861
- end
862
-
863
- it 'works for symbols that look like instance variable names' do
864
- ':@foo'.
865
- must_be_parsed_as s(:lit, :@foo)
866
- end
867
-
868
- it 'works for symbols that look like class names' do
869
- ':Foo'.
870
- must_be_parsed_as s(:lit, :Foo)
871
- end
872
-
873
- it 'works for symbols that look like keywords' do
874
- ':class'.must_be_parsed_as s(:lit, :class)
875
- end
876
-
877
- it 'works for :__LINE__' do
878
- ':__LINE__'.
879
- must_be_parsed_as s(:lit, :__LINE__)
880
- end
881
-
882
- it 'works for :__FILE__' do
883
- ':__FILE__'.
884
- must_be_parsed_as s(:lit, :__FILE__)
885
- end
886
-
887
- it 'works for a backtick symbol' do
888
- ':`'.must_be_parsed_as s(:lit, :`)
889
- end
890
-
891
- it 'works for simple dsyms' do
892
- ':"foo"'.
893
- must_be_parsed_as s(:lit, :foo)
894
- end
895
-
896
- it 'works for dsyms with interpolations' do
897
- ':"foo#{bar}"'.
898
- must_be_parsed_as s(:dsym,
899
- 'foo',
900
- s(:evstr, s(:call, nil, :bar)))
901
- end
902
-
903
- it 'works for dsyms with interpolations at the start' do
904
- ':"#{bar}"'.
905
- must_be_parsed_as s(:dsym,
906
- '',
907
- s(:evstr, s(:call, nil, :bar)))
908
- end
909
-
910
- it 'works for dsyms with escape sequences' do
911
- ':"foo\nbar"'.
912
- must_be_parsed_as s(:lit, :"foo\nbar")
913
- end
914
-
915
- it 'works for dsyms with multiple lines' do
916
- ":\"foo\nbar\"".
917
- must_be_parsed_as s(:lit, :"foo\nbar")
918
- end
919
-
920
- it 'works for dsyms with line continuations' do
921
- ":\"foo\\\nbar\"".
922
- must_be_parsed_as s(:lit, :foobar)
923
- end
924
-
925
- it 'works with single quoted dsyms' do
926
- ":'foo'".
927
- must_be_parsed_as s(:lit, :foo)
928
- end
929
-
930
- it 'works with single quoted dsyms with escaped single quotes' do
931
- ":'foo\\'bar'".
932
- must_be_parsed_as s(:lit, :'foo\'bar')
933
- end
934
-
935
- it 'works with single quoted dsyms with multiple lines' do
936
- ":'foo\nbar'".
937
- must_be_parsed_as s(:lit, :"foo\nbar")
938
- end
939
-
940
- it 'works with single quoted dsyms with line continuations' do
941
- ":'foo\\\nbar'".
942
- must_be_parsed_as s(:lit, :"foo\\\nbar")
943
- end
944
-
945
- it 'works with single quoted dsyms with embedded backslashes' do
946
- ":'foo\\abar'".
947
- must_be_parsed_as s(:lit, :"foo\\abar")
948
- end
949
-
950
- it 'works with barewords that need to be interpreted as symbols' do
951
- 'alias foo bar'.
952
- must_be_parsed_as s(:alias,
953
- s(:lit, :foo), s(:lit, :bar))
954
- end
955
-
956
- it 'assigns a line number to the result' do
957
- result = parser.parse ':foo'
958
- result.line.must_equal 1
959
- end
960
- end
961
-
962
- describe 'for backtick string literals' do
963
- it 'works for basic backtick strings' do
964
- '`foo`'.
965
- must_be_parsed_as s(:xstr, 'foo')
966
- end
967
-
968
- it 'works for interpolated backtick strings' do
969
- '`foo#{bar}`'.
970
- must_be_parsed_as s(:dxstr,
971
- 'foo',
972
- s(:evstr, s(:call, nil, :bar)))
973
- end
974
-
975
- it 'works for backtick strings interpolated at the start' do
976
- '`#{foo}`'.
977
- must_be_parsed_as s(:dxstr, '',
978
- s(:evstr, s(:call, nil, :foo)))
979
- end
980
-
981
- it 'works for backtick strings with escape sequences' do
982
- '`foo\\n`'.
983
- must_be_parsed_as s(:xstr, "foo\n")
984
- end
985
-
986
- it 'works for backtick strings with multiple lines' do
987
- "`foo\nbar`".
988
- must_be_parsed_as s(:xstr, "foo\nbar")
989
- end
990
-
991
- it 'works for backtick strings with line continuations' do
992
- "`foo\\\nbar`".
993
- must_be_parsed_as s(:xstr, 'foobar')
994
- end
995
- end
996
-
997
- describe 'for array literals' do
998
- it 'works for an empty array' do
999
- '[]'.
1000
- must_be_parsed_as s(:array)
1001
- end
1002
-
1003
- it 'works for a simple case with splat' do
1004
- '[*foo]'.
1005
- must_be_parsed_as s(:array,
1006
- s(:splat, s(:call, nil, :foo)))
1007
- end
1008
-
1009
- it 'works for a multi-element case with splat' do
1010
- '[foo, *bar]'.
1011
- must_be_parsed_as s(:array,
1012
- s(:call, nil, :foo),
1013
- s(:splat, s(:call, nil, :bar)))
1014
- end
1015
- end
1016
-
1017
- describe 'for hash literals' do
1018
- it 'works for an empty hash' do
1019
- '{}'.
1020
- must_be_parsed_as s(:hash)
1021
- end
1022
-
1023
- it 'works for a hash with one pair' do
1024
- '{foo => bar}'.
1025
- must_be_parsed_as s(:hash,
1026
- s(:call, nil, :foo),
1027
- s(:call, nil, :bar))
1028
- end
1029
-
1030
- it 'works for a hash with multiple pairs' do
1031
- '{foo => bar, baz => qux}'.
1032
- must_be_parsed_as s(:hash,
1033
- s(:call, nil, :foo),
1034
- s(:call, nil, :bar),
1035
- s(:call, nil, :baz),
1036
- s(:call, nil, :qux))
1037
- end
1038
-
1039
- it 'works for a hash with label keys' do
1040
- '{foo: bar, baz: qux}'.
1041
- must_be_parsed_as s(:hash,
1042
- s(:lit, :foo),
1043
- s(:call, nil, :bar),
1044
- s(:lit, :baz),
1045
- s(:call, nil, :qux))
1046
- end
1047
-
1048
- it 'works for a hash with dynamic label keys' do
1049
- "{'foo': bar}".
1050
- must_be_parsed_as s(:hash,
1051
- s(:lit, :foo),
1052
- s(:call, nil, :bar))
1053
- end
1054
-
1055
- it 'works for a hash with splat' do
1056
- '{foo: bar, baz: qux, **quux}'.
1057
- must_be_parsed_as s(:hash,
1058
- s(:lit, :foo), s(:call, nil, :bar),
1059
- s(:lit, :baz), s(:call, nil, :qux),
1060
- s(:kwsplat, s(:call, nil, :quux)))
1061
- end
1062
- end
1063
-
1064
- describe 'for number literals' do
1065
- it 'works for floats' do
1066
- '3.14'.
1067
- must_be_parsed_as s(:lit, 3.14)
1068
- end
1069
-
1070
- it 'works for octal integer literals' do
1071
- '0700'.
1072
- must_be_parsed_as s(:lit, 448)
1073
- end
1074
-
1075
- it 'handles negative sign for integers' do
1076
- '-1'.
1077
- must_be_parsed_as s(:lit, -1)
1078
- end
1079
-
1080
- it 'handles space after negative sign for integers' do
1081
- '-1 '.
1082
- must_be_parsed_as s(:lit, -1)
1083
- end
1084
-
1085
- it 'handles negative sign for floats' do
1086
- '-3.14'.
1087
- must_be_parsed_as s(:lit, -3.14)
1088
- end
1089
-
1090
- it 'handles space after negative sign for floats' do
1091
- '-3.14 '.
1092
- must_be_parsed_as s(:lit, -3.14)
1093
- end
1094
-
1095
- it 'handles positive sign' do
1096
- '+1'.
1097
- must_be_parsed_as s(:lit, 1)
1098
- end
1099
-
1100
- it 'works for rationals' do
1101
- '1000r'.
1102
- must_be_parsed_as s(:lit, 1000r)
1103
- end
1104
- end
1105
-
1106
- describe 'in extra compatible mode' do
1107
- it 'converts \r to carriage returns in double-quoted strings' do
1108
- '"foo\\rbar"'.must_be_parsed_as s(:str, "foo\rbar"), extra_compatible: true
1109
- end
1110
-
1111
- it 'removes \r from heredocs' do
1112
- "<<FOO\nbar\\rbaz\\r\nFOO".
1113
- must_be_parsed_as s(:str, "barbaz\n"), extra_compatible: true
1114
- end
1115
- end
1116
- end
1117
- end