ripper_ruby_parser 0.0.8 → 1.0.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 (31) hide show
  1. checksums.yaml +7 -0
  2. data/{README.rdoc → README.md} +17 -17
  3. data/Rakefile +3 -1
  4. data/lib/ripper_ruby_parser/{commenting_sexp_builder.rb → commenting_ripper_parser.rb} +22 -6
  5. data/lib/ripper_ruby_parser/parser.rb +3 -18
  6. data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +2 -1
  7. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +6 -10
  8. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +37 -60
  9. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +31 -25
  10. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +18 -8
  11. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +22 -18
  12. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +12 -23
  13. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +16 -8
  14. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +41 -15
  15. data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +40 -23
  16. data/lib/ripper_ruby_parser/sexp_processor.rb +38 -19
  17. data/lib/ripper_ruby_parser/version.rb +1 -1
  18. data/test/pt_testcase/pt_test.rb +15 -1
  19. data/test/test_helper.rb +6 -3
  20. data/test/unit/commenting_ripper_parser_test.rb +121 -0
  21. data/test/unit/parser_assignment_test.rb +23 -24
  22. data/test/unit/parser_blocks_test.rb +207 -35
  23. data/test/unit/parser_conditionals_test.rb +251 -9
  24. data/test/unit/parser_literals_test.rb +348 -8
  25. data/test/unit/parser_loops_test.rb +20 -21
  26. data/test/unit/parser_method_calls_test.rb +132 -8
  27. data/test/unit/parser_operators_test.rb +97 -7
  28. data/test/unit/parser_test.rb +631 -1231
  29. data/test/unit/sexp_processor_test.rb +26 -28
  30. metadata +28 -38
  31. data/test/unit/commenting_sexp_builder_test.rb +0 -113
@@ -2,25 +2,267 @@ require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
2
 
3
3
  describe RipperRubyParser::Parser do
4
4
  describe "#parse" do
5
+ describe "for regular if" do
6
+ it "works with a single statement" do
7
+ "if foo; bar; end".
8
+ must_be_parsed_as s(:if,
9
+ s(:call, nil, :foo),
10
+ s(:call, nil, :bar),
11
+ nil)
12
+ end
13
+
14
+ it "works with multiple statements" do
15
+ "if foo; bar; baz; end".
16
+ must_be_parsed_as s(:if,
17
+ s(:call, nil, :foo),
18
+ s(:block,
19
+ s(:call, nil, :bar),
20
+ s(:call, nil, :baz)),
21
+ nil)
22
+ end
23
+
24
+ it "works with an else clause" do
25
+ "if foo; bar; else; baz; end".
26
+ must_be_parsed_as s(:if,
27
+ s(:call, nil, :foo),
28
+ s(:call, nil, :bar),
29
+ s(:call, nil, :baz))
30
+ end
31
+
32
+ it "works with an elsif clause" do
33
+ "if foo; bar; elsif baz; qux; end".
34
+ must_be_parsed_as s(:if,
35
+ s(:call, nil, :foo),
36
+ s(:call, nil, :bar),
37
+ s(:if,
38
+ s(:call, nil, :baz),
39
+ s(:call, nil, :qux),
40
+ nil))
41
+ end
42
+
43
+ it "handles a negative condition correctly" do
44
+ "if not foo; bar; end".
45
+ must_be_parsed_as s(:if,
46
+ s(:call, s(:call, nil, :foo), :!),
47
+ s(:call, nil, :bar),
48
+ nil)
49
+ end
50
+
51
+ it "handles a negative condition in elsif correctly" do
52
+ "if foo; bar; elsif not baz; qux; end".
53
+ must_be_parsed_as s(:if,
54
+ s(:call, nil, :foo),
55
+ s(:call, nil, :bar),
56
+ s(:if,
57
+ s(:call, s(:call, nil, :baz), :!),
58
+ s(:call, nil, :qux), nil))
59
+ end
60
+
61
+ it "handles bare regex literal in condition" do
62
+ "if /foo/; bar; end".
63
+ must_be_parsed_as s(:if,
64
+ s(:match, s(:lit, /foo/)),
65
+ s(:call, nil, :bar),
66
+ nil)
67
+ end
68
+
69
+ it "handles interpolated regex in condition" do
70
+ 'if /#{foo}/; bar; end'.
71
+ must_be_parsed_as s(:if,
72
+ s(:dregx, "", s(:evstr, s(:call, nil, :foo))),
73
+ s(:call, nil, :bar),
74
+ nil)
75
+ end
76
+
77
+ it "handles block conditions" do
78
+ "if (foo; bar); baz; end".
79
+ must_be_parsed_as s(:if,
80
+ s(:block, s(:call, nil, :foo), s(:call, nil, :bar)),
81
+ s(:call, nil, :baz),
82
+ nil)
83
+ end
84
+
85
+ it "converts :dot2 to :flip2" do
86
+ "if foo..bar; baz; end".
87
+ must_be_parsed_as s(:if,
88
+ s(:flip2, s(:call, nil, :foo), s(:call, nil, :bar)),
89
+ s(:call, nil, :baz),
90
+ nil)
91
+ end
92
+
93
+ it "converts :dot3 to :flip3" do
94
+ "if foo...bar; baz; end".
95
+ must_be_parsed_as s(:if,
96
+ s(:flip3, s(:call, nil, :foo), s(:call, nil, :bar)),
97
+ s(:call, nil, :baz),
98
+ nil)
99
+ end
100
+ end
101
+
5
102
  describe "for postfix if" do
