parent
cffcd910c4
commit
8cf5e0f079
5 changed files with 34 additions and 16 deletions
|
@ -8,10 +8,15 @@ module Mutant
|
||||||
#
|
#
|
||||||
# @param regexp [String]
|
# @param regexp [String]
|
||||||
#
|
#
|
||||||
# @return [Regexp::Expression]
|
# @return [Regexp::Expression, nil]
|
||||||
|
#
|
||||||
|
# rubocop:disable Lint/HandleExceptions
|
||||||
def self.parse(regexp)
|
def self.parse(regexp)
|
||||||
::Regexp::Parser.parse(regexp)
|
::Regexp::Parser.parse(regexp)
|
||||||
|
# regexp_parser is more strict than MRI
|
||||||
|
rescue ::Regexp::Scanner::PrematureEndError
|
||||||
end
|
end
|
||||||
|
# rubocop:enable Lint/HandleExceptions
|
||||||
|
|
||||||
# Convert expression into ast node
|
# Convert expression into ast node
|
||||||
#
|
#
|
||||||
|
|
|
@ -42,7 +42,7 @@ module Mutant
|
||||||
#
|
#
|
||||||
# @return [undefined]
|
# @return [undefined]
|
||||||
def mutate_body
|
def mutate_body
|
||||||
return unless body.all?(&method(:n_str?))
|
return unless body.all?(&method(:n_str?)) && body_ast
|
||||||
|
|
||||||
Mutator.mutate(body_ast).each do |mutation|
|
Mutator.mutate(body_ast).each do |mutation|
|
||||||
source = AST::Regexp.to_expression(mutation).to_s
|
source = AST::Regexp.to_expression(mutation).to_s
|
||||||
|
@ -52,14 +52,14 @@ module Mutant
|
||||||
|
|
||||||
# AST representation of regexp body
|
# AST representation of regexp body
|
||||||
#
|
#
|
||||||
# @return [Parser::AST::Node]
|
# @return [Parser::AST::Node, nil]
|
||||||
def body_ast
|
def body_ast
|
||||||
AST::Regexp.to_ast(body_expression)
|
body_expression and AST::Regexp.to_ast(body_expression)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Expression representation of regexp body
|
# Expression representation of regexp body
|
||||||
#
|
#
|
||||||
# @return [Regexp::Expression]
|
# @return [Regexp::Expression, nil]
|
||||||
def body_expression
|
def body_expression
|
||||||
AST::Regexp.parse(body.map(&:children).join)
|
AST::Regexp.parse(body.map(&:children).join)
|
||||||
end
|
end
|
||||||
|
|
|
@ -76,6 +76,15 @@ Mutant::Meta::Example.add :regexp do
|
||||||
mutation '/(?(1)(foo)(?:bar))/'
|
mutation '/(?(1)(foo)(?:bar))/'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Case where MRI would accept an expression but regexp_parser not.
|
||||||
|
Mutant::Meta::Example.add :regexp do
|
||||||
|
source '/u{/'
|
||||||
|
|
||||||
|
singleton_mutations
|
||||||
|
mutation '//'
|
||||||
|
mutation '/nomatch\A/'
|
||||||
|
end
|
||||||
|
|
||||||
Pathname
|
Pathname
|
||||||
.glob(Pathname.new(__dir__).join('regexp', '*.rb'))
|
.glob(Pathname.new(__dir__).join('regexp', '*.rb'))
|
||||||
.sort
|
.sort
|
||||||
|
|
|
@ -7,15 +7,7 @@
|
||||||
ruby_glob_pattern: '**/*_spec.rb'
|
ruby_glob_pattern: '**/*_spec.rb'
|
||||||
mutation_coverage: false
|
mutation_coverage: false
|
||||||
mutation_generation: true
|
mutation_generation: true
|
||||||
expected_errors:
|
expected_errors: {}
|
||||||
"#<Parser::SyntaxError: invalid multibyte escape: /\xAA/>":
|
|
||||||
- language/regexp/escapes_spec.rb
|
|
||||||
'#<RegexpError: invalid multibyte escape: /\xAA/>':
|
|
||||||
- language/regexp/escapes_spec.rb
|
|
||||||
"#<Regexp::Scanner::PrematureEndError: Premature end of pattern at #{str}>":
|
|
||||||
- language/regexp/interpolation_spec.rb
|
|
||||||
'#<Regexp::Scanner::PrematureEndError: Premature end of pattern at \xA>':
|
|
||||||
- language/regexp/escapes_spec.rb
|
|
||||||
exclude:
|
exclude:
|
||||||
- core/string/casecmp_spec.rb
|
- core/string/casecmp_spec.rb
|
||||||
- core/symbol/casecmp_spec.rb
|
- core/symbol/casecmp_spec.rb
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.describe Mutant::AST::Regexp, '.parse' do
|
RSpec.describe Mutant::AST::Regexp, '.parse' do
|
||||||
it 'parses using minor ruby version' do
|
def apply(input)
|
||||||
expect(described_class.parse(/foo/).to_re).to eql(/foo/)
|
described_class.parse(input)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'on regexp regexp_parser does accept' do
|
||||||
|
it 'parses using minor ruby version' do
|
||||||
|
expect(apply(/foo/).to_re).to eql(/foo/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'on regexp regexp_parser does not accept' do
|
||||||
|
it 'returns nil' do
|
||||||
|
expect(apply(/u{/)).to be(nil)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue