ripper_ruby_parser 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -496,6 +496,41 @@ describe RipperRubyParser::Parser do
496
496
  s(:call, nil, :baz)),
497
497
  nil)
498
498
  end
499
+
500
+ it 'cleans up a multi-statement begin..end in the when clause' do
501
+ 'case foo; when bar; begin; baz; qux; end; end'.
502
+ must_be_parsed_as s(:case,
503
+ s(:call, nil, :foo),
504
+ s(:when,
505
+ s(:array, s(:call, nil, :bar)),
506
+ s(:call, nil, :baz),
507
+ s(:call, nil, :qux)),
508
+ nil)
509
+ end
510
+
511
+ it 'cleans up a multi-statement begin..end at start of the when clause' do
512
+ 'case foo; when bar; begin; baz; qux; end; quuz; end'.
513
+ must_be_parsed_as s(:case,
514
+ s(:call, nil, :foo),
515
+ s(:when,
516
+ s(:array, s(:call, nil, :bar)),
517
+ s(:call, nil, :baz),
518
+ s(:call, nil, :qux),
519
+ s(:call, nil, :quuz)),
520
+ nil)
521
+ end
522
+
523
+ it 'keeps up a multi-statement begin..end in the else clause' do
524
+ 'case foo; when bar; baz; else; begin; qux; quuz; end; end'.
525
+ must_be_parsed_as s(:case,
526
+ s(:call, nil, :foo),
527
+ s(:when,
528
+ s(:array, s(:call, nil, :bar)),
529
+ s(:call, nil, :baz)),
530
+ s(:block,
531
+ s(:call, nil, :qux),
532
+ s(:call, nil, :quuz)))
533
+ end
499
534
  end
500
535
  end
501
536
  end
@@ -78,15 +78,6 @@ describe RipperRubyParser::Parser do
78
78
  s(:str, 'baz'))
79
79
  end
80
80
 
81
- it 'works for a simple interpolation in extra-compatible mode' do
82
- '/foo#{bar}baz/'.
83
- must_be_parsed_as s(:dregx,
84
- 'foo',
85
- s(:evstr, s(:call, nil, :bar)),
86
- s(:str, 'baz')),
87
- extra_compatible: true
88
- end
89
-
90
81
  it 'works for a regex literal with flags and interpolation' do
91
82
  '/foo#{bar}/ixm'.
92
83
  must_be_parsed_as s(:dregx,
@@ -267,11 +258,6 @@ describe RipperRubyParser::Parser do
267
258
  '"foo\\u273bbar"'.must_be_parsed_as s(:str, 'foo✻bar')
268
259
  end
269
260
 
270
- it 'works with unicode escapes in extra-compatible mode' do
271
- '"foo\\u273bbar"'.
272
- must_be_parsed_as s(:str, 'foo✻r'), extra_compatible: true
273
- end
274
-
275
261
  it 'works with unicode escapes with braces' do
276
262
  '"foo\\u{273b}bar"'.must_be_parsed_as s(:str, 'foo✻bar')
277
263
  end
@@ -280,10 +266,6 @@ describe RipperRubyParser::Parser do
280
266
  '"2\302\275"'.must_be_parsed_as s(:str, '2½')
281
267
  end
282
268
 
283
- it 'converts to unicode if possible in extra-compatible mode' do
284
- '"2\302\275"'.must_be_parsed_as s(:str, '2½'), extra_compatible: true
285
- end
286
-
287
269
  it 'does not convert to unicode if result is not valid' do
288
270
  '"2\x82\302\275"'.
289
271
  must_be_parsed_as s(:str,
@@ -291,82 +273,113 @@ describe RipperRubyParser::Parser do
291
273
  end
292
274
  end
293
275
 
294
- describe 'with interpolations' do
295
- describe 'containing just a literal string' do
296
- it 'performs the interpolation when it is at the end' do
297
- '"foo#{"bar"}"'.must_be_parsed_as s(:str, 'foobar')
298
- end
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
299
280
 
300
- it 'performs the interpolation when it is in the middle' do
301
- '"foo#{"bar"}baz"'.must_be_parsed_as s(:str, 'foobarbaz')
302
- end
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
303
284
 
304
- it 'performs the interpolation when it is at the start' do
305
- '"#{"foo"}bar"'.must_be_parsed_as s(:str, 'foobar')
306
- end
285
+ it 'performs the interpolation when it is at the start' do
286
+ '"#{"foo"}bar"'.must_be_parsed_as s(:str, 'foobar')
307
287
  end
288
+ end
308
289
 
309
- describe 'without braces' do
310
- it 'works for ivars' do
311
- "\"foo\#@bar\"".must_be_parsed_as s(:dstr,
312
- 'foo',
313
- s(:evstr, s(:ivar, :@bar)))
314
- end
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
315
296
 
316
- it 'works for gvars' do
317
- "\"foo\#$bar\"".must_be_parsed_as s(:dstr,
318
- 'foo',
319
- s(:evstr, s(:gvar, :$bar)))
320
- end
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
321
302
 
322
- it 'works for cvars' do
323
- "\"foo\#@@bar\"".must_be_parsed_as s(:dstr,
324
- 'foo',
325
- s(:evstr, s(:cvar, :@@bar)))
326
- end
303
+ it 'works for cvars' do
304
+ "\"foo\#@@bar\"".must_be_parsed_as s(:dstr,
305
+ 'foo',
306
+ s(:evstr, s(:cvar, :@@bar)))
327
307
  end
308
+ end
328
309
 
329
- describe 'with braces' do
330
- it 'works for trivial interpolated strings' do
331
- '"#{foo}"'.
332
- must_be_parsed_as s(:dstr,
333
- '',
334
- s(:evstr,
335
- s(:call, nil, :foo)))
336
- end
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
337
318
 
338
- it 'works for basic interpolated strings' do
339
- '"foo#{bar}"'.
340
- must_be_parsed_as s(:dstr,
341
- 'foo',
342
- s(:evstr,
343
- s(:call, nil, :bar)))
344
- end
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
345
326
 
346
- it 'works for strings with several interpolations' do
347
- '"foo#{bar}baz#{qux}"'.
348
- must_be_parsed_as s(:dstr,
349
- 'foo',
350
- s(:evstr, s(:call, nil, :bar)),
351
- s(:str, 'baz'),
352
- s(:evstr, s(:call, nil, :qux)))
353
- end
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
354
335
 
355
- it 'correctly handles two interpolations in a row' do
356
- "\"\#{bar}\#{qux}\"".
357
- must_be_parsed_as s(:dstr,
358
- '',
359
- s(:evstr, s(:call, nil, :bar)),
360
- s(:evstr, s(:call, nil, :qux)))
361
- end
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
362
343
 
363
- it 'works with an empty interpolation' do
364
- "\"foo\#{}bar\"".
365
- must_be_parsed_as s(:dstr,
366
- 'foo',
367
- s(:evstr),
368
- s(:str, 'bar'))
369
- end
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)))
370
383
  end
371
384
  end
372
385
 
@@ -402,34 +415,13 @@ describe RipperRubyParser::Parser do
402
415
  s(:evstr, s(:call, nil, :foo)),
403
416
  s(:str, "\u0000"))
404
417
  end
405
- end
406
-
407
- describe 'with interpolations and escape sequences in extra-compatible mode' do
408
- it 'does not convert to unicode after interpolation' do
409
- '"#{foo}2\302\275"'.
410
- must_be_parsed_as s(:dstr,
411
- '',
412
- s(:evstr, s(:call, nil, :foo)),
413
- s(:str, (+"2\xC2\xBD").force_encoding('ascii-8bit'))),
414
- extra_compatible: true
415
- end
416
-
417
- it 'keeps single null byte as ascii after interpolation' do
418
- '"#{foo}\0"'.
419
- must_be_parsed_as s(:dstr,
420
- '',
421
- s(:evstr, s(:call, nil, :foo)),
422
- s(:str, (+"\x00").force_encoding('ascii-8bit'))),
423
- extra_compatible: true
424
- end
425
418
 
426
419
  it 'converts string with null to unicode after interpolation' do
427
420
  '"#{foo}bar\0"'.
428
421
  must_be_parsed_as s(:dstr,
429
422
  '',
430
423
  s(:evstr, s(:call, nil, :foo)),
431
- s(:str, "bar\x00")),
432
- extra_compatible: true
424
+ s(:str, "bar\x00"))
433
425
  end
434
426
  end
435
427
 
@@ -458,12 +450,6 @@ describe RipperRubyParser::Parser do
458
450
  "'foo\\\nbar'".
459
451
  must_be_parsed_as s(:str, "foo\\\nbar")
460
452
  end
461
-
462
- it 'handles escape sequences correctly in extra-compatible mode' do
463
- "'foo\\'bar\\\nbaz\\aqux'".
464
- must_be_parsed_as s(:str, "foo'bar\\\nbaz\\aqux"),
465
- extra_compatible: true
466
- end
467
453
  end
468
454
 
469
455
  describe 'with %Q-delimited strings' do
@@ -613,10 +599,9 @@ describe RipperRubyParser::Parser do
613
599
  must_be_parsed_as s(:str, "bar\tbaz\n")
614
600
  end
615
601
 
616
- it 'works for escape sequences in extra-compatible mode' do
617
- "<<FOO\nbar\\tbaz\nFOO".
618
- must_be_parsed_as s(:str, "bar\tbaz\n"),
619
- extra_compatible: true
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")
620
605
  end
621
606
 
622
607
  it 'does not unescape with single quoted version' do
@@ -624,12 +609,6 @@ describe RipperRubyParser::Parser do
624
609
  must_be_parsed_as s(:str, "bar\\tbaz\n")
625
610
  end
626
611
 
627
- it 'does not unescape with single quoted version in extra-compatible mode' do
628
- "<<'FOO'\nbar\\tbaz\nFOO".
629
- must_be_parsed_as s(:str, "bar\\tbaz\n"),
630
- extra_compatible: true
631
- end
632
-
633
612
  it 'works with multiple lines with the single quoted version' do
634
613
  "<<'FOO'\nbar\nbaz\nFOO".
635
614
  must_be_parsed_as s(:str, "bar\nbaz\n")
@@ -660,11 +639,25 @@ describe RipperRubyParser::Parser do
660
639
  must_be_parsed_as s(:str, "2½\n")
661
640
  end
662
641
 
663
- it 'does not convert to unicode in extra-compatible mode' do
664
- "<<FOO\n2\\302\\275\nFOO".
665
- must_be_parsed_as s(:str,
666
- (+"2\xC2\xBD\n").force_encoding('ascii-8bit')),
667
- extra_compatible: true
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"))
668
661
  end
669
662
  end
670
663
  end
@@ -739,13 +732,6 @@ describe RipperRubyParser::Parser do
739
732
  '%W(2\302\275)'.must_be_parsed_as s(:array, s(:str, '2½'))
740
733
  end
741
734
 
742
- it 'does not convert to unicode if possible in extra-compatible mode' do
743
- '%W(2\302\275)'.
744
- must_be_parsed_as s(:array,
745
- s(:str, (+"2\xC2\xBD").force_encoding('ascii-8bit'))),
746
- extra_compatible: true
747
- end
748
-
749
735
  it 'correctly handles line continuation' do
750
736
  "%W(foo\\\nbar baz)".
751
737
  must_be_parsed_as s(:array,
@@ -760,20 +746,6 @@ describe RipperRubyParser::Parser do
760
746
  s(:str, 'bar'),
761
747
  s(:str, 'baz'))
762
748
  end
763
-
764
- it 'handles escaped spaces in extra-compatible mode' do
765
- '%W(foo bar\ baz)'.
766
- must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar baz')),
767
- extra_compatible: true
768
- end
769
-
770
- it 'correctly handles line continuation in extra-compatible mode' do
771
- "%W(foo\\\nbar baz)".
772
- must_be_parsed_as s(:array,
773
- s(:str, "foo\nbar"),
774
- s(:str, 'baz')),
775
- extra_compatible: true
776
- end
777
749
  end
778
750
 
779
751
  describe 'for symbol list literals with %i delimiter' do
@@ -912,6 +884,10 @@ describe RipperRubyParser::Parser do
912
884
  must_be_parsed_as s(:lit, :__FILE__)
913
885
  end
914
886
 
887
+ it 'works for a backtick symbol' do
888
+ ':`'.must_be_parsed_as s(:lit, :`)
889
+ end
890
+
915
891
  it 'works for simple dsyms' do
916
892
  ':"foo"'.
917
893
  must_be_parsed_as s(:lit, :foo)
@@ -1126,5 +1102,16 @@ describe RipperRubyParser::Parser do
1126
1102
  must_be_parsed_as s(:lit, 1000r)
1127
1103
  end
1128
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
1129
1116
  end
1130
1117
  end
@@ -172,6 +172,27 @@ describe RipperRubyParser::Parser do
172
172
  s(:nil))
173
173
  end
174
174
 
175
+ it 'works with argument destructuring' do
176
+ 'def foo((bar, baz)); end'.
177
+ must_be_parsed_as s(:defn, :foo,
178
+ s(:args, s(:masgn, :bar, :baz)),
179
+ s(:nil))
180
+ end
181
+
182
+ it 'works with argument destructuring including splat' do
183
+ 'def foo((bar, *baz)); end'.
184
+ must_be_parsed_as s(:defn, :foo,
185
+ s(:args, s(:masgn, :bar, :'*baz')),
186
+ s(:nil))
187
+ end
188
+
189
+ it 'works with nested argument destructuring' do
190
+ 'def foo((bar, (baz, qux))); end'.
191
+ must_be_parsed_as s(:defn, :foo,
192
+ s(:args, s(:masgn, :bar, s(:masgn, :baz, :qux))),
193
+ s(:nil))
194
+ end
195
+
175
196
  it 'works when the method name is an operator' do
176
197
  'def +; end'.
177
198
  must_be_parsed_as s(:defn, :+, s(:args),
@@ -389,7 +410,7 @@ describe RipperRubyParser::Parser do
389
410
  end
390
411
 
391
412
  describe 'when extra compatibility is turned on' do
392
- it 'treats block kwargs as calls' do
413
+ it 'still treats block kwargs as lvars' do
393
414
  'def foo(**bar); baz { |**qux| bar; qux }; end'.
394
415
  must_be_parsed_as s(:defn, :foo,
395
416
  s(:args, :"**bar"),
@@ -398,7 +419,7 @@ describe RipperRubyParser::Parser do
398
419
  s(:args, :"**qux"),
399
420
  s(:block,
400
421
  s(:lvar, :bar),
401
- s(:call, nil, :qux)))),
422
+ s(:lvar, :qux)))),
402
423
  extra_compatible: true
403
424
  end
404
425
  end