unparser 0.4.5 → 0.5.0

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 -3
  3. data/bin/unparser +1 -1
  4. data/lib/unparser.rb +117 -62
  5. data/lib/unparser/ast.rb +1 -2
  6. data/lib/unparser/ast/local_variable_scope.rb +9 -79
  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 +25 -428
  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 +17 -179
  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 +49 -8
  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 +229 -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 +152 -101
  88. data/.circleci/config.yml +0 -41
  89. data/.gitignore +0 -37
  90. data/.rspec +0 -4
  91. data/.rubocop.yml +0 -9
  92. data/Changelog.md +0 -146
  93. data/Gemfile +0 -11
  94. data/Gemfile.lock +0 -180
  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 -87
  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 -1841
  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,1841 +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)|
552
- d
553
- end
554
- RUBY
555
-
556
- assert_source <<~'RUBY'
557
- foo.bar do |(a, b), c|
558
- d
559
- end
560
- RUBY
561
-
562
- assert_source <<~'RUBY'
563
- foo.bar do |*a; b|
564
- end
565
- RUBY
566
-
567
- assert_source <<~'RUBY'
568
- foo.bar do |a; b|
569
- end
570
- RUBY
571
-
572
- assert_source <<~'RUBY'
573
- foo.bar do |; a, b|
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 |(a, (*))|
585
- d
586
- end
587
- RUBY
588
-
589
- assert_source <<~'RUBY'
590
- foo.bar do |(a, b)|
591
- d
592
- end
593
- RUBY
594
-
595
- assert_source <<~'RUBY'
596
- foo.bar do
597
- end.baz
598
- RUBY
599
-
600
- assert_source <<~'RUBY'
601
- FOO()
602
- RUBY
603
-
604
- assert_terminated '(1..2).max'
605
- assert_terminated '1..2.max'
606
- assert_unterminated 'a || return'
607
- assert_unterminated 'foo << (bar * baz)'
608
-
609
- assert_source <<~'RUBY'
610
- foo ||= (a, _ = b)
611
- RUBY
612
-
613
- assert_source <<~'RUBY'
614
- begin
615
- rescue
616
- end.bar
617
- RUBY
618
-
619
- assert_source <<~'RUBY'
620
- case (def foo
621
- end
622
- :bar)
623
- when bar
624
- end.baz
625
- RUBY
626
-
627
- assert_source <<~'RUBY'
628
- case foo
629
- when bar
630
- end.baz
631
- RUBY
632
-
633
- assert_source <<~'RUBY'
634
- class << self
635
- end.bar
636
- RUBY
637
-
638
- assert_source <<~'RUBY'
639
- def self.foo
640
- end.bar
641
- RUBY
642
-
643
- assert_source <<~'RUBY'
644
- def foo
645
- end.bar
646
- RUBY
647
-
648
- assert_source <<~'RUBY'
649
- until foo
650
- end.bar
651
- RUBY
652
-
653
- assert_source <<~'RUBY'
654
- while foo
655
- end.bar
656
- RUBY
657
-
658
- assert_source <<~'RUBY'
659
- loop do
660
- end.bar
661
- RUBY
662
-
663
- assert_source <<~'RUBY'
664
- class Foo
665
- end.bar
666
- RUBY
667
-
668
- assert_source <<~'RUBY'
669
- module Foo
670
- end.bar
671
- RUBY
672
-
673
- assert_source <<~'RUBY'
674
- if foo
675
- end.baz
676
- RUBY
677
-
678
- assert_source <<~'RUBY'
679
- local = 1
680
- local.bar
681
- RUBY
682
-
683
- assert_terminated 'foo.bar(*args)'
684
- assert_terminated 'foo.bar(*arga, foo, *argb)'
685
- assert_terminated 'foo.bar(*args, foo)'
686
- assert_terminated 'foo.bar(foo, *args)'
687
- assert_terminated 'foo.bar(foo, *args, &block)'
688
- assert_source <<~'RUBY'
689
- foo(bar, *args)
690
- RUBY
691
-
692
- assert_terminated 'foo(*args, &block)'
693
- assert_terminated 'foo.bar(&baz)'
694
- assert_terminated 'foo.bar(:baz, &baz)'
695
- assert_terminated 'foo.bar=:baz'
696
-
697
- assert_unterminated 'self.foo=:bar'
698
-
699
- assert_terminated 'foo.bar(baz: boz)'
700
- assert_terminated 'foo.bar(foo, "baz" => boz)'
701
- assert_terminated 'foo.bar({ foo: boz }, boz)'
702
- assert_terminated 'foo.bar(foo, {})'
703
- end
704
-
705
- context 'begin; end' do
706
- assert_generates s(:begin), ''
707
-
708
- assert_source <<~'RUBY'
709
- begin
710
- end
711
- RUBY
712
-
713
- assert_source <<~'RUBY'
714
- foo
715
- bar
716
- RUBY
717
-
718
- assert_source <<~'RUBY'
719
- begin
720
- foo
721
- bar
722
- end.blah
723
- RUBY
724
- end
725
-
726
- context 'begin / rescue / ensure' do
727
- assert_source <<~'RUBY'
728
- begin
729
- foo
730
- ensure
731
- bar
732
- baz
733
- end
734
- RUBY
735
-
736
- assert_source <<~'RUBY'
737
- begin
738
- foo
739
- rescue
740
- baz
741
- end
742
- RUBY
743
-
744
- assert_source <<~'RUBY'
745
- begin
746
- begin
747
- foo
748
- bar
749
- rescue
750
- end
751
- rescue
752
- baz
753
- bar
754
- end
755
- RUBY
756
-
757
- assert_source <<~'RUBY'
758
- begin
759
- raise(Exception) rescue foo = bar
760
- rescue Exception
761
- end
762
- RUBY
763
-
764
- assert_source <<~'RUBY'
765
- begin
766
- foo
767
- bar
768
- rescue
769
- baz
770
- bar
771
- end
772
- RUBY
773
-
774
- assert_source <<~'RUBY'
775
- begin
776
- foo
777
- rescue Exception
778
- bar
779
- end
780
- RUBY
781
-
782
- assert_source <<~'RUBY'
783
- begin
784
- foo
785
- rescue => bar
786
- bar
787
- end
788
- RUBY
789
-
790
- assert_source <<~'RUBY'
791
- begin
792
- foo
793
- rescue Exception, Other => bar
794
- bar
795
- end
796
- RUBY
797
-
798
- assert_source <<~'RUBY'
799
- class << self
800
- undef :bar rescue nil
801
- end
802
- RUBY
803
-
804
- assert_source <<~'RUBY'
805
- module Foo
806
- undef :bar rescue nil
807
- end
808
- RUBY
809
-
810
- assert_source <<~'RUBY'
811
- class Foo
812
- undef :bar rescue nil
813
- end
814
- RUBY
815
-
816
- assert_source <<~'RUBY'
817
- begin
818
- rescue Exception => e
819
- end
820
- RUBY
821
-
822
- assert_source <<~'RUBY'
823
- begin
824
- ensure
825
- end
826
- RUBY
827
-
828
- assert_source <<~'RUBY'
829
- begin
830
- rescue
831
- ensure
832
- end
833
- RUBY
834
-
835
- assert_source <<~'RUBY'
836
- begin
837
- foo
838
- rescue Exception => bar
839
- bar
840
- end
841
- RUBY
842
-
843
- assert_source <<~'RUBY'
844
- begin
845
- bar
846
- rescue SomeError, *bar
847
- baz
848
- end
849
- RUBY
850
-
851
- assert_source <<~'RUBY'
852
- begin
853
- bar
854
- rescue SomeError, *bar => exception
855
- baz
856
- end
857
- RUBY
858
-
859
- assert_source <<~'RUBY'
860
- begin
861
- bar
862
- rescue *bar
863
- baz
864
- end
865
- RUBY
866
-
867
- assert_source <<~'RUBY'
868
- begin
869
- bar
870
- rescue LoadError
871
- end
872
- RUBY
873
-
874
- assert_source <<~'RUBY'
875
- begin
876
- bar
877
- rescue
878
- else
879
- baz
880
- end
881
- RUBY
882
-
883
- assert_source <<~'RUBY'
884
- begin
885
- bar
886
- rescue *bar => exception
887
- baz
888
- end
889
- RUBY
890
-
891
- assert_source <<~'RUBY'
892
- m do
893
- rescue Exception => e
894
- end
895
- RUBY
896
-
897
- assert_source <<~'RUBY'
898
- m do
899
- ensure
900
- end
901
- RUBY
902
-
903
- assert_source <<~'RUBY'
904
- m do
905
- rescue
906
- ensure
907
- end
908
- RUBY
909
-
910
- assert_source <<~'RUBY'
911
- m do
912
- foo
913
- rescue Exception => bar
914
- bar
915
- end
916
- RUBY
917
-
918
- assert_source <<~'RUBY'
919
- m do
920
- bar
921
- rescue SomeError, *bar
922
- baz
923
- end
924
- RUBY
925
-
926
- assert_source <<~'RUBY'
927
- m do
928
- bar
929
- rescue SomeError, *bar => exception
930
- baz
931
- end
932
- RUBY
933
-
934
- assert_source <<~'RUBY'
935
- m do
936
- bar
937
- rescue *bar
938
- baz
939
- end
940
- RUBY
941
-
942
- assert_source <<~'RUBY'
943
- m do
944
- bar
945
- rescue LoadError
946
- end
947
- RUBY
948
-
949
- assert_source <<~'RUBY'
950
- m do
951
- bar
952
- rescue
953
- else
954
- baz
955
- end
956
- RUBY
957
-
958
- assert_source <<~'RUBY'
959
- m do
960
- bar
961
- rescue *bar => exception
962
- baz
963
- end
964
- RUBY
965
-
966
- assert_source 'foo rescue bar'
967
- assert_source 'foo rescue return bar'
968
- assert_source 'x = (foo rescue return bar)'
969
-
970
- %w(while until if).each do |keyword|
971
- assert_source <<~RUBY
972
- #{keyword} (
973
- foo rescue false
974
- )
975
- end
976
- RUBY
977
-
978
- assert_generates <<~RUBY, <<~GENERATED
979
- foo rescue false #{keyword} true
980
- RUBY
981
- #{keyword} true
982
- foo rescue false
983
- end
984
- GENERATED
985
- end
986
-
987
- assert_generates <<~'RUBY', <<~GENERATED
988
- case (foo rescue false)
989
- when true
990
- end
991
- RUBY
992
- case (
993
- foo rescue false
994
- )
995
- when true
996
- end
997
- GENERATED
998
- end
999
-
1000
- context 'super' do
1001
- assert_source 'super'
1002
-
1003
- assert_source 'super()'
1004
- assert_source 'super(a)'
1005
- assert_source 'super(a, b)'
1006
- assert_source 'super(&block)'
1007
- assert_source 'super(a, &block)'
1008
-
1009
- assert_source <<~'RUBY'
1010
- super(a do
1011
- foo
1012
- end)
1013
- RUBY
1014
-
1015
- assert_source <<~'RUBY'
1016
- super do
1017
- foo
1018
- end
1019
- RUBY
1020
-
1021
- assert_source <<~'RUBY'
1022
- super(a) do
1023
- foo
1024
- end
1025
- RUBY
1026
-
1027
- assert_source <<~'RUBY'
1028
- super() do
1029
- foo
1030
- end
1031
- RUBY
1032
-
1033
- assert_source <<~'RUBY'
1034
- super(a, b) do
1035
- foo
1036
- end
1037
- RUBY
1038
-
1039
- end
1040
-
1041
- context 'undef' do
1042
- assert_source 'undef :foo'
1043
- assert_source 'undef :foo, :bar'
1044
- end
1045
-
1046
- context 'BEGIN' do
1047
- assert_source <<~'RUBY'
1048
- BEGIN {
1049
- foo
1050
- }
1051
- RUBY
1052
- end
1053
-
1054
- context 'END' do
1055
- assert_source <<~'RUBY'
1056
- END {
1057
- foo
1058
- }
1059
- RUBY
1060
- end
1061
-
1062
- context 'alias' do
1063
- assert_source <<~'RUBY'
1064
- alias $foo $bar
1065
- RUBY
1066
-
1067
- assert_source <<~'RUBY'
1068
- alias :foo :bar
1069
- RUBY
1070
- end
1071
-
1072
- context 'yield' do
1073
- context 'without arguments' do
1074
- assert_source 'yield'
1075
- end
1076
-
1077
- context 'with argument' do
1078
- assert_source 'yield(a)'
1079
- end
1080
-
1081
- context 'with arguments' do
1082
- assert_source 'yield(a, b)'
1083
- end
1084
- end
1085
-
1086
- context 'if statement' do
1087
- assert_source <<~'RUBY'
1088
- if /foo/
1089
- bar
1090
- end
1091
- RUBY
1092
-
1093
- assert_source <<~'RUBY'
1094
- if 3
1095
- 9
1096
- end
1097
- RUBY
1098
-
1099
- assert_source <<~'RUBY'
1100
- if 4
1101
- 5
1102
- else
1103
- 6
1104
- end
1105
- RUBY
1106
-
1107
- assert_source <<~'RUBY'
1108
- unless 3
1109
- nil
1110
- end
1111
- RUBY
1112
-
1113
- assert_source <<~'RUBY'
1114
- unless 3
1115
- 9
1116
- end
1117
- RUBY
1118
-
1119
- assert_source <<~'RUBY'
1120
- if foo
1121
- end
1122
- RUBY
1123
-
1124
- assert_source <<~'RUBY'
1125
- foo = bar if foo
1126
- RUBY
1127
-
1128
- assert_source <<~'RUBY'
1129
- foo = bar unless foo
1130
- RUBY
1131
-
1132
- assert_source <<~'RUBY'
1133
- def foo(*foo)
1134
- unless foo
1135
- foo = bar
1136
- end
1137
- end
1138
- RUBY
1139
-
1140
- assert_source <<~'RUBY'
1141
- each do |foo|
1142
- unless foo
1143
- foo = bar
1144
- end
1145
- end
1146
- RUBY
1147
- end
1148
-
1149
- context 'def' do
1150
- context 'on instance' do
1151
-
1152
- assert_source <<~'RUBY'
1153
- def foo
1154
- end
1155
- RUBY
1156
-
1157
- assert_source <<~'RUBY'
1158
- def foo
1159
- bar
1160
- end
1161
- RUBY
1162
-
1163
- assert_source <<~'RUBY'
1164
- def foo
1165
- foo
1166
- rescue
1167
- bar
1168
- ensure
1169
- baz
1170
- end
1171
- RUBY
1172
-
1173
- assert_source <<~'RUBY'
1174
- begin
1175
- foo
1176
- ensure
1177
- bar rescue nil
1178
- end
1179
- RUBY
1180
-
1181
- assert_source <<~'RUBY'
1182
- def foo
1183
- bar
1184
- ensure
1185
- baz
1186
- end
1187
- RUBY
1188
-
1189
- assert_source <<~'RUBY'
1190
- def self.foo
1191
- bar
1192
- rescue
1193
- baz
1194
- end
1195
- RUBY
1196
-
1197
- assert_source <<~'RUBY'
1198
- def foo
1199
- bar
1200
- rescue
1201
- baz
1202
- end
1203
- RUBY
1204
-
1205
- assert_source <<~'RUBY'
1206
- def foo(bar)
1207
- bar
1208
- end
1209
- RUBY
1210
-
1211
- assert_source <<~'RUBY'
1212
- def foo(bar, baz)
1213
- bar
1214
- end
1215
- RUBY
1216
-
1217
- assert_source <<~'RUBY'
1218
- def foo(bar = ())
1219
- bar
1220
- end
1221
- RUBY
1222
-
1223
- assert_source <<~'RUBY'
1224
- def foo(bar = (baz
1225
- nil))
1226
- end
1227
- RUBY
1228
-
1229
- assert_source <<~'RUBY'
1230
- def foo(bar = true)
1231
- bar
1232
- end
1233
- RUBY
1234
-
1235
- assert_source <<~'RUBY'
1236
- def foo(bar, baz = true)
1237
- bar
1238
- end
1239
- RUBY
1240
-
1241
- assert_source <<~'RUBY'
1242
- def foo(bar: 1)
1243
- end
1244
- RUBY
1245
-
1246
- assert_source <<~'RUBY'
1247
- def foo(bar: bar)
1248
- end
1249
- RUBY
1250
-
1251
- assert_source <<~'RUBY'
1252
- def foo(bar: bar())
1253
- end
1254
- RUBY
1255
-
1256
- assert_source <<~'RUBY'
1257
- def foo(*)
1258
- bar
1259
- end
1260
- RUBY
1261
-
1262
- assert_source <<~'RUBY'
1263
- def foo(*bar)
1264
- bar
1265
- end
1266
- RUBY
1267
-
1268
- assert_source <<~'RUBY'
1269
- def foo(bar, *baz)
1270
- bar
1271
- end
1272
- RUBY
1273
-
1274
- assert_source <<~'RUBY'
1275
- def foo(baz = true, *bor)
1276
- bar
1277
- end
1278
- RUBY
1279
-
1280
- assert_source <<~'RUBY'
1281
- def foo(baz = true, *bor, &block)
1282
- bar
1283
- end
1284
- RUBY
1285
-
1286
- assert_source <<~'RUBY'
1287
- def foo(bar, baz = true, *bor)
1288
- bar
1289
- end
1290
- RUBY
1291
-
1292
- assert_source <<~'RUBY'
1293
- def foo(&block)
1294
- bar
1295
- end
1296
- RUBY
1297
-
1298
- assert_source <<~'RUBY'
1299
- def foo(bar, &block)
1300
- bar
1301
- end
1302
- RUBY
1303
-
1304
- assert_source <<~'RUBY'
1305
- def foo
1306
- bar
1307
- baz
1308
- end
1309
- RUBY
1310
-
1311
- assert_source <<~'RUBY'
1312
- def (foo do |bar|
1313
- end).bar
1314
- bar
1315
- end
1316
- RUBY
1317
-
1318
- assert_source <<~'RUBY'
1319
- def (foo(1)).bar
1320
- bar
1321
- end
1322
- RUBY
1323
-
1324
- assert_source <<~'RUBY'
1325
- def (Foo::Bar.baz).bar
1326
- baz
1327
- end
1328
- RUBY
1329
-
1330
- assert_source <<~'RUBY'
1331
- def (Foo::Bar).bar
1332
- baz
1333
- end
1334
- RUBY
1335
-
1336
- assert_source <<~'RUBY'
1337
- def Foo.bar
1338
- baz
1339
- end
1340
- RUBY
1341
-
1342
- assert_source <<~'RUBY'
1343
- def foo.bar
1344
- baz
1345
- end
1346
- RUBY
1347
- end
1348
-
1349
- context 'on singleton' do
1350
- assert_source <<~'RUBY'
1351
- def self.foo
1352
- end
1353
- RUBY
1354
-
1355
- assert_source <<~'RUBY'
1356
- def self.foo
1357
- bar
1358
- end
1359
- RUBY
1360
-
1361
- assert_source <<~'RUBY'
1362
- def self.foo
1363
- bar
1364
- baz
1365
- end
1366
- RUBY
1367
-
1368
- assert_source <<~'RUBY'
1369
- def Foo.bar
1370
- bar
1371
- end
1372
- RUBY
1373
-
1374
- end
1375
-
1376
- context 'class' do
1377
- assert_source <<~'RUBY'
1378
- class TestClass
1379
- end
1380
- RUBY
1381
-
1382
- assert_source <<~'RUBY'
1383
- class << some_object
1384
- end
1385
- RUBY
1386
-
1387
- assert_source <<~'RUBY'
1388
- class << some_object
1389
- the_body
1390
- end
1391
- RUBY
1392
-
1393
- assert_source <<~'RUBY'
1394
- class SomeNameSpace::TestClass
1395
- end
1396
- RUBY
1397
-
1398
- assert_source <<~'RUBY'
1399
- class Some::Name::Space::TestClass
1400
- end
1401
- RUBY
1402
-
1403
- assert_source <<~'RUBY'
1404
- class TestClass < Object
1405
- end
1406
- RUBY
1407
-
1408
- assert_source <<~'RUBY'
1409
- class TestClass < SomeNameSpace::Object
1410
- end
1411
- RUBY
1412
-
1413
- assert_source <<~'RUBY'
1414
- class TestClass
1415
- def foo
1416
- :bar
1417
- end
1418
- end
1419
- RUBY
1420
-
1421
- assert_source <<~'RUBY'
1422
- class ::TestClass
1423
- end
1424
- RUBY
1425
- end
1426
-
1427
- context 'module' do
1428
-
1429
- assert_source <<~'RUBY'
1430
- module TestModule
1431
- end
1432
- RUBY
1433
-
1434
- assert_source <<~'RUBY'
1435
- module SomeNameSpace::TestModule
1436
- end
1437
- RUBY
1438
-
1439
- assert_source <<~'RUBY'
1440
- module Some::Name::Space::TestModule
1441
- end
1442
- RUBY
1443
-
1444
- assert_source <<~'RUBY'
1445
- module TestModule
1446
- def foo
1447
- :bar
1448
- end
1449
- end
1450
- RUBY
1451
-
1452
- end
1453
-
1454
- context 'op assign' do
1455
- %w(|= ||= &= &&= += -= *= /= **= %=).each do |op|
1456
- assert_source "self.foo #{op} bar"
1457
- assert_source "foo[key] #{op} bar"
1458
- assert_source "a #{op} (true\nfalse)"
1459
- end
1460
- end
1461
-
1462
- context 'element assignment' do
1463
- assert_source 'foo[index] = value'
1464
- assert_source 'foo[*index] = value'
1465
- assert_source 'foo[a, b] = value'
1466
- assert_source 'foo[1..2] = value'
1467
- assert_source 'foo.[]=()'
1468
- assert_source 'foo.[]=true'
1469
- assert_source 'foo.[]=(1, 2)'
1470
- assert_source 'foo[] = 1'
1471
- assert_unterminated 'foo[] = 1'
1472
-
1473
- %w(+ - * / % & | || &&).each do |operator|
1474
- context "with #{operator}" do
1475
- assert_source "foo[index] #{operator}= 2"
1476
- assert_source "foo[] #{operator}= 2"
1477
- end
1478
- end
1479
- end
1480
-
1481
- context 'defined?' do
1482
- assert_source <<~'RUBY'
1483
- defined?(@foo)
1484
- RUBY
1485
-
1486
- assert_source <<~'RUBY'
1487
- defined?(Foo)
1488
- RUBY
1489
-
1490
- assert_source <<~'RUBY'
1491
- defined?((a, b = [1, 2]))
1492
- RUBY
1493
- end
1494
- end
1495
-
1496
- context 'lambda' do
1497
- assert_source <<~'RUBY'
1498
- lambda do
1499
- end
1500
- RUBY
1501
-
1502
- assert_source <<~'RUBY'
1503
- lambda do |a, b|
1504
- a
1505
- end
1506
- RUBY
1507
-
1508
- assert_source <<~'RUBY'
1509
- ->() do
1510
- end
1511
- RUBY
1512
-
1513
- assert_source <<~'RUBY'
1514
- ->(a) do
1515
- end
1516
- RUBY
1517
-
1518
- assert_source <<~'RUBY'
1519
- ->(a, b) do
1520
- end
1521
- RUBY
1522
- end
1523
-
1524
- context 'match operators' do
1525
- assert_source '/bar/ =~ foo'
1526
- assert_source '/bar/ =~ :foo'
1527
- assert_source '(/bar/ =~ :foo).foo'
1528
- assert_source 'foo =~ /bar/'
1529
- assert_source 'foo(foo =~ /bar/)'
1530
- assert_source '(foo =~ /bar/).foo'
1531
- end
1532
-
1533
- context 'binary operator methods' do
1534
- %w(+ - * / & | << >> == === != <= < <=> > >= =~ !~ ^ **).each do |operator|
1535
- assert_source "(-1) #{operator} 2"
1536
- assert_source "(-1.2) #{operator} 2"
1537
- assert_source "left.#{operator}(*foo)"
1538
- assert_source "left.#{operator}(a, b)"
1539
- assert_source "self #{operator} b"
1540
- assert_source "a #{operator} b"
1541
- assert_source "(a #{operator} b).foo"
1542
- end
1543
-
1544
- assert_source 'left / right'
1545
- end
1546
-
1547
- context 'nested binary operators' do
1548
- assert_source '(a + b) / (c - d)'
1549
- assert_source '(a + b) / c.-(e, f)'
1550
- assert_source '(a + b) / c.-(*f)'
1551
- end
1552
-
1553
- context 'binary operator' do
1554
- assert_source 'a || (return foo)'
1555
- assert_source '(return foo) || a'
1556
- assert_source 'a || (break foo)'
1557
- assert_source '(break foo) || a'
1558
- assert_source '(a || b).foo'
1559
- assert_source 'a || (b || c)'
1560
- end
1561
-
1562
- { or: :'||', and: :'&&' }.each do |word, symbol|
1563
- assert_generates "a #{word} return foo", "a #{symbol} (return foo)"
1564
- assert_generates "a #{word} break foo", "a #{symbol} (break foo)"
1565
- assert_generates "a #{word} next foo", "a #{symbol} (next foo)"
1566
- end
1567
-
1568
- context 'expansion of shortcuts' do
1569
- assert_source 'a += 2'
1570
- assert_source 'a -= 2'
1571
- assert_source 'a **= 2'
1572
- assert_source 'a *= 2'
1573
- assert_source 'a /= 2'
1574
- end
1575
-
1576
- context 'shortcuts' do
1577
- assert_source 'a &&= b'
1578
- assert_source 'a ||= 2'
1579
- assert_source '(a ||= 2).bar'
1580
- assert_source '(h ||= {})[k] = v'
1581
- end
1582
-
1583
- context 'flip flops' do
1584
- context 'inclusive' do
1585
- assert_source <<~'RUBY'
1586
- if ((i == 4)..(i == 4))
1587
- foo
1588
- end
1589
- RUBY
1590
- end
1591
-
1592
- context 'exclusive' do
1593
- assert_source <<~'RUBY'
1594
- if ((i == 4)...(i == 4))
1595
- foo
1596
- end
1597
- RUBY
1598
- end
1599
- end
1600
-
1601
- context 'case statement' do
1602
- assert_source <<~'RUBY'
1603
- case
1604
- when bar
1605
- baz
1606
- when baz
1607
- bar
1608
- end
1609
- RUBY
1610
-
1611
- assert_source <<~'RUBY'
1612
- case foo
1613
- when bar
1614
- when baz
1615
- bar
1616
- end
1617
- RUBY
1618
-
1619
- assert_source <<~'RUBY'
1620
- case foo
1621
- when bar
1622
- baz
1623
- when baz
1624
- bar
1625
- end
1626
- RUBY
1627
-
1628
- assert_source <<~'RUBY'
1629
- case foo
1630
- when bar, baz
1631
- :other
1632
- end
1633
- RUBY
1634
-
1635
- assert_source <<~'RUBY'
1636
- case foo
1637
- when *bar
1638
- :value
1639
- end
1640
- RUBY
1641
-
1642
- assert_source <<~'RUBY'
1643
- case foo
1644
- when bar
1645
- baz
1646
- else
1647
- :foo
1648
- end
1649
- RUBY
1650
- end
1651
-
1652
- context 'for' do
1653
- assert_source <<~'RUBY'
1654
- bar(for a in bar do
1655
- baz
1656
- end)
1657
- RUBY
1658
- assert_source <<~'RUBY'
1659
- for a in bar do
1660
- baz
1661
- end
1662
- RUBY
1663
-
1664
- assert_source <<~'RUBY'
1665
- for a, *b 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
- end
1676
-
1677
- context 'unary operators' do
1678
- assert_source '!1'
1679
- assert_source '!(!1)'
1680
- assert_source '!(!(foo || bar))'
1681
- assert_source '!(!1).baz'
1682
- assert_source '~a'
1683
- assert_source '-a'
1684
- assert_source '+a'
1685
- assert_source '-(-a).foo'
1686
- end
1687
-
1688
- context 'loop' do
1689
- assert_source <<~'RUBY'
1690
- loop do
1691
- foo
1692
- end
1693
- RUBY
1694
- end
1695
-
1696
- context 'post conditions' do
1697
- assert_source <<~'RUBY'
1698
- x = (begin
1699
- foo
1700
- end while baz)
1701
- RUBY
1702
-
1703
- assert_source <<~'RUBY'
1704
- begin
1705
- foo
1706
- end while baz
1707
- RUBY
1708
-
1709
- assert_source <<~'RUBY'
1710
- begin
1711
- foo
1712
- bar
1713
- end until baz
1714
- RUBY
1715
-
1716
- assert_source <<~'RUBY'
1717
- begin
1718
- foo
1719
- bar
1720
- end while baz
1721
- RUBY
1722
- end
1723
-
1724
- context 'while' do
1725
- assert_source <<~'RUBY'
1726
- while false
1727
- end
1728
- RUBY
1729
-
1730
- assert_source <<~'RUBY'
1731
- while false
1732
- 3
1733
- end
1734
- RUBY
1735
-
1736
- assert_source <<~'RUBY'
1737
- while (foo do
1738
- end)
1739
- :body
1740
- end
1741
- RUBY
1742
- end
1743
-
1744
- context 'until' do
1745
- assert_source <<~'RUBY'
1746
- until false
1747
- end
1748
- RUBY
1749
-
1750
- assert_source <<~'RUBY'
1751
- until false
1752
- 3
1753
- end
1754
- RUBY
1755
-
1756
- assert_source <<~'RUBY'
1757
- until (foo do
1758
- end)
1759
- :body
1760
- end
1761
- RUBY
1762
- end
1763
-
1764
- assert_source <<~'RUBY'
1765
- # comment before
1766
- a_line_of_code
1767
- RUBY
1768
-
1769
- assert_source <<~'RUBY'
1770
- a_line_of_code # comment after
1771
- RUBY
1772
-
1773
- assert_source <<~'RUBY'
1774
- nested do # first
1775
- # second
1776
- something # comment
1777
- # another
1778
- end
1779
- # last
1780
- RUBY
1781
-
1782
- assert_generates <<~'RUBY', <<~'RUBY'
1783
- foo if bar
1784
- # comment
1785
- RUBY
1786
- if bar
1787
- foo
1788
- end
1789
- # comment
1790
- RUBY
1791
-
1792
- assert_source <<~'RUBY'
1793
- def noop
1794
- # do nothing
1795
- end
1796
- RUBY
1797
-
1798
- assert_source <<~'RUBY'
1799
- =begin
1800
- block comment
1801
- =end
1802
- nested do
1803
- =begin
1804
- another block comment
1805
- =end
1806
- something
1807
- =begin
1808
- last block comment
1809
- =end
1810
- end
1811
- RUBY
1812
-
1813
- assert_generates(<<~'RUBY', <<~'RUBY')
1814
- 1 + # first
1815
- 2 # second
1816
- RUBY
1817
- 1 + 2 # first # second
1818
- RUBY
1819
-
1820
- assert_generates(<<~'RUBY', <<~'RUBY')
1821
- 1 +
1822
- # first
1823
- 2 # second
1824
- RUBY
1825
- 1 + 2 # first # second
1826
- RUBY
1827
-
1828
- assert_generates(<<~'RUBY', <<~'RUBY')
1829
- 1 +
1830
- =begin
1831
- block comment
1832
- =end
1833
- 2
1834
- RUBY
1835
- 1 + 2
1836
- =begin
1837
- block comment
1838
- =end
1839
- RUBY
1840
- end
1841
- end