6
- it "normalizes negative conditions" do
103
+ it "works with a simple condition" do
104
+ "foo if bar".
105
+ must_be_parsed_as s(:if,
106
+ s(:call, nil, :bar),
107
+ s(:call, nil, :foo),
108
+ nil)
109
+ end
110
+
111
+ it "handles negative conditions" do
7
112
  "foo if not bar".
8
113
  must_be_parsed_as s(:if,
9
- s(:call, nil, :bar, s(:arglist)),
114
+ s(:call, s(:call, nil, :bar), :!),
115
+ s(:call, nil, :foo),
116
+ nil)
117
+ end
118
+
119
+ it "handles bare regex literal in condition" do
120
+ "foo if /bar/".
121
+ must_be_parsed_as s(:if,
122
+ s(:match, s(:lit, /bar/)),
123
+ s(:call, nil, :foo),
124
+ nil)
125
+ end
126
+
127
+ it "handles interpolated regex in condition" do
128
+ 'foo if /#{bar}/'.
129
+ must_be_parsed_as s(:if,
130
+ s(:dregx, "", s(:evstr, s(:call, nil, :bar))),
131
+ s(:call, nil, :foo),
132
+ nil)
133
+ end
134
+ end
135
+
136
+ describe "for regular unless" do
137
+ it "works with a single statement" do
138
+ "unless bar; foo; end".
139
+ must_be_parsed_as s(:if,
140
+ s(:call, nil, :bar),
141
+ nil,
142
+ s(:call, nil, :foo))
143
+ end
144
+
145
+ it "works with an else clause" do
146
+ "unless foo; bar; else; baz; end".
147
+ must_be_parsed_as s(:if,
148
+ s(:call, nil, :foo),
149
+ s(:call, nil, :baz),
150
+ s(:call, nil, :bar))
151
+ end
152
+ it "handles bare regex literal in condition" do
153
+ "unless /foo/; bar; end".
154
+ must_be_parsed_as s(:if,
155
+ s(:match, s(:lit, /foo/)),
156
+ nil,
157
+ s(:call, nil, :bar))
158
+ end
159
+
160
+ it "handles interpolated regex in condition" do
161
+ 'unless /#{foo}/; bar; end'.
162
+ must_be_parsed_as s(:if,
163
+ s(:dregx, "", s(:evstr, s(:call, nil, :foo))),
164
+ nil,
165
+ s(:call, nil, :bar))
166
+ end
167
+ end
168
+
169
+ describe "for postfix unless" do
170
+ it "works with a simple condition" do
171
+ "foo unless bar".
172
+ must_be_parsed_as s(:if,
173
+ s(:call, nil, :bar),
174
+ nil,
175
+ s(:call, nil, :foo))
176
+ end
177
+
178
+ it "handles bare regex literal in condition" do
179
+ "foo unless /bar/".
180
+ must_be_parsed_as s(:if,
181
+ s(:match, s(:lit, /bar/)),
182
+ nil,
183
+ s(:call, nil, :foo))
184
+ end
185
+
186
+ it "handles interpolated regex in condition" do
187
+ 'foo unless /#{bar}/'.
188
+ must_be_parsed_as s(:if,
189
+ s(:dregx, "", s(:evstr, s(:call, nil, :bar))),
10
190
  nil,
11
- s(:call, nil, :foo, s(:arglist)))
191
+ s(:call, nil, :foo))
12
192
  end
13
193
  end
14
194
 
15
- describe "for case" do
16
- it "emulates RubyParser's strange handling of splat" do
195
+ describe "for case block" do
196
+ it "works with a single when clause" do
197
+ "case foo; when bar; baz; end".
198
+ must_be_parsed_as s(:case,
199
+ s(:call, nil, :foo),
200
+ s(:when,
201
+ s(:array, s(:call, nil, :bar)),
202
+ s(:call, nil, :baz)),
203
+ nil)
204
+ end
205
+
206
+ it "works with multiple when clauses" do
207
+ "case foo; when bar; baz; when qux; quux; end".
208
+ must_be_parsed_as s(:case,
209
+ s(:call, nil, :foo),
210
+ s(:when,
211
+ s(:array, s(:call, nil, :bar)),
212
+ s(:call, nil, :baz)),
213
+ s(:when,
214
+ s(:array, s(:call, nil, :qux)),
215
+ s(:call, nil, :quux)),
216
+ nil)
217
+ end
218
+
219
+ it "works with multiple statements in the when block" do
220
+ "case foo; when bar; baz; qux; end".
221
+ must_be_parsed_as s(:case,
222
+ s(:call, nil, :foo),
223
+ s(:when,
224
+ s(:array, s(:call, nil, :bar)),
225
+ s(:call, nil, :baz),
226
+ s(:call, nil, :qux)),
227
+ nil)
228
+ end
229
+
230
+ it "works with an else clause" do
231
+ "case foo; when bar; baz; else; qux; end".
232
+ must_be_parsed_as s(:case,
233
+ s(:call, nil, :foo),
234
+ s(:when,
235
+ s(:array, s(:call, nil, :bar)),
236
+ s(:call, nil, :baz)),
237
+ s(:call, nil, :qux))
238
+ end
239
+
240
+ it "works with an empty when block" do
241
+ "case foo; when bar; end".
242
+ must_be_parsed_as s(:case,
243
+ s(:call, nil, :foo),
244
+ s(:when, s(:array, s(:call, nil, :bar)), nil),
245
+ nil)
246
+ end
247
+
248
+ it "works with an empty else block" do
249
+ "case foo; when bar; baz; else; end".
250
+ must_be_parsed_as s(:case,
251
+ s(:call, nil, :foo),
252
+ s(:when,
253
+ s(:array, s(:call, nil, :bar)),
254
+ s(:call, nil, :baz)),
255
+ nil)
256
+ end
257
+
258
+ it "works with a splat in the when clause" do
17
259
  "case foo; when *bar; baz; end".
18
- must_be_parsed_as s(:case, s(:call, nil, :foo, s(:arglist)),
260
+ must_be_parsed_as s(:case,
261
+ s(:call, nil, :foo),
19
262
  s(:when,
20
263
  s(:array,
21
- s(:when, s(:call, nil, :bar, s(:arglist)),
22
- nil)),
23
- s(:call, nil, :baz, s(:arglist))),
264
+ s(:splat, s(:call, nil, :bar))),
265
+ s(:call, nil, :baz)),
24
266
  nil)
25
267
 
26
268
  end
@@ -4,6 +4,41 @@ require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
4
4
  describe RipperRubyParser::Parser do
5
5
  describe "#parse" do
6
6
  describe "for regexp literals" do
