unparser 0.4.7 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -2
  3. data/bin/unparser +1 -1
  4. data/lib/unparser.rb +134 -62
  5. data/lib/unparser/ast.rb +0 -1
  6. data/lib/unparser/ast/local_variable_scope.rb +6 -76
  7. data/lib/unparser/buffer.rb +19 -16
  8. data/lib/unparser/cli.rb +84 -77
  9. data/lib/unparser/{cli/color.rb → color.rb} +0 -13
  10. data/lib/unparser/comments.rb +0 -26
  11. data/lib/unparser/constants.rb +4 -53
  12. data/lib/unparser/diff.rb +98 -0
  13. data/lib/unparser/dsl.rb +0 -32
  14. data/lib/unparser/emitter.rb +24 -425
  15. data/lib/unparser/emitter/alias.rb +2 -8
  16. data/lib/unparser/emitter/args.rb +45 -0
  17. data/lib/unparser/emitter/argument.rb +8 -166
  18. data/lib/unparser/emitter/array.rb +27 -0
  19. data/lib/unparser/emitter/array_pattern.rb +29 -0
  20. data/lib/unparser/emitter/assignment.rb +36 -127
  21. data/lib/unparser/emitter/begin.rb +9 -84
  22. data/lib/unparser/emitter/binary.rb +7 -20
  23. data/lib/unparser/emitter/block.rb +57 -41
  24. data/lib/unparser/emitter/case.rb +6 -48
  25. data/lib/unparser/emitter/case_guard.rb +27 -0
  26. data/lib/unparser/emitter/case_match.rb +40 -0
  27. data/lib/unparser/emitter/cbase.rb +1 -3
  28. data/lib/unparser/emitter/class.rb +6 -26
  29. data/lib/unparser/emitter/const_pattern.rb +24 -0
  30. data/lib/unparser/emitter/def.rb +7 -51
  31. data/lib/unparser/emitter/defined.rb +2 -12
  32. data/lib/unparser/emitter/dstr.rb +22 -0
  33. data/lib/unparser/emitter/dsym.rb +41 -0
  34. data/lib/unparser/emitter/flipflop.rb +11 -10
  35. data/lib/unparser/emitter/float.rb +29 -0
  36. data/lib/unparser/emitter/flow_modifier.rb +8 -55
  37. data/lib/unparser/emitter/for.rb +5 -19
  38. data/lib/unparser/emitter/hash.rb +74 -0
  39. data/lib/unparser/emitter/hash_pattern.rb +67 -0
  40. data/lib/unparser/emitter/hookexe.rb +5 -11
  41. data/lib/unparser/emitter/if.rb +9 -73
  42. data/lib/unparser/emitter/in_match.rb +21 -0
  43. data/lib/unparser/emitter/in_pattern.rb +34 -0
  44. data/lib/unparser/emitter/index.rb +21 -88
  45. data/lib/unparser/emitter/kwbegin.rb +31 -0
  46. data/lib/unparser/emitter/lambda.rb +0 -8
  47. data/lib/unparser/emitter/masgn.rb +20 -0
  48. data/lib/unparser/emitter/match.rb +3 -17
  49. data/lib/unparser/emitter/match_alt.rb +23 -0
  50. data/lib/unparser/emitter/match_as.rb +21 -0
  51. data/lib/unparser/emitter/match_rest.rb +26 -0
  52. data/lib/unparser/emitter/match_var.rb +19 -0
  53. data/lib/unparser/emitter/mlhs.rb +40 -0
  54. data/lib/unparser/emitter/module.rb +3 -9
  55. data/lib/unparser/emitter/op_assign.rb +12 -27
  56. data/lib/unparser/emitter/pin.rb +19 -0
  57. data/lib/unparser/emitter/primitive.rb +93 -0
  58. data/lib/unparser/emitter/range.rb +35 -0
  59. data/lib/unparser/emitter/regexp.rb +35 -0
  60. data/lib/unparser/emitter/repetition.rb +17 -57
  61. data/lib/unparser/emitter/rescue.rb +1 -97
  62. data/lib/unparser/emitter/root.rb +17 -1
  63. data/lib/unparser/emitter/send.rb +10 -219
  64. data/lib/unparser/emitter/simple.rb +33 -0
  65. data/lib/unparser/emitter/splat.rb +2 -18
  66. data/lib/unparser/emitter/super.rb +1 -29
  67. data/lib/unparser/emitter/undef.rb +1 -9
  68. data/lib/unparser/emitter/variable.rb +1 -31
  69. data/lib/unparser/emitter/xstr.rb +72 -0
  70. data/lib/unparser/emitter/yield.rb +1 -9
  71. data/lib/unparser/generation.rb +250 -0
  72. data/lib/unparser/node_details.rb +21 -0
  73. data/lib/unparser/node_details/send.rb +62 -0
  74. data/lib/unparser/node_helpers.rb +45 -6
  75. data/lib/unparser/validation.rb +172 -0
  76. data/lib/unparser/writer.rb +15 -0
  77. data/lib/unparser/writer/binary.rb +99 -0
  78. data/lib/unparser/writer/dynamic_string.rb +233 -0
  79. data/lib/unparser/writer/resbody.rb +40 -0
  80. data/lib/unparser/writer/rescue.rb +39 -0
  81. data/lib/unparser/writer/send.rb +124 -0
  82. data/lib/unparser/{emitter → writer}/send/attribute_assignment.rb +11 -26
  83. data/lib/unparser/writer/send/binary.rb +27 -0
  84. data/lib/unparser/writer/send/conditional.rb +25 -0
  85. data/lib/unparser/writer/send/regular.rb +33 -0
  86. data/lib/unparser/{emitter → writer}/send/unary.rb +10 -17
  87. metadata +127 -104
  88. data/.circleci/config.yml +0 -49
  89. data/.gitignore +0 -37
  90. data/.rspec +0 -4
  91. data/.rubocop.yml +0 -9
  92. data/Changelog.md +0 -156
  93. data/Gemfile +0 -9
  94. data/Gemfile.lock +0 -181
  95. data/LICENSE +0 -20
  96. data/Rakefile +0 -22
  97. data/config/devtools.yml +0 -2
  98. data/config/flay.yml +0 -3
  99. data/config/flog.yml +0 -2
  100. data/config/mutant.yml +0 -6
  101. data/config/reek.yml +0 -98
  102. data/config/rubocop.yml +0 -122
  103. data/config/yardstick.yml +0 -2
  104. data/lib/unparser/cli/differ.rb +0 -152
  105. data/lib/unparser/cli/source.rb +0 -267
  106. data/lib/unparser/emitter/empty.rb +0 -23
  107. data/lib/unparser/emitter/ensure.rb +0 -37
  108. data/lib/unparser/emitter/literal.rb +0 -10
  109. data/lib/unparser/emitter/literal/array.rb +0 -29
  110. data/lib/unparser/emitter/literal/dynamic.rb +0 -53
  111. data/lib/unparser/emitter/literal/dynamic_body.rb +0 -132
  112. data/lib/unparser/emitter/literal/execute_string.rb +0 -38
  113. data/lib/unparser/emitter/literal/hash.rb +0 -156
  114. data/lib/unparser/emitter/literal/primitive.rb +0 -145
  115. data/lib/unparser/emitter/literal/range.rb +0 -36
  116. data/lib/unparser/emitter/literal/regexp.rb +0 -114
  117. data/lib/unparser/emitter/literal/singleton.rb +0 -26
  118. data/lib/unparser/emitter/meta.rb +0 -16
  119. data/lib/unparser/emitter/redo.rb +0 -25
  120. data/lib/unparser/emitter/resbody.rb +0 -76
  121. data/lib/unparser/emitter/retry.rb +0 -25
  122. data/lib/unparser/emitter/send/binary.rb +0 -57
  123. data/lib/unparser/emitter/send/conditional.rb +0 -40
  124. data/lib/unparser/emitter/send/regular.rb +0 -40
  125. data/lib/unparser/preprocessor.rb +0 -159
  126. data/spec/integration/unparser/corpus_spec.rb +0 -111
  127. data/spec/integrations.yml +0 -92
  128. data/spec/spec_helper.rb +0 -20
  129. data/spec/unit/unparser/buffer/append_spec.rb +0 -24
  130. data/spec/unit/unparser/buffer/append_without_prefix_spec.rb +0 -23
  131. data/spec/unit/unparser/buffer/capture_content_spec.rb +0 -17
  132. data/spec/unit/unparser/buffer/content_spec.rb +0 -38
  133. data/spec/unit/unparser/buffer/fresh_line_spec.rb +0 -20
  134. data/spec/unit/unparser/buffer/indent_spec.rb +0 -20
  135. data/spec/unit/unparser/buffer/nl_spec.rb +0 -16
  136. data/spec/unit/unparser/buffer/unindent_spec.rb +0 -20
  137. data/spec/unit/unparser/comments/consume_spec.rb +0 -22
  138. data/spec/unit/unparser/comments/take_all_spec.rb +0 -19
  139. data/spec/unit/unparser/comments/take_before_spec.rb +0 -46
  140. data/spec/unit/unparser/comments/take_eol_comments_spec.rb +0 -32
  141. data/spec/unit/unparser/emitter/class_methods/handle_spec.rb +0 -17
  142. data/spec/unit/unparser_spec.rb +0 -1849
  143. data/unparser.gemspec +0 -32
