unparser 0.4.6 → 0.5.1

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 +117 -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 +151 -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 +151 -100
  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 -150
  93. data/Gemfile +0 -11
  94. data/Gemfile.lock +0 -176
  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 -1847
  143. data/unparser.gemspec +0 -30
@@ -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,1847 +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..2'
269
- assert_unterminated '(0.0 / 0.0)..1'
270
- assert_unterminated '1..(0.0 / 0.0)'
271
- assert_unterminated '(0.0 / 0.0)..100'
272
- end
273
-
274
- context 'erange' do
275
- assert_unterminated '1...2'
276
- end
277
-
278
- context 'float' do
279
- assert_source '-0.1'
280
- assert_terminated '0.1'
281
- assert_terminated '0.1'
282
- assert_generates '10.2e10000000000', 'Float::INFINITY'
283
- assert_generates '-10.2e10000000000', '-Float::INFINITY'
284
- assert_generates s(:float, -0.1), '-0.1'
285
- assert_generates s(:float, 0.1), '0.1'
286
- end
287
-
288
- context 'array' do
289
- assert_terminated '[1, 2]'
290
- assert_terminated '[1, (), n2]'
291
- assert_terminated '[1]'
292
- assert_terminated '[]'
293
- assert_terminated '[1, *@foo]'
294
- assert_terminated '[*@foo, 1]'
295
- assert_terminated '[*@foo, *@baz]'
296
- assert_generates '%w(foo bar)', '["foo", "bar"]'
297
- end
298
-
299
- context 'hash' do
300
- assert_terminated '{}'
301
- assert_source '{ () => () }'
302
- assert_source '{ 1 => 2 }'
303
- assert_source '{ 1 => 2, 3 => 4 }'
304
-
305
- # special case for 2.1.3
306
- assert_source "{ foo: (if true\nend) }"
307
-
308
- context 'with symbol keys' do
309
- assert_source '{ a: (1 rescue foo), b: 2 }'
310
- assert_source '{ a: 1, b: 2 }'
311
- assert_source '{ a: :a }'
312
- assert_source '{ :"a b" => 1 }'
313
- assert_source '{ :-@ => 1 }'
314
- end
315
- end
316
- end
317
-
318
- context 'access' do
319
- %w(@a @@a $a $1 $` CONST SCOPED::CONST ::TOPLEVEL ::TOPLEVEL::CONST).each do |expression|
320
- assert_terminated(expression)
321
- end
322
- end
323
-
324
- context 'control keywords' do
325
- %w(retry redo).each do |expression|
326
- assert_terminated(expression)
327
- end
328
- end
329
-
330
- context 'singletons' do
331
- %w(self true false nil).each do |expression|
332
- assert_terminated(expression)
333
- end
334
- end
335
-
336
- context 'magic keywords' do
337
- assert_source '__ENCODING__'
338
-
339
- # These two assertions don't actually need to be wrapped in this block since `true` is the default,
340
- # but it is helpful to contrast with the assertions farther down.
341
- with_builder_options(emit_file_line_as_literals: true) do
342
- assert_generates '__FILE__', '"(string)"'
343
- assert_generates '__LINE__', '1'
344
- end
345
-
346
- with_builder_options(emit_file_line_as_literals: false) do
347
- assert_source '__FILE__'
348
- assert_source '__LINE__'
349
- end
350
- end
351
-
352
- context 'assignment' do
353
- context 'single' do
354
- assert_unterminated 'a = 1'
355
- assert_unterminated '@a = 1'
356
- assert_unterminated '@@a = 1'
357
- assert_unterminated '$a = 1'
358
- assert_unterminated 'CONST = 1'
359
- assert_unterminated 'Name::Spaced::CONST = 1'
360
- assert_unterminated '::Foo = ::Bar'
361
- end
362
-
363
- context 'lvar assigned from method with same name' do
364
- assert_unterminated 'foo = foo()'
365
- end
366
-
367
- context 'lvar introduction from condition' do
368
- assert_source 'foo = bar while foo'
369
- assert_source 'foo = bar until foo'
370
- assert_source <<~'RUBY'
371
- foo = exp
372
- while foo
373
- foo = bar
374
- end
375
- RUBY
376
-
377
- # Ugly I know. But its correct :D
378
- #
379
- # if foo { |pair| }
380
- # pair = :foo
381
- # foo
382
- # end
383
- assert_source <<~'RUBY'
384
- if foo do |pair|
385
- pair
386
- end
387
- pair = :foo
388
- foo
389
- end
390
- RUBY
391
-
392
- assert_source <<~'RUBY'
393
- while foo
394
- foo = bar
395
- end
396
- RUBY
397
-
398
- assert_source <<~'RUBY'
399
- each do |bar|
400
- while foo
401
- foo = bar
402
- end
403
- end
404
- RUBY
405
-
406
- assert_source <<~'RUBY'
407
- def foo
408
- foo = bar while foo != baz
409
- end
410
- RUBY
411
-
412
- assert_source <<~'RUBY'
413
- each do |baz|
414
- while foo
415
- foo = bar
416
- end
417
- end
418
- RUBY
419
-
420
- assert_source <<~'RUBY'
421
- each do |foo|
422
- while foo
423
- foo = bar
424
- end
425
- end
426
- RUBY
427
- end
428
-
429
- context 'multiple' do
430
- assert_source 'a, * = [1, 2]'
431
- assert_source 'a, *foo = [1, 2]'
432
- assert_source '*a = []'
433
- assert_source '*foo = [1, 2]'
434
- assert_source 'a, = foo'
435
- assert_unterminated 'a, b = [1, 2]'
436
- assert_unterminated '@a, @b = [1, 2]'
437
- assert_unterminated 'a.foo, a.bar = [1, 2]'
438
- assert_unterminated 'a[0], a[1] = [1, 2]'
439
- assert_unterminated 'a[*foo], a[1] = [1, 2]'
440
- assert_unterminated '@@a, @@b = [1, 2]'
441
- assert_unterminated '$a, $b = [1, 2]'
442
- assert_unterminated 'a, b = foo'
443
- assert_unterminated 'a, (b, c) = [1, [2, 3]]'
444
- assert_unterminated 'a = (b, c = 1)'
445
- assert_unterminated '(a,), b = 1'
446
- end
447
- end
448
-
449
- %w(next return break).each do |keyword|
450
-
451
- context keyword do
452
- assert_terminated keyword.to_s
453
- assert_unterminated "#{keyword} 1"
454
- assert_unterminated "#{keyword} 2, 3"
455
- assert_unterminated "#{keyword} *nil"
456
- assert_unterminated "#{keyword} *foo, bar"
457
-
458
- assert_generates <<~RUBY, <<~RUBY
459
- foo do |bar|
460
- bar =~ // || #{keyword}
461
- baz
462
- end
463
- RUBY
464
- foo do |bar|
465
- (bar =~ //) || #{keyword}
466
- baz
467
- end
468
- RUBY
469
-
470
- assert_generates <<~RUBY, <<~RUBY
471
- #{keyword}(a ? b : c)
472
- RUBY
473
- #{keyword} (if a
474
- b
475
- else
476
- c
477
- end)
478
- RUBY
479
- end
480
- end
481
-
482
- context 'conditional send (csend)' do
483
- assert_terminated 'a&.b'
484
- assert_terminated 'a&.b(c)'
485
- end
486
-
487
- context 'send' do
488
- assert_terminated 'foo'
489
- assert_terminated 'self.foo'
490
- assert_terminated 'a.foo'
491
- assert_terminated 'A.foo'
492
- assert_terminated 'foo[]'
493
- assert_terminated 'foo[1]'
494
- assert_terminated 'foo[*baz]'
495
- assert_terminated 'foo(1)'
496
- assert_terminated 'foo(bar)'
497
- assert_terminated 'foo(&block)'
498
- assert_terminated 'foo(&(foo || bar))'
499
- assert_terminated 'foo(*arguments)'
500
- assert_terminated 'foo(*arguments)'
501
-
502
- assert_source <<~'RUBY'
503
- foo do
504
- end
505
- RUBY
506
-
507
- assert_source <<~'RUBY'
508
- foo do |a|
509
- end
510
- RUBY
511
-
512
- assert_source <<~'RUBY'
513
- foo do |a, |
514
- end
515
- RUBY
516
-
517
- assert_source <<~'RUBY'
518
- foo do |a, b|
519
- end
520
- RUBY
521
-
522
- assert_source <<~'RUBY'
523
- foo(1) do
524
- nil
525
- end
526
- RUBY
527
-
528
- assert_source <<~'RUBY'
529
- foo do |a, *b|
530
- nil
531
- end
532
- RUBY
533
-
534
- assert_source <<~'RUBY'
535
- foo do |a, *|
536
- nil
537
- end
538
- RUBY
539
-
540
- assert_source <<~'RUBY'
541
- foo do
542
- bar
543
- end
544
- RUBY
545
-
546
- assert_source <<~'RUBY'
547
- foo.bar(*args)
548
- RUBY
549
-
550
- assert_source <<~'RUBY'
551
- foo.bar do |(a, b), c|
552
- d
553
- end
554
- RUBY
555
-
556
- assert_source <<~'RUBY'
557
- foo.bar do |*a; b|
558
- end
559
- RUBY
560
-
561
- assert_source <<~'RUBY'
562
- foo.bar do |a; b|
563
- end
564
- RUBY
565
-
566
- assert_source <<~'RUBY'
567
- foo.bar do |; a, b|
568
- end
569
- RUBY
570
-
571
- assert_source <<~'RUBY'
572
- foo.bar do |*|
573
- d
574
- end
575
- RUBY
576
-
577
- assert_source <<~'RUBY'
578
- foo.bar do |(*)|
579
- d
580
- end
581
- RUBY
582
-
583
- assert_source <<~'RUBY'
584
- foo.bar do |((*))|
585
- d
586
- end
587
- RUBY
588
-
589
- assert_source <<~'RUBY'
590
- foo.bar do |(a, (*))|
591
- d
592
- end
593
- RUBY
594
-
595
- assert_source <<~'RUBY'
596
- foo.bar do |(a, b)|
597
- d
598
- end
599
- RUBY
600
-
601
- assert_source <<~'RUBY'
602
- foo.bar do
603
- end.baz
604
- RUBY
605
-
606
- assert_source <<~'RUBY'
607
- FOO()
608
- RUBY
609
-
610
- assert_terminated '(1..2).max'
611
- assert_terminated '1..2.max'
612
- assert_unterminated 'a || return'
613
- assert_unterminated 'foo << (bar * baz)'
614
-
615
- assert_source <<~'RUBY'
616
- foo ||= (a, _ = b)
617
- RUBY
618
-
619
- assert_source <<~'RUBY'
620
- begin
621
- rescue
622
- end.bar
623
- RUBY
624
-
625
- assert_source <<~'RUBY'
626
- case (def foo
627
- end
628
- :bar)
629
- when bar
630
- end.baz
631
- RUBY
632
-
633
- assert_source <<~'RUBY'
634
- case foo
635
- when bar
636
- end.baz
637
- RUBY
638
-
639
- assert_source <<~'RUBY'
640
- class << self
641
- end.bar
642
- RUBY
643
-
644
- assert_source <<~'RUBY'
645
- def self.foo
646
- end.bar
647
- RUBY
648
-
649
- assert_source <<~'RUBY'
650
- def foo
651
- end.bar
652
- RUBY
653
-
654
- assert_source <<~'RUBY'
655
- until foo
656
- end.bar
657
- RUBY
658
-
659
- assert_source <<~'RUBY'
660
- while foo
661
- end.bar
662
- RUBY
663
-
664
- assert_source <<~'RUBY'
665
- loop do
666
- end.bar
667
- RUBY
668
-
669
- assert_source <<~'RUBY'
670
- class Foo
671
- end.bar
672
- RUBY
673
-
674
- assert_source <<~'RUBY'
675
- module Foo
676
- end.bar
677
- RUBY
678
-
679
- assert_source <<~'RUBY'
680
- if foo
681
- end.baz
682
- RUBY
683
-
684
- assert_source <<~'RUBY'
685
- local = 1
686
- local.bar
687
- RUBY
688
-
689
- assert_terminated 'foo.bar(*args)'
690
- assert_terminated 'foo.bar(*arga, foo, *argb)'
691
- assert_terminated 'foo.bar(*args, foo)'
692
- assert_terminated 'foo.bar(foo, *args)'
693
- assert_terminated 'foo.bar(foo, *args, &block)'
694
- assert_source <<~'RUBY'
695
- foo(bar, *args)
696
- RUBY
697
-
698
- assert_terminated 'foo(*args, &block)'
699
- assert_terminated 'foo.bar(&baz)'
700
- assert_terminated 'foo.bar(:baz, &baz)'
701
- assert_terminated 'foo.bar=:baz'
702
-
703
- assert_unterminated 'self.foo=:bar'
704
-
705
- assert_terminated 'foo.bar(baz: boz)'
706
- assert_terminated 'foo.bar(foo, "baz" => boz)'
707
- assert_terminated 'foo.bar({ foo: boz }, boz)'
708
- assert_terminated 'foo.bar(foo, {})'
709
- end
710
-
711
- context 'begin; end' do
712
- assert_generates s(:begin), ''
713
-
714
- assert_source <<~'RUBY'
715
- begin
716
- end
717
- RUBY
718
-
719
- assert_source <<~'RUBY'
720
- foo
721
- bar
722
- RUBY
723
-
724
- assert_source <<~'RUBY'
725
- begin
726
- foo
727
- bar
728
- end.blah
729
- RUBY
730
- end
731
-
732
- context 'begin / rescue / ensure' do
733
- assert_source <<~'RUBY'
734
- begin
735
- foo
736
- ensure
737
- bar
738
- baz
739
- end
740
- RUBY
741
-
742
- assert_source <<~'RUBY'
743
- begin
744
- foo
745
- rescue
746
- baz
747
- end
748
- RUBY
749
-
750
- assert_source <<~'RUBY'
751
- begin
752
- begin
753
- foo
754
- bar
755
- rescue
756
- end
757
- rescue
758
- baz
759
- bar
760
- end
761
- RUBY
762
-
763
- assert_source <<~'RUBY'
764
- begin
765
- raise(Exception) rescue foo = bar
766
- rescue Exception
767
- end
768
- RUBY
769
-
770
- assert_source <<~'RUBY'
771
- begin
772
- foo
773
- bar
774
- rescue
775
- baz
776
- bar
777
- end
778
- RUBY
779
-
780
- assert_source <<~'RUBY'
781
- begin
782
- foo
783
- rescue Exception
784
- bar
785
- end
786
- RUBY
787
-
788
- assert_source <<~'RUBY'
789
- begin
790
- foo
791
- rescue => bar
792
- bar
793
- end
794
- RUBY
795
-
796
- assert_source <<~'RUBY'
797
- begin
798
- foo
799
- rescue Exception, Other => bar
800
- bar
801
- end
802
- RUBY
803
-
804
- assert_source <<~'RUBY'
805
- class << self
806
- undef :bar rescue nil
807
- end
808
- RUBY
809
-
810
- assert_source <<~'RUBY'
811
- module Foo
812
- undef :bar rescue nil
813
- end
814
- RUBY
815
-
816
- assert_source <<~'RUBY'
817
- class Foo
818
- undef :bar rescue nil
819
- end
820
- RUBY
821
-
822
- assert_source <<~'RUBY'
823
- begin
824
- rescue Exception => e
825
- end
826
- RUBY
827
-
828
- assert_source <<~'RUBY'
829
- begin
830
- ensure
831
- end
832
- RUBY
833
-
834
- assert_source <<~'RUBY'
835
- begin
836
- rescue
837
- ensure
838
- end
839
- RUBY
840
-
841
- assert_source <<~'RUBY'
842
- begin
843
- foo
844
- rescue Exception => bar
845
- bar
846
- end
847
- RUBY
848
-
849
- assert_source <<~'RUBY'
850
- begin
851
- bar
852
- rescue SomeError, *bar
853
- baz
854
- end
855
- RUBY
856
-
857
- assert_source <<~'RUBY'
858
- begin
859
- bar
860
- rescue SomeError, *bar => exception
861
- baz
862
- end
863
- RUBY
864
-
865
- assert_source <<~'RUBY'
866
- begin
867
- bar
868
- rescue *bar
869
- baz
870
- end
871
- RUBY
872
-
873
- assert_source <<~'RUBY'
874
- begin
875
- bar
876
- rescue LoadError
877
- end
878
- RUBY
879
-
880
- assert_source <<~'RUBY'
881
- begin
882
- bar
883
- rescue
884
- else
885
- baz
886
- end
887
- RUBY
888
-
889
- assert_source <<~'RUBY'
890
- begin
891
- bar
892
- rescue *bar => exception
893
- baz
894
- end
895
- RUBY
896
-
897
- assert_source <<~'RUBY'
898
- m do
899
- rescue Exception => e
900
- end
901
- RUBY
902
-
903
- assert_source <<~'RUBY'
904
- m do
905
- ensure
906
- end
907
- RUBY
908
-
909
- assert_source <<~'RUBY'
910
- m do
911
- rescue
912
- ensure
913
- end
914
- RUBY
915
-
916
- assert_source <<~'RUBY'
917
- m do
918
- foo
919
- rescue Exception => bar
920
- bar
921
- end
922
- RUBY
923
-
924
- assert_source <<~'RUBY'
925
- m do
926
- bar
927
- rescue SomeError, *bar
928
- baz
929
- end
930
- RUBY
931
-
932
- assert_source <<~'RUBY'
933
- m do
934
- bar
935
- rescue SomeError, *bar => exception
936
- baz
937
- end
938
- RUBY
939
-
940
- assert_source <<~'RUBY'
941
- m do
942
- bar
943
- rescue *bar
944
- baz
945
- end
946
- RUBY
947
-
948
- assert_source <<~'RUBY'
949
- m do
950
- bar
951
- rescue LoadError
952
- end
953
- RUBY
954
-
955
- assert_source <<~'RUBY'
956
- m do
957
- bar
958
- rescue
959
- else
960
- baz
961
- end
962
- RUBY
963
-
964
- assert_source <<~'RUBY'
965
- m do
966
- bar
967
- rescue *bar => exception
968
- baz
969
- end
970
- RUBY
971
-
972
- assert_source 'foo rescue bar'
973
- assert_source 'foo rescue return bar'
974
- assert_source 'x = (foo rescue return bar)'
975
-
976
- %w(while until if).each do |keyword|
977
- assert_source <<~RUBY
978
- #{keyword} (
979
- foo rescue false
980
- )
981
- end
982
- RUBY
983
-
984
- assert_generates <<~RUBY, <<~GENERATED
985
- foo rescue false #{keyword} true
986
- RUBY
987
- #{keyword} true
988
- foo rescue false
989
- end
990
- GENERATED
991
- end
992
-
993
- assert_generates <<~'RUBY', <<~GENERATED
994
- case (foo rescue false)
995
- when true
996
- end
997
- RUBY
998
- case (
999
- foo rescue false
1000
- )
1001
- when true
1002
- end
1003
- GENERATED
1004
- end
1005
-
1006
- context 'super' do
1007
- assert_source 'super'
1008
-
1009
- assert_source 'super()'
1010
- assert_source 'super(a)'
1011
- assert_source 'super(a, b)'
1012
- assert_source 'super(&block)'
1013
- assert_source 'super(a, &block)'
1014
-
1015
- assert_source <<~'RUBY'
1016
- super(a do
1017
- foo
1018
- end)
1019
- RUBY
1020
-
1021
- assert_source <<~'RUBY'
1022
- super do
1023
- foo
1024
- end
1025
- RUBY
1026
-
1027
- assert_source <<~'RUBY'
1028
- super(a) do
1029
- foo
1030
- end
1031
- RUBY
1032
-
1033
- assert_source <<~'RUBY'
1034
- super() do
1035
- foo
1036
- end
1037
- RUBY
1038
-
1039
- assert_source <<~'RUBY'
1040
- super(a, b) do
1041
- foo
1042
- end
1043
- RUBY
1044
-
1045
- end
1046
-
1047
- context 'undef' do
1048
- assert_source 'undef :foo'
1049
- assert_source 'undef :foo, :bar'
1050
- end
1051
-
1052
- context 'BEGIN' do
1053
- assert_source <<~'RUBY'
1054
- BEGIN {
1055
- foo
1056
- }
1057
- RUBY
1058
- end
1059
-
1060
- context 'END' do
1061
- assert_source <<~'RUBY'
1062
- END {
1063
- foo
1064
- }
1065
- RUBY
1066
- end
1067
-
1068
- context 'alias' do
1069
- assert_source <<~'RUBY'
1070
- alias $foo $bar
1071
- RUBY
1072
-
1073
- assert_source <<~'RUBY'
1074
- alias :foo :bar
1075
- RUBY
1076
- end
1077
-
1078
- context 'yield' do
1079
- context 'without arguments' do
1080
- assert_source 'yield'
1081
- end
1082
-
1083
- context 'with argument' do
1084
- assert_source 'yield(a)'
1085
- end
1086
-
1087
- context 'with arguments' do
1088
- assert_source 'yield(a, b)'
1089
- end
1090
- end
1091
-
1092
- context 'if statement' do
1093
- assert_source <<~'RUBY'
1094
- if /foo/
1095
- bar
1096
- end
1097
- RUBY
1098
-
1099
- assert_source <<~'RUBY'
1100
- if 3
1101
- 9
1102
- end
1103
- RUBY
1104
-
1105
- assert_source <<~'RUBY'
1106
- if 4
1107
- 5
1108
- else
1109
- 6
1110
- end
1111
- RUBY
1112
-
1113
- assert_source <<~'RUBY'
1114
- unless 3
1115
- nil
1116
- end
1117
- RUBY
1118
-
1119
- assert_source <<~'RUBY'
1120
- unless 3
1121
- 9
1122
- end
1123
- RUBY
1124
-
1125
- assert_source <<~'RUBY'
1126
- if foo
1127
- end
1128
- RUBY
1129
-
1130
- assert_source <<~'RUBY'
1131
- foo = bar if foo
1132
- RUBY
1133
-
1134
- assert_source <<~'RUBY'
1135
- foo = bar unless foo
1136
- RUBY
1137
-
1138
- assert_source <<~'RUBY'
1139
- def foo(*foo)
1140
- unless foo
1141
- foo = bar
1142
- end
1143
- end
1144
- RUBY
1145
-
1146
- assert_source <<~'RUBY'
1147
- each do |foo|
1148
- unless foo
1149
- foo = bar
1150
- end
1151
- end
1152
- RUBY
1153
- end
1154
-
1155
- context 'def' do
1156
- context 'on instance' do
1157
-
1158
- assert_source <<~'RUBY'
1159
- def foo
1160
- end
1161
- RUBY
1162
-
1163
- assert_source <<~'RUBY'
1164
- def foo
1165
- bar
1166
- end
1167
- RUBY
1168
-
1169
- assert_source <<~'RUBY'
1170
- def foo
1171
- foo
1172
- rescue
1173
- bar
1174
- ensure
1175
- baz
1176
- end
1177
- RUBY
1178
-
1179
- assert_source <<~'RUBY'
1180
- begin
1181
- foo
1182
- ensure
1183
- bar rescue nil
1184
- end
1185
- RUBY
1186
-
1187
- assert_source <<~'RUBY'
1188
- def foo
1189
- bar
1190
- ensure
1191
- baz
1192
- end
1193
- RUBY
1194
-
1195
- assert_source <<~'RUBY'
1196
- def self.foo
1197
- bar
1198
- rescue
1199
- baz
1200
- end
1201
- RUBY
1202
-
1203
- assert_source <<~'RUBY'
1204
- def foo
1205
- bar
1206
- rescue
1207
- baz
1208
- end
1209
- RUBY
1210
-
1211
- assert_source <<~'RUBY'
1212
- def foo(bar)
1213
- bar
1214
- end
1215
- RUBY
1216
-
1217
- assert_source <<~'RUBY'
1218
- def foo(bar, baz)
1219
- bar
1220
- end
1221
- RUBY
1222
-
1223
- assert_source <<~'RUBY'
1224
- def foo(bar = ())
1225
- bar
1226
- end
1227
- RUBY
1228
-
1229
- assert_source <<~'RUBY'
1230
- def foo(bar = (baz
1231
- nil))
1232
- end
1233
- RUBY
1234
-
1235
- assert_source <<~'RUBY'
1236
- def foo(bar = true)
1237
- bar
1238
- end
1239
- RUBY
1240
-
1241
- assert_source <<~'RUBY'
1242
- def foo(bar, baz = true)
1243
- bar
1244
- end
1245
- RUBY
1246
-
1247
- assert_source <<~'RUBY'
1248
- def foo(bar: 1)
1249
- end
1250
- RUBY
1251
-
1252
- assert_source <<~'RUBY'
1253
- def foo(bar: bar)
1254
- end
1255
- RUBY
1256
-
1257
- assert_source <<~'RUBY'
1258
- def foo(bar: bar())
1259
- end
1260
- RUBY
1261
-
1262
- assert_source <<~'RUBY'
1263
- def foo(*)
1264
- bar
1265
- end
1266
- RUBY
1267
-
1268
- assert_source <<~'RUBY'
1269
- def foo(*bar)
1270
- bar
1271
- end
1272
- RUBY
1273
-
1274
- assert_source <<~'RUBY'
1275
- def foo(bar, *baz)
1276
- bar
1277
- end
1278
- RUBY
1279
-
1280
- assert_source <<~'RUBY'
1281
- def foo(baz = true, *bor)
1282
- bar
1283
- end
1284
- RUBY
1285
-
1286
- assert_source <<~'RUBY'
1287
- def foo(baz = true, *bor, &block)
1288
- bar
1289
- end
1290
- RUBY
1291
-
1292
- assert_source <<~'RUBY'
1293
- def foo(bar, baz = true, *bor)
1294
- bar
1295
- end
1296
- RUBY
1297
-
1298
- assert_source <<~'RUBY'
1299
- def foo(&block)
1300
- bar
1301
- end
1302
- RUBY
1303
-
1304
- assert_source <<~'RUBY'
1305
- def foo(bar, &block)
1306
- bar
1307
- end
1308
- RUBY
1309
-
1310
- assert_source <<~'RUBY'
1311
- def foo
1312
- bar
1313
- baz
1314
- end
1315
- RUBY
1316
-
1317
- assert_source <<~'RUBY'
1318
- def (foo do |bar|
1319
- end).bar
1320
- bar
1321
- end
1322
- RUBY
1323
-
1324
- assert_source <<~'RUBY'
1325
- def (foo(1)).bar
1326
- bar
1327
- end
1328
- RUBY
1329
-
1330
- assert_source <<~'RUBY'
1331
- def (Foo::Bar.baz).bar
1332
- baz
1333
- end
1334
- RUBY
1335
-
1336
- assert_source <<~'RUBY'
1337
- def (Foo::Bar).bar
1338
- baz
1339
- end
1340
- RUBY
1341
-
1342
- assert_source <<~'RUBY'
1343
- def Foo.bar
1344
- baz
1345
- end
1346
- RUBY
1347
-
1348
- assert_source <<~'RUBY'
1349
- def foo.bar
1350
- baz
1351
- end
1352
- RUBY
1353
- end
1354
-
1355
- context 'on singleton' do
1356
- assert_source <<~'RUBY'
1357
- def self.foo
1358
- end
1359
- RUBY
1360
-
1361
- assert_source <<~'RUBY'
1362
- def self.foo
1363
- bar
1364
- end
1365
- RUBY
1366
-
1367
- assert_source <<~'RUBY'
1368
- def self.foo
1369
- bar
1370
- baz
1371
- end
1372
- RUBY
1373
-
1374
- assert_source <<~'RUBY'
1375
- def Foo.bar
1376
- bar
1377
- end
1378
- RUBY
1379
-
1380
- end
1381
-
1382
- context 'class' do
1383
- assert_source <<~'RUBY'
1384
- class TestClass
1385
- end
1386
- RUBY
1387
-
1388
- assert_source <<~'RUBY'
1389
- class << some_object
1390
- end
1391
- RUBY
1392
-
1393
- assert_source <<~'RUBY'
1394
- class << some_object
1395
- the_body
1396
- end
1397
- RUBY
1398
-
1399
- assert_source <<~'RUBY'
1400
- class SomeNameSpace::TestClass
1401
- end
1402
- RUBY
1403
-
1404
- assert_source <<~'RUBY'
1405
- class Some::Name::Space::TestClass
1406
- end
1407
- RUBY
1408
-
1409
- assert_source <<~'RUBY'
1410
- class TestClass < Object
1411
- end
1412
- RUBY
1413
-
1414
- assert_source <<~'RUBY'
1415
- class TestClass < SomeNameSpace::Object
1416
- end
1417
- RUBY
1418
-
1419
- assert_source <<~'RUBY'
1420
- class TestClass
1421
- def foo
1422
- :bar
1423
- end
1424
- end
1425
- RUBY
1426
-
1427
- assert_source <<~'RUBY'
1428
- class ::TestClass
1429
- end
1430
- RUBY
1431
- end
1432
-
1433
- context 'module' do
1434
-
1435
- assert_source <<~'RUBY'
1436
- module TestModule
1437
- end
1438
- RUBY
1439
-
1440
- assert_source <<~'RUBY'
1441
- module SomeNameSpace::TestModule
1442
- end
1443
- RUBY
1444
-
1445
- assert_source <<~'RUBY'
1446
- module Some::Name::Space::TestModule
1447
- end
1448
- RUBY
1449
-
1450
- assert_source <<~'RUBY'
1451
- module TestModule
1452
- def foo
1453
- :bar
1454
- end
1455
- end
1456
- RUBY
1457
-
1458
- end
1459
-
1460
- context 'op assign' do
1461
- %w(|= ||= &= &&= += -= *= /= **= %=).each do |op|
1462
- assert_source "self.foo #{op} bar"
1463
- assert_source "foo[key] #{op} bar"
1464
- assert_source "a #{op} (true\nfalse)"
1465
- end
1466
- end
1467
-
1468
- context 'element assignment' do
1469
- assert_source 'foo[index] = value'
1470
- assert_source 'foo[*index] = value'
1471
- assert_source 'foo[a, b] = value'
1472
- assert_source 'foo[1..2] = value'
1473
- assert_source 'foo.[]=()'
1474
- assert_source 'foo.[]=true'
1475
- assert_source 'foo.[]=(1, 2)'
1476
- assert_source 'foo[] = 1'
1477
- assert_unterminated 'foo[] = 1'
1478
-
1479
- %w(+ - * / % & | || &&).each do |operator|
1480
- context "with #{operator}" do
1481
- assert_source "foo[index] #{operator}= 2"
1482
- assert_source "foo[] #{operator}= 2"
1483
- end
1484
- end
1485
- end
1486
-
1487
- context 'defined?' do
1488
- assert_source <<~'RUBY'
1489
- defined?(@foo)
1490
- RUBY
1491
-
1492
- assert_source <<~'RUBY'
1493
- defined?(Foo)
1494
- RUBY
1495
-
1496
- assert_source <<~'RUBY'
1497
- defined?((a, b = [1, 2]))
1498
- RUBY
1499
- end
1500
- end
1501
-
1502
- context 'lambda' do
1503
- assert_source <<~'RUBY'
1504
- lambda do
1505
- end
1506
- RUBY
1507
-
1508
- assert_source <<~'RUBY'
1509
- lambda do |a, b|
1510
- a
1511
- end
1512
- RUBY
1513
-
1514
- assert_source <<~'RUBY'
1515
- ->() do
1516
- end
1517
- RUBY
1518
-
1519
- assert_source <<~'RUBY'
1520
- ->(a) do
1521
- end
1522
- RUBY
1523
-
1524
- assert_source <<~'RUBY'
1525
- ->(a, b) do
1526
- end
1527
- RUBY
1528
- end
1529
-
1530
- context 'match operators' do
1531
- assert_source '/bar/ =~ foo'
1532
- assert_source '/bar/ =~ :foo'
1533
- assert_source '(/bar/ =~ :foo).foo'
1534
- assert_source 'foo =~ /bar/'
1535
- assert_source 'foo(foo =~ /bar/)'
1536
- assert_source '(foo =~ /bar/).foo'
1537
- end
1538
-
1539
- context 'binary operator methods' do
1540
- %w(+ - * / & | << >> == === != <= < <=> > >= =~ !~ ^ **).each do |operator|
1541
- assert_source "(-1) #{operator} 2"
1542
- assert_source "(-1.2) #{operator} 2"
1543
- assert_source "left.#{operator}(*foo)"
1544
- assert_source "left.#{operator}(a, b)"
1545
- assert_source "self #{operator} b"
1546
- assert_source "a #{operator} b"
1547
- assert_source "(a #{operator} b).foo"
1548
- end
1549
-
1550
- assert_source 'left / right'
1551
- end
1552
-
1553
- context 'nested binary operators' do
1554
- assert_source '(a + b) / (c - d)'
1555
- assert_source '(a + b) / c.-(e, f)'
1556
- assert_source '(a + b) / c.-(*f)'
1557
- end
1558
-
1559
- context 'binary operator' do
1560
- assert_source 'a || (return foo)'
1561
- assert_source '(return foo) || a'
1562
- assert_source 'a || (break foo)'
1563
- assert_source '(break foo) || a'
1564
- assert_source '(a || b).foo'
1565
- assert_source 'a || (b || c)'
1566
- end
1567
-
1568
- { or: :'||', and: :'&&' }.each do |word, symbol|
1569
- assert_generates "a #{word} return foo", "a #{symbol} (return foo)"
1570
- assert_generates "a #{word} break foo", "a #{symbol} (break foo)"
1571
- assert_generates "a #{word} next foo", "a #{symbol} (next foo)"
1572
- end
1573
-
1574
- context 'expansion of shortcuts' do
1575
- assert_source 'a += 2'
1576
- assert_source 'a -= 2'
1577
- assert_source 'a **= 2'
1578
- assert_source 'a *= 2'
1579
- assert_source 'a /= 2'
1580
- end
1581
-
1582
- context 'shortcuts' do
1583
- assert_source 'a &&= b'
1584
- assert_source 'a ||= 2'
1585
- assert_source '(a ||= 2).bar'
1586
- assert_source '(h ||= {})[k] = v'
1587
- end
1588
-
1589
- context 'flip flops' do
1590
- context 'inclusive' do
1591
- assert_source <<~'RUBY'
1592
- if ((i == 4)..(i == 4))
1593
- foo
1594
- end
1595
- RUBY
1596
- end
1597
-
1598
- context 'exclusive' do
1599
- assert_source <<~'RUBY'
1600
- if ((i == 4)...(i == 4))
1601
- foo
1602
- end
1603
- RUBY
1604
- end
1605
- end
1606
-
1607
- context 'case statement' do
1608
- assert_source <<~'RUBY'
1609
- case
1610
- when bar
1611
- baz
1612
- when baz
1613
- bar
1614
- end
1615
- RUBY
1616
-
1617
- assert_source <<~'RUBY'
1618
- case foo
1619
- when bar
1620
- when baz
1621
- bar
1622
- end
1623
- RUBY
1624
-
1625
- assert_source <<~'RUBY'
1626
- case foo
1627
- when bar
1628
- baz
1629
- when baz
1630
- bar
1631
- end
1632
- RUBY
1633
-
1634
- assert_source <<~'RUBY'
1635
- case foo
1636
- when bar, baz
1637
- :other
1638
- end
1639
- RUBY
1640
-
1641
- assert_source <<~'RUBY'
1642
- case foo
1643
- when *bar
1644
- :value
1645
- end
1646
- RUBY
1647
-
1648
- assert_source <<~'RUBY'
1649
- case foo
1650
- when bar
1651
- baz
1652
- else
1653
- :foo
1654
- end
1655
- RUBY
1656
- end
1657
-
1658
- context 'for' do
1659
- assert_source <<~'RUBY'
1660
- bar(for a in bar do
1661
- baz
1662
- end)
1663
- RUBY
1664
- assert_source <<~'RUBY'
1665
- for a in bar do
1666
- baz
1667
- end
1668
- RUBY
1669
-
1670
- assert_source <<~'RUBY'
1671
- for a, *b in bar do
1672
- baz
1673
- end
1674
- RUBY
1675
-
1676
- assert_source <<~'RUBY'
1677
- for a, b in bar do
1678
- baz
1679
- end
1680
- RUBY
1681
- end
1682
-
1683
- context 'unary operators' do
1684
- assert_source '!1'
1685
- assert_source '!(!1)'
1686
- assert_source '!(!(foo || bar))'
1687
- assert_source '!(!1).baz'
1688
- assert_source '~a'
1689
- assert_source '-a'
1690
- assert_source '+a'
1691
- assert_source '-(-a).foo'
1692
- end
1693
-
1694
- context 'loop' do
1695
- assert_source <<~'RUBY'
1696
- loop do
1697
- foo
1698
- end
1699
- RUBY
1700
- end
1701
-
1702
- context 'post conditions' do
1703
- assert_source <<~'RUBY'
1704
- x = (begin
1705
- foo
1706
- end while baz)
1707
- RUBY
1708
-
1709
- assert_source <<~'RUBY'
1710
- begin
1711
- foo
1712
- end while baz
1713
- RUBY
1714
-
1715
- assert_source <<~'RUBY'
1716
- begin
1717
- foo
1718
- bar
1719
- end until baz
1720
- RUBY
1721
-
1722
- assert_source <<~'RUBY'
1723
- begin
1724
- foo
1725
- bar
1726
- end while baz
1727
- RUBY
1728
- end
1729
-
1730
- context 'while' do
1731
- assert_source <<~'RUBY'
1732
- while false
1733
- end
1734
- RUBY
1735
-
1736
- assert_source <<~'RUBY'
1737
- while false
1738
- 3
1739
- end
1740
- RUBY
1741
-
1742
- assert_source <<~'RUBY'
1743
- while (foo do
1744
- end)
1745
- :body
1746
- end
1747
- RUBY
1748
- end
1749
-
1750
- context 'until' do
1751
- assert_source <<~'RUBY'
1752
- until false
1753
- end
1754
- RUBY
1755
-
1756
- assert_source <<~'RUBY'
1757
- until false
1758
- 3
1759
- end
1760
- RUBY
1761
-
1762
- assert_source <<~'RUBY'
1763
- until (foo do
1764
- end)
1765
- :body
1766
- end
1767
- RUBY
1768
- end
1769
-
1770
- assert_source <<~'RUBY'
1771
- # comment before
1772
- a_line_of_code
1773
- RUBY
1774
-
1775
- assert_source <<~'RUBY'
1776
- a_line_of_code # comment after
1777
- RUBY
1778
-
1779
- assert_source <<~'RUBY'
1780
- nested do # first
1781
- # second
1782
- something # comment
1783
- # another
1784
- end
1785
- # last
1786
- RUBY
1787
-
1788
- assert_generates <<~'RUBY', <<~'RUBY'
1789
- foo if bar
1790
- # comment
1791
- RUBY
1792
- if bar
1793
- foo
1794
- end
1795
- # comment
1796
- RUBY
1797
-
1798
- assert_source <<~'RUBY'
1799
- def noop
1800
- # do nothing
1801
- end
1802
- RUBY
1803
-
1804
- assert_source <<~'RUBY'
1805
- =begin
1806
- block comment
1807
- =end
1808
- nested do
1809
- =begin
1810
- another block comment
1811
- =end
1812
- something
1813
- =begin
1814
- last block comment
1815
- =end
1816
- end
1817
- RUBY
1818
-
1819
- assert_generates(<<~'RUBY', <<~'RUBY')
1820
- 1 + # first
1821
- 2 # second
1822
- RUBY
1823
- 1 + 2 # first # second
1824
- RUBY
1825
-
1826
- assert_generates(<<~'RUBY', <<~'RUBY')
1827
- 1 +
1828
- # first
1829
- 2 # second
1830
- RUBY
1831
- 1 + 2 # first # second
1832
- RUBY
1833
-
1834
- assert_generates(<<~'RUBY', <<~'RUBY')
1835
- 1 +
1836
- =begin
1837
- block comment
1838
- =end
1839
- 2
1840
- RUBY
1841
- 1 + 2
1842
- =begin
1843
- block comment
1844
- =end
1845
- RUBY
1846
- end
1847
- end