Skip to content

Commit e98d015

Browse files
authored
Add RegexpNode regopt predicates (#20)
As suggested by @bbatsov in rubocop/rubocop#8073 (comment)
1 parent 7f23111 commit e98d015

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### New features
66

77
* [#4](https://github.com/rubocop-hq/rubocop-ast/issues/4): Add `interpolation?` for `RegexpNode`. ([@tejasbubane][])
8+
* [#20](https://github.com/rubocop-hq/rubocop-ast/pull/20): Add option predicates for `RegexpNode`. ([@owst][])
89

910
## 0.0.3 (2020-05-15)
1011

@@ -28,3 +29,4 @@
2829
* Gem extracted from RuboCop. ([@marcandre][])
2930

3031
[@marcandre]: https://github.com/marcandre
32+
[@owst]: https://github.com/owst

lib/rubocop/ast/node/regexp_node.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,37 @@ def content
3636
def interpolation?
3737
children.any?(&:begin_type?)
3838
end
39+
40+
# @return [Bool] if regexp uses the multiline regopt
41+
def multiline?
42+
regopt_include?(:m)
43+
end
44+
45+
# @return [Bool] if regexp uses the extended regopt
46+
def extended?
47+
regopt_include?(:x)
48+
end
49+
50+
# @return [Bool] if regexp uses the ignore-case regopt
51+
def ignore_case?
52+
regopt_include?(:i)
53+
end
54+
55+
# @return [Bool] if regexp uses the single-interpolation regopt
56+
def single_interpolation?
57+
regopt_include?(:o)
58+
end
59+
60+
# @return [Bool] if regexp uses the no-encoding regopt
61+
def no_encoding?
62+
regopt_include?(:n)
63+
end
64+
65+
private
66+
67+
def regopt_include?(option)
68+
regopt.children.include?(option)
69+
end
3970
end
4071
end
4172
end

spec/rubocop/ast/regexp_node_spec.rb

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,134 @@
160160
it { expect(regexp_node.interpolation?).to eq(false) }
161161
end
162162
end
163+
164+
describe '#multiline?' do
165+
context 'with no options' do
166+
let(:source) { '/x/' }
167+
168+
it { expect(regexp_node.multiline?).to be(false) }
169+
end
170+
171+
context 'with other options' do
172+
let(:source) { '/x/ix' }
173+
174+
it { expect(regexp_node.multiline?).to be(false) }
175+
end
176+
177+
context 'with only m option' do
178+
let(:source) { '/x/m' }
179+
180+
it { expect(regexp_node.multiline?).to be(true) }
181+
end
182+
183+
context 'with m and other options' do
184+
let(:source) { '/x/imx' }
185+
186+
it { expect(regexp_node.multiline?).to be(true) }
187+
end
188+
end
189+
190+
describe '#extended?' do
191+
context 'with no options' do
192+
let(:source) { '/x/' }
193+
194+
it { expect(regexp_node.extended?).to be(false) }
195+
end
196+
197+
context 'with other options' do
198+
let(:source) { '/x/im' }
199+
200+
it { expect(regexp_node.extended?).to be(false) }
201+
end
202+
203+
context 'with only x option' do
204+
let(:source) { '/x/x' }
205+
206+
it { expect(regexp_node.extended?).to be(true) }
207+
end
208+
209+
context 'with x and other options' do
210+
let(:source) { '/x/ixm' }
211+
212+
it { expect(regexp_node.extended?).to be(true) }
213+
end
214+
end
215+
216+
describe '#ignore_case?' do
217+
context 'with no options' do
218+
let(:source) { '/x/' }
219+
220+
it { expect(regexp_node.ignore_case?).to be(false) }
221+
end
222+
223+
context 'with other options' do
224+
let(:source) { '/x/xm' }
225+
226+
it { expect(regexp_node.ignore_case?).to be(false) }
227+
end
228+
229+
context 'with only i option' do
230+
let(:source) { '/x/i' }
231+
232+
it { expect(regexp_node.ignore_case?).to be(true) }
233+
end
234+
235+
context 'with i and other options' do
236+
let(:source) { '/x/xim' }
237+
238+
it { expect(regexp_node.ignore_case?).to be(true) }
239+
end
240+
end
241+
242+
describe '#no_encoding?' do
243+
context 'with no options' do
244+
let(:source) { '/x/' }
245+
246+
it { expect(regexp_node.no_encoding?).to be(false) }
247+
end
248+
249+
context 'with other options' do
250+
let(:source) { '/x/xm' }
251+
252+
it { expect(regexp_node.no_encoding?).to be(false) }
253+
end
254+
255+
context 'with only n option' do
256+
let(:source) { '/x/n' }
257+
258+
it { expect(regexp_node.no_encoding?).to be(true) }
259+
end
260+
261+
context 'with n and other options' do
262+
let(:source) { '/x/xnm' }
263+
264+
it { expect(regexp_node.no_encoding?).to be(true) }
265+
end
266+
end
267+
268+
describe '#single_interpolation?' do
269+
context 'with no options' do
270+
let(:source) { '/x/' }
271+
272+
it { expect(regexp_node.single_interpolation?).to be(false) }
273+
end
274+
275+
context 'with other options' do
276+
let(:source) { '/x/xm' }
277+
278+
it { expect(regexp_node.single_interpolation?).to be(false) }
279+
end
280+
281+
context 'with only o option' do
282+
let(:source) { '/x/o' }
283+
284+
it { expect(regexp_node.single_interpolation?).to be(true) }
285+
end
286+
287+
context 'with o and other options' do
288+
let(:source) { '/x/xom' }
289+
290+
it { expect(regexp_node.single_interpolation?).to be(true) }
291+
end
292+
end
163293
end

0 commit comments

Comments
 (0)