unparser 0.4.7 → 0.5.2

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 (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