@@ -1,20 +0,0 @@
1
- require 'yaml'
2
- require 'pathname'
3
- require 'unparser'
4
- require 'anima'
5
- require 'morpher'
6
- require 'devtools/spec_helper'
7
-
8
- require 'parser/current'
9
-
10
- module SpecHelper
11
- def s(type, *children)
12
- Parser::AST::Node.new(type, children)
13
- end
14
- end
15
-
16
- RSpec.configure do |config|
17
- config.include(SpecHelper)
18
- config.extend(SpecHelper)
19
- config.raise_errors_for_deprecations!
20
- end
@@ -1,24 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Buffer, '#append' do
4
- subject { object.append(string) }
5
-
6
- let(:object) { described_class.new }
7
- let(:string) { 'foo' }
8
-
9
- specify do
10
- expect { subject }.to change { object.content }.from('').to('foo')
11
- end
12
-
13
- # Yeah duplicate, mutant will be improved ;)
14
- it 'should prefix with indentation if line is empty' do
15
- object.append('foo')
16
- object.nl
17
- object.indent
18
- object.append('bar')
19
- object.append('baz')
20
- expect(object.content).to eql("foo\n barbaz")
21
- end
22
-
23
- it_should_behave_like 'a command method'
24
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Buffer, '#append_without_prefix' do
4
- subject { object.append_without_prefix(string) }
5
-
6
- let(:object) { described_class.new }
7
- let(:string) { 'foo' }
8
-
9
- specify do
10
- expect { subject }.to change { object.content }.from('').to('foo')
11
- end
12
-
13
- it 'should not prefix with indentation' do
14
- object.append_without_prefix('foo')
15
- object.nl
16
- object.indent
17
- object.append_without_prefix('bar')
18
- object.append_without_prefix('baz')
19
- expect(object.content).to eql("foo\nbarbaz")
20
- end
21
-
22
- it_should_behave_like 'a command method'
23
- end
@@ -1,17 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Buffer, '#capture_content' do
4
-
5
- let(:object) { described_class.new }
6
-
7
- it 'should capture only the content appended within the block' do
8
- object.append('foo')
9
- object.nl
10
- object.indent
11
- captured = object.capture_content do
12
- object.append('bar')
13
- object.nl
14
- end
15
- expect(captured).to eql(" bar\n")
16
- end
17
- end
@@ -1,38 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Buffer, '#content' do
4
- subject { object.content }
5
-
6
- let(:object) { described_class.new }
7
-
8
- shared_examples_for 'buffer content' do
9
- it 'contains expected content' do
10
- should eql(expected_content)
11
- end
12
-
13
- it { should be_frozen }
14
-
15
- it 'returns fresh string copies' do
16
- first = object.content
17
- second = object.content
18
- expect(first).to eql(second)
19
- expect(first).not_to be(second)
20
- end
21
- end
22
-
23
- context 'with empty buffer' do
24
- let(:expected_content) { '' }
25
-
26
- it_should_behave_like 'buffer content'
27
- end
28
-
29
- context 'with filled buffer' do
30
- before do
31
- object.append('foo')
32
- end
33
-
34
- let(:expected_content) { 'foo' }
35
-
36
- it_behaves_like 'buffer content'
37
- end
38
- end
@@ -1,20 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Buffer, '#fresh_line?' do
4
- let(:object) { described_class.new }
5
-
6
- it 'should return true while buffer is empty' do
7
- expect(object.fresh_line?).to eql(true)
8
- end
9
-
10
- it 'should return false after content has been appended' do
11
- object.append('foo')
12
- expect(object.fresh_line?).to eql(false)
13
- end
14
-
15
- it 'should return true after a nl has been appended' do
16
- object.append('foo')
17
- object.nl
18
- expect(object.fresh_line?).to eql(true)
19
- end
20
- end
@@ -1,20 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Buffer, '#indent' do
4
- let(:object) { described_class.new }
5
-
6
- subject { object.indent }
7
-
8
- it 'should indent with two spaces' do
9
- object.append('foo')
10
- object.nl
11
- object.indent
12
- object.append('bar')
13
- object.nl
14
- object.indent
15
- object.append('baz')
16
- expect(object.content).to eql("foo\n bar\n baz")
17
- end
18
-
19
- it_should_behave_like 'a command method'
20
- end
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Buffer, '#nl' do
4
- let(:object) { described_class.new }
5
-
6
- subject { object.nl }
7
-
8
- it 'writes a newline' do
9
- object.append('foo')
10
- subject
11
- object.append('bar')
12
- expect(object.content).to eql("foo\nbar")
13
- end
14
-
15
- it_should_behave_like 'a command method'
16
- end
@@ -1,20 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Buffer, '#unindent' do
4
- let(:object) { described_class.new }
5
-
6
- subject { object.unindent }
7
-
8
- it 'unindents two chars' do
9
- object.append('foo')
10
- object.nl
11
- object.indent
12
- object.append('bar')
13
- object.nl
14
- object.unindent
15
- object.append('baz')
16
- expect(object.content).to eql("foo\n bar\nbaz")
17
- end
18
-
19
- it_should_behave_like 'a command method'
20
- end
@@ -1,22 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Comments, '#consume' do
4
-
5
- let(:ast_and_comments) do
6
- Unparser.parse_with_comments(<<~'RUBY')
7
- def hi # EOL 1
8
- end # EOL 2
9
- RUBY
10
- end
11
- let(:ast) { ast_and_comments[0] }
12
- let(:comments) { ast_and_comments[1] }
13
- let(:object) { described_class.new(comments) }
14
-
15
- it 'should cause further EOL comments to be returned' do
16
- expect(object.take_eol_comments).to eql([])
17
- object.consume(ast, :name)
18
- expect(object.take_eol_comments).to eql([comments[0]])
19
- object.consume(ast, :end)
20
- expect(object.take_eol_comments).to eql([comments[1]])
21
- end
22
- end
@@ -1,19 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Comments, '#take_all' do
4
-
5
- let(:ast_and_comments) do
6
- Unparser.parse_with_comments(<<~'RUBY')
7
- def hi # EOL 1
8
- end # EOL 2
9
- RUBY
10
- end
11
- let(:ast) { ast_and_comments[0] }
12
- let(:comments) { ast_and_comments[1] }
13
- let(:object) { described_class.new(comments) }
14
-
15
- it 'should take all comments' do
16
- expect(object.take_all).to eql(comments)
17
- expect(object.take_all).to eql([])
18
- end
19
- end
@@ -1,46 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Comments, '#take_before' do
4
-
5
- let(:ast) { ast_and_comments[0] }
6
- let(:comments) { ast_and_comments[1] }
7
- let(:object) { described_class.new(comments) }
8
-
9
- context 'usual case' do
10
-
11
- let(:ast_and_comments) do
12
- Unparser.parse_with_comments(<<~'RUBY')
13
- def hi # EOL 1
14
- # comment
15
- end # EOL 2
16
- RUBY
17
- end
18
-
19
- it 'should return no comments if none are before the node' do
20
- expect(object.take_before(ast, :expression)).to eql([])
21
- end
22
-
23
- it 'should return only the comments that are before the specified part of the node' do
24
- expect(object.take_before(ast, :end)).to eql(comments.first(2))
25
- expect(object.take_all).to eql([comments[2]])
26
- end
27
- end
28
-
29
- context 'when node does not respond to source part' do
30
-
31
- let(:ast_and_comments) do
32
- Unparser.parse_with_comments(<<~'RUBY')
33
- expression ? :foo : :bar # EOL 1
34
- # EOL 2
35
- RUBY
36
- end
37
-
38
- it 'should return no comments if none are before the node' do
39
- expect(object.take_before(ast, :expression)).to eql([])
40
- end
41
-
42
- it 'should return only the comments that are before the specified part of the node' do
43
- expect(object.take_before(ast, :end)).to eql([])
44
- end
45
- end
46
- end
@@ -1,32 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Comments, '#take_eol_comments' do
4
-
5
- let(:ast_and_comments) do
6
- Unparser.parse_with_comments(<<~'RUBY')
7
- def hi # EOL 1
8
- =begin
9
- doc comment
10
- =end
11
- end # EOL 2
12
- RUBY
13
- end
14
- let(:ast) { ast_and_comments[0] }
15
- let(:comments) { ast_and_comments[1] }
16
- let(:object) { described_class.new(comments) }
17
-
18
- it 'should return no comments if nothing has been consumed' do
19
- expect(object.take_eol_comments).to eql([])
20
- end
21
-
22
- it 'should return comments once their line has been consumed' do
23
- object.consume(ast, :name)
24
- expect(object.take_eol_comments).to eql([comments[0]])
25
- end
26
-
27
- it 'should leave doc comments to be taken later' do
28
- object.consume(ast)
29
- expect(object.take_eol_comments).to eql([comments[0], comments[2]])
30
- expect(object.take_all).to eql([comments[1]])
31
- end
32
- end
@@ -1,17 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser::Emitter, '.handle', mutant_expression: 'Unparser::Emitter*' do
4
- subject { class_under_test.class_eval { handle :foo } }
5
-
6
- let(:class_under_test) do
7
- Class.new(described_class)
8
- end
9
-
10
- before do
11
- stub_const('Unparser::Emitter::REGISTRY', {})
12
- end
13
-
14
- it 'should register emitter' do
15
- expect { subject }.to change { Unparser::Emitter::REGISTRY }.from({}).to(foo: class_under_test)
16
- end
17
- end
@@ -1,1849 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Unparser, mutant_expression: 'Unparser::Emitter*' do
4
- describe '.buffer' do
5
- let(:source) { 'a + b' }
6
-
7
- def apply
8
- described_class.buffer(source)
9
- end
10
-
11
- it 'returns parser buffer with expected name' do
12
- expect(apply.name).to eql('(string)')
13
- end
14
-
15
- it 'returns parser buffer with pre-filled source' do
16
- expect(apply.source).to eql(source)
17
- end
18
- end
19
-
20
- describe '.parser' do
21
- let(:invalid_source_buffer) { Unparser.buffer('a +') }
22
-
23
- def apply
24
- described_class.parser
25
- end
26
-
27
- context 'failure' do
28
- def apply
29
- super.tap do |parser|
30
- parser.diagnostics.consumer = ->(_) {}
31
- end
32
- end
33
-
34
- it 'returns a parser that fails with syntax error' do
35
- expect { apply.parse(invalid_source_buffer) }
36
- .to raise_error(Parser::SyntaxError)
37
- end
38
- end
39
-
40
- context 'warnings' do
41
- before do
42
- allow(Kernel).to receive(:warn)
43
- end
44
-
45
- it 'returns a parser that warns on diagnostics' do
46
- expect { apply.parse(invalid_source_buffer) }
47
- .to raise_error(Parser::SyntaxError)
48
-
49
- expect(Kernel).to have_received(:warn)
50
- .with([
51
- "(string):1:4: error: unexpected token $end",
52
- "(string):1: a +", "(string):1: "
53
- ])
54
- end
55
- end
56
- end
57
-
58
- describe '.parse' do
59
- def apply
60
- described_class.parse('self[1]=2')
61
- end
62
-
63
- it 'returns expected AST' do
64
- expect(apply).to eql(s(:indexasgn, s(:self), s(:int, 1), s(:int, 2)))
65
- end
66
- end
67
-
68
- describe '.unparse' do
69
- let(:builder_options) { {} }
70
-
71
- def parser
72
- Unparser.parser.tap do |parser|
73
- builder_options.each do |name, value|
74
- parser.builder.public_send(:"#{name}=", value)
75
- end
76
- end
77
- end
78
-
79
- def buffer(input)
80
- Unparser.buffer(input)
81
- end
82
-
83
- def parse_with_comments(string)
84
- parser.parse_with_comments(buffer(string))
85
- end
86
-
87
- def self.with_builder_options(options, &block)
88
- context "with #{options}" do
89
- let(:builder_options) { options }
90
-
91
- class_eval(&block)
92
- end
93
- end
94
-
95
- def assert_round_trip(string, parser)
96
- ast, comments = parse_with_comments(string)
97
- generated = Unparser.unparse(ast, comments)
98
- expect(generated).to eql(string.chomp)
99
- generated_ast, _comments = parse_with_comments(generated)
100
- expect(ast == generated_ast).to be(true)
101
- end
102
-
103
- def assert_generates_from_string(parser, string, expected)
104
- ast_with_comments = parse_with_comments(string)
105
- assert_generates_from_ast(parser, ast_with_comments, expected.chomp)
106
- end
107
-
108
- def assert_generates_from_ast(parser, ast_with_comments, expected)
109
- generated = Unparser.unparse(*ast_with_comments)
110
- expect(generated).to eql(expected)
111
- ast, comments = parse_with_comments(generated)
112
- expect(Unparser.unparse(ast, comments)).to eql(expected)
113
- end
114
-
115
- def self.assert_unterminated(expression)
116
- assert_source(expression)
117
- assert_source("(#{expression}).foo")
118
- end
119
-
120
- def self.assert_terminated(expression)
121
- assert_source(expression)
122
- assert_source("foo(#{expression})")
123
- assert_source("#{expression}.foo")
124
- end
125
-
126
- def self.assert_generates(input, expected)
127
- it "should generate #{input} as #{expected}" do
128
- if input.is_a?(String)
129
- assert_generates_from_string(parser, input, expected)
130
- else
131
- assert_generates_from_ast(parser, [input, []], expected)
132
- end
133
- end
134
- end
135
-
136
- def self.assert_round_trip(input)
137
- it "should round trip #{input}" do
138
- assert_round_trip(input, parser)
139
- end
140
- end
141
-
142
- def self.assert_source(input)
143
- assert_round_trip(input)
144
- end
145
-
146
- context 'kwargs' do
147
- assert_source <<~RUBY
148
- def foo(bar:, baz:)
149
- end
150
- RUBY
151
-
152
- assert_source <<~RUBY
153
- foo(**bar)
154
- RUBY
155
-
156
- assert_source <<~RUBY
157
- def foo(bar:, baz: "value")
158
- end
159
- RUBY
160
- end
161
-
162
- context 'literal' do
163
- context 'int' do
164
- assert_generates '-0', '0'
165
- assert_source '++1'
166
- assert_terminated '1'
167
- assert_unterminated '-1'
168
- assert_generates '0x1', '1'
169
- assert_generates '1_000', '1000'
170
- assert_generates '1e10', '10000000000.0'
171
- assert_generates '10e10000000000', 'Float::INFINITY'
172
- assert_generates '-10e10000000000', '-Float::INFINITY'
173
- end
174
-
175
- context 'rational' do
176
- assert_terminated '1r'
177
- assert_generates '1.0r', '1r'
178
- assert_generates '-0r', '0r'
179
-
180
- assert_terminated '1.5r'
181
- assert_terminated '1.3r'
182
- end
183
-
184
- context 'complex' do
185
- %w(
186
- 5i
187
- -5i
188
- 0.6i
189
- -0.6i
190
- 1000000000000000000000000000000i
191
- 1ri
192
- ).each do |expression|
193
- assert_terminated(expression)
194
- end
195
- end
196
-
197
- context 'string' do
198
- assert_generates '?c', '"c"'
199
- assert_generates '"foo" "bar"', '"#{"foo"}#{"bar"}"'
200
- assert_generates '"foo" "bar #{baz}"', '"#{"foo"}#{"#{"bar "}#{baz}"}"'
201
- assert_generates '%Q(foo"#{@bar})', '"#{"foo\\""}#{@bar}"'
202
- assert_generates '"foo#{1}bar"', '"#{"foo"}#{1}#{"bar"}"'
203
- assert_generates '"\\\\#{}"', '"#{"\\\\"}#{}"'
204
- assert_generates '"#{}\#{}"', '"#{}#{"\#{}"}"'
205
- assert_generates '"\#{}#{}"', '"#{"\#{}"}#{}"'
206
- assert_terminated '"\""'
207
- assert_terminated '"foo bar"'
208
- assert_terminated '"foo\nbar"'
209
- # Within indentation
210
- assert_generates <<~'RUBY', <<~'RUBY'
211
- if foo
212
- "
213
- #{foo}
214
- "
215
- end
216
- RUBY
217
- if foo
218
- "#{"\n"}#{" "}#{foo}#{"\n"}#{" "}"
219
- end
220
- RUBY
221
- end
222
-
223
- context 'execute string' do
224
- assert_generates '`foo`', '`#{"foo"}`'
225
- assert_generates '`foo#{@bar}`', '`#{"foo"}#{@bar}`'
226
- assert_generates '%x(\))', '`#{")"}`'
227
- assert_generates '%x(`)', '`#{"`"}`'
228
- assert_generates '`"`', '`#{"\\""}`'
229
- end
230
-
231
- context 'symbol' do
232
- assert_generates s(:sym, :foo), ':foo'
233
- assert_generates s(:sym, :"A B"), ':"A B"'
234
- assert_terminated ':foo'
235
- assert_terminated ':"A B"'
236
- assert_terminated ':"A\"B"'
237
- assert_terminated ':""'
238
- end
239
-
240
- context 'regexp' do
241
- assert_terminated '/foo/'
242
- assert_terminated %q(/[^-+',.\/:@[:alnum:]\[\]]+/)
243
- assert_terminated '/foo#{@bar}/'
244
- assert_terminated '/foo#{@bar}/imx'
245
- assert_terminated '/#{"\u0000"}/'
246
- assert_terminated "/\n/"
247
- assert_terminated '/\n/'
248
- assert_terminated "/\n/x"
249
- # Within indentation
250
- assert_source <<~RUBY
251
- if foo
252
- /
253
- /
254
- end
255
- RUBY
256
- assert_generates '%r(/)', '/\//'
257
- assert_generates '%r(\))', '/\)/'
258
- assert_generates '%r(#{@bar}baz)', '/#{@bar}baz/'
259
- assert_terminated '/\/\//x'
260
- end
261
-
262
- context 'dynamic symbol' do
263
- assert_generates ':"foo#{bar}baz"', ':"#{"foo"}#{bar}#{"baz"}"'
264
- assert_source ':"#{"foo"}"'
265
- end
266
-
267
- context 'irange' do
268
- assert_unterminated '1..'
269
- assert_unterminated '1..2'
270
- assert_unterminated '(0.0 / 0.0)..1'
271
- assert_unterminated '1..(0.0 / 0.0)'
272
- assert_unterminated '(0.0 / 0.0)..100'
273
- end
274
-
275
- context 'erange' do
276
- assert_unterminated '1...'
277
- assert_unterminated '1...2'
278
- end
279
-
280
- context 'float' do
281
- assert_source '-0.1'
282
- assert_terminated '0.1'
283
- assert_terminated '0.1'
284
- assert_generates '10.2e10000000000', 'Float::INFINITY'
285
- assert_generates '-10.2e10000000000', '-Float::INFINITY'
286
- assert_generates s(:float, -0.1), '-0.1'
287
- assert_generates s(:float, 0.1), '0.1'
288
- end
289
-
290
- context 'array' do
291
- assert_terminated '[1, 2]'
292
- assert_terminated '[1, (), n2]'
293
- assert_terminated '[1]'
294
- assert_terminated '[]'
295
- assert_terminated '[1, *@foo]'
296
- assert_terminated '[*@foo, 1]'
297
- assert_terminated '[*@foo, *@baz]'
298
- assert_generates '%w(foo bar)', '["foo", "bar"]'
299
- end
300
-
301
- context 'hash' do
302
- assert_terminated '{}'
303
- assert_source '{ () => () }'
304
- assert_source '{ 1 => 2 }'
305
- assert_source '{ 1 => 2, 3 => 4 }'
306
-
307
- # special case for 2.1.3
308
- assert_source "{ foo: (if true\nend) }"
309
-
310
- context 'with symbol keys' do
311
- assert_source '{ a: (1 rescue foo), b: 2 }'
312
- assert_source '{ a: 1, b: 2 }'
313
- assert_source '{ a: :a }'
314
- assert_source '{ :"a b" => 1 }'
315
- assert_source '{ :-@ => 1 }'
316
- end
317
- end
318
- end
319
-
320
- context 'access' do
321
- %w(@a @@a $a $1 $` CONST SCOPED::CONST ::TOPLEVEL ::TOPLEVEL::CONST).each do |expression|
322
- assert_terminated(expression)
323
- end
324
- end
325
-
326
- context 'control keywords' do
327
- %w(retry redo).each do |expression|
328
- assert_terminated(expression)
329
- end
330
- end
331
-
332
- context 'singletons' do
333
- %w(self true false nil).each do |expression|
334
- assert_terminated(expression)
335
- end
336
- end
337
-
338
- context 'magic keywords' do
339
- assert_source '__ENCODING__'
340
-
341
- # These two assertions don't actually need to be wrapped in this block since `true` is the default,
342
- # but it is helpful to contrast with the assertions farther down.
343
- with_builder_options(emit_file_line_as_literals: true) do
344
- assert_generates '__FILE__', '"(string)"'
345
- assert_generates '__LINE__', '1'
346
- end
347
-
348
- with_builder_options(emit_file_line_as_literals: false) do
349
- assert_source '__FILE__'
350
- assert_source '__LINE__'
351
- end
352
- end
353
-
354
- context 'assignment' do
355
- context 'single' do
356
- assert_unterminated 'a = 1'
357
- assert_unterminated '@a = 1'
358
- assert_unterminated '@@a = 1'
359
- assert_unterminated '$a = 1'
360
- assert_unterminated 'CONST = 1'
361
- assert_unterminated 'Name::Spaced::CONST = 1'
362
- assert_unterminated '::Foo = ::Bar'
363
- end
364
-
365
- context 'lvar assigned from method with same name' do
366
- assert_unterminated 'foo = foo()'
367
- end
368
-
369
- context 'lvar introduction from condition' do
370
- assert_source 'foo = bar while foo'
371
- assert_source 'foo = bar until foo'
372
- assert_source <<~'RUBY'
373
- foo = exp
374
- while foo
375
- foo = bar
376
- end
377
- RUBY
378
-
379
- # Ugly I know. But its correct :D
380
- #
381
- # if foo { |pair| }
382
- # pair = :foo
383
- # foo
384
- # end
385
- assert_source <<~'RUBY'
386
- if foo do |pair|
387
- pair
388
- end
389
- pair = :foo
390
- foo
391
- end
392
- RUBY
393
-
394
- assert_source <<~'RUBY'
395
- while foo
396
- foo = bar
397
- end
398
- RUBY
399
-
400
- assert_source <<~'RUBY'
401
- each do |bar|
402
- while foo
403
- foo = bar
404
- end
405
- end
406
- RUBY
407
-
408
- assert_source <<~'RUBY'
409
- def foo
410
- foo = bar while foo != baz
411
- end
412
- RUBY
413
-
414
- assert_source <<~'RUBY'
415
- each do |baz|
416
- while foo
417
- foo = bar
418
- end
419
- end
420
- RUBY
421
-
422
- assert_source <<~'RUBY'
423
- each do |foo|
424
- while foo
425
- foo = bar
426
- end
427
- end
428
- RUBY
429
- end
430
-
431
- context 'multiple' do
432
- assert_source 'a, * = [1, 2]'
433
- assert_source 'a, *foo = [1, 2]'
434
- assert_source '*a = []'
435
- assert_source '*foo = [1, 2]'
436
- assert_source 'a, = foo'
437
- assert_unterminated 'a, b = [1, 2]'
438
- assert_unterminated '@a, @b = [1, 2]'
439
- assert_unterminated 'a.foo, a.bar = [1, 2]'
440
- assert_unterminated 'a[0], a[1] = [1, 2]'
441
- assert_unterminated 'a[*foo], a[1] = [1, 2]'
442
- assert_unterminated '@@a, @@b = [1, 2]'
443
- assert_unterminated '$a, $b = [1, 2]'
444
- assert_unterminated 'a, b = foo'
445
- assert_unterminated 'a, (b, c) = [1, [2, 3]]'
446
- assert_unterminated 'a = (b, c = 1)'
447
- assert_unterminated '(a,), b = 1'
448
- end
449
- end
450
-
451
- %w(next return break).each do |keyword|
452
-
453
- context keyword do
454
- assert_terminated keyword.to_s
455
- assert_unterminated "#{keyword} 1"
456
- assert_unterminated "#{keyword} 2, 3"
457
- assert_unterminated "#{keyword} *nil"
458
- assert_unterminated "#{keyword} *foo, bar"
459
-
460
- assert_generates <<~RUBY, <<~RUBY
461
- foo do |bar|
462
- bar =~ // || #{keyword}
463
- baz
464
- end
465
- RUBY
466
- foo do |bar|
467
- (bar =~ //) || #{keyword}
468
- baz
469
- end
470
- RUBY
471
-
472
- assert_generates <<~RUBY, <<~RUBY
473
- #{keyword}(a ? b : c)
474
- RUBY
475
- #{keyword} (if a
476
- b
477
- else
478
- c
479
- end)
480
- RUBY
481
- end
482
- end
483
-
484
- context 'conditional send (csend)' do
485
- assert_terminated 'a&.b'
486
- assert_terminated 'a&.b(c)'
487
- end
488
-
489
- context 'send' do
490
- assert_terminated 'foo'
491
- assert_terminated 'self.foo'
492
- assert_terminated 'a.foo'
493
- assert_terminated 'A.foo'
494
- assert_terminated 'foo[]'
495
- assert_terminated 'foo[1]'
496
- assert_terminated 'foo[*baz]'
497
- assert_terminated 'foo(1)'
498
- assert_terminated 'foo(bar)'
499
- assert_terminated 'foo(&block)'
500
- assert_terminated 'foo(&(foo || bar))'
501
- assert_terminated 'foo(*arguments)'
502
- assert_terminated 'foo(*arguments)'
503
-
504
- assert_source <<~'RUBY'
505
- foo do
506
- end
507
- RUBY
508
-
509
- assert_source <<~'RUBY'
510
- foo do |a|
511
- end
512
- RUBY
513
-
514
- assert_source <<~'RUBY'
515
- foo do |a, |
516
- end
517
- RUBY
518
-
519
- assert_source <<~'RUBY'
520
- foo do |a, b|
521
- end
522
- RUBY
523
-
524
- assert_source <<~'RUBY'
525
- foo(1) do
526
- nil
527
- end
528
- RUBY
529
-
530
- assert_source <<~'RUBY'
531
- foo do |a, *b|
532
- nil
533
- end
534
- RUBY
535
-
536
- assert_source <<~'RUBY'
537
- foo do |a, *|
538
- nil
539
- end
540
- RUBY
541
-
542
- assert_source <<~'RUBY'
543
- foo do
544
- bar
545
- end
546
- RUBY
547
-
548
- assert_source <<~'RUBY'
549
- foo.bar(*args)
550
- RUBY
551
-
552
- assert_source <<~'RUBY'
553
- foo.bar do |(a, b), c|
554
- d
555
- end
556
- RUBY
557
-
558
- assert_source <<~'RUBY'
559
- foo.bar do |*a; b|
560
- end
561
- RUBY
562
-
563
- assert_source <<~'RUBY'
564
- foo.bar do |a; b|
565
- end
566
- RUBY
567
-
568
- assert_source <<~'RUBY'
569
- foo.bar do |; a, b|
570
- end
571
- RUBY
572
-
573
- assert_source <<~'RUBY'
574
- foo.bar do |*|
575
- d
576
- end
577
- RUBY
578
-
579
- assert_source <<~'RUBY'
580
- foo.bar do |(*)|
581
- d
582
- end
583
- RUBY
584
-
585
- assert_source <<~'RUBY'
586
- foo.bar do |((*))|
587
- d
588
- end
589
- RUBY
590
-
591
- assert_source <<~'RUBY'
592
- foo.bar do |(a, (*))|
593
- d
594
- end
595
- RUBY
596
-
597
- assert_source <<~'RUBY'
598
- foo.bar do |(a, b)|
599
- d
600
- end
601
- RUBY
602
-
603
- assert_source <<~'RUBY'
604
- foo.bar do
605
- end.baz
606
- RUBY
607
-
608
- assert_source <<~'RUBY'
609
- FOO()
610
- RUBY
611
-
612
- assert_terminated '(1..2).max'
613
- assert_terminated '1..2.max'
614
- assert_unterminated 'a || return'
615
- assert_unterminated 'foo << (bar * baz)'
616
-
617
- assert_source <<~'RUBY'
618
- foo ||= (a, _ = b)
619
- RUBY
620
-
621
- assert_source <<~'RUBY'
622
- begin
623
- rescue
624
- end.bar
625
- RUBY
626
-
627
- assert_source <<~'RUBY'
628
- case (def foo
629
- end
630
- :bar)
631
- when bar
632
- end.baz
633
- RUBY
634
-
635
- assert_source <<~'RUBY'
636
- case foo
637
- when bar
638
- end.baz
639
- RUBY
640
-
641
- assert_source <<~'RUBY'
642
- class << self
643
- end.bar
644
- RUBY
645
-
646
- assert_source <<~'RUBY'
647
- def self.foo
648
- end.bar
649
- RUBY
650
-
651
- assert_source <<~'RUBY'
652
- def foo
653
- end.bar
654
- RUBY
655
-
656
- assert_source <<~'RUBY'
657
- until foo
658
- end.bar
659
- RUBY
660
-
661
- assert_source <<~'RUBY'
662
- while foo
663
- end.bar
664
- RUBY
665
-
666
- assert_source <<~'RUBY'
667
- loop do
668
- end.bar
669
- RUBY
670
-
671
- assert_source <<~'RUBY'
672
- class Foo
673
- end.bar
674
- RUBY
675
-
676
- assert_source <<~'RUBY'
677
- module Foo
678
- end.bar
679
- RUBY
680
-
681
- assert_source <<~'RUBY'
682
- if foo
683
- end.baz
684
- RUBY
685
-
686
- assert_source <<~'RUBY'
687
- local = 1
688
- local.bar
689
- RUBY
690
-
691
- assert_terminated 'foo.bar(*args)'
692
- assert_terminated 'foo.bar(*arga, foo, *argb)'
693
- assert_terminated 'foo.bar(*args, foo)'
694
- assert_terminated 'foo.bar(foo, *args)'
695
- assert_terminated 'foo.bar(foo, *args, &block)'
696
- assert_source <<~'RUBY'
697
- foo(bar, *args)
698
- RUBY
699
-
700
- assert_terminated 'foo(*args, &block)'
701
- assert_terminated 'foo.bar(&baz)'
702
- assert_terminated 'foo.bar(:baz, &baz)'
703
- assert_terminated 'foo.bar=:baz'
704
-
705
- assert_unterminated 'self.foo=:bar'
706
-
707
- assert_terminated 'foo.bar(baz: boz)'
708
- assert_terminated 'foo.bar(foo, "baz" => boz)'
709
- assert_terminated 'foo.bar({ foo: boz }, boz)'
710
- assert_terminated 'foo.bar(foo, {})'
711
- end
712
-
713
- context 'begin; end' do
714
- assert_generates s(:begin), ''
715
-
716
- assert_source <<~'RUBY'
717
- begin
718
- end
719
- RUBY
720
-
721
- assert_source <<~'RUBY'
722
- foo
723
- bar
724
- RUBY
725
-
726
- assert_source <<~'RUBY'
727
- begin
728
- foo
729
- bar
730
- end.blah
731
- RUBY
732
- end
733
-
734
- context 'begin / rescue / ensure' do
735
- assert_source <<~'RUBY'
736
- begin
737
- foo
738
- ensure
739
- bar
740
- baz
741
- end
742
- RUBY
743
-
744
- assert_source <<~'RUBY'
745
- begin
746
- foo
747
- rescue
748
- baz
749
- end
750
- RUBY
751
-
752
- assert_source <<~'RUBY'
753
- begin
754
- begin
755
- foo
756
- bar
757
- rescue
758
- end
759
- rescue
760
- baz
761
- bar
762
- end
763
- RUBY
764
-
765
- assert_source <<~'RUBY'
766
- begin
767
- raise(Exception) rescue foo = bar
768
- rescue Exception
769
- end
770
- RUBY
771
-
772
- assert_source <<~'RUBY'
773
- begin
774
- foo
775
- bar
776
- rescue
777
- baz
778
- bar
779
- end
780
- RUBY
781
-
782
- assert_source <<~'RUBY'
783
- begin
784
- foo
785
- rescue Exception
786
- bar
787
- end
788
- RUBY
789
-
790
- assert_source <<~'RUBY'
791
- begin
792
- foo
793
- rescue => bar
794
- bar
795
- end
796
- RUBY
797
-
798
- assert_source <<~'RUBY'
799
- begin
800
- foo
801
- rescue Exception, Other => bar
802
- bar
803
- end
804
- RUBY
805
-
806
- assert_source <<~'RUBY'
807
- class << self
808
- undef :bar rescue nil
809
- end
810
- RUBY
811
-
812
- assert_source <<~'RUBY'
813
- module Foo
814
- undef :bar rescue nil
815
- end
816
- RUBY
817
-
818
- assert_source <<~'RUBY'
819
- class Foo
820
- undef :bar rescue nil
821
- end
822
- RUBY
823
-
824
- assert_source <<~'RUBY'
825
- begin
826
- rescue Exception => e
827
- end
828
- RUBY
829
-
830
- assert_source <<~'RUBY'
831
- begin
832
- ensure
833
- end
834
- RUBY
835
-
836
- assert_source <<~'RUBY'
837
- begin
838
- rescue
839
- ensure
840
- end
841
- RUBY
842
-
843
- assert_source <<~'RUBY'
844
- begin
845
- foo
846
- rescue Exception => bar
847
- bar
848
- end
849
- RUBY
850
-
851
- assert_source <<~'RUBY'
852
- begin
853
- bar
854
- rescue SomeError, *bar
855
- baz
856
- end
857
- RUBY
858
-
859
- assert_source <<~'RUBY'
860
- begin
861
- bar
862
- rescue SomeError, *bar => exception
863
- baz
864
- end
865
- RUBY
866
-
867
- assert_source <<~'RUBY'
868
- begin
869
- bar
870
- rescue *bar
871
- baz
872
- end
873
- RUBY
874
-
875
- assert_source <<~'RUBY'
876
- begin
877
- bar
878
- rescue LoadError
879
- end
880
- RUBY
881
-
882
- assert_source <<~'RUBY'
883
- begin
884
- bar
885
- rescue
886
- else
887
- baz
888
- end
889
- RUBY
890
-
891
- assert_source <<~'RUBY'
892
- begin
893
- bar
894
- rescue *bar => exception
895
- baz
896
- end
897
- RUBY
898
-
899
- assert_source <<~'RUBY'
900
- m do
901
- rescue Exception => e
902
- end
903
- RUBY
904
-
905
- assert_source <<~'RUBY'
906
- m do
907
- ensure
908
- end
909
- RUBY
910
-
911
- assert_source <<~'RUBY'
912
- m do
913
- rescue
914
- ensure
915
- end
916
- RUBY
917
-
918
- assert_source <<~'RUBY'
919
- m do
920
- foo
921
- rescue Exception => bar
922
- bar
923
- end
924
- RUBY
925
-
926
- assert_source <<~'RUBY'
927
- m do
928
- bar
929
- rescue SomeError, *bar
930
- baz
931
- end
932
- RUBY
933
-
934
- assert_source <<~'RUBY'
935
- m do
936
- bar
937
- rescue SomeError, *bar => exception
938
- baz
939
- end
940
- RUBY
941
-
942
- assert_source <<~'RUBY'
943
- m do
944
- bar
945
- rescue *bar
946
- baz
947
- end
948
- RUBY
949
-
950
- assert_source <<~'RUBY'
951
- m do
952
- bar
953
- rescue LoadError
954
- end
955
- RUBY
956
-
957
- assert_source <<~'RUBY'
958
- m do
959
- bar
960
- rescue
961
- else
962
- baz
963
- end
964
- RUBY
965
-
966
- assert_source <<~'RUBY'
967
- m do
968
- bar
969
- rescue *bar => exception
970
- baz
971
- end
972
- RUBY
973
-
974
- assert_source 'foo rescue bar'
975
- assert_source 'foo rescue return bar'
976
- assert_source 'x = (foo rescue return bar)'
977
-
978
- %w(while until if).each do |keyword|
979
- assert_source <<~RUBY
980
- #{keyword} (
981
- foo rescue false
982
- )
983
- end
984
- RUBY
985
-
986
- assert_generates <<~RUBY, <<~GENERATED
987
- foo rescue false #{keyword} true
988
- RUBY
989
- #{keyword} true
990
- foo rescue false
991
- end
992
- GENERATED
993
- end
994
-
995
- assert_generates <<~'RUBY', <<~GENERATED
996
- case (foo rescue false)
997
- when true
998
- end
999
- RUBY
1000
- case (
1001
- foo rescue false
1002
- )
1003
- when true
1004
- end
1005
- GENERATED
1006
- end
1007
-
1008
- context 'super' do
1009
- assert_source 'super'
1010
-
1011
- assert_source 'super()'
1012
- assert_source 'super(a)'
1013
- assert_source 'super(a, b)'
1014
- assert_source 'super(&block)'
1015
- assert_source 'super(a, &block)'
1016
-
1017
- assert_source <<~'RUBY'
1018
- super(a do
1019
- foo
1020
- end)
1021
- RUBY
1022
-
1023
- assert_source <<~'RUBY'
1024
- super do
1025
- foo
1026
- end
1027
- RUBY
1028
-
1029
- assert_source <<~'RUBY'
1030
- super(a) do
1031
- foo
1032
- end
1033
- RUBY
1034
-
1035
- assert_source <<~'RUBY'
1036
- super() do
1037
- foo
1038
- end
1039
- RUBY
1040
-
1041
- assert_source <<~'RUBY'
1042
- super(a, b) do
1043
- foo
1044
- end
1045
- RUBY
1046
-
1047
- end
1048
-
1049
- context 'undef' do
1050
- assert_source 'undef :foo'
1051
- assert_source 'undef :foo, :bar'
1052
- end
1053
-
1054
- context 'BEGIN' do
1055
- assert_source <<~'RUBY'
1056
- BEGIN {
1057
- foo
1058
- }
1059
- RUBY
1060
- end
1061
-
1062
- context 'END' do
1063
- assert_source <<~'RUBY'
1064
- END {
1065
- foo
1066
- }
1067
- RUBY
1068
- end
1069
-
1070
- context 'alias' do
1071
- assert_source <<~'RUBY'
1072
- alias $foo $bar
1073
- RUBY
1074
-
1075
- assert_source <<~'RUBY'
1076
- alias :foo :bar
1077
- RUBY
1078
- end
1079
-
1080
- context 'yield' do
1081
- context 'without arguments' do
1082
- assert_source 'yield'
1083
- end
1084
-
1085
- context 'with argument' do
1086
- assert_source 'yield(a)'
1087
- end
1088
-
1089
- context 'with arguments' do
1090
- assert_source 'yield(a, b)'
1091
- end
1092
- end
1093
-
1094
- context 'if statement' do
1095
- assert_source <<~'RUBY'
1096
- if /foo/
1097
- bar
1098
- end
1099
- RUBY
1100
-
1101
- assert_source <<~'RUBY'
1102
- if 3
1103
- 9
1104
- end
1105
- RUBY
1106
-
1107
- assert_source <<~'RUBY'
1108
- if 4
1109
- 5
1110
- else
1111
- 6
1112
- end
1113
- RUBY
1114
-
1115
- assert_source <<~'RUBY'
1116
- unless 3
1117
- nil
1118
- end
1119
- RUBY
1120
-
1121
- assert_source <<~'RUBY'
1122
- unless 3
1123
- 9
1124
- end
1125
- RUBY
1126
-
1127
- assert_source <<~'RUBY'
1128
- if foo
1129
- end
1130
- RUBY
1131
-
1132
- assert_source <<~'RUBY'
1133
- foo = bar if foo
1134
- RUBY
1135
-
1136
- assert_source <<~'RUBY'
1137
- foo = bar unless foo
1138
- RUBY
1139
-
1140
- assert_source <<~'RUBY'
1141
- def foo(*foo)
1142
- unless foo
1143
- foo = bar
1144
- end
1145
- end
1146
- RUBY
1147
-
1148
- assert_source <<~'RUBY'
1149
- each do |foo|
1150
- unless foo
1151
- foo = bar
1152
- end
1153
- end
1154
- RUBY
1155
- end
1156
-
1157
- context 'def' do
1158
- context 'on instance' do
1159
-
1160
- assert_source <<~'RUBY'
1161
- def foo
1162
- end
1163
- RUBY
1164
-
1165
- assert_source <<~'RUBY'
1166
- def foo
1167
- bar
1168
- end
1169
- RUBY
1170
-
1171
- assert_source <<~'RUBY'
1172
- def foo
1173
- foo
1174
- rescue
1175
- bar
1176
- ensure
1177
- baz
1178
- end
1179
- RUBY
1180
-
1181
- assert_source <<~'RUBY'
1182
- begin
1183
- foo
1184
- ensure
1185
- bar rescue nil
1186
- end
1187
- RUBY
1188
-
1189
- assert_source <<~'RUBY'
1190
- def foo
1191
- bar
1192
- ensure
1193
- baz
1194
- end
1195
- RUBY
1196
-
1197
- assert_source <<~'RUBY'
1198
- def self.foo
1199
- bar
1200
- rescue
1201
- baz
1202
- end
1203
- RUBY
1204
-
1205
- assert_source <<~'RUBY'
1206
- def foo
1207
- bar
1208
- rescue
1209
- baz
1210
- end
1211
- RUBY
1212
-
1213
- assert_source <<~'RUBY'
1214
- def foo(bar)
1215
- bar
1216
- end
1217
- RUBY
1218
-
1219
- assert_source <<~'RUBY'
1220
- def foo(bar, baz)
1221
- bar
1222
- end
1223
- RUBY
1224
-
1225
- assert_source <<~'RUBY'
1226
- def foo(bar = ())
1227
- bar
1228
- end
1229
- RUBY
1230
-
1231
- assert_source <<~'RUBY'
1232
- def foo(bar = (baz
1233
- nil))
1234
- end
1235
- RUBY
1236
-
1237
- assert_source <<~'RUBY'
1238
- def foo(bar = true)
1239
- bar
1240
- end
1241
- RUBY
1242
-
1243
- assert_source <<~'RUBY'
1244
- def foo(bar, baz = true)
1245
- bar
1246
- end
1247
- RUBY
1248
-
1249
- assert_source <<~'RUBY'
1250
- def foo(bar: 1)
1251
- end
1252
- RUBY
1253
-
1254
- assert_source <<~'RUBY'
1255
- def foo(bar: bar)
1256
- end
1257
- RUBY
1258
-
1259
- assert_source <<~'RUBY'
1260
- def foo(bar: bar())
1261
- end
1262
- RUBY
1263
-
1264
- assert_source <<~'RUBY'
1265
- def foo(*)
1266
- bar
1267
- end
1268
- RUBY
1269
-
1270
- assert_source <<~'RUBY'
1271
- def foo(*bar)
1272
- bar
1273
- end
1274
- RUBY
1275
-
1276
- assert_source <<~'RUBY'
1277
- def foo(bar, *baz)
1278
- bar
1279
- end
1280
- RUBY
1281
-
1282
- assert_source <<~'RUBY'
1283
- def foo(baz = true, *bor)
1284
- bar
1285
- end
1286
- RUBY
1287
-
1288
- assert_source <<~'RUBY'
1289
- def foo(baz = true, *bor, &block)
1290
- bar
1291
- end
1292
- RUBY
1293
-
1294
- assert_source <<~'RUBY'
1295
- def foo(bar, baz = true, *bor)
1296
- bar
1297
- end
1298
- RUBY
1299
-
1300
- assert_source <<~'RUBY'
1301
- def foo(&block)
1302
- bar
1303
- end
1304
- RUBY
1305
-
1306
- assert_source <<~'RUBY'
1307
- def foo(bar, &block)
1308
- bar
1309
- end
1310
- RUBY
1311
-
1312
- assert_source <<~'RUBY'
1313
- def foo
1314
- bar
1315
- baz
1316
- end
1317
- RUBY
1318
-
1319
- assert_source <<~'RUBY'
1320
- def (foo do |bar|
1321
- end).bar
1322
- bar
1323
- end
1324
- RUBY
1325
-
1326
- assert_source <<~'RUBY'
1327
- def (foo(1)).bar
1328
- bar
1329
- end
1330
- RUBY
1331
-
1332
- assert_source <<~'RUBY'
1333
- def (Foo::Bar.baz).bar
1334
- baz
1335
- end
1336
- RUBY
1337
-
1338
- assert_source <<~'RUBY'
1339
- def (Foo::Bar).bar
1340
- baz
1341
- end
1342
- RUBY
1343
-
1344
- assert_source <<~'RUBY'
1345
- def Foo.bar
1346
- baz
1347
- end
1348
- RUBY
1349
-
1350
- assert_source <<~'RUBY'
1351
- def foo.bar
1352
- baz
1353
- end
1354
- RUBY
1355
- end
1356
-
1357
- context 'on singleton' do
1358
- assert_source <<~'RUBY'
1359
- def self.foo
1360
- end
1361
- RUBY
1362
-
1363
- assert_source <<~'RUBY'
1364
- def self.foo
1365
- bar
1366
- end
1367
- RUBY
1368
-
1369
- assert_source <<~'RUBY'
1370
- def self.foo
1371
- bar
1372
- baz
1373
- end
1374
- RUBY
1375
-
1376
- assert_source <<~'RUBY'
1377
- def Foo.bar
1378
- bar
1379
- end
1380
- RUBY
1381
-
1382
- end
1383
-
1384
- context 'class' do
1385
- assert_source <<~'RUBY'
1386
- class TestClass
1387
- end
1388
- RUBY
1389
-
1390
- assert_source <<~'RUBY'
1391
- class << some_object
1392
- end
1393
- RUBY
1394
-
1395
- assert_source <<~'RUBY'
1396
- class << some_object
1397
- the_body
1398
- end
1399
- RUBY
1400
-
1401
- assert_source <<~'RUBY'
1402
- class SomeNameSpace::TestClass
1403
- end
1404
- RUBY
1405
-
1406
- assert_source <<~'RUBY'
1407
- class Some::Name::Space::TestClass
1408
- end
1409
- RUBY
1410
-
1411
- assert_source <<~'RUBY'
1412
- class TestClass < Object
1413
- end
1414
- RUBY
1415
-
1416
- assert_source <<~'RUBY'
1417
- class TestClass < SomeNameSpace::Object
1418
- end
1419
- RUBY
1420
-
1421
- assert_source <<~'RUBY'
1422
- class TestClass
1423
- def foo
1424
- :bar
1425
- end
1426
- end
1427
- RUBY
1428
-
1429
- assert_source <<~'RUBY'
1430
- class ::TestClass
1431
- end
1432
- RUBY
1433
- end
1434
-
1435
- context 'module' do
1436
-
1437
- assert_source <<~'RUBY'
1438
- module TestModule
1439
- end
1440
- RUBY
1441
-
1442
- assert_source <<~'RUBY'
1443
- module SomeNameSpace::TestModule
1444
- end
1445
- RUBY
1446
-
1447
- assert_source <<~'RUBY'
1448
- module Some::Name::Space::TestModule
1449
- end
1450
- RUBY
1451
-
1452
- assert_source <<~'RUBY'
1453
- module TestModule
1454
- def foo
1455
- :bar
1456
- end
1457
- end
1458
- RUBY
1459
-
1460
- end
1461
-
1462
- context 'op assign' do
1463
- %w(|= ||= &= &&= += -= *= /= **= %=).each do |op|
1464
- assert_source "self.foo #{op} bar"
1465
- assert_source "foo[key] #{op} bar"
1466
- assert_source "a #{op} (true\nfalse)"
1467
- end
1468
- end
1469
-
1470
- context 'element assignment' do
1471
- assert_source 'foo[index] = value'
1472
- assert_source 'foo[*index] = value'
1473
- assert_source 'foo[a, b] = value'
1474
- assert_source 'foo[1..2] = value'
1475
- assert_source 'foo.[]=()'
1476
- assert_source 'foo.[]=true'
1477
- assert_source 'foo.[]=(1, 2)'
1478
- assert_source 'foo[] = 1'
1479
- assert_unterminated 'foo[] = 1'
1480
-
1481
- %w(+ - * / % & | || &&).each do |operator|
1482
- context "with #{operator}" do
1483
- assert_source "foo[index] #{operator}= 2"
1484
- assert_source "foo[] #{operator}= 2"
1485
- end
1486
- end
1487
- end
1488
-
1489
- context 'defined?' do
1490
- assert_source <<~'RUBY'
1491
- defined?(@foo)
1492
- RUBY
1493
-
1494
- assert_source <<~'RUBY'
1495
- defined?(Foo)
1496
- RUBY
1497
-
1498
- assert_source <<~'RUBY'
1499
- defined?((a, b = [1, 2]))
1500
- RUBY
1501
- end
1502
- end
1503
-
1504
- context 'lambda' do
1505
- assert_source <<~'RUBY'
1506
- lambda do
1507
- end
1508
- RUBY
1509
-
1510
- assert_source <<~'RUBY'
1511
- lambda do |a, b|
1512
- a
1513
- end
1514
- RUBY
1515
-
1516
- assert_source <<~'RUBY'
1517
- ->() do
1518
- end
1519
- RUBY
1520
-
1521
- assert_source <<~'RUBY'
1522
- ->(a) do
1523
- end
1524
- RUBY
1525
-
1526
- assert_source <<~'RUBY'
1527
- ->(a, b) do
1528
- end
1529
- RUBY
1530
- end
1531
-
1532
- context 'match operators' do
1533
- assert_source '/bar/ =~ foo'
1534
- assert_source '/bar/ =~ :foo'
1535
- assert_source '(/bar/ =~ :foo).foo'
1536
- assert_source 'foo =~ /bar/'
1537
- assert_source 'foo(foo =~ /bar/)'
1538
- assert_source '(foo =~ /bar/).foo'
1539
- end
1540
-
1541
- context 'binary operator methods' do
1542
- %w(+ - * / & | << >> == === != <= < <=> > >= =~ !~ ^ **).each do |operator|
1543
- assert_source "(-1) #{operator} 2"
1544
- assert_source "(-1.2) #{operator} 2"
1545
- assert_source "left.#{operator}(*foo)"
1546
- assert_source "left.#{operator}(a, b)"
1547
- assert_source "self #{operator} b"
1548
- assert_source "a #{operator} b"
1549
- assert_source "(a #{operator} b).foo"
1550
- end
1551
-
1552
- assert_source 'left / right'
1553
- end
1554
-
1555
- context 'nested binary operators' do
1556
- assert_source '(a + b) / (c - d)'
1557
- assert_source '(a + b) / c.-(e, f)'
1558
- assert_source '(a + b) / c.-(*f)'
1559
- end
1560
-
1561
- context 'binary operator' do
1562
- assert_source 'a || (return foo)'
1563
- assert_source '(return foo) || a'
1564
- assert_source 'a || (break foo)'
1565
- assert_source '(break foo) || a'
1566
- assert_source '(a || b).foo'
1567
- assert_source 'a || (b || c)'
1568
- end
1569
-
1570
- { or: :'||', and: :'&&' }.each do |word, symbol|
1571
- assert_generates "a #{word} return foo", "a #{symbol} (return foo)"
1572
- assert_generates "a #{word} break foo", "a #{symbol} (break foo)"
1573
- assert_generates "a #{word} next foo", "a #{symbol} (next foo)"
1574
- end
1575
-
1576
- context 'expansion of shortcuts' do
1577
- assert_source 'a += 2'
1578
- assert_source 'a -= 2'
1579
- assert_source 'a **= 2'
1580
- assert_source 'a *= 2'
1581
- assert_source 'a /= 2'
1582
- end
1583
-
1584
- context 'shortcuts' do
1585
- assert_source 'a &&= b'
1586
- assert_source 'a ||= 2'
1587
- assert_source '(a ||= 2).bar'
1588
- assert_source '(h ||= {})[k] = v'
1589
- end
1590
-
1591
- context 'flip flops' do
1592
- context 'inclusive' do
1593
- assert_source <<~'RUBY'
1594
- if ((i == 4)..(i == 4))
1595
- foo
1596
- end
1597
- RUBY
1598
- end
1599
-
1600
- context 'exclusive' do
1601
- assert_source <<~'RUBY'
1602
- if ((i == 4)...(i == 4))
1603
- foo
1604
- end
1605
- RUBY
1606
- end
1607
- end
1608
-
1609
- context 'case statement' do
1610
- assert_source <<~'RUBY'
1611
- case
1612
- when bar
1613
- baz
1614
- when baz
1615
- bar
1616
- end
1617
- RUBY
1618
-
1619
- assert_source <<~'RUBY'
1620
- case foo
1621
- when bar
1622
- when baz
1623
- bar
1624
- end
1625
- RUBY
1626
-
1627
- assert_source <<~'RUBY'
1628
- case foo
1629
- when bar
1630
- baz
1631
- when baz
1632
- bar
1633
- end
1634
- RUBY
1635
-
1636
- assert_source <<~'RUBY'
1637
- case foo
1638
- when bar, baz
1639
- :other
1640
- end
1641
- RUBY
1642
-
1643
- assert_source <<~'RUBY'
1644
- case foo
1645
- when *bar
1646
- :value
1647
- end
1648
- RUBY
1649
-
1650
- assert_source <<~'RUBY'
1651
- case foo
1652
- when bar
1653
- baz
1654
- else
1655
- :foo
1656
- end
1657
- RUBY
1658
- end
1659
-
1660
- context 'for' do
1661
- assert_source <<~'RUBY'
1662
- bar(for a in bar do
1663
- baz
1664
- end)
1665
- RUBY
1666
- assert_source <<~'RUBY'
1667
- for a in bar do
1668
- baz
1669
- end
1670
- RUBY
1671
-
1672
- assert_source <<~'RUBY'
1673
- for a, *b in bar do
1674
- baz
1675
- end
1676
- RUBY
1677
-
1678
- assert_source <<~'RUBY'
1679
- for a, b in bar do
1680
- baz
1681
- end
1682
- RUBY
1683
- end
1684
-
1685
- context 'unary operators' do
1686
- assert_source '!1'
1687
- assert_source '!(!1)'
1688
- assert_source '!(!(foo || bar))'
1689
- assert_source '!(!1).baz'
1690
- assert_source '~a'
1691
- assert_source '-a'
1692
- assert_source '+a'
1693
- assert_source '-(-a).foo'
1694
- end
1695
-
1696
- context 'loop' do
1697
- assert_source <<~'RUBY'
1698
- loop do
1699
- foo
1700
- end
1701
- RUBY
1702
- end
1703
-
1704
- context 'post conditions' do
1705
- assert_source <<~'RUBY'
1706
- x = (begin
1707
- foo
1708
- end while baz)
1709
- RUBY
1710
-
1711
- assert_source <<~'RUBY'
1712
- begin
1713
- foo
1714
- end while baz
1715
- RUBY
1716
-
1717
- assert_source <<~'RUBY'
1718
- begin
1719
- foo
1720
- bar
1721
- end until baz
1722
- RUBY
1723
-
1724
- assert_source <<~'RUBY'
1725
- begin
1726
- foo
1727
- bar
1728
- end while baz
1729
- RUBY
1730
- end
1731
-
1732
- context 'while' do
1733
- assert_source <<~'RUBY'
1734
- while false
1735
- end
1736
- RUBY
1737
-
1738
- assert_source <<~'RUBY'
1739
- while false
1740
- 3
1741
- end
1742
- RUBY
1743
-
1744
- assert_source <<~'RUBY'
1745
- while (foo do
1746
- end)
1747
- :body
1748
- end
1749
- RUBY
1750
- end
1751
-
1752
- context 'until' do
1753
- assert_source <<~'RUBY'
1754
- until false
1755
- end
1756
- RUBY
1757
-
1758
- assert_source <<~'RUBY'
1759
- until false
1760
- 3
1761
- end
1762
- RUBY
1763
-
1764
- assert_source <<~'RUBY'
1765
- until (foo do
1766
- end)
1767
- :body
1768
- end
1769
- RUBY
1770
- end
1771
-
1772
- assert_source <<~'RUBY'
1773
- # comment before
1774
- a_line_of_code
1775
- RUBY
1776
-
1777
- assert_source <<~'RUBY'
1778
- a_line_of_code # comment after
1779
- RUBY
1780
-
1781
- assert_source <<~'RUBY'
1782
- nested do # first
1783
- # second
1784
- something # comment
1785
- # another
1786
- end
1787
- # last
1788
- RUBY
1789
-
1790
- assert_generates <<~'RUBY', <<~'RUBY'
1791
- foo if bar
1792
- # comment
1793
- RUBY
1794
- if bar
1795
- foo
1796
- end
1797
- # comment
1798
- RUBY
1799
-
1800
- assert_source <<~'RUBY'
1801
- def noop
1802
- # do nothing
1803
- end
1804
- RUBY
1805
-
1806
- assert_source <<~'RUBY'
1807
- =begin
1808
- block comment
1809
- =end
1810
- nested do
1811
- =begin
1812
- another block comment
1813
- =end
1814
- something
1815
- =begin
1816
- last block comment
1817
- =end
1818
- end
1819
- RUBY
1820
-
1821
- assert_generates(<<~'RUBY', <<~'RUBY')
1822
- 1 + # first
1823
- 2 # second
1824
- RUBY
1825
- 1 + 2 # first # second
1826
- RUBY
1827
-
1828
- assert_generates(<<~'RUBY', <<~'RUBY')
1829
- 1 +
1830
- # first
1831
- 2 # second
1832
- RUBY
1833
- 1 + 2 # first # second
1834
- RUBY
1835
-
1836
- assert_generates(<<~'RUBY', <<~'RUBY')
1837
- 1 +
1838
- =begin
1839
- block comment
1840
- =end
1841
- 2
1842
- RUBY
1843
- 1 + 2
1844
- =begin
1845
- block comment
1846
- =end
1847
- RUBY
1848
- end
1849
- end