unparser 0.4.6 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -2
  3. data/bin/unparser +1 -1
  4. data/lib/unparser.rb +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