7
+ it "works for a simple regex literal" do
8
+ "/foo/".
9
+ must_be_parsed_as s(:lit, /foo/)
10
+ end
11
+
12
+ it "works for regex literals with escaped right bracket" do
13
+ '/\\)/'.
14
+ must_be_parsed_as s(:lit, /\)/)
15
+ end
16
+
17
+ it "works for regex literals with escape sequences" do
18
+ '/\\)\\n\\\\/'.
19
+ must_be_parsed_as s(:lit, /\)\n\\/)
20
+ end
21
+
22
+ it "works for a regex literal with the multiline flag" do
23
+ "/foo/m".
24
+ must_be_parsed_as s(:lit, /foo/m)
25
+ end
26
+
27
+ it "works for a regex literal with the extended flag" do
28
+ "/foo/x".
29
+ must_be_parsed_as s(:lit, /foo/x)
30
+ end
31
+
32
+ it "works for a regex literal with the ignorecase flag" do
33
+ "/foo/i".
34
+ must_be_parsed_as s(:lit, /foo/i)
35
+ end
36
+
37
+ it "works for a regex literal with a combination of flags" do
38
+ "/foo/ixm".
39
+ must_be_parsed_as s(:lit, /foo/ixm)
40
+ end
41
+
7
42
  it "works with the no-encoding flag" do
8
43
  parser = RipperRubyParser::Parser.new
9
44
  result = parser.parse "/foo/n"
@@ -13,12 +48,28 @@ describe RipperRubyParser::Parser do
13
48
  end
14
49
 
15
50
  describe "with interpolations" do
51
+ it "works for a simple interpolation" do
52
+ '/foo#{bar}baz/'.
53
+ must_be_parsed_as s(:dregx,
54
+ "foo",
55
+ s(:evstr, s(:call, nil, :bar)),
56
+ s(:str, "baz"))
57
+ end
58
+
59
+ it "works for a regex literal with flags and interpolation" do
60
+ '/foo#{bar}/ixm'.
61
+ must_be_parsed_as s(:dregx,
62
+ "foo",
63
+ s(:evstr, s(:call, nil, :bar)),
64
+ 7)
65
+ end
66
+
16
67
  it "works with the no-encoding flag" do
17
68
  '/foo#{bar}/n'.
18
69
  must_be_parsed_as s(:dregx,
19
70
  "foo",
20
71
  s(:evstr,
21
- s(:call, nil, :bar, s(:arglist))), 32)
72
+ s(:call, nil, :bar)), 32)
22
73
  end
23
74
 
24
75
  it "works with the unicode-encoding flag" do
@@ -26,7 +77,7 @@ describe RipperRubyParser::Parser do
26
77
  must_be_parsed_as s(:dregx,
27
78
  "foo",
28
79
  s(:evstr,
29
- s(:call, nil, :bar, s(:arglist))), 16)
80
+ s(:call, nil, :bar)), 16)
30
81
  end
31
82
 
32
83
  it "works with the euc-encoding flag" do
@@ -34,7 +85,7 @@ describe RipperRubyParser::Parser do
34
85
  must_be_parsed_as s(:dregx,
35
86
  "foo",
36
87
  s(:evstr,
37
- s(:call, nil, :bar, s(:arglist))), 16)
88
+ s(:call, nil, :bar)), 16)
38
89
  end
39
90
 
40
91
  it "works with the sjis-encoding flag" do
@@ -42,7 +93,22 @@ describe RipperRubyParser::Parser do
42
93
  must_be_parsed_as s(:dregx,
43
94
  "foo",
44
95
  s(:evstr,
45
- s(:call, nil, :bar, s(:arglist))), 16)
96
+ s(:call, nil, :bar)), 16)
97
+ end
98
+
99
+ it "works for a regex literal with interpolate-once flag" do
100
+ '/foo#{bar}/o'.
101
+ must_be_parsed_as s(:dregx_once,
102
+ "foo",
103
+ s(:evstr, s(:call, nil, :bar)))
104
+ end
105
+
106
+ it "works with an empty interpolation" do
107
+ '/foo#{}bar/'.
108
+ must_be_parsed_as s(:dregx,
109
+ "foo",
110
+ s(:evstr),
111
+ s(:str, "bar"))
46
112
  end
47
113
 
48
114
  describe "containing just a literal string" do
@@ -62,7 +128,49 @@ describe RipperRubyParser::Parser do
62
128
  end
63
129
 
64
130
  describe "for string literals" do
131
+ it "works for empty strings" do
132
+ "''".
133
+ must_be_parsed_as s(:str, "")
134
+ end
135
+
136
+ it "sets the encoding for literal strings to utf8 even if ascii would do" do
137
+ parser = RipperRubyParser::Parser.new
138
+ result = parser.parse "\"foo\""
139
+ result.must_equal s(:str, "foo")
140
+ result[1].encoding.to_s.must_equal "UTF-8"
141
+ end
142
+
65
143
  describe "with escape sequences" do
144
+ it "works for strings with escape sequences" do
145
+ "\"\\n\"".
146
+ must_be_parsed_as s(:str, "\n")
147
+ end
148
+
149
+ it "works for strings with useless escape sequences" do
150
+ "\"F\\OO\"".
151
+ must_be_parsed_as s(:str, "FOO")
152
+ end
153
+
154
+ it "works for strings with escaped backslashes" do
155
+ "\"\\\\n\"".
156
+ must_be_parsed_as s(:str, "\\n")
157
+ end
158
+
159
+ it "works for a double-quoted string representing a regex literal with escaped right bracket" do
160
+ "\"/\\\\)/\"".
161
+ must_be_parsed_as s(:str, "/\\)/")
162
+ end
163
+
164
+ it "works for a double-quoted string containing a uselessly escaped right bracket" do
165
+ "\"/\\)/\"".
166
+ must_be_parsed_as s(:str, "/)/")
167
+ end
168
+
169
+ it "works for a string containing escaped quotes" do
170
+ "\"\\\"\"".
171
+ must_be_parsed_as s(:str, "\"")
172
+ end
173
+
66
174
  it "works with hex escapes" do
67
175
  "\"\\x36\"".must_be_parsed_as s(:str, "6")
68
176
  "\"\\x4a\"".must_be_parsed_as s(:str, "J")
@@ -143,6 +251,57 @@ describe RipperRubyParser::Parser do
143
251
  s(:evstr, s(:cvar, :@@bar)))
144
252
  end
145
253
  end
254
+
255
+ describe "with braces" do
256
+ it "works for trivial interpolated strings" do
257
+ '"#{foo}"'.
258
+ must_be_parsed_as s(:dstr,
259
+ "",
260
+ s(:evstr,
261
+ s(:call, nil, :foo)))
262
+ end
263
+
264
+ it "works for basic interpolated strings" do
265
+ '"foo#{bar}"'.
266
+ must_be_parsed_as s(:dstr,
267
+ "foo",
268
+ s(:evstr,
269
+ s(:call, nil, :bar)))
270
+ end
271
+
272
+ it "works for strings with several interpolations" do
273
+ '"foo#{bar}baz#{qux}"'.
274
+ must_be_parsed_as s(:dstr,
275
+ "foo",
276
+ s(:evstr, s(:call, nil, :bar)),
277
+ s(:str, "baz"),
278
+ s(:evstr, s(:call, nil, :qux)))
279
+ end
280
+
281
+ it "correctly handles two interpolations in a row" do
282
+ "\"\#{bar}\#{qux}\"".
283
+ must_be_parsed_as s(:dstr,
284
+ "",
285
+ s(:evstr, s(:call, nil, :bar)),
286
+ s(:evstr, s(:call, nil, :qux)))
287
+ end
288
+
289
+ it "works for strings with interpolations followed by escape sequences" do
290
+ '"#{foo}\\n"'.
291
+ must_be_parsed_as s(:dstr,
292
+ "",
293
+ s(:evstr, s(:call, nil, :foo)),
294
+ s(:str, "\n"))
295
+ end
296
+
297
+ it "works with an empty interpolation" do
298
+ "\"foo\#{}bar\"".
299
+ must_be_parsed_as s(:dstr,
300
+ "foo",
301
+ s(:evstr),
302
+ s(:str, "bar"))
303
+ end
304
+ end
146
305
  end
147
306
 
148
307
  describe "with string concatenation" do
@@ -154,14 +313,14 @@ describe RipperRubyParser::Parser do
154
313
  "\"foo\" \"bar\#{baz}\"".
155
314
  must_be_parsed_as s(:dstr,
156
315
  "foobar",
157
- s(:evstr, s(:call, nil, :baz, s(:arglist))))
316
+ s(:evstr, s(:call, nil, :baz)))
158
317
  end
159
318
 
160
319
  it "performs the concatenation when the left string has interpolations" do
161
320
  "\"foo\#{bar}\" \"baz\"".
162
321
  must_be_parsed_as s(:dstr,
163
322
  "foo",
164
- s(:evstr, s(:call, nil, :bar, s(:arglist))),
323
+ s(:evstr, s(:call, nil, :bar)),
165
324
  s(:str, "baz"))
166
325
  end
167
326
 
@@ -169,11 +328,192 @@ describe RipperRubyParser::Parser do
169
328
  "\"foo\#{bar}\" \"baz\#{qux}\"".
170
329
  must_be_parsed_as s(:dstr,
171
330
  "foo",
172
- s(:evstr, s(:call, nil, :bar, s(:arglist))),
331
+ s(:evstr, s(:call, nil, :bar)),
173
332
  s(:str, "baz"),
174
- s(:evstr, s(:call, nil, :qux, s(:arglist))))
333
+ s(:evstr, s(:call, nil, :qux)))
334
+ end
335
+
336
+ it "removes empty substrings from the concatenation when both strings have interpolations" do
337
+ "\"foo\#{bar}\" \"\#{qux}\"".
338
+ must_be_parsed_as s(:dstr,
339
+ "foo",
340
+ s(:evstr, s(:call, nil, :bar)),
341
+ s(:evstr, s(:call, nil, :qux)))
175
342
  end
176
343
  end
177
344
  end
