/
one_line_conditional_spec.rb
155 lines (124 loc) · 4.74 KB
/
one_line_conditional_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# frozen_string_literal: true
RSpec.describe RuboCop::Cop::Style::OneLineConditional do
subject(:cop) { described_class.new }
shared_examples 'offense' do |condition|
it 'registers an offense' do
inspect_source(source)
expect(cop.messages)
.to eq(['Favor the ternary operator (`?:`)' \
" over `#{condition}/then/else/end` constructs."])
end
end
shared_examples 'no offense' do
it 'does not register an offense' do
expect_no_offenses(source)
end
end
shared_examples 'autocorrect' do |correct_code|
it 'auto-corrects' do
corrected = autocorrect_source(source)
expect(corrected).to eq(correct_code)
end
end
context 'one line if/then/else/end' do
let(:source) { 'if cond then run else dont end' }
include_examples 'offense', 'if'
include_examples 'autocorrect', 'cond ? run : dont'
context 'empty else' do
let(:source) { 'if cond then run else end' }
include_examples 'no offense'
end
end
context 'one line if/then/else/end when `then` branch has no body' do
let(:source) { 'if cond then else dont end' }
include_examples 'offense', 'if'
include_examples 'autocorrect', 'cond ? nil : dont'
end
context 'one line if/then/end' do
let(:source) { 'if cond then run end' }
include_examples 'no offense'
end
context 'one line unless/then/else/end' do
let(:source) { 'unless cond then run else dont end' }
include_examples 'offense', 'unless'
include_examples 'autocorrect', 'cond ? dont : run'
context 'empty else' do
let(:source) { 'unless cond then run else end' }
include_examples 'no offense'
end
end
context 'one line unless/then/end' do
let(:source) { 'unless cond then run end' }
include_examples 'no offense'
end
%w[| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ ! != !~
&& ||].each do |operator|
it 'parenthesizes the expression if it is preceded by an operator' do
corrected =
autocorrect_source("a #{operator} if cond then run else dont end")
expect(corrected).to eq("a #{operator} (cond ? run : dont)")
end
end
shared_examples 'changed precedence' do |expr|
it "adds parentheses around `#{expr}`" do
corrected = autocorrect_source("if #{expr} then #{expr} else #{expr} end")
expect(corrected).to eq("(#{expr}) ? (#{expr}) : (#{expr})")
end
end
it_behaves_like 'changed precedence', 'puts 1'
it_behaves_like 'changed precedence', 'defined? :A'
it_behaves_like 'changed precedence', 'yield a'
it_behaves_like 'changed precedence', 'super b'
it_behaves_like 'changed precedence', 'not a'
it_behaves_like 'changed precedence', 'a and b'
it_behaves_like 'changed precedence', 'a or b'
it_behaves_like 'changed precedence', 'a = b'
it_behaves_like 'changed precedence', 'a ? b : c'
it 'does not parenthesize expressions when they do not contain method ' \
'calls with unparenthesized arguments' do
corrected =
autocorrect_source('if a(0) then puts(1) else yield(2) end')
expect(corrected).to eq('a(0) ? puts(1) : yield(2)')
end
it 'does not parenthesize expressions when they contain unparenthesized ' \
'operator method calls' do
corrected = autocorrect_source('if 0 + 0 then 1 + 1 else 2 + 2 end')
expect(corrected).to eq('0 + 0 ? 1 + 1 : 2 + 2')
end
it 'does not break when one of the branches contains a retry keyword' do
expect_offense(<<~RUBY)
if true then retry else 7 end
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Favor the ternary operator (`?:`) over `if/then/else/end` constructs.
RUBY
expect_correction(<<~RUBY)
true ? retry : 7
RUBY
end
it 'does not break when one of the branches contains a break keyword' do
expect_offense(<<~RUBY)
if true then break else 7 end
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Favor the ternary operator (`?:`) over `if/then/else/end` constructs.
RUBY
expect_correction(<<~RUBY)
true ? break : 7
RUBY
end
it 'does not break when one of the branches contains a self keyword' do
expect_offense(<<~RUBY)
if true then self else 7 end
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Favor the ternary operator (`?:`) over `if/then/else/end` constructs.
RUBY
expect_correction(<<~RUBY)
true ? self : 7
RUBY
end
it 'does not break when one of the branches contains `next` keyword' do
expect_offense(<<~RUBY)
map{ |line| if line.match(/^\s*#/) || line.strip.empty? then next else line end }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Favor the ternary operator (`?:`) over `if/then/else/end` constructs.
RUBY
expect_correction(<<~RUBY)
map{ |line| (line.match(/^ *#/) || line.strip.empty?) ? next : line }
RUBY
end
end