ripper_ruby_parser 1.4.2 → 1.5.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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -1
  3. data/README.md +41 -9
  4. data/Rakefile +2 -0
  5. data/lib/ripper_ruby_parser.rb +2 -0
  6. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +23 -45
  7. data/lib/ripper_ruby_parser/parser.rb +11 -1
  8. data/lib/ripper_ruby_parser/sexp_handlers.rb +2 -6
  9. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +49 -35
  10. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +78 -39
  11. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +16 -15
  12. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +19 -15
  13. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +138 -30
  14. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +10 -6
  15. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +59 -14
  16. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +56 -32
  17. data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +20 -27
  18. data/lib/ripper_ruby_parser/sexp_processor.rb +40 -10
  19. data/lib/ripper_ruby_parser/syntax_error.rb +2 -0
  20. data/lib/ripper_ruby_parser/unescape.rb +32 -11
  21. data/lib/ripper_ruby_parser/version.rb +3 -1
  22. data/test/end_to_end/comments_test.rb +2 -0
  23. data/test/end_to_end/comparison_test.rb +2 -0
  24. data/test/end_to_end/lib_comparison_test.rb +2 -0
  25. data/test/end_to_end/line_numbering_test.rb +2 -0
  26. data/test/end_to_end/samples_comparison_test.rb +5 -29
  27. data/test/end_to_end/test_comparison_test.rb +2 -0
  28. data/test/pt_testcase/pt_test.rb +2 -0
  29. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +16 -2
  30. data/test/ripper_ruby_parser/parser_test.rb +17 -688
  31. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +459 -26
  32. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +152 -82
  33. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +91 -0
  34. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +331 -24
  35. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +88 -0
  36. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +58 -5
  37. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +392 -0
  38. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +174 -12
  39. data/test/ripper_ruby_parser/sexp_processor_test.rb +8 -18
  40. data/test/ripper_ruby_parser/version_test.rb +2 -0
  41. data/test/samples/comments.rb +13 -0
  42. data/test/samples/conditionals.rb +23 -0
  43. data/test/samples/loops.rb +36 -0
  44. data/test/samples/misc.rb +157 -5
  45. data/test/samples/number.rb +7 -0
  46. data/test/samples/strings.rb +39 -0
  47. data/test/test_helper.rb +22 -1
  48. metadata +18 -12
  49. data/lib/ripper_ruby_parser/sexp_handlers/arguments.rb +0 -29
  50. data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +0 -21
  51. data/lib/ripper_ruby_parser/sexp_handlers/hashes.rb +0 -48
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../../test_helper.rb', File.dirname(__FILE__))
2
4
 
3
5
  describe RipperRubyParser::Parser do
6
+ let(:parser) { RipperRubyParser::Parser.new }
7
+
4
8
  describe '#parse' do
5
9
  describe 'for regexp literals' do
6
10
  it 'works for a simple regex literal' do
@@ -18,6 +22,11 @@ describe RipperRubyParser::Parser do
18
22
  must_be_parsed_as s(:lit, /\)\n\\/)
19
23
  end
20
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
+
21
30
  it 'works for a regex literal with the multiline flag' do
22
31
  '/foo/m'.
23
32
  must_be_parsed_as s(:lit, /foo/m)
@@ -34,16 +43,13 @@ describe RipperRubyParser::Parser do
34
43
  end
35
44
 
36
45
  it 'works for a regex literal with a combination of flags' do
37
- '/foo/ixm'.
38
- must_be_parsed_as s(:lit, /foo/ixm)
46
+ '/foo/ixmn'.
47
+ must_be_parsed_as s(:lit, /foo/mixn)
39
48
  end
40
49
 
41
50
  it 'works with the no-encoding flag' do
42
- parser = RipperRubyParser::Parser.new
43
- result = parser.parse '/foo/n'
44
- # Use inspect since regular == finds no difference between /foo/n
45
- # and /foo/
46
- result.inspect.must_equal s(:lit, /foo/n).inspect
51
+ '/foo/n'.
52
+ must_be_parsed_as s(:lit, /foo/n)
47
53
  end
48
54
 
49
55
  it 'works with line continuation' do
@@ -72,6 +78,15 @@ describe RipperRubyParser::Parser do
72
78
  s(:str, 'baz'))
73
79
  end
74
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
+
75
90
  it 'works for a regex literal with flags and interpolation' do
76
91
  '/foo#{bar}/ixm'.
77
92
  must_be_parsed_as s(:dregx,
@@ -96,6 +111,14 @@ describe RipperRubyParser::Parser do
96
111
  s(:call, nil, :bar)), 16)
97
112
  end
98
113
 
114
+ it 'works with unicode flag plus other flag' do
115
+ '/foo#{bar}/un'.
116
+ must_be_parsed_as s(:dregx,
117
+ 'foo',
118
+ s(:evstr,
119
+ s(:call, nil, :bar)), 48)
120
+ end
121
+
99
122
  it 'works with the euc-encoding flag' do
100
123
  '/foo#{bar}/e'.
101
124
  must_be_parsed_as s(:dregx,
@@ -156,6 +179,11 @@ describe RipperRubyParser::Parser do
156
179
  result[1].encoding.to_s.must_equal 'UTF-8'
157
180
  end
158
181
 
182
+ it 'handles line breaks within double-quoted strings' do
183
+ "\"foo\nbar\"".
184
+ must_be_parsed_as s(:str, "foo\nbar")
185
+ end
186
+
159
187
  it 'handles line continuation with double-quoted strings' do
160
188
  "\"foo\\\nbar\"".
161
189
  must_be_parsed_as s(:str, 'foobar')
@@ -235,21 +263,31 @@ describe RipperRubyParser::Parser do
235
263
  '"foo\\C-Zbar"'.must_be_parsed_as s(:str, "foo\C-Zbar")
236
264
  end
237
265
 
238
- # TODO: Implement remaining escape sequence cases.
239
-
240
- it 'works with unicode escapes (unlike RubyParser)' do
266
+ it 'works with unicode escapes' do
241
267
  '"foo\\u273bbar"'.must_be_parsed_as s(:str, 'foo✻bar')
242
268
  end
243
269
 
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
+ it 'works with unicode escapes with braces' do
276
+ '"foo\\u{273b}bar"'.must_be_parsed_as s(:str, 'foo✻bar')
277
+ end
278
+
244
279
  it 'converts to unicode if possible' do
245
280
  '"2\302\275"'.must_be_parsed_as s(:str, '2½')
246
281
  end
247
282
 
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
+
248
287
  it 'does not convert to unicode if result is not valid' do
249
- parser = RipperRubyParser::Parser.new
250
- result = parser.parse '"2\x82\302\275"'
251
- expected = s(:str, "2\x82\xC2\xBD".force_encoding(Encoding::US_ASCII))
252
- result.inspect.must_equal expected.inspect
288
+ '"2\x82\302\275"'.
289
+ must_be_parsed_as s(:str,
290
+ (+"2\x82\xC2\xBD").force_encoding('ascii-8bit'))
253
291
  end
254
292
  end
255
293
 
@@ -348,6 +386,51 @@ describe RipperRubyParser::Parser do
348
386
  s(:evstr, s(:array, s(:lit, :foo), s(:str, 'bar'))),
349
387
  s(:str, "\n"))
350
388
  end
389
+
390
+ it 'converts to unicode after interpolation' do
391
+ '"#{foo}2\302\275"'.
392
+ must_be_parsed_as s(:dstr,
393
+ '',
394
+ s(:evstr, s(:call, nil, :foo)),
395
+ s(:str, '2½'))
396
+ end
397
+
398
+ it 'convert single null byte to unicode after interpolation' do
399
+ '"#{foo}\0"'.
400
+ must_be_parsed_as s(:dstr,
401
+ '',
402
+ s(:evstr, s(:call, nil, :foo)),
403
+ s(:str, "\u0000"))
404
+ 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
+
426
+ it 'converts string with null to unicode after interpolation' do
427
+ '"#{foo}bar\0"'.
428
+ must_be_parsed_as s(:dstr,
429
+ '',
430
+ s(:evstr, s(:call, nil, :foo)),
431
+ s(:str, "bar\x00")),
432
+ extra_compatible: true
433
+ end
351
434
  end
352
435
 
353
436
  describe 'with single quoted strings' do
@@ -375,6 +458,12 @@ describe RipperRubyParser::Parser do
375
458
  "'foo\\\nbar'".
376
459
  must_be_parsed_as s(:str, "foo\\\nbar")
377
460
  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
378
467
  end
379
468
 
380
469
  describe 'with %Q-delimited strings' do
@@ -388,12 +477,39 @@ describe RipperRubyParser::Parser do
388
477
  must_be_parsed_as s(:str, "foo\nbar")
389
478
  end
390
479
 
480
+ it 'works for multi-line strings' do
481
+ "%Q[foo\nbar]".
482
+ must_be_parsed_as s(:str, "foo\nbar")
483
+ end
484
+
391
485
  it 'handles line continuation' do
392
486
  "%Q[foo\\\nbar]".
393
487
  must_be_parsed_as s(:str, 'foobar')
394
488
  end
395
489
  end
396
490
 
491
+ describe 'with %q-delimited strings' do
492
+ it 'works for the simple case' do
493
+ '%q[bar]'.
494
+ must_be_parsed_as s(:str, 'bar')
495
+ end
496
+
497
+ it 'does not handle for escape sequences' do
498
+ '%q[foo\\nbar]'.
499
+ must_be_parsed_as s(:str, 'foo\nbar')
500
+ end
501
+
502
+ it 'works for multi-line strings' do
503
+ "%q[foo\nbar]".
504
+ must_be_parsed_as s(:str, "foo\nbar")
505
+ end
506
+
507
+ it 'handles line continuation' do
508
+ "%q[foo\\\nbar]".
509
+ must_be_parsed_as s(:str, "foo\\\nbar")
510
+ end
511
+ end
512
+
397
513
  describe 'with %-delimited strings' do
398
514
  it 'works for the simple case' do
399
515
  '%(bar)'.
@@ -405,6 +521,16 @@ describe RipperRubyParser::Parser do
405
521
  must_be_parsed_as s(:str, "foo\nbar")
406
522
  end
407
523
 
524
+ it 'works for multiple lines' do
525
+ "%(foo\nbar)".
526
+ must_be_parsed_as s(:str, "foo\nbar")
527
+ end
528
+
529
+ it 'works with line continuations' do
530
+ "%(foo\\\nbar)".
531
+ must_be_parsed_as s(:str, 'foobar')
532
+ end
533
+
408
534
  it 'works for odd delimiters' do
409
535
  '%!foo\nbar!'.
410
536
  must_be_parsed_as s(:str, "foo\nbar")
@@ -467,11 +593,58 @@ describe RipperRubyParser::Parser do
467
593
  must_be_parsed_as s(:str, "bar\n")
468
594
  end
469
595
 
596
+ it 'works with multiple lines' do
597
+ "<<FOO\nbar\nbaz\nFOO".
598
+ must_be_parsed_as s(:str, "bar\nbaz\n")
599
+ end
600
+
601
+ it 'works for the indentable case' do
602
+ "<<-FOO\n bar\n FOO".
603
+ must_be_parsed_as s(:str, " bar\n")
604
+ end
605
+
606
+ it 'works for the automatically outdenting case' do
607
+ " <<~FOO\n bar\n FOO".
608
+ must_be_parsed_as s(:str, "bar\n")
609
+ end
610
+
470
611
  it 'works for escape sequences' do
471
612
  "<<FOO\nbar\\tbaz\nFOO".
472
613
  must_be_parsed_as s(:str, "bar\tbaz\n")
473
614
  end
474
615
 
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
620
+ end
621
+
622
+ it 'does not unescape with single quoted version' do
623
+ "<<'FOO'\nbar\\tbaz\nFOO".
624
+ must_be_parsed_as s(:str, "bar\\tbaz\n")
625
+ end
626
+
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
+ it 'works with multiple lines with the single quoted version' do
634
+ "<<'FOO'\nbar\nbaz\nFOO".
635
+ must_be_parsed_as s(:str, "bar\nbaz\n")
636
+ end
637
+
638
+ it 'does not unescape with indentable single quoted version' do
639
+ "<<-'FOO'\n bar\\tbaz\n FOO".
640
+ must_be_parsed_as s(:str, " bar\\tbaz\n")
641
+ end
642
+
643
+ it 'does not unescape the automatically outdenting single quoted version' do
644
+ "<<~'FOO'\n bar\\tbaz\n FOO".
645
+ must_be_parsed_as s(:str, "bar\\tbaz\n")
646
+ end
647
+
475
648
  it 'handles line continuation' do
476
649
  "<<FOO\nbar\\\nbaz\nFOO".
477
650
  must_be_parsed_as s(:str, "barbaz\n")
@@ -482,11 +655,16 @@ describe RipperRubyParser::Parser do
482
655
  must_be_parsed_as s(:str, "bar\\\nbaz\n")
483
656
  end
484
657
 
485
- it 'does not convert to unicode even if possible' do
486
- parser = RipperRubyParser::Parser.new
487
- result = parser.parse "<<FOO\n2\\302\\275\nFOO"
488
- expected = s(:str, "2\xC2\xBD\n".force_encoding(Encoding::US_ASCII))
489
- result.inspect.must_equal expected.inspect
658
+ it 'converts to unicode' do
659
+ "<<FOO\n2\\302\\275\nFOO".
660
+ must_be_parsed_as s(:str, "2½\n")
661
+ end
662
+
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
490
668
  end
491
669
  end
492
670
  end
@@ -506,6 +684,11 @@ describe RipperRubyParser::Parser do
506
684
  "%w(foo\\\nbar baz)".
507
685
  must_be_parsed_as s(:array, s(:str, "foo\nbar"), s(:str, 'baz'))
508
686
  end
687
+
688
+ it 'handles escaped spaces' do
689
+ '%w(foo bar\ baz)'.
690
+ must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar baz'))
691
+ end
509
692
  end
510
693
 
511
694
  describe 'for word list literals with %W delimiter' do
@@ -514,6 +697,11 @@ describe RipperRubyParser::Parser do
514
697
  must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar'))
515
698
  end
516
699
 
700
+ it 'handles escaped spaces' do
701
+ '%W(foo bar\ baz)'.
702
+ must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar baz'))
703
+ end
704
+
517
705
  it 'correctly handles interpolation' do
518
706
  "%W(foo \#{bar} baz)".
519
707
  must_be_parsed_as s(:array,
@@ -547,12 +735,45 @@ describe RipperRubyParser::Parser do
547
735
  s(:str, 'baz'))
548
736
  end
549
737
 
738
+ it 'converts to unicode if possible' do
739
+ '%W(2\302\275)'.must_be_parsed_as s(:array, s(:str, '2½'))
740
+ end
741
+
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
+
550
749
  it 'correctly handles line continuation' do
551
750
  "%W(foo\\\nbar baz)".
552
751
  must_be_parsed_as s(:array,
553
752
  s(:str, "foo\nbar"),
554
753
  s(:str, 'baz'))
555
754
  end
755
+
756
+ it 'correctly handles multiple lines' do
757
+ "%W(foo\nbar baz)".
758
+ must_be_parsed_as s(:array,
759
+ s(:str, 'foo'),
760
+ s(:str, 'bar'),
761
+ s(:str, 'baz'))
762
+ 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
556
777
  end
557
778
 
558
779
  describe 'for symbol list literals with %i delimiter' do
@@ -609,6 +830,14 @@ describe RipperRubyParser::Parser do
609
830
  s(:lit, :"foo\nbar"),
610
831
  s(:lit, :baz))
611
832
  end
833
+
834
+ it 'correctly handles multiple lines' do
835
+ "%I(foo\nbar baz)".
836
+ must_be_parsed_as s(:array,
837
+ s(:lit, :foo),
838
+ s(:lit, :bar),
839
+ s(:lit, :baz))
840
+ end
612
841
  end
613
842
 
614
843
  describe 'for character literals' do
@@ -629,27 +858,27 @@ describe RipperRubyParser::Parser do
629
858
 
630
859
  it 'works for escaped character literals with meta' do
631
860
  '?\\M-a'.
632
- must_be_parsed_as s(:str, "\xE1".force_encoding('ascii-8bit'))
861
+ must_be_parsed_as s(:str, (+"\xE1").force_encoding('ascii-8bit'))
633
862
  end
634
863
 
635
864
  it 'works for escaped character literals with meta plus shorthand ctrl' do
636
865
  '?\\M-\\ca'.
637
- must_be_parsed_as s(:str, "\x81".force_encoding('ascii-8bit'))
866
+ must_be_parsed_as s(:str, (+"\x81").force_encoding('ascii-8bit'))
638
867
  end
639
868
 
640
869
  it 'works for escaped character literals with shorthand ctrl plus meta' do
641
870
  '?\\c\\M-a'.
642
- must_be_parsed_as s(:str, "\x81".force_encoding('ascii-8bit'))
871
+ must_be_parsed_as s(:str, (+"\x81").force_encoding('ascii-8bit'))
643
872
  end
644
873
 
645
874
  it 'works for escaped character literals with meta plus ctrl' do
646
875
  '?\\M-\\C-a'.
647
- must_be_parsed_as s(:str, "\x81".force_encoding('ascii-8bit'))
876
+ must_be_parsed_as s(:str, (+"\x81").force_encoding('ascii-8bit'))
648
877
  end
649
878
 
650
879
  it 'works for escaped character literals with ctrl plus meta' do
651
880
  '?\\C-\\M-a'.
652
- must_be_parsed_as s(:str, "\x81".force_encoding('ascii-8bit'))
881
+ must_be_parsed_as s(:str, (+"\x81").force_encoding('ascii-8bit'))
653
882
  end
654
883
  end
655
884
 
@@ -664,6 +893,25 @@ describe RipperRubyParser::Parser do
664
893
  must_be_parsed_as s(:lit, :@foo)
665
894
  end
666
895
 
896
+ it 'works for symbols that look like class names' do
897
+ ':Foo'.
898
+ must_be_parsed_as s(:lit, :Foo)
899
+ end
900
+
901
+ it 'works for symbols that look like keywords' do
902
+ ':class'.must_be_parsed_as s(:lit, :class)
903
+ end
904
+
905
+ it 'works for :__LINE__' do
906
+ ':__LINE__'.
907
+ must_be_parsed_as s(:lit, :__LINE__)
908
+ end
909
+
910
+ it 'works for :__FILE__' do
911
+ ':__FILE__'.
912
+ must_be_parsed_as s(:lit, :__FILE__)
913
+ end
914
+
667
915
  it 'works for simple dsyms' do
668
916
  ':"foo"'.
669
917
  must_be_parsed_as s(:lit, :foo)
@@ -676,11 +924,28 @@ describe RipperRubyParser::Parser do
676
924
  s(:evstr, s(:call, nil, :bar)))
677
925
  end
678
926
 
927
+ it 'works for dsyms with interpolations at the start' do
928
+ ':"#{bar}"'.
929
+ must_be_parsed_as s(:dsym,
930
+ '',
931
+ s(:evstr, s(:call, nil, :bar)))
932
+ end
933
+
679
934
  it 'works for dsyms with escape sequences' do
680
935
  ':"foo\nbar"'.
681
936
  must_be_parsed_as s(:lit, :"foo\nbar")
682
937
  end
683
938
 
939
+ it 'works for dsyms with multiple lines' do
940
+ ":\"foo\nbar\"".
941
+ must_be_parsed_as s(:lit, :"foo\nbar")
942
+ end
943
+
944
+ it 'works for dsyms with line continuations' do
945
+ ":\"foo\\\nbar\"".
946
+ must_be_parsed_as s(:lit, :foobar)
947
+ end
948
+
684
949
  it 'works with single quoted dsyms' do
685
950
  ":'foo'".
686
951
  must_be_parsed_as s(:lit, :foo)
@@ -691,10 +956,31 @@ describe RipperRubyParser::Parser do
691
956
  must_be_parsed_as s(:lit, :'foo\'bar')
692
957
  end
693
958
 
959
+ it 'works with single quoted dsyms with multiple lines' do
960
+ ":'foo\nbar'".
961
+ must_be_parsed_as s(:lit, :"foo\nbar")
962
+ end
963
+
964
+ it 'works with single quoted dsyms with line continuations' do
965
+ ":'foo\\\nbar'".
966
+ must_be_parsed_as s(:lit, :"foo\\\nbar")
967
+ end
968
+
694
969
  it 'works with single quoted dsyms with embedded backslashes' do
695
970
  ":'foo\\abar'".
696
971
  must_be_parsed_as s(:lit, :"foo\\abar")
697
972
  end
973
+
974
+ it 'works with barewords that need to be interpreted as symbols' do
975
+ 'alias foo bar'.
976
+ must_be_parsed_as s(:alias,
977
+ s(:lit, :foo), s(:lit, :bar))
978
+ end
979
+
980
+ it 'assigns a line number to the result' do
981
+ result = parser.parse ':foo'
982
+ result.line.must_equal 1
983
+ end
698
984
  end
699
985
 
700
986
  describe 'for backtick string literals' do
@@ -710,10 +996,26 @@ describe RipperRubyParser::Parser do
710
996
  s(:evstr, s(:call, nil, :bar)))
711
997
  end
712
998
 
999
+ it 'works for backtick strings interpolated at the start' do
1000
+ '`#{foo}`'.
1001
+ must_be_parsed_as s(:dxstr, '',
1002
+ s(:evstr, s(:call, nil, :foo)))
1003
+ end
1004
+
713
1005
  it 'works for backtick strings with escape sequences' do
714
1006
  '`foo\\n`'.
715
1007
  must_be_parsed_as s(:xstr, "foo\n")
716
1008
  end
1009
+
1010
+ it 'works for backtick strings with multiple lines' do
1011
+ "`foo\nbar`".
1012
+ must_be_parsed_as s(:xstr, "foo\nbar")
1013
+ end
1014
+
1015
+ it 'works for backtick strings with line continuations' do
1016
+ "`foo\\\nbar`".
1017
+ must_be_parsed_as s(:xstr, 'foobar')
1018
+ end
717
1019
  end
718
1020
 
719
1021
  describe 'for array literals' do
@@ -818,6 +1120,11 @@ describe RipperRubyParser::Parser do
818
1120
  '+1'.
819
1121
  must_be_parsed_as s(:lit, 1)
820
1122
  end
1123
+
1124
+ it 'works for rationals' do
1125
+ '1000r'.
1126
+ must_be_parsed_as s(:lit, 1000r)
1127
+ end
821
1128
  end
822
1129
  end
823
1130
  end