345
+
346
+ describe "for word list literals" do
347
+ it "correctly handles interpolation" do
348
+ "%W(foo \#{bar} baz)".
349
+ must_be_parsed_as s(:array,
350
+ s(:str, "foo"),
351
+ s(:dstr, "", s(:evstr, s(:call, nil, :bar))),
352
+ s(:str, "baz"))
353
+ end
354
+
355
+ it "correctly handles braceless interpolation" do
356
+ "%W(foo \#@bar baz)".
357
+ must_be_parsed_as s(:array,
358
+ s(:str, "foo"),
359
+ s(:dstr, "", s(:evstr, s(:ivar, :@bar))),
360
+ s(:str, "baz"))
361
+ end
362
+ end
363
+
364
+ describe "for character literals" do
365
+ it "works for simple character literals" do
366
+ "?a".
367
+ must_be_parsed_as s(:str, "a")
368
+ end
369
+
370
+ it "works for escaped character literals" do
371
+ "?\\n".
372
+ must_be_parsed_as s(:str, "\n")
373
+ end
374
+
375
+ it "works for escaped character literals with ctrl" do
376
+ "?\\C-a".
377
+ must_be_parsed_as s(:str, "\u0001")
378
+ end
379
+
380
+ it "works for escaped character literals with meta" do
381
+ "?\\M-a".
382
+ must_be_parsed_as s(:str, "\xE1".force_encoding("ascii-8bit"))
383
+ end
384
+
385
+ it "works for escaped character literals with meta plus shorthand ctrl" do
386
+ "?\\M-\\ca".
387
+ must_be_parsed_as s(:str, "\x81".force_encoding("ascii-8bit"))
388
+ end
389
+
390
+ it "works for escaped character literals with shorthand ctrl plus meta" do
391
+ "?\\c\\M-a".
392
+ must_be_parsed_as s(:str, "\x81".force_encoding("ascii-8bit"))
393
+ end
394
+
395
+ it "works for escaped character literals with meta plus ctrl" do
396
+ "?\\M-\\C-a".
397
+ must_be_parsed_as s(:str, "\x81".force_encoding("ascii-8bit"))
398
+ end
399
+
400
+ it "works for escaped character literals with ctrl plus meta" do
401
+ "?\\C-\\M-a".
402
+ must_be_parsed_as s(:str, "\x81".force_encoding("ascii-8bit"))
403
+ end
404
+ end
405
+
406
+ describe "for symbol literals" do
407
+ it "works for simple symbols" do
408
+ ":foo".
409
+ must_be_parsed_as s(:lit, :foo)
410
+ end
411
+
412
+ it "works for symbols that look like instance variable names" do
413
+ ":@foo".
414
+ must_be_parsed_as s(:lit, :@foo)
415
+ end
416
+
417
+ it "works for simple dsyms" do
418
+ ':"foo"'.
419
+ must_be_parsed_as s(:lit, :foo)
420
+ end
421
+
422
+ it "works for dsyms with interpolations" do
423
+ ':"foo#{bar}"'.
424
+ must_be_parsed_as s(:dsym,
425
+ "foo",
426
+ s(:evstr, s(:call, nil, :bar)))
427
+ end
428
+ end
429
+
430
+ describe "for backtick string literals" do
431
+ it "works for basic backtick strings" do
432
+ '`foo`'.
433
+ must_be_parsed_as s(:xstr, "foo")
434
+ end
435
+
436
+ it "works for interpolated backtick strings" do
437
+ '`foo#{bar}`'.
438
+ must_be_parsed_as s(:dxstr,
439
+ "foo",
440
+ s(:evstr, s(:call, nil, :bar)))
441
+ end
442
+
443
+ it "works for backtick strings with escape sequences" do
444
+ '`foo\\n`'.
445
+ must_be_parsed_as s(:xstr, "foo\n")
446
+ end
447
+ end
448
+
449
+ describe "for array literals" do
450
+ it "works for an empty array" do
451
+ "[]".
452
+ must_be_parsed_as s(:array)
453
+ end
454
+
455
+ it "works for a simple case with splat" do
456
+ "[*foo]".
457
+ must_be_parsed_as s(:array,
458
+ s(:splat, s(:call, nil, :foo)))
459
+ end
460
+
461
+ it "works for a multi-element case with splat" do
462
+ "[foo, *bar]".
463
+ must_be_parsed_as s(:array,
464
+ s(:call, nil, :foo),
465
+ s(:splat, s(:call, nil, :bar)))
466
+ end
467
+
468
+ it "works for an array created with %W" do
469
+ "%W(foo bar)".
470
+ must_be_parsed_as s(:array, s(:str, "foo"), s(:str, "bar"))
471
+ end
472
+ end
473
+
474
+ describe "for hash literals" do
475
+ it "works for an empty hash" do
476
+ "{}".
477
+ must_be_parsed_as s(:hash)
478
+ end
479
+
480
+ it "works for a hash with one pair" do
481
+ "{foo => bar}".
482
+ must_be_parsed_as s(:hash,
483
+ s(:call, nil, :foo),
484
+ s(:call, nil, :bar))
485
+ end
486
+
487
+ it "works for a hash with multiple pairs" do
488
+ "{foo => bar, baz => qux}".
489
+ must_be_parsed_as s(:hash,
490
+ s(:call, nil, :foo),
491
+ s(:call, nil, :bar),
492
+ s(:call, nil, :baz),
493
+ s(:call, nil, :qux))
494
+ end
495
+
496
+ it "works for a hash with label keys (Ruby 1.9 only)" do
497
+ "{foo: bar, baz: qux}".
498
+ must_be_parsed_as s(:hash,
499
+ s(:lit, :foo),
500
+ s(:call, nil, :bar),
501
+ s(:lit, :baz),
502
+ s(:call, nil, :qux))
503
+ end
504
+ end
505
+
506
+ describe "for number literals" do
507
+ it "works for floats" do
508
+ "3.14".
509
+ must_be_parsed_as s(:lit, 3.14)
510
+ end
511
+
512
+ it "works for octal integer literals" do
513
+ "0700".
514
+ must_be_parsed_as s(:lit, 448)
515
+ end
516
+ end
517
+
178
518
  end
179
519
  end