to_source 0.1.3 → 0.2.16

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 (89) hide show
  1. data/.gitignore +6 -6
  2. data/.rspec +1 -0
  3. data/.travis.yml +12 -1
  4. data/Changelog.md +115 -0
  5. data/Gemfile +5 -3
  6. data/Gemfile.devtools +67 -0
  7. data/Guardfile +18 -0
  8. data/LICENSE +21 -0
  9. data/README.md +52 -0
  10. data/Rakefile +3 -8
  11. data/TODO +9 -0
  12. data/bin/to_source +17 -0
  13. data/config/flay.yml +3 -0
  14. data/config/flog.yml +2 -0
  15. data/config/roodi.yml +26 -0
  16. data/config/site.reek +97 -0
  17. data/config/yardstick.yml +2 -0
  18. data/lib/to_source/command.rb +106 -0
  19. data/lib/to_source/emitter/access.rb +28 -0
  20. data/lib/to_source/emitter/actual_arguments.rb +89 -0
  21. data/lib/to_source/emitter/alias.rb +27 -0
  22. data/lib/to_source/emitter/assignment.rb +119 -0
  23. data/lib/to_source/emitter/attribute_assignment.rb +28 -0
  24. data/lib/to_source/emitter/begin.rb +71 -0
  25. data/lib/to_source/emitter/binary_operator.rb +63 -0
  26. data/lib/to_source/emitter/binary_operator_method.rb +58 -0
  27. data/lib/to_source/emitter/block.rb +29 -0
  28. data/lib/to_source/emitter/block_argument.rb +23 -0
  29. data/lib/to_source/emitter/block_pass.rb +23 -0
  30. data/lib/to_source/emitter/case.rb +85 -0
  31. data/lib/to_source/emitter/class.rb +44 -0
  32. data/lib/to_source/emitter/concat_arguments.rb +28 -0
  33. data/lib/to_source/emitter/default_arguments.rb +22 -0
  34. data/lib/to_source/emitter/define.rb +99 -0
  35. data/lib/to_source/emitter/defined.rb +24 -0
  36. data/lib/to_source/emitter/element_assignment.rb +29 -0
  37. data/lib/to_source/emitter/element_reference.rb +25 -0
  38. data/lib/to_source/emitter/empty_body.rb +21 -0
  39. data/lib/to_source/emitter/ensure.rb +50 -0
  40. data/lib/to_source/emitter/ensure_body.rb +27 -0
  41. data/lib/to_source/emitter/execute_string.rb +22 -0
  42. data/lib/to_source/emitter/formal_arguments.rb +212 -0
  43. data/lib/to_source/emitter/if.rb +96 -0
  44. data/lib/to_source/emitter/iter.rb +27 -0
  45. data/lib/to_source/emitter/keyword_value.rb +67 -0
  46. data/lib/to_source/emitter/literal/dynamic.rb +178 -0
  47. data/lib/to_source/emitter/literal.rb +232 -0
  48. data/lib/to_source/emitter/loop.rb +40 -0
  49. data/lib/to_source/emitter/match3.rb +25 -0
  50. data/lib/to_source/emitter/module.rb +28 -0
  51. data/lib/to_source/emitter/multiple_assignment.rb +49 -0
  52. data/lib/to_source/emitter/nth_ref.rb +22 -0
  53. data/lib/to_source/emitter/op_assign1.rb +27 -0
  54. data/lib/to_source/emitter/op_assign2.rb +27 -0
  55. data/lib/to_source/emitter/pattern_arguments.rb +24 -0
  56. data/lib/to_source/emitter/rescue.rb +28 -0
  57. data/lib/to_source/emitter/rescue_condition.rb +93 -0
  58. data/lib/to_source/emitter/scope.rb +24 -0
  59. data/lib/to_source/emitter/scope_name.rb +23 -0
  60. data/lib/to_source/emitter/scoped_name.rb +28 -0
  61. data/lib/to_source/emitter/send.rb +133 -0
  62. data/lib/to_source/emitter/send_with_arguments.rb +103 -0
  63. data/lib/to_source/emitter/singleton_class.rb +38 -0
  64. data/lib/to_source/emitter/splat.rb +24 -0
  65. data/lib/to_source/emitter/splat_when.rb +23 -0
  66. data/lib/to_source/emitter/static.rb +52 -0
  67. data/lib/to_source/emitter/super.rb +92 -0
  68. data/lib/to_source/emitter/to_array.rb +22 -0
  69. data/lib/to_source/emitter/to_string.rb +24 -0
  70. data/lib/to_source/emitter/toplevel.rb +24 -0
  71. data/lib/to_source/emitter/unary_operator_method.rb +27 -0
  72. data/lib/to_source/emitter/unless.rb +45 -0
  73. data/lib/to_source/emitter/util.rb +28 -0
  74. data/lib/to_source/emitter/when.rb +63 -0
  75. data/lib/to_source/emitter/yield.rb +28 -0
  76. data/lib/to_source/emitter/z_super.rb +24 -0
  77. data/lib/to_source/emitter.rb +278 -0
  78. data/lib/to_source/state.rb +144 -0
  79. data/lib/to_source.rb +78 -11
  80. data/spec/spec_helper.rb +11 -0
  81. data/spec/unit/to_source/class_methods/run_spec.rb +1254 -0
  82. data/to_source.gemspec +16 -14
  83. metadata +160 -20
  84. data/.rvmrc +0 -1
  85. data/Readme.md +0 -38
  86. data/lib/to_source/core_ext/node.rb +0 -22
  87. data/lib/to_source/version.rb +0 -3
  88. data/lib/to_source/visitor.rb +0 -377
  89. data/test/to_source/visitor_test.rb +0 -202
@@ -0,0 +1,1254 @@
1
+ require 'spec_helper'
2
+
3
+ describe ToSource,'.to_source' do
4
+ def compress(code)
5
+ lines = code.split("\n")
6
+ match = /\A( *)/.match(lines.first)
7
+ whitespaces = match[1].to_s.length
8
+ stripped = lines.map do |line|
9
+ line[whitespaces..-1]
10
+ end
11
+ joined = stripped.join("\n")
12
+ end
13
+
14
+ def assert_round_trip(code)
15
+ node = code.to_ast
16
+ generated = ToSource.to_source(node)
17
+ generated.should eql(code)
18
+ # This is nonsense but I had a case where it helps?
19
+ second_node = generated.to_ast
20
+ second = ToSource.to_source(second_node)
21
+ second.should eql(code)
22
+ end
23
+
24
+ def assert_entrypoints(node)
25
+ node.instance_variables.each do |ivar|
26
+ value = node.instance_variable_get(ivar)
27
+ next unless value.kind_of?(Rubinius::AST::Node)
28
+ ToSource.to_source(value)
29
+ assert_entrypoints(value)
30
+ end
31
+ end
32
+
33
+ shared_examples_for 'a source generation method' do
34
+ it 'should create original source' do
35
+ assert_round_trip(compress(expected_source))
36
+ end
37
+
38
+ it 'should be able to use all wrapped nodes as entrypoints' do
39
+ assert_entrypoints(expected_source.to_ast)
40
+ end
41
+ end
42
+
43
+ def self.assert_source(source)
44
+ let(:node) { source.to_ast }
45
+ let(:source) { source }
46
+ let(:expected_source) { source }
47
+
48
+ it_should_behave_like 'a source generation method'
49
+ end
50
+
51
+ def self.assert_converts(converted, source)
52
+ let(:node) { source.to_ast }
53
+ let(:source) { source }
54
+ let(:expected_source) { converted }
55
+ it_should_behave_like 'a source generation method'
56
+ end
57
+
58
+ context 'class' do
59
+ context 'simple' do
60
+ assert_source <<-RUBY
61
+ class TestClass
62
+
63
+ end
64
+ RUBY
65
+ end
66
+
67
+ context 'singleton class inheritance' do
68
+ assert_source <<-RUBY
69
+ class << some_object
70
+ the_body
71
+ end
72
+ RUBY
73
+ end
74
+
75
+ context 'scoped' do
76
+ assert_source <<-RUBY
77
+ class SomeNameSpace::TestClass
78
+
79
+ end
80
+ RUBY
81
+ end
82
+
83
+ context 'deeply scoped' do
84
+ assert_source <<-RUBY
85
+ class Some::Name::Space::TestClass
86
+
87
+ end
88
+ RUBY
89
+ end
90
+
91
+ context 'with subclass' do
92
+ assert_source <<-RUBY
93
+ class TestClass < Object
94
+
95
+ end
96
+ RUBY
97
+ end
98
+
99
+ context 'with scoped superclass' do
100
+ assert_source <<-RUBY
101
+ class TestClass < SomeNameSpace::Object
102
+
103
+ end
104
+ RUBY
105
+ end
106
+
107
+ context 'with body' do
108
+ assert_source <<-RUBY
109
+ class TestClass
110
+ def foo
111
+ :bar
112
+ end
113
+ end
114
+ RUBY
115
+ end
116
+
117
+ context 'toplevel' do
118
+ assert_source <<-RUBY
119
+ class ::TestClass
120
+
121
+ end
122
+ RUBY
123
+ end
124
+ end
125
+
126
+ context 'module nodes' do
127
+ context 'simple' do
128
+ assert_source <<-RUBY
129
+ module TestModule
130
+
131
+ end
132
+ RUBY
133
+ end
134
+
135
+ context 'scoped' do
136
+ assert_source <<-RUBY
137
+ module SomeNameSpace::TestModule
138
+
139
+ end
140
+ RUBY
141
+ end
142
+
143
+ context 'deeply scoped' do
144
+ assert_source <<-RUBY
145
+ module Some::Name::Space::TestModule
146
+
147
+ end
148
+ RUBY
149
+ end
150
+
151
+ context 'with body' do
152
+ assert_source <<-RUBY
153
+ module TestModule
154
+ def foo
155
+ :bar
156
+ end
157
+ end
158
+ RUBY
159
+ end
160
+ end
161
+
162
+ context 'single assignment' do
163
+ context 'to local variable' do
164
+ assert_source 'foo = 1'
165
+ end
166
+
167
+ context 'to instance variable' do
168
+ assert_source '@foo = 1'
169
+ end
170
+
171
+ context 'to global variable' do
172
+ assert_source '$foo = 1'
173
+ end
174
+
175
+ context 'to class variable' do
176
+ assert_source '@@foo = 1'
177
+ end
178
+
179
+
180
+ context 'to constant' do
181
+ assert_source 'SOME_CONSTANT = 1'
182
+ end
183
+ end
184
+
185
+ context 'conditional element assignment' do
186
+ assert_source 'foo[key] ||= bar'
187
+ end
188
+
189
+ context 'attribute assignment on merge' do
190
+ assert_source 'self.foo |= bar'
191
+ end
192
+
193
+
194
+ context 'element assignment' do
195
+ assert_source 'array[index] = value'
196
+ end
197
+
198
+ context 'multiple assignment' do
199
+ context 'to local variable' do
200
+ assert_source 'a, b = 1, 2'
201
+ end
202
+
203
+ context 'to instance variable' do
204
+ assert_source '@a, @b = 1, 2'
205
+ end
206
+
207
+ context 'to class variable' do
208
+ assert_source '@@a, @@b = 1, 2'
209
+ end
210
+
211
+ context 'to global variable' do
212
+ assert_source '$a, $b = 1, 2'
213
+ end
214
+
215
+ context 'unbalanced' do
216
+ assert_source 'a, b = foo'
217
+ end
218
+ end
219
+
220
+ context 'defined' do
221
+ context 'with instance varialbe' do
222
+ assert_source <<-RUBY
223
+ defined?(@foo)
224
+ RUBY
225
+ end
226
+
227
+ context 'with constant' do
228
+ assert_source <<-RUBY
229
+ defined?(Foo)
230
+ RUBY
231
+ end
232
+ end
233
+
234
+ context 'access' do
235
+ context 'on local variable' do
236
+ assert_source <<-RUBY
237
+ foo = 1
238
+ foo
239
+ RUBY
240
+ end
241
+
242
+ context 'on class variable' do
243
+ assert_source '@@foo'
244
+ end
245
+
246
+ context 'on nth ref global variable' do
247
+ assert_source '$1'
248
+ end
249
+
250
+ context 'on global variable' do
251
+ assert_source '$foo'
252
+ end
253
+
254
+ context 'on instance variable' do
255
+ assert_source '@foo'
256
+ end
257
+
258
+ context 'toplevel constant' do
259
+ assert_source '::Rubinius'
260
+ end
261
+
262
+ context 'constant' do
263
+ assert_source 'Rubinius'
264
+ end
265
+
266
+ context 'scoped constant' do
267
+ assert_source 'Rubinius::Debugger'
268
+ end
269
+ end
270
+
271
+ context 'literal' do
272
+ context 'fixnum' do
273
+ assert_source '1'
274
+ end
275
+
276
+ context 'float' do
277
+ assert_source '1.0'
278
+ end
279
+
280
+ context 'negated numeric' do
281
+ assert_source '-1'
282
+ end
283
+
284
+ context 'string' do
285
+ assert_source '"foo"'
286
+ end
287
+
288
+ context 'execute string' do
289
+ assert_source '`foo`'
290
+ end
291
+
292
+ context 'symbol' do
293
+ assert_source ':foo'
294
+ end
295
+
296
+ context 'true' do
297
+ assert_source 'true'
298
+ end
299
+
300
+ context 'false' do
301
+ assert_source 'false'
302
+ end
303
+
304
+ context 'nil' do
305
+ assert_source 'nil'
306
+ end
307
+
308
+ context 'empty array' do
309
+ assert_source '[]'
310
+ end
311
+
312
+ context 'array' do
313
+ context 'simple' do
314
+ assert_source '[1, 2, 3]'
315
+ end
316
+
317
+ context 'with splat' do
318
+ assert_source '[1, *foo]'
319
+ end
320
+ end
321
+
322
+ context 'empty hash' do
323
+ assert_source '{}'
324
+ end
325
+
326
+ context 'hash' do
327
+ assert_source '{:answer => 42, :bar => :baz}'
328
+ end
329
+
330
+ context 'inclusive range' do
331
+ assert_source '20..34'
332
+ end
333
+
334
+ context 'exclusive range' do
335
+ assert_source '20...34'
336
+ end
337
+
338
+ context 'regexp' do
339
+ context 'simple' do
340
+ assert_source '/.*/'
341
+ end
342
+
343
+ context 'with escapes' do
344
+ assert_source '/\//'
345
+ end
346
+
347
+ context 'with non slash literal containing slashes' do
348
+ assert_converts '/\//', '%r(/)'
349
+ end
350
+ end
351
+
352
+ context 'dynamic string' do
353
+ context 'simple' do
354
+ assert_source '"foo#{bar}baz"'
355
+ end
356
+
357
+ context 'with escapes' do
358
+ assert_source '"fo\no#{bar}b\naz"'
359
+ end
360
+
361
+ context 'with dynamic segment in the front' do
362
+ assert_source '"#{bar}foo"'
363
+ end
364
+
365
+ context 'with dynamic segment in the end' do
366
+ assert_source '"foo#{bar}"'
367
+ end
368
+ end
369
+
370
+ context 'dynamic symbol' do
371
+ context 'simple' do
372
+ assert_source ':"foo#{bar}baz"'
373
+ end
374
+
375
+ context 'with escapes' do
376
+ assert_source ':"fo\no#{bar}b\naz"'
377
+ end
378
+
379
+ context 'with dynamic segment in the front' do
380
+ assert_source ':"#{bar}foo"'
381
+ end
382
+
383
+ context 'with dynamic segment in the end' do
384
+ assert_source ':"foo#{bar}"'
385
+ end
386
+ end
387
+
388
+ context 'dynamic execute' do
389
+ context 'simple' do
390
+ assert_source '`foo#{bar}baz`'
391
+ end
392
+
393
+ context 'with escapes' do
394
+ assert_source '`fo\no#{bar}b\naz`'
395
+ end
396
+
397
+ context 'with dynamic segment in the front' do
398
+ assert_source '`#{bar}foo`'
399
+ end
400
+
401
+ context 'with dynamic segment in the end' do
402
+ assert_source '`foo#{bar}`'
403
+ end
404
+ end
405
+
406
+ context 'dynamic regexp' do
407
+ context 'simple' do
408
+ assert_source '/foo#{bar}baz/'
409
+ end
410
+
411
+ context 'split groups' do
412
+ assert_source '/(#{foo})*/'
413
+ end
414
+
415
+ context 'with escapes' do
416
+ assert_source '/fo\no#{bar}b\naz/'
417
+ end
418
+
419
+ context 'with dynamic segment in the front' do
420
+ assert_source '/#{bar}foo/'
421
+ end
422
+
423
+ context 'with dynamic segment in the end' do
424
+ assert_source '/foo#{bar}/'
425
+ end
426
+ end
427
+ end
428
+
429
+ context 'send' do
430
+ context 'as element reference' do
431
+ assert_source 'foo[index]'
432
+ end
433
+
434
+ context 'as element reference on self' do
435
+ assert_source 'self[foo]'
436
+ end
437
+
438
+ context 'without arguments' do
439
+ assert_source 'foo.bar'
440
+ end
441
+
442
+ context 'with arguments' do
443
+ assert_source 'foo.bar(:baz, :yeah)'
444
+ end
445
+
446
+ context 'to self' do
447
+
448
+ context 'explicitly' do
449
+ assert_source 'self.foo'
450
+ end
451
+
452
+ context 'explicitly with message name equals a keyword' do
453
+ assert_source 'self.and'
454
+ end
455
+
456
+ context 'implicitly' do
457
+ assert_source 'foo'
458
+ end
459
+
460
+ context 'with arguments' do
461
+ context 'implicitly' do
462
+ assert_source 'bar(:baz, :yeah)'
463
+ end
464
+
465
+ context 'explicitly' do
466
+ assert_source 'self.bar(:baz, :yeah)'
467
+ end
468
+ end
469
+ end
470
+
471
+ context 'with block' do
472
+ assert_source <<-RUBY
473
+ foo.bar do
474
+ 3
475
+ 4
476
+ end
477
+ RUBY
478
+ end
479
+
480
+ context 'with block that takes pattern and formal arguments' do
481
+ assert_source <<-RUBY
482
+ foo.bar do |(a, b), c|
483
+ d
484
+ end
485
+ RUBY
486
+ end
487
+
488
+
489
+ context 'with block that takes pattern and no formal arguments' do
490
+ assert_source <<-RUBY
491
+ foo.bar do |(a, b)|
492
+ d
493
+ end
494
+ RUBY
495
+ end
496
+
497
+ context 'with block that takes arguments' do
498
+ assert_source <<-RUBY
499
+ foo.bar do |a|
500
+ 3
501
+ 4
502
+ end
503
+ RUBY
504
+ end
505
+
506
+ context 'with arguments and block' do
507
+ assert_source <<-RUBY
508
+ foo.bar(baz) do
509
+ 4
510
+ end
511
+ RUBY
512
+ end
513
+
514
+ context 'with splat argument' do
515
+ assert_source 'foo.bar(*args)'
516
+ end
517
+
518
+ context 'with formal and splat argument' do
519
+ assert_source 'foo.bar(foo, *args)'
520
+ end
521
+
522
+ context 'with formal splat and block argument' do
523
+ assert_source 'foo.bar(foo, *args, &block)'
524
+ end
525
+
526
+ context 'with formal splat and block' do
527
+ assert_source <<-RUBY
528
+ foo(bar, *args)
529
+ RUBY
530
+ end
531
+
532
+ context 'with splat and block argument' do
533
+ assert_source <<-RUBY
534
+ foo(*args, &block)
535
+ RUBY
536
+ end
537
+
538
+ context 'with passing block argument' do
539
+ assert_source 'foo.bar(&baz)'
540
+ end
541
+
542
+ context 'with formal and block argument' do
543
+ assert_source 'foo.bar(:baz, &baz)'
544
+ end
545
+
546
+ context 'attribute assignment' do
547
+ context 'on foreign object' do
548
+ assert_source 'foo.bar= :baz'
549
+ end
550
+
551
+ context 'on self' do
552
+ assert_source 'self.foo= :bar'
553
+ end
554
+ end
555
+ end
556
+
557
+ context 'lambda' do
558
+ assert_source <<-RUBY
559
+ lambda do |a, b|
560
+ a
561
+ end
562
+ RUBY
563
+ end
564
+
565
+ context 'super' do
566
+ context 'without arguments' do
567
+ assert_source 'super'
568
+ end
569
+
570
+ context 'without arguments and block' do
571
+ assert_source <<-RUBY
572
+ super do
573
+ foo
574
+ end
575
+ RUBY
576
+ end
577
+
578
+ context 'with explicit zero arguments' do
579
+ assert_source 'super()'
580
+ end
581
+
582
+ context 'with explicit zero arguments and block' do
583
+ assert_source <<-RUBY
584
+ super() do
585
+ foo
586
+ end
587
+ RUBY
588
+ end
589
+
590
+ context 'with argument' do
591
+ assert_source 'super(a)'
592
+ end
593
+
594
+ context 'with argument and block' do
595
+ assert_source <<-RUBY
596
+ super(a) do
597
+ foo
598
+ end
599
+ RUBY
600
+ end
601
+
602
+ context 'with arguments' do
603
+ assert_source 'super(a, b)'
604
+ end
605
+
606
+ context 'with arguments and block' do
607
+ assert_source <<-RUBY
608
+ super(a, b) do
609
+ foo
610
+ end
611
+ RUBY
612
+ end
613
+
614
+ context 'with block argument' do
615
+ assert_source 'super(&block)'
616
+ end
617
+
618
+ context 'with formal and block argument' do
619
+ assert_source 'super(a, &block)'
620
+ end
621
+ end
622
+
623
+ context 'break' do
624
+ assert_source 'break'
625
+ end
626
+
627
+ context 'break with arguments' do
628
+ assert_source 'break(a)'
629
+ end
630
+
631
+ context 'next' do
632
+ assert_source 'next'
633
+ end
634
+
635
+ context 'match operator' do
636
+ assert_source <<-RUBY
637
+ foo =~ /bar/
638
+ RUBY
639
+ end
640
+
641
+ context 'alias' do
642
+ assert_source <<-RUBY
643
+ alias foo bar
644
+ RUBY
645
+ end
646
+
647
+ context 'yield' do
648
+ context 'without arguments' do
649
+ assert_source 'yield'
650
+ end
651
+
652
+ context 'with argument' do
653
+ assert_source 'yield(a)'
654
+ end
655
+
656
+ context 'with arguments' do
657
+ assert_source 'yield(a, b)'
658
+ end
659
+ end
660
+
661
+ context 'binary operators methods' do
662
+ %w(+ - * / & | && || << >> == === != <= < <=> > >= =~ !~ ^ **).each do |operator|
663
+ context "on literals #{operator}" do
664
+ assert_source "((1) #{operator} (2))"
665
+ end
666
+
667
+ context "on self #{operator}" do
668
+ assert_source "((self) #{operator} (b))"
669
+ end
670
+
671
+ context "on send #{operator}" do
672
+ assert_source "((a) #{operator} (b))"
673
+ end
674
+ end
675
+
676
+ context 'binary operator and keywords' do
677
+ assert_source '((a) || (break(foo)))'
678
+ end
679
+
680
+ context 'sending methods to result of binary operator' do
681
+ assert_source '((a) || (b)).foo'
682
+ end
683
+
684
+ context 'nested binary operators' do
685
+ assert_source '((a) || (((b) || (c))))'
686
+ end
687
+ end
688
+
689
+ { :or => :'||', :and => :'&&' }.each do |word, symbol|
690
+ context "word form form equivalency of #{word} and #{symbol}" do
691
+ assert_converts "((a) #{symbol} (break(foo)))", "a #{word} break foo"
692
+ end
693
+ end
694
+
695
+ context 'expansion of shortcuts' do
696
+ context 'on += operator' do
697
+ assert_converts 'a = ((a) + (2))', 'a += 2'
698
+ end
699
+
700
+ context 'on -= operator' do
701
+ assert_converts 'a = ((a) - (2))', 'a -= 2'
702
+ end
703
+
704
+ context 'on **= operator' do
705
+ assert_converts 'a = ((a) ** (2))', 'a **= 2'
706
+ end
707
+
708
+ context 'on *= operator' do
709
+ assert_converts 'a = ((a) * (2))', 'a *= 2'
710
+ end
711
+
712
+ context 'on /= operator' do
713
+ assert_converts 'a = ((a) / (2))', 'a /= 2'
714
+ end
715
+ end
716
+
717
+ context 'shortcuts' do
718
+ context 'on &&= operator' do
719
+ assert_source '(a &&= (b))'
720
+ end
721
+
722
+ context 'on ||= operator' do
723
+ assert_source '(a ||= (2))'
724
+ end
725
+
726
+ context 'calling methods on shortcuts' do
727
+ assert_source '(a ||= (2)).bar'
728
+ end
729
+ end
730
+
731
+ context 'unary operators' do
732
+ context 'negation' do
733
+ assert_source '!1'
734
+ end
735
+
736
+ context 'double negation' do
737
+ assert_source '!!1'
738
+ end
739
+
740
+ context 'unary match' do
741
+ assert_source '~a'
742
+ end
743
+
744
+ context 'unary minus' do
745
+ assert_source '-a'
746
+ end
747
+
748
+ context 'unary plus' do
749
+ assert_source '+a'
750
+ end
751
+ end
752
+
753
+ context 'if statement' do
754
+ context 'without else branch' do
755
+ context 'single statement in branch' do
756
+ assert_source <<-RUBY
757
+ if 3
758
+ 9
759
+ end
760
+ RUBY
761
+ end
762
+
763
+ context 'multiple statements in branch' do
764
+ assert_source <<-RUBY
765
+ if 3
766
+ 9
767
+ 10
768
+ end
769
+ RUBY
770
+ end
771
+ end
772
+
773
+ context 'with else branch' do
774
+ context 'single expression in branch' do
775
+ assert_source <<-RUBY
776
+ if 4
777
+ 5
778
+ else
779
+ 6
780
+ end
781
+ RUBY
782
+ end
783
+
784
+ context 'multiple expressions in branch' do
785
+ assert_source <<-RUBY
786
+ if 4
787
+ 5
788
+ else
789
+ 6
790
+ 7
791
+ end
792
+ RUBY
793
+ end
794
+ end
795
+
796
+ context 'unless' do
797
+ context 'single statement in branch' do
798
+ assert_source <<-RUBY
799
+ unless 3
800
+ 9
801
+ end
802
+ RUBY
803
+ end
804
+
805
+ context 'single statement in branch' do
806
+ assert_source <<-RUBY
807
+ unless 3
808
+ 9
809
+ 10
810
+ end
811
+ RUBY
812
+ end
813
+ end
814
+ end
815
+
816
+ context 'case statement' do
817
+ context 'without else branch' do
818
+ assert_source <<-RUBY
819
+ case
820
+ when bar
821
+ baz
822
+ when baz
823
+ bar
824
+ end
825
+ RUBY
826
+ end
827
+ end
828
+
829
+ context 'receiver case statement' do
830
+ context 'without else branch' do
831
+ assert_source <<-RUBY
832
+ case foo
833
+ when bar
834
+ baz
835
+ when baz
836
+ bar
837
+ end
838
+ RUBY
839
+ end
840
+
841
+ context 'with multivalued conditions' do
842
+ assert_source <<-RUBY
843
+ case foo
844
+ when bar, baz
845
+ :other
846
+ end
847
+ RUBY
848
+ end
849
+
850
+ context 'with splat operator' do
851
+ assert_source <<-RUBY
852
+ case foo
853
+ when *bar
854
+ :value
855
+ end
856
+ RUBY
857
+ end
858
+
859
+ context 'with else branch' do
860
+ assert_source <<-RUBY
861
+ case foo
862
+ when bar
863
+ baz
864
+ else
865
+ :foo
866
+ end
867
+ RUBY
868
+ end
869
+ end
870
+
871
+ context 'loop' do
872
+ assert_source <<-RUBY
873
+ loop do
874
+ foo
875
+ end
876
+ RUBY
877
+ end
878
+
879
+ context 'while' do
880
+ context 'single statement in body' do
881
+ assert_source <<-RUBY
882
+ while false
883
+ 3
884
+ end
885
+ RUBY
886
+ end
887
+
888
+ context 'multiple expressions in body' do
889
+ assert_source <<-RUBY
890
+ while false
891
+ 3
892
+ 5
893
+ end
894
+ RUBY
895
+ end
896
+ end
897
+
898
+ context 'until' do
899
+ context 'with single expression in body' do
900
+ assert_source <<-RUBY
901
+ until false
902
+ 3
903
+ end
904
+ RUBY
905
+ end
906
+
907
+ context 'with multiple expressions in body' do
908
+ assert_source <<-RUBY
909
+ while false
910
+ 3
911
+ 5
912
+ end
913
+ RUBY
914
+ end
915
+ end
916
+
917
+ # Note:
918
+ #
919
+ # Do not remove method_call from
920
+ #
921
+ # begin
922
+ # stuff
923
+ # end.method_call
924
+ #
925
+ # As 19mode would optimize begin end blocks away
926
+ #
927
+ context 'begin' do
928
+ context 'simple' do
929
+ assert_source <<-RUBY
930
+ begin
931
+ foo
932
+ bar
933
+ end.some_method
934
+ RUBY
935
+ end
936
+
937
+ context 'with rescue condition' do
938
+ assert_source <<-RUBY
939
+ x = begin
940
+ foo
941
+ rescue
942
+ bar
943
+ end.some_method
944
+ RUBY
945
+ end
946
+
947
+ context 'with with ensure' do
948
+ assert_source <<-RUBY
949
+ begin
950
+ foo
951
+ ensure
952
+ bar
953
+ end.some_method
954
+ RUBY
955
+ end
956
+ end
957
+
958
+ context 'rescue' do
959
+ context 'as block' do
960
+ assert_source <<-RUBY
961
+ begin
962
+ foo
963
+ foo
964
+ rescue
965
+ bar
966
+ end
967
+ RUBY
968
+ end
969
+ context 'without rescue condition' do
970
+ assert_source <<-RUBY
971
+ begin
972
+ bar
973
+ rescue
974
+ baz
975
+ end
976
+ RUBY
977
+ end
978
+
979
+ context 'within a block' do
980
+ assert_source <<-RUBY
981
+ foo do
982
+ begin
983
+ bar
984
+ rescue
985
+ baz
986
+ end
987
+ end
988
+ RUBY
989
+ end
990
+
991
+ context 'with rescue condition' do
992
+ context 'without assignment' do
993
+ assert_source <<-RUBY
994
+ begin
995
+ bar
996
+ rescue SomeError
997
+ baz
998
+ end
999
+ RUBY
1000
+ end
1001
+
1002
+ context 'with assignment' do
1003
+ assert_source <<-RUBY
1004
+ begin
1005
+ bar
1006
+ rescue SomeError => exception
1007
+ baz
1008
+ end
1009
+ RUBY
1010
+ end
1011
+ end
1012
+
1013
+ context 'with multivalued rescue condition' do
1014
+ context 'without assignment' do
1015
+ assert_source <<-RUBY
1016
+ begin
1017
+ bar
1018
+ rescue SomeError, SomeOtherError
1019
+ baz
1020
+ end
1021
+ RUBY
1022
+ end
1023
+
1024
+ context 'with assignment' do
1025
+ assert_source <<-RUBY
1026
+ begin
1027
+ bar
1028
+ rescue SomeError, SomeOther => exception
1029
+ baz
1030
+ end
1031
+ RUBY
1032
+ end
1033
+ end
1034
+
1035
+ context 'with multiple rescue conditions' do
1036
+ assert_source <<-RUBY
1037
+ begin
1038
+ foo
1039
+ rescue SomeError
1040
+ bar
1041
+ rescue
1042
+ baz
1043
+ end
1044
+ RUBY
1045
+ end
1046
+
1047
+ context 'with normal and splat condition' do
1048
+ context 'without assignment' do
1049
+ assert_source <<-RUBY
1050
+ begin
1051
+ bar
1052
+ rescue SomeError, *bar
1053
+ baz
1054
+ end
1055
+ RUBY
1056
+ end
1057
+
1058
+ context 'with assignment' do
1059
+ assert_source <<-RUBY
1060
+ begin
1061
+ bar
1062
+ rescue SomeError, *bar => exception
1063
+ baz
1064
+ end
1065
+ RUBY
1066
+ end
1067
+ end
1068
+
1069
+ context 'with splat condition' do
1070
+ context 'without assignment' do
1071
+ assert_source <<-RUBY
1072
+ begin
1073
+ bar
1074
+ rescue *bar
1075
+ baz
1076
+ end
1077
+ RUBY
1078
+ end
1079
+
1080
+ context 'with assignment' do
1081
+ assert_source <<-RUBY
1082
+ begin
1083
+ bar
1084
+ rescue *bar => exception
1085
+ baz
1086
+ end
1087
+ RUBY
1088
+ end
1089
+ end
1090
+ end
1091
+
1092
+ context '__FILE__' do
1093
+ assert_source '__FILE__'
1094
+ end
1095
+
1096
+ context 'ensure' do
1097
+ assert_source <<-RUBY
1098
+ begin
1099
+ bar
1100
+ ensure
1101
+ baz
1102
+ end
1103
+ RUBY
1104
+ end
1105
+
1106
+ context 'return' do
1107
+ context 'with expression' do
1108
+ assert_source 'return(9)'
1109
+ end
1110
+
1111
+ context 'without expression' do
1112
+ assert_source 'return'
1113
+ end
1114
+ end
1115
+
1116
+ context 'define' do
1117
+ context 'on instance' do
1118
+ context 'without arguments' do
1119
+ assert_source <<-RUBY
1120
+ def foo
1121
+ bar
1122
+ end
1123
+ RUBY
1124
+ end
1125
+
1126
+ context 'with single argument' do
1127
+ assert_source <<-RUBY
1128
+ def foo(bar)
1129
+ bar
1130
+ end
1131
+ RUBY
1132
+ end
1133
+
1134
+ context 'with multiple arguments' do
1135
+ assert_source <<-RUBY
1136
+ def foo(bar, baz)
1137
+ bar
1138
+ end
1139
+ RUBY
1140
+ end
1141
+
1142
+ context 'with optional argument' do
1143
+ assert_source <<-RUBY
1144
+ def foo(bar = true)
1145
+ bar
1146
+ end
1147
+ RUBY
1148
+ end
1149
+
1150
+ context 'with required and optional arguments' do
1151
+ assert_source <<-RUBY
1152
+ def foo(bar, baz = true)
1153
+ bar
1154
+ end
1155
+ RUBY
1156
+ end
1157
+
1158
+ context 'with unnamed splat argument' do
1159
+ assert_source <<-RUBY
1160
+ def foo(*)
1161
+ bar
1162
+ end
1163
+ RUBY
1164
+ end
1165
+
1166
+ context 'with splat argument' do
1167
+ assert_source <<-RUBY
1168
+ def foo(*bar)
1169
+ bar
1170
+ end
1171
+ RUBY
1172
+ end
1173
+
1174
+ context 'with required and splat arguments' do
1175
+ assert_source <<-RUBY
1176
+ def foo(bar, *baz)
1177
+ bar
1178
+ end
1179
+ RUBY
1180
+ end
1181
+
1182
+ context 'with optional and splat argument' do
1183
+ assert_source <<-RUBY
1184
+ def foo(baz = true, *bor)
1185
+ bar
1186
+ end
1187
+ RUBY
1188
+ end
1189
+
1190
+ context 'with optional and splat and block argument' do
1191
+ assert_source <<-RUBY
1192
+ def foo(baz = true, *bor, &block)
1193
+ bar
1194
+ end
1195
+ RUBY
1196
+ end
1197
+
1198
+ context 'with required optional and splat argument' do
1199
+ assert_source <<-RUBY
1200
+ def foo(bar, baz = true, *bor)
1201
+ bar
1202
+ end
1203
+ RUBY
1204
+ end
1205
+
1206
+ context 'with block argument' do
1207
+ assert_source <<-RUBY
1208
+ def foo(&block)
1209
+ bar
1210
+ end
1211
+ RUBY
1212
+ end
1213
+
1214
+ context 'with required and block arguments' do
1215
+ assert_source <<-RUBY
1216
+ def foo(bar, &block)
1217
+ bar
1218
+ end
1219
+ RUBY
1220
+ end
1221
+
1222
+ context 'with spat and block arguments' do
1223
+ assert_source <<-RUBY
1224
+ def initialize(attributes, options)
1225
+ @attributes = freeze_object(attributes)
1226
+ @options = freeze_object(options)
1227
+ @attribute_for = Hash[@attributes.map do |attribute|
1228
+ attribute.name
1229
+ end.zip(@attributes)]
1230
+ @keys = coerce_keys
1231
+ end
1232
+ RUBY
1233
+ end
1234
+ end
1235
+
1236
+ context 'on singleton' do
1237
+ context 'on self' do
1238
+ assert_source <<-RUBY
1239
+ def self.foo
1240
+ bar
1241
+ end
1242
+ RUBY
1243
+ end
1244
+
1245
+ context 'on constant' do
1246
+ assert_source <<-RUBY
1247
+ def Foo.bar
1248
+ bar
1249
+ end
1250
+ RUBY
1251
+ end
1252
+ end
1253
+ end
1254
+ end