ripper_ruby_parser 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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