mutant 0.8.18 → 0.8.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{circle.yml → .circleci/config.yml} +3 -9
- data/.rubocop.yml +1 -1
- data/Changelog.md +5 -0
- data/Gemfile.lock +6 -6
- data/README.md +1 -1
- data/config/flay.yml +1 -1
- data/lib/mutant.rb +4 -5
- data/lib/mutant/ast/regexp.rb +0 -15
- data/lib/mutant/ast/regexp/transformer/direct.rb +65 -47
- data/lib/mutant/ast/regexp/transformer/named_group.rb +59 -0
- data/lib/mutant/ast/regexp/transformer/options_group.rb +22 -7
- data/lib/mutant/ast/regexp/transformer/recursive.rb +14 -8
- data/lib/mutant/ast/regexp/transformer/root.rb +1 -1
- data/lib/mutant/ast/regexp/transformer/text.rb +7 -5
- data/lib/mutant/ast/types.rb +29 -6
- data/lib/mutant/expression/namespace.rb +1 -1
- data/lib/mutant/matcher/method/instance.rb +3 -1
- data/lib/mutant/mutator/node/generic.rb +1 -0
- data/lib/mutant/mutator/node/literal/regex.rb +0 -1
- data/lib/mutant/mutator/node/regexp/character_type.rb +1 -1
- data/lib/mutant/version.rb +1 -1
- data/lib/mutant/warning_filter.rb +1 -1
- data/meta/regexp.rb +3 -0
- data/meta/regexp/character_types.rb +1 -1
- data/mutant.gemspec +2 -2
- data/spec/integrations.yml +2 -4
- data/spec/support/warnings.yml +1 -3
- data/spec/unit/mutant/ast/regexp_spec.rb +108 -23
- data/spec/unit/mutant/matcher/method/instance_spec.rb +4 -4
- data/test_app/lib/test_app.rb +1 -1
- metadata +7 -10
- data/lib/mutant/ast/regexp/transformer/alternative.rb +0 -41
- data/lib/mutant/ast/regexp/transformer/character_set.rb +0 -48
- data/spec/unit/mutant/ast/regexp/supported_predicate_spec.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dbaeba3292082f39979c87a1918f1a75a681f4cca1299fee251373779c1f381b
|
4
|
+
data.tar.gz: b1e57ca598f25e27d1c74e2b17d2033edb1d3b602742eb0fa62a6a7ac1f1058a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53d8e07cbcfc3ce3c8f1848ae34438f5e31ee3cbb8af8784e02e1f5a4cccc61554ac9f404d07083c0ce1210b4329de873e0ecb3e274260798484a1cabc53f758
|
7
|
+
data.tar.gz: 5ca7d7e28311f4c359d07f823d069b1ace3ed8b408bcb5c9f912d6f106ff469be4d38a4e7ea37afd46083d30eab818039c72f306d323ee4a364e5a6fb3b0beb8
|
@@ -4,20 +4,14 @@ defaults: &defaults
|
|
4
4
|
- checkout
|
5
5
|
- run: bundle install
|
6
6
|
- run: bundle exec rake ci
|
7
|
-
|
8
7
|
version: 2
|
9
8
|
jobs:
|
10
|
-
|
9
|
+
ruby_2_5:
|
11
10
|
<<: *defaults
|
12
11
|
docker:
|
13
|
-
- image: circleci/ruby:2.3
|
14
|
-
ruby_2_4:
|
15
|
-
<<: *defaults
|
16
|
-
docker:
|
17
|
-
- image: circleci/ruby:2.4.1
|
12
|
+
- image: circleci/ruby:2.5.3
|
18
13
|
workflows:
|
19
14
|
version: 2
|
20
15
|
test:
|
21
16
|
jobs:
|
22
|
-
-
|
23
|
-
- ruby_2_4
|
17
|
+
- ruby_2_5
|
data/.rubocop.yml
CHANGED
data/Changelog.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mutant (0.8.
|
4
|
+
mutant (0.8.18)
|
5
5
|
abstract_type (~> 0.0.7)
|
6
6
|
adamantium (~> 0.2.0)
|
7
7
|
anima (~> 0.3.0)
|
@@ -15,10 +15,10 @@ PATH
|
|
15
15
|
parallel (~> 1.3)
|
16
16
|
parser (~> 2.5.1)
|
17
17
|
procto (~> 0.0.2)
|
18
|
-
regexp_parser (~>
|
18
|
+
regexp_parser (~> 1.2)
|
19
19
|
unparser (~> 0.2.5)
|
20
|
-
mutant-rspec (0.8.
|
21
|
-
mutant (~> 0.8.
|
20
|
+
mutant-rspec (0.8.18)
|
21
|
+
mutant (~> 0.8.18)
|
22
22
|
rspec-core (>= 3.4.0, < 4.0.0)
|
23
23
|
|
24
24
|
GEM
|
@@ -107,7 +107,7 @@ GEM
|
|
107
107
|
kwalify (~> 0.7.0)
|
108
108
|
parser (>= 2.5.0.0, < 2.6, != 2.5.1.1)
|
109
109
|
rainbow (>= 2.0, < 4.0)
|
110
|
-
regexp_parser (
|
110
|
+
regexp_parser (1.2.0)
|
111
111
|
rspec (3.8.0)
|
112
112
|
rspec-core (~> 3.8.0)
|
113
113
|
rspec-expectations (~> 3.8.0)
|
@@ -170,4 +170,4 @@ DEPENDENCIES
|
|
170
170
|
mutant!
|
171
171
|
|
172
172
|
BUNDLED WITH
|
173
|
-
1.
|
173
|
+
1.17.1
|
data/README.md
CHANGED
@@ -353,7 +353,7 @@ Sorted by recency:
|
|
353
353
|
[sitepoint]: http://www.sitepoint.com/mutation-testing-mutant/
|
354
354
|
[arkency1]: http://blog.arkency.com/2015/06/how-good-are-your-ruby-tests-testing-your-tests-with-mutant/
|
355
355
|
[arkency2]: http://blog.arkency.com/2015/05/mutation-testing-and-continuous-integration/
|
356
|
-
[arkency3]: http://blog.arkency.com/2015/04/why-i-want-to-introduce-mutation-testing-to-the-rails-event-store-gem/
|
356
|
+
[arkency3]: http://blog.arkency.com/2015/04/why-i-want-to-introduce-mutation-testing-to-the-rails-event-store-gem/
|
357
357
|
[solnic]: http://solnic.eu/2013/01/23/mutation-testing-with-mutant.html
|
358
358
|
|
359
359
|
Support
|
data/config/flay.yml
CHANGED
data/lib/mutant.rb
CHANGED
@@ -56,13 +56,12 @@ require 'mutant/ast/node_predicates'
|
|
56
56
|
require 'mutant/ast/regexp'
|
57
57
|
require 'mutant/ast/regexp/transformer'
|
58
58
|
require 'mutant/ast/regexp/transformer/direct'
|
59
|
-
require 'mutant/ast/regexp/transformer/
|
60
|
-
require 'mutant/ast/regexp/transformer/recursive'
|
61
|
-
require 'mutant/ast/regexp/transformer/quantifier'
|
59
|
+
require 'mutant/ast/regexp/transformer/named_group'
|
62
60
|
require 'mutant/ast/regexp/transformer/options_group'
|
63
|
-
require 'mutant/ast/regexp/transformer/
|
61
|
+
require 'mutant/ast/regexp/transformer/quantifier'
|
62
|
+
require 'mutant/ast/regexp/transformer/recursive'
|
64
63
|
require 'mutant/ast/regexp/transformer/root'
|
65
|
-
require 'mutant/ast/regexp/transformer/
|
64
|
+
require 'mutant/ast/regexp/transformer/text'
|
66
65
|
require 'mutant/ast/meta'
|
67
66
|
require 'mutant/ast/meta/send'
|
68
67
|
require 'mutant/ast/meta/const'
|
data/lib/mutant/ast/regexp.rb
CHANGED
@@ -4,10 +4,6 @@ module Mutant
|
|
4
4
|
module AST
|
5
5
|
# Regexp source mapper
|
6
6
|
module Regexp
|
7
|
-
UNSUPPORTED_EXPRESSION_TYPE = :conditional
|
8
|
-
|
9
|
-
private_constant(*constants(false))
|
10
|
-
|
11
7
|
# Parse regex string into expression
|
12
8
|
#
|
13
9
|
# @param regexp [String]
|
@@ -17,17 +13,6 @@ module Mutant
|
|
17
13
|
::Regexp::Parser.parse(regexp)
|
18
14
|
end
|
19
15
|
|
20
|
-
# Check if expression is supported by mapper
|
21
|
-
#
|
22
|
-
# @param expression [Regexp::Expression]
|
23
|
-
#
|
24
|
-
# @return [Boolean]
|
25
|
-
def self.supported?(expression)
|
26
|
-
expression.terminal? || expression.all? do |subexp|
|
27
|
-
!subexp.type.equal?(UNSUPPORTED_EXPRESSION_TYPE) && supported?(subexp)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
16
|
# Convert expression into ast node
|
32
17
|
#
|
33
18
|
# @param expression [Regexp::Expression]
|
@@ -38,53 +38,71 @@ module Mutant
|
|
38
38
|
|
39
39
|
# rubocop:disable LineLength
|
40
40
|
TABLE = Table.create(
|
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
|
-
[:
|
41
|
+
[:regexp_alnum_posixclass, [:posixclass, :alnum, '[:alnum:]'], ::Regexp::Expression::PosixClass],
|
42
|
+
[:regexp_alpha_posixclass, [:posixclass, :alpha, '[:alpha:]'], ::Regexp::Expression::PosixClass],
|
43
|
+
[:regexp_alpha_property, [:property, :alpha, '\p{Alpha}'], ::Regexp::Expression::UnicodeProperty::Alpha],
|
44
|
+
[:regexp_alternation_escape, [:escape, :alternation, '\|'], ::Regexp::Expression::EscapeSequence::Literal],
|
45
|
+
[:regexp_arabic_property, [:property, :arabic, '\p{Arabic}'], ::Regexp::Expression::UnicodeProperty::Script],
|
46
|
+
[:regexp_ascii_posixclass, [:posixclass, :ascii, '[:ascii:]'], ::Regexp::Expression::PosixClass],
|
47
|
+
[:regexp_backspace_escape, [:escape, :backspace, '\b'], ::Regexp::Expression::EscapeSequence::Backspace],
|
48
|
+
[:regexp_bell_escape, [:escape, :bell, '\a'], ::Regexp::Expression::EscapeSequence::Literal],
|
49
|
+
[:regexp_blank_posixclass, [:posixclass, :blank, '[:blank:]'], ::Regexp::Expression::PosixClass],
|
50
|
+
[:regexp_bol_anchor, [:anchor, :bol, '^'], ::Regexp::Expression::Anchor::BeginningOfLine],
|
51
|
+
[:regexp_bol_escape, [:escape, :bol, '\^'], ::Regexp::Expression::EscapeSequence::Literal],
|
52
|
+
[:regexp_bos_anchor, [:anchor, :bos, '\\A'], ::Regexp::Expression::Anchor::BeginningOfString],
|
53
|
+
[:regexp_carriage_escape, [:escape, :carriage, '\r'], ::Regexp::Expression::EscapeSequence::Literal],
|
54
|
+
[:regexp_cntrl_posixclass, [:posixclass, :cntrl, '[:cntrl:]'], ::Regexp::Expression::PosixClass],
|
55
|
+
[:regexp_digit_posixclass, [:posixclass, :digit, '[:digit:]'], ::Regexp::Expression::PosixClass],
|
56
|
+
[:regexp_digit_type, [:type, :digit, '\d'], ::Regexp::Expression::CharacterType::Digit],
|
57
|
+
[:regexp_dot_escape, [:escape, :dot, '\.'], ::Regexp::Expression::EscapeSequence::Literal],
|
58
|
+
[:regexp_dot_meta, [:meta, :dot, '.'], ::Regexp::Expression::CharacterType::Any],
|
59
|
+
[:regexp_eol_anchor, [:anchor, :eol, '$'], ::Regexp::Expression::Anchor::EndOfLine],
|
60
|
+
[:regexp_eol_escape, [:escape, :eol, '\$'], ::Regexp::Expression::EscapeSequence::Literal],
|
61
|
+
[:regexp_eos_anchor, [:anchor, :eos, '\\z'], ::Regexp::Expression::Anchor::EndOfString],
|
62
|
+
[:regexp_eos_ob_eol_anchor, [:anchor, :eos_ob_eol, '\\Z'], ::Regexp::Expression::Anchor::EndOfStringOrBeforeEndOfLine],
|
63
|
+
[:regexp_escape_escape, [:escape, :escape, '\e'], ::Regexp::Expression::EscapeSequence::AsciiEscape],
|
64
|
+
[:regexp_form_feed_escape, [:escape, :form_feed, '\f'], ::Regexp::Expression::EscapeSequence::FormFeed],
|
65
|
+
[:regexp_graph_posixclass, [:posixclass, :graph, '[:graph:]'], ::Regexp::Expression::PosixClass],
|
66
|
+
[:regexp_group_close_escape, [:escape, :group_close, '\)'], ::Regexp::Expression::EscapeSequence::Literal],
|
67
|
+
[:regexp_group_open_escape, [:escape, :group_open, '\('], ::Regexp::Expression::EscapeSequence::Literal],
|
68
|
+
[:regexp_han_property, [:property, :han, '\p{Han}'], ::Regexp::Expression::UnicodeProperty::Script],
|
69
|
+
[:regexp_hangul_property, [:property, :hangul, '\p{Hangul}'], ::Regexp::Expression::UnicodeProperty::Script],
|
70
|
+
[:regexp_hex_type, [:type, :hex, '\h'], ::Regexp::Expression::CharacterType::Hex],
|
71
|
+
[:regexp_hiragana_property, [:property, :hiragana, '\p{Hiragana}'], ::Regexp::Expression::UnicodeProperty::Script],
|
72
|
+
[:regexp_interval_close_escape, [:escape, :interval_close, '\}'], ::Regexp::Expression::EscapeSequence::Literal],
|
73
|
+
[:regexp_interval_open_escape, [:escape, :interval_open, '\{'], ::Regexp::Expression::EscapeSequence::Literal],
|
74
|
+
[:regexp_katakana_property, [:property, :katakana, '\p{Katakana}'], ::Regexp::Expression::UnicodeProperty::Script],
|
75
|
+
[:regexp_letter_property, [:property, :letter, '\p{L}'], ::Regexp::Expression::UnicodeProperty::Letter::Any],
|
76
|
+
[:regexp_linebreak_type, [:type, :linebreak, '\R'], ::Regexp::Expression::CharacterType::Linebreak],
|
77
|
+
[:regexp_lower_posixclass, [:posixclass, :lower, '[:lower:]'], ::Regexp::Expression::PosixClass],
|
78
|
+
[:regexp_mark_keep, [:keep, :mark, '\K'], ::Regexp::Expression::Keep::Mark],
|
79
|
+
[:regexp_match_start_anchor, [:anchor, :match_start, '\\G'], ::Regexp::Expression::Anchor::MatchStart],
|
80
|
+
[:regexp_newline_escape, [:escape, :newline, '\n'], ::Regexp::Expression::EscapeSequence::Literal],
|
81
|
+
[:regexp_nondigit_type, [:type, :nondigit, '\D'], ::Regexp::Expression::CharacterType::NonDigit],
|
82
|
+
[:regexp_nonhex_type, [:type, :nonhex, '\H'], ::Regexp::Expression::CharacterType::NonHex],
|
83
|
+
[:regexp_nonspace_type, [:type, :nonspace, '\S'], ::Regexp::Expression::CharacterType::NonSpace],
|
84
|
+
[:regexp_nonword_boundary_anchor, [:anchor, :nonword_boundary, '\\B'], ::Regexp::Expression::Anchor::NonWordBoundary],
|
85
|
+
[:regexp_nonword_type, [:type, :nonword, '\W'], ::Regexp::Expression::CharacterType::NonWord],
|
86
|
+
[:regexp_one_or_more_escape, [:escape, :one_or_more, '\+'], ::Regexp::Expression::EscapeSequence::Literal],
|
87
|
+
[:regexp_print_nonposixclass, [:nonposixclass, :print, '[:^print:]'], ::Regexp::Expression::PosixClass],
|
88
|
+
[:regexp_print_nonproperty, [:nonproperty, :print, '\P{Print}'], ::Regexp::Expression::UnicodeProperty::Print],
|
89
|
+
[:regexp_print_posixclass, [:posixclass, :print, '[:print:]'], ::Regexp::Expression::PosixClass],
|
90
|
+
[:regexp_print_posixclass, [:posixclass, :print, '[:print:]'], ::Regexp::Expression::PosixClass],
|
91
|
+
[:regexp_print_property, [:property, :print, '\p{Print}'], ::Regexp::Expression::UnicodeProperty::Print],
|
92
|
+
[:regexp_punct_posixclass, [:posixclass, :punct, '[:punct:]'], ::Regexp::Expression::PosixClass],
|
93
|
+
[:regexp_set_close_escape, [:escape, :set_close, '\]'], ::Regexp::Expression::EscapeSequence::Literal],
|
94
|
+
[:regexp_set_open_escape, [:escape, :set_open, '\['], ::Regexp::Expression::EscapeSequence::Literal],
|
95
|
+
[:regexp_space_posixclass, [:posixclass, :space, '[:space:]'], ::Regexp::Expression::PosixClass],
|
96
|
+
[:regexp_space_type, [:type, :space, '\s'], ::Regexp::Expression::CharacterType::Space],
|
97
|
+
[:regexp_upper_posixclass, [:posixclass, :upper, '[:upper:]'], ::Regexp::Expression::PosixClass],
|
98
|
+
[:regexp_vertical_tab_escape, [:escape, :vertical_tab, '\v'], ::Regexp::Expression::EscapeSequence::VerticalTab],
|
99
|
+
[:regexp_word_boundary_anchor, [:anchor, :word_boundary, '\b'], ::Regexp::Expression::Anchor::WordBoundary],
|
100
|
+
[:regexp_word_posixclass, [:posixclass, :word, '[:word:]'], ::Regexp::Expression::PosixClass],
|
101
|
+
[:regexp_word_type, [:type, :word, '\w'], ::Regexp::Expression::CharacterType::Word],
|
102
|
+
[:regexp_xdigit_posixclass, [:posixclass, :xdigit, '[:xdigit:]'], ::Regexp::Expression::PosixClass],
|
103
|
+
[:regexp_xgrapheme_type, [:type, :xgrapheme, '\X'], ::Regexp::Expression::CharacterType::ExtendedGrapheme],
|
104
|
+
[:regexp_zero_or_more_escape, [:escape, :zero_or_more, '\*'], ::Regexp::Expression::EscapeSequence::Literal],
|
105
|
+
[:regexp_zero_or_one_escape, [:escape, :zero_or_one, '\?'], ::Regexp::Expression::EscapeSequence::Literal]
|
88
106
|
)
|
89
107
|
|
90
108
|
private
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mutant
|
4
|
+
module AST
|
5
|
+
module Regexp
|
6
|
+
class Transformer
|
7
|
+
# Transformer for named groups
|
8
|
+
class NamedGroup < self
|
9
|
+
register :regexp_named_group
|
10
|
+
|
11
|
+
# Mapper from `Regexp::Expression` to `Parser::AST::Node`
|
12
|
+
class ExpressionToAST < Transformer::ExpressionToAST
|
13
|
+
|
14
|
+
# Transform named group into node
|
15
|
+
#
|
16
|
+
# @return [Parser::AST::Node]
|
17
|
+
def call
|
18
|
+
quantify(ast(expression.name, *children))
|
19
|
+
end
|
20
|
+
end # ExpressionToAST
|
21
|
+
|
22
|
+
# Mapper from `Parser::AST::Node` to `Regexp::Expression`
|
23
|
+
class ASTToExpression < Transformer::ASTToExpression
|
24
|
+
include NamedChildren
|
25
|
+
|
26
|
+
children :name
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Convert node into expression
|
31
|
+
#
|
32
|
+
# @return [Regexp::Expression::Group::Named]
|
33
|
+
def transform
|
34
|
+
named_group.tap do |expression|
|
35
|
+
expression.expressions = subexpressions
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Recursive mapping of children
|
40
|
+
#
|
41
|
+
# @return [Array<Regexp::Expression>]
|
42
|
+
def subexpressions
|
43
|
+
remaining_children.map(&Regexp.public_method(:to_expression))
|
44
|
+
end
|
45
|
+
|
46
|
+
# Named group instance constructed using name
|
47
|
+
#
|
48
|
+
# @return [Regexp::Expression::Group::Named]
|
49
|
+
def named_group
|
50
|
+
::Regexp::Expression::Group::Named.new(
|
51
|
+
::Regexp::Token.new(:group, :named, "(?<#{name}>")
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end # ASTToExpression
|
55
|
+
end # NamedGroup
|
56
|
+
end # Transformer
|
57
|
+
end # Regexp
|
58
|
+
end # AST
|
59
|
+
end # Mutant
|
@@ -7,6 +7,7 @@ module Mutant
|
|
7
7
|
# Transformer for option groups
|
8
8
|
class OptionsGroup < self
|
9
9
|
register :regexp_options_group
|
10
|
+
register :regexp_options_switch_group
|
10
11
|
|
11
12
|
# Mapper from `Regexp::Expression` to `Parser::AST::Node`
|
12
13
|
class ExpressionToAST < Transformer::ExpressionToAST
|
@@ -15,7 +16,7 @@ module Mutant
|
|
15
16
|
#
|
16
17
|
# @return [Parser::AST::Node]
|
17
18
|
def call
|
18
|
-
quantify(ast(expression.
|
19
|
+
quantify(ast(expression.option_changes, *children))
|
19
20
|
end
|
20
21
|
end # ExpressionToAST
|
21
22
|
|
@@ -23,11 +24,11 @@ module Mutant
|
|
23
24
|
class ASTToExpression < Transformer::ASTToExpression
|
24
25
|
include NamedChildren
|
25
26
|
|
26
|
-
children :
|
27
|
+
children :option_changes
|
27
28
|
|
28
29
|
private
|
29
30
|
|
30
|
-
#
|
31
|
+
# Convert node into expression
|
31
32
|
#
|
32
33
|
# @return [Regexp::Expression::Group::Options]
|
33
34
|
def transform
|
@@ -48,17 +49,31 @@ module Mutant
|
|
48
49
|
# @return [Regexp::Expression::Group::Options]
|
49
50
|
def options_group
|
50
51
|
::Regexp::Expression::Group::Options.new(
|
51
|
-
::Regexp::Token.new(:group,
|
52
|
+
::Regexp::Token.new(:group, type, text)
|
52
53
|
)
|
53
54
|
end
|
54
55
|
|
55
|
-
#
|
56
|
+
# Options group type derived from node type
|
57
|
+
#
|
58
|
+
# @return [Symbol]
|
59
|
+
def type
|
60
|
+
{
|
61
|
+
regexp_options_group: :options,
|
62
|
+
regexp_options_switch_group: :options_switch
|
63
|
+
}.fetch(node.type)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Flag text constructed from enabled and disabled options
|
56
67
|
#
|
57
68
|
# @return [String]
|
58
69
|
def text
|
59
|
-
|
70
|
+
pos, neg = option_changes.partition { |_opt, val| val }.map do |arr|
|
71
|
+
arr.map(&:first).join
|
72
|
+
end
|
73
|
+
neg_opt_sep = '-' unless neg.empty?
|
74
|
+
content_sep = ':' unless type.equal?(:options_switch)
|
60
75
|
|
61
|
-
"(?#{
|
76
|
+
"(?#{pos}#{neg_opt_sep}#{neg}#{content_sep}"
|
62
77
|
end
|
63
78
|
end # ASTToExpression
|
64
79
|
end # OptionsGroup
|
@@ -21,15 +21,21 @@ module Mutant
|
|
21
21
|
include LookupTable
|
22
22
|
|
23
23
|
# rubocop:disable LineLength
|
24
|
+
# Expression::Sequence represents conditional branches, alternation branches, and intersection branches
|
24
25
|
TABLE = Table.create(
|
25
|
-
[:regexp_alternation_meta, [:meta,
|
26
|
-
[:
|
27
|
-
[:
|
28
|
-
[:
|
29
|
-
[:
|
30
|
-
[:regexp_lookahead_assertion, [:assertion,
|
31
|
-
[:
|
32
|
-
[:
|
26
|
+
[:regexp_alternation_meta, [:meta, :alternation, '|'], ::Regexp::Expression::Alternation],
|
27
|
+
[:regexp_atomic_group, [:group, :atomic, '(?>'], ::Regexp::Expression::Group::Atomic],
|
28
|
+
[:regexp_capture_group, [:group, :capture, '('], ::Regexp::Expression::Group::Capture],
|
29
|
+
[:regexp_character_set, [:set, :character, '['], ::Regexp::Expression::CharacterSet],
|
30
|
+
[:regexp_intersection_set, [:set, :intersection, '&&'], ::Regexp::Expression::CharacterSet::Intersection],
|
31
|
+
[:regexp_lookahead_assertion, [:assertion, :lookahead, '(?='], ::Regexp::Expression::Assertion::Lookahead],
|
32
|
+
[:regexp_lookbehind_assertion, [:assertion, :lookbehind, '(?<='], ::Regexp::Expression::Assertion::Lookbehind],
|
33
|
+
[:regexp_nlookahead_assertion, [:assertion, :nlookahead, '(?!'], ::Regexp::Expression::Assertion::NegativeLookahead],
|
34
|
+
[:regexp_nlookbehind_assertion, [:assertion, :nlookbehind, '(?<!'], ::Regexp::Expression::Assertion::NegativeLookbehind],
|
35
|
+
[:regexp_open_conditional, [:conditional, :open, '(?'], ::Regexp::Expression::Conditional::Expression],
|
36
|
+
[:regexp_passive_group, [:group, :passive, '(?:'], ::Regexp::Expression::Group::Passive],
|
37
|
+
[:regexp_range_set, [:set, :range, '-'], ::Regexp::Expression::CharacterSet::Range],
|
38
|
+
[:regexp_sequence_expression, [:expression, :sequence, ''], ::Regexp::Expression::Sequence]
|
33
39
|
)
|
34
40
|
|
35
41
|
private
|
@@ -20,22 +20,24 @@ module Mutant
|
|
20
20
|
class ASTToExpression < Transformer::ASTToExpression
|
21
21
|
include LookupTable
|
22
22
|
|
23
|
+
# rubocop:disable LineLength
|
23
24
|
TABLE = Table.create(
|
24
25
|
[:regexp_literal_literal, %i[literal literal], ::Regexp::Expression::Literal],
|
25
26
|
[:regexp_comment_group, %i[group comment], ::Regexp::Expression::Group::Comment],
|
26
|
-
[:regexp_named_group, %i[group named], ::Regexp::Expression::Group::Named],
|
27
27
|
[:regexp_number_backref, %i[backref number], ::Regexp::Expression::Backreference::Number],
|
28
28
|
[:regexp_name_call_backref, %i[backref name_call], ::Regexp::Expression::Backreference::NameCall],
|
29
29
|
[:regexp_whitespace_free_space, %i[free_space whitespace], ::Regexp::Expression::WhiteSpace],
|
30
30
|
[:regexp_comment_free_space, %i[free_space comment], ::Regexp::Expression::WhiteSpace],
|
31
|
-
[:regexp_hex_escape, %i[escape hex], ::Regexp::Expression::EscapeSequence::
|
31
|
+
[:regexp_hex_escape, %i[escape hex], ::Regexp::Expression::EscapeSequence::Hex],
|
32
|
+
[:regexp_octal_escape, %i[escape octal], ::Regexp::Expression::EscapeSequence::Octal],
|
32
33
|
[:regexp_literal_escape, %i[escape literal], ::Regexp::Expression::EscapeSequence::Literal],
|
33
34
|
[:regexp_backslash_escape, %i[escape backslash], ::Regexp::Expression::EscapeSequence::Literal],
|
34
35
|
[:regexp_tab_escape, %i[escape tab], ::Regexp::Expression::EscapeSequence::Literal],
|
35
|
-
[:regexp_codepoint_list_escape, %i[escape codepoint_list], ::Regexp::Expression::EscapeSequence::
|
36
|
-
[:regexp_codepoint_escape, %i[escape codepoint], ::Regexp::Expression::EscapeSequence::
|
36
|
+
[:regexp_codepoint_list_escape, %i[escape codepoint_list], ::Regexp::Expression::EscapeSequence::CodepointList],
|
37
|
+
[:regexp_codepoint_escape, %i[escape codepoint], ::Regexp::Expression::EscapeSequence::Codepoint],
|
37
38
|
[:regexp_control_escape, %i[escape control], ::Regexp::Expression::EscapeSequence::Control],
|
38
|
-
[:regexp_meta_sequence_escape, %i[escape meta_sequence], ::Regexp::Expression::EscapeSequence::Control]
|
39
|
+
[:regexp_meta_sequence_escape, %i[escape meta_sequence], ::Regexp::Expression::EscapeSequence::Control],
|
40
|
+
[:regexp_condition_conditional, %i[conditional condition], ::Regexp::Expression::Conditional::Condition]
|
39
41
|
)
|
40
42
|
|
41
43
|
private
|
data/lib/mutant/ast/types.rb
CHANGED
@@ -45,23 +45,32 @@ module Mutant
|
|
45
45
|
|
46
46
|
# Nodes generated by regular expression body parsing
|
47
47
|
REGEXP = symbolset.(%w[
|
48
|
+
regexp_alnum_posixclass
|
49
|
+
regexp_alpha_posixclass
|
48
50
|
regexp_alpha_property
|
49
51
|
regexp_alternation_escape
|
50
52
|
regexp_alternation_meta
|
53
|
+
regexp_arabic_property
|
54
|
+
regexp_ascii_posixclass
|
51
55
|
regexp_atomic_group
|
52
56
|
regexp_backslash_escape
|
57
|
+
regexp_backspace_escape
|
53
58
|
regexp_bell_escape
|
59
|
+
regexp_blank_posixclass
|
54
60
|
regexp_bol_anchor
|
55
61
|
regexp_bol_escape
|
56
62
|
regexp_bos_anchor
|
57
63
|
regexp_capture_group
|
58
64
|
regexp_carriage_escape
|
59
65
|
regexp_character_set
|
66
|
+
regexp_cntrl_posixclass
|
60
67
|
regexp_codepoint_escape
|
61
68
|
regexp_codepoint_list_escape
|
62
69
|
regexp_comment_free_space
|
63
70
|
regexp_comment_group
|
71
|
+
regexp_condition_conditional
|
64
72
|
regexp_control_escape
|
73
|
+
regexp_digit_posixclass
|
65
74
|
regexp_digit_type
|
66
75
|
regexp_dot_escape
|
67
76
|
regexp_dot_meta
|
@@ -71,21 +80,29 @@ module Mutant
|
|
71
80
|
regexp_eos_ob_eol_anchor
|
72
81
|
regexp_escape_escape
|
73
82
|
regexp_form_feed_escape
|
83
|
+
regexp_graph_posixclass
|
74
84
|
regexp_greedy_interval
|
75
85
|
regexp_greedy_one_or_more
|
76
86
|
regexp_greedy_zero_or_more
|
77
87
|
regexp_greedy_zero_or_one
|
78
88
|
regexp_group_close_escape
|
79
89
|
regexp_group_open_escape
|
90
|
+
regexp_han_property
|
91
|
+
regexp_hangul_property
|
80
92
|
regexp_hex_escape
|
81
93
|
regexp_hex_type
|
94
|
+
regexp_hiragana_property
|
95
|
+
regexp_intersection_set
|
82
96
|
regexp_interval_close_escape
|
83
97
|
regexp_interval_open_escape
|
84
|
-
|
98
|
+
regexp_katakana_property
|
99
|
+
regexp_letter_property
|
100
|
+
regexp_linebreak_type
|
85
101
|
regexp_literal_escape
|
86
102
|
regexp_literal_literal
|
87
103
|
regexp_lookahead_assertion
|
88
104
|
regexp_lookbehind_assertion
|
105
|
+
regexp_lower_posixclass
|
89
106
|
regexp_mark_keep
|
90
107
|
regexp_match_start_anchor
|
91
108
|
regexp_meta_sequence_escape
|
@@ -100,34 +117,40 @@ module Mutant
|
|
100
117
|
regexp_nonword_boundary_anchor
|
101
118
|
regexp_nonword_type
|
102
119
|
regexp_number_backref
|
120
|
+
regexp_octal_escape
|
103
121
|
regexp_one_or_more_escape
|
104
122
|
regexp_open_conditional
|
105
123
|
regexp_options_group
|
124
|
+
regexp_options_switch_group
|
106
125
|
regexp_passive_group
|
107
126
|
regexp_possessive_interval
|
108
127
|
regexp_possessive_one_or_more
|
109
128
|
regexp_possessive_zero_or_more
|
110
129
|
regexp_possessive_zero_or_one
|
130
|
+
regexp_print_nonposixclass
|
111
131
|
regexp_print_nonproperty
|
132
|
+
regexp_print_posixclass
|
133
|
+
regexp_print_posixclass
|
112
134
|
regexp_print_property
|
135
|
+
regexp_punct_posixclass
|
136
|
+
regexp_range_set
|
113
137
|
regexp_reluctant_interval
|
114
138
|
regexp_reluctant_one_or_more
|
115
139
|
regexp_reluctant_zero_or_more
|
116
140
|
regexp_root_expression
|
117
|
-
regexp_script_arabic_property
|
118
|
-
regexp_script_han_property
|
119
|
-
regexp_script_hangul_property
|
120
|
-
regexp_script_hiragana_property
|
121
|
-
regexp_script_katakana_property
|
122
141
|
regexp_sequence_expression
|
123
142
|
regexp_set_close_escape
|
124
143
|
regexp_set_open_escape
|
144
|
+
regexp_space_posixclass
|
125
145
|
regexp_space_type
|
126
146
|
regexp_tab_escape
|
147
|
+
regexp_upper_posixclass
|
127
148
|
regexp_vertical_tab_escape
|
128
149
|
regexp_whitespace_free_space
|
129
150
|
regexp_word_boundary_anchor
|
151
|
+
regexp_word_posixclass
|
130
152
|
regexp_word_type
|
153
|
+
regexp_xdigit_posixclass
|
131
154
|
regexp_xgrapheme_type
|
132
155
|
regexp_zero_or_more_escape
|
133
156
|
regexp_zero_or_one_escape
|
@@ -12,10 +12,12 @@ module Mutant
|
|
12
12
|
# @param [UnboundMethod] method
|
13
13
|
#
|
14
14
|
# @return [Matcher::Method::Instance]
|
15
|
+
#
|
16
|
+
# :reek:ManualDispatch
|
15
17
|
def self.new(scope, target_method)
|
16
18
|
name = target_method.name
|
17
19
|
evaluator =
|
18
|
-
if scope.
|
20
|
+
if scope.respond_to?(:memoized?) && scope.memoized?(name)
|
19
21
|
Evaluator::Memoized
|
20
22
|
else
|
21
23
|
Evaluator
|
@@ -43,7 +43,6 @@ module Mutant
|
|
43
43
|
# @return [undefined]
|
44
44
|
def mutate_body
|
45
45
|
return unless body.all?(&method(:n_str?))
|
46
|
-
return unless AST::Regexp.supported?(body_expression)
|
47
46
|
|
48
47
|
Mutator.mutate(body_ast).each do |mutation|
|
49
48
|
source = AST::Regexp.to_expression(mutation).to_s
|
@@ -12,7 +12,7 @@ module Mutant
|
|
12
12
|
regexp_space_type: :regexp_nonspace_type,
|
13
13
|
regexp_word_boundary_anchor: :regexp_nonword_boundary_anchor,
|
14
14
|
regexp_word_type: :regexp_nonword_type,
|
15
|
-
regexp_xgrapheme_type: :
|
15
|
+
regexp_xgrapheme_type: :regexp_linebreak_type
|
16
16
|
}
|
17
17
|
|
18
18
|
MAP = IceNine.deep_freeze(map.merge(map.invert))
|
data/lib/mutant/version.rb
CHANGED
data/meta/regexp.rb
CHANGED
@@ -6,7 +6,7 @@ mutations = {
|
|
6
6
|
[:regexp_space_type, '/\s/'] => [:regexp_nonspace_type, '/\S/'],
|
7
7
|
[:regexp_word_boundary_anchor, '/\b/'] => [:regexp_nonword_boundary_anchor, '/\B/'],
|
8
8
|
[:regexp_word_type, '/\w/'] => [:regexp_nonword_type, '/\W/'],
|
9
|
-
[:regexp_xgrapheme_type, '/\X/'] => [:
|
9
|
+
[:regexp_xgrapheme_type, '/\X/'] => [:regexp_linebreak_type, '/\R/']
|
10
10
|
}
|
11
11
|
|
12
12
|
mutations = mutations.merge(mutations.invert)
|
data/mutant.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.extra_rdoc_files = %w[LICENSE]
|
22
22
|
gem.executables = %w[mutant]
|
23
23
|
|
24
|
-
gem.required_ruby_version = '>= 2.
|
24
|
+
gem.required_ruby_version = '>= 2.5'
|
25
25
|
|
26
26
|
gem.add_runtime_dependency('abstract_type', '~> 0.0.7')
|
27
27
|
gem.add_runtime_dependency('adamantium', '~> 0.2.0')
|
@@ -36,7 +36,7 @@ Gem::Specification.new do |gem|
|
|
36
36
|
gem.add_runtime_dependency('parallel', '~> 1.3')
|
37
37
|
gem.add_runtime_dependency('parser', '~> 2.5.1')
|
38
38
|
gem.add_runtime_dependency('procto', '~> 0.0.2')
|
39
|
-
gem.add_runtime_dependency('regexp_parser', '~>
|
39
|
+
gem.add_runtime_dependency('regexp_parser', '~> 1.2')
|
40
40
|
gem.add_runtime_dependency('unparser', '~> 0.2.5')
|
41
41
|
|
42
42
|
gem.add_development_dependency('bundler', '~> 1.10')
|
data/spec/integrations.yml
CHANGED
@@ -23,13 +23,11 @@
|
|
23
23
|
- name: regexp_parser
|
24
24
|
namespace: Regexp
|
25
25
|
repo_uri: 'https://github.com/ammar/regexp_parser.git'
|
26
|
-
repo_ref: '
|
26
|
+
repo_ref: 'v1.2.0'
|
27
27
|
ruby_glob_pattern: '**/*.rb'
|
28
28
|
mutation_coverage: false
|
29
29
|
mutation_generation: true
|
30
|
-
expected_errors:
|
31
|
-
"Regexp::Syntax::Ruby::V233 does not implement: [escape:codepoint]":
|
32
|
-
- regexp_parser/test/parser/test_escapes.rb
|
30
|
+
expected_errors: {}
|
33
31
|
exclude: []
|
34
32
|
- name: auom
|
35
33
|
namespace: AUOM
|
data/spec/support/warnings.yml
CHANGED
@@ -3,6 +3,4 @@
|
|
3
3
|
- 'lib/parallel.rb:222: warning: shadowing outer local variable - args'
|
4
4
|
- 'lib/parallel.rb:227: warning: shadowing outer local variable - args'
|
5
5
|
- 'lib/parser/lexer.rb:10836: warning: assigned but unused variable - testEof'
|
6
|
-
- 'lib/regexp_parser/scanner.rb:
|
7
|
-
- 'lib/regexp_parser/scanner.rb:1689: warning: assigned but unused variable - testEof'
|
8
|
-
- 'lib/regexp_parser/scanner.rb:1692: warning: assigned but unused variable - testEof'
|
6
|
+
- 'lib/regexp_parser/scanner.rb:1146: warning: assigned but unused variable - testEof'
|
@@ -202,17 +202,53 @@ end
|
|
202
202
|
RegexpSpec.expect_mapping(/[ab]+/, :regexp_character_set) do
|
203
203
|
s(:regexp_root_expression,
|
204
204
|
s(:regexp_greedy_one_or_more, 1, -1,
|
205
|
-
s(:regexp_character_set,
|
205
|
+
s(:regexp_character_set,
|
206
|
+
s(:regexp_literal_literal, 'a'),
|
207
|
+
s(:regexp_literal_literal, 'b'))))
|
206
208
|
end
|
207
209
|
|
208
210
|
RegexpSpec.expect_mapping(/[ab]/, :regexp_character_set) do
|
209
211
|
s(:regexp_root_expression,
|
210
|
-
s(:regexp_character_set,
|
212
|
+
s(:regexp_character_set,
|
213
|
+
s(:regexp_literal_literal, 'a'),
|
214
|
+
s(:regexp_literal_literal, 'b')))
|
211
215
|
end
|
212
216
|
|
213
217
|
RegexpSpec.expect_mapping(/[a-j]/, :regexp_character_set) do
|
214
218
|
s(:regexp_root_expression,
|
215
|
-
s(:regexp_character_set,
|
219
|
+
s(:regexp_character_set,
|
220
|
+
s(:regexp_range_set,
|
221
|
+
s(:regexp_literal_literal, 'a'),
|
222
|
+
s(:regexp_literal_literal, 'j'))))
|
223
|
+
end
|
224
|
+
|
225
|
+
RegexpSpec.expect_mapping(/[\b]/, :regexp_backspace_escape) do
|
226
|
+
s(:regexp_root_expression,
|
227
|
+
s(:regexp_character_set,
|
228
|
+
s(:regexp_backspace_escape)))
|
229
|
+
end
|
230
|
+
|
231
|
+
RegexpSpec.expect_mapping(/()(?(1)a|b)/, :regexp_open_conditional) do
|
232
|
+
s(:regexp_root_expression,
|
233
|
+
s(:regexp_capture_group),
|
234
|
+
s(:regexp_open_conditional,
|
235
|
+
s(:regexp_condition_conditional, '(1)'),
|
236
|
+
s(:regexp_sequence_expression,
|
237
|
+
s(:regexp_literal_literal, 'a')),
|
238
|
+
s(:regexp_sequence_expression,
|
239
|
+
s(:regexp_literal_literal, 'b'))))
|
240
|
+
end
|
241
|
+
|
242
|
+
RegexpSpec.expect_mapping(/[ab&&bc]/, :regexp_intersection_set) do
|
243
|
+
s(:regexp_root_expression,
|
244
|
+
s(:regexp_character_set,
|
245
|
+
s(:regexp_intersection_set,
|
246
|
+
s(:regexp_sequence_expression,
|
247
|
+
s(:regexp_literal_literal, 'a'),
|
248
|
+
s(:regexp_literal_literal, 'b')),
|
249
|
+
s(:regexp_sequence_expression,
|
250
|
+
s(:regexp_literal_literal, 'b'),
|
251
|
+
s(:regexp_literal_literal, 'c')))))
|
216
252
|
end
|
217
253
|
|
218
254
|
RegexpSpec.expect_mapping(/\u{9879}/, :regexp_codepoint_list_escape) do
|
@@ -225,7 +261,7 @@ RegexpSpec.expect_mapping(/(?#foo)/, :regexp_comment_group) do
|
|
225
261
|
s(:regexp_comment_group, '(?#foo)'))
|
226
262
|
end
|
227
263
|
|
228
|
-
RegexpSpec.expect_mapping(/(?x
|
264
|
+
RegexpSpec.expect_mapping(/(?x: # comment
|
229
265
|
)/, :regexp_comment_free_space) do
|
230
266
|
s(:regexp_root_expression,
|
231
267
|
s(:regexp_options_group, {
|
@@ -304,7 +340,9 @@ end
|
|
304
340
|
RegexpSpec.expect_mapping(/[ab]+/, :regexp_greedy_one_or_more) do
|
305
341
|
s(:regexp_root_expression,
|
306
342
|
s(:regexp_greedy_one_or_more, 1, -1,
|
307
|
-
s(:regexp_character_set,
|
343
|
+
s(:regexp_character_set,
|
344
|
+
s(:regexp_literal_literal, 'a'),
|
345
|
+
s(:regexp_literal_literal, 'b'))))
|
308
346
|
end
|
309
347
|
|
310
348
|
RegexpSpec.expect_mapping(/(a)*/, :regexp_greedy_zero_or_more) do
|
@@ -336,6 +374,11 @@ RegexpSpec.expect_mapping(/\(/, :regexp_group_open_escape) do
|
|
336
374
|
s(:regexp_group_open_escape))
|
337
375
|
end
|
338
376
|
|
377
|
+
RegexpSpec.expect_mapping(/\101/, :regexp_octal_escape) do
|
378
|
+
s(:regexp_root_expression,
|
379
|
+
s(:regexp_octal_escape, '\\101'))
|
380
|
+
end
|
381
|
+
|
339
382
|
RegexpSpec.expect_mapping(/\xFF/n, :regexp_hex_escape) do
|
340
383
|
s(:regexp_root_expression,
|
341
384
|
s(:regexp_hex_escape, '\\xFF'))
|
@@ -346,11 +389,16 @@ RegexpSpec.expect_mapping(/\h/, :regexp_hex_type) do
|
|
346
389
|
s(:regexp_hex_type))
|
347
390
|
end
|
348
391
|
|
349
|
-
RegexpSpec.expect_mapping(/\H/, :
|
392
|
+
RegexpSpec.expect_mapping(/\H/, :regexp_nonhex_type) do
|
350
393
|
s(:regexp_root_expression,
|
351
394
|
s(:regexp_nonhex_type))
|
352
395
|
end
|
353
396
|
|
397
|
+
RegexpSpec.expect_mapping(/\R/, :regexp_linebreak_type) do
|
398
|
+
s(:regexp_root_expression,
|
399
|
+
s(:regexp_linebreak_type))
|
400
|
+
end
|
401
|
+
|
354
402
|
RegexpSpec.expect_mapping(/\X/, :regexp_xgrapheme_type) do
|
355
403
|
s(:regexp_root_expression,
|
356
404
|
s(:regexp_xgrapheme_type))
|
@@ -366,9 +414,9 @@ RegexpSpec.expect_mapping(/\{/, :regexp_interval_open_escape) do
|
|
366
414
|
s(:regexp_interval_open_escape))
|
367
415
|
end
|
368
416
|
|
369
|
-
RegexpSpec.expect_mapping(/\p{L}/, :
|
417
|
+
RegexpSpec.expect_mapping(/\p{L}/, :regexp_letter_property) do
|
370
418
|
s(:regexp_root_expression,
|
371
|
-
s(:
|
419
|
+
s(:regexp_letter_property))
|
372
420
|
end
|
373
421
|
|
374
422
|
RegexpSpec.expect_mapping(/\-/, :regexp_literal_escape) do
|
@@ -424,14 +472,16 @@ RegexpSpec.expect_mapping(/\G/, :regexp_match_start_anchor) do
|
|
424
472
|
s(:regexp_match_start_anchor))
|
425
473
|
end
|
426
474
|
|
427
|
-
RegexpSpec.expect_mapping(/(?<foo>)
|
475
|
+
RegexpSpec.expect_mapping(/(?<foo>a)+/, :regexp_named_group) do
|
428
476
|
s(:regexp_root_expression,
|
429
|
-
s(:
|
477
|
+
s(:regexp_greedy_one_or_more, 1, -1,
|
478
|
+
s(:regexp_named_group, 'foo',
|
479
|
+
s(:regexp_literal_literal, 'a'))))
|
430
480
|
end
|
431
481
|
|
432
482
|
RegexpSpec.expect_mapping(/(?<a>)\g<a>/, :regexp_name_call_backref) do
|
433
483
|
s(:regexp_root_expression,
|
434
|
-
s(:regexp_named_group, '
|
484
|
+
s(:regexp_named_group, 'a'),
|
435
485
|
s(:regexp_name_call_backref, '\\g<a>'))
|
436
486
|
end
|
437
487
|
|
@@ -477,7 +527,7 @@ RegexpSpec.expect_mapping(/\+/, :regexp_one_or_more_escape) do
|
|
477
527
|
s(:regexp_one_or_more_escape))
|
478
528
|
end
|
479
529
|
|
480
|
-
RegexpSpec.expect_mapping(/(?i
|
530
|
+
RegexpSpec.expect_mapping(/(?i:a)+/, :regexp_options_group) do
|
481
531
|
s(:regexp_root_expression,
|
482
532
|
s(:regexp_greedy_one_or_more, 1, -1,
|
483
533
|
s(:regexp_options_group,
|
@@ -487,7 +537,25 @@ RegexpSpec.expect_mapping(/(?i-:a)+/, :regexp_options_group) do
|
|
487
537
|
s(:regexp_literal_literal, 'a'))))
|
488
538
|
end
|
489
539
|
|
490
|
-
RegexpSpec.expect_mapping(/(?x
|
540
|
+
RegexpSpec.expect_mapping(/(?i-x:a)+/, :regexp_options_group) do
|
541
|
+
s(:regexp_root_expression,
|
542
|
+
s(:regexp_greedy_one_or_more, 1, -1,
|
543
|
+
s(:regexp_options_group,
|
544
|
+
{
|
545
|
+
i: true,
|
546
|
+
x: false
|
547
|
+
},
|
548
|
+
s(:regexp_literal_literal, 'a'))))
|
549
|
+
end
|
550
|
+
|
551
|
+
RegexpSpec.expect_mapping(/a(?i)b/, :regexp_options_switch_group) do
|
552
|
+
s(:regexp_root_expression,
|
553
|
+
s(:regexp_literal_literal, 'a'),
|
554
|
+
s(:regexp_options_switch_group, i: true),
|
555
|
+
s(:regexp_literal_literal, 'b'))
|
556
|
+
end
|
557
|
+
|
558
|
+
RegexpSpec.expect_mapping(/(?x: #{"\n"} )/, :regexp_whitespace_free_space) do
|
491
559
|
s(:regexp_root_expression,
|
492
560
|
s(:regexp_options_group,
|
493
561
|
{
|
@@ -526,6 +594,23 @@ RegexpSpec.expect_mapping(/.?+/, :regexp_possessive_zero_or_one) do
|
|
526
594
|
s(:regexp_dot_meta)))
|
527
595
|
end
|
528
596
|
|
597
|
+
RegexpSpec.expect_mapping(/\P{Print}/, :regexp_print_nonproperty) do
|
598
|
+
s(:regexp_root_expression,
|
599
|
+
s(:regexp_print_nonproperty))
|
600
|
+
end
|
601
|
+
|
602
|
+
RegexpSpec.expect_mapping(/[[:print:]]/, :regexp_print_posixclass) do
|
603
|
+
s(:regexp_root_expression,
|
604
|
+
s(:regexp_character_set,
|
605
|
+
s(:regexp_print_posixclass)))
|
606
|
+
end
|
607
|
+
|
608
|
+
RegexpSpec.expect_mapping(/[[:^print:]]/, :regexp_print_nonposixclass) do
|
609
|
+
s(:regexp_root_expression,
|
610
|
+
s(:regexp_character_set,
|
611
|
+
s(:regexp_print_nonposixclass)))
|
612
|
+
end
|
613
|
+
|
529
614
|
RegexpSpec.expect_mapping(/.{1,3}?/, :regexp_reluctant_interval) do
|
530
615
|
s(:regexp_root_expression,
|
531
616
|
s(:regexp_reluctant_interval, 1, 3,
|
@@ -544,29 +629,29 @@ RegexpSpec.expect_mapping(/.*?/, :regexp_reluctant_zero_or_more) do
|
|
544
629
|
s(:regexp_dot_meta)))
|
545
630
|
end
|
546
631
|
|
547
|
-
RegexpSpec.expect_mapping(/\p{Arabic}/, :
|
632
|
+
RegexpSpec.expect_mapping(/\p{Arabic}/, :regexp_arabic_property) do
|
548
633
|
s(:regexp_root_expression,
|
549
|
-
s(:
|
634
|
+
s(:regexp_arabic_property))
|
550
635
|
end
|
551
636
|
|
552
|
-
RegexpSpec.expect_mapping(/\p{Han}/, :
|
637
|
+
RegexpSpec.expect_mapping(/\p{Han}/, :regexp_han_property) do
|
553
638
|
s(:regexp_root_expression,
|
554
|
-
s(:
|
639
|
+
s(:regexp_han_property))
|
555
640
|
end
|
556
641
|
|
557
|
-
RegexpSpec.expect_mapping(/\p{Hangul}/, :
|
642
|
+
RegexpSpec.expect_mapping(/\p{Hangul}/, :regexp_hangul_property) do
|
558
643
|
s(:regexp_root_expression,
|
559
|
-
s(:
|
644
|
+
s(:regexp_hangul_property))
|
560
645
|
end
|
561
646
|
|
562
|
-
RegexpSpec.expect_mapping(/\p{Hiragana}/, :
|
647
|
+
RegexpSpec.expect_mapping(/\p{Hiragana}/, :regexp_hiragana_property) do
|
563
648
|
s(:regexp_root_expression,
|
564
|
-
s(:
|
649
|
+
s(:regexp_hiragana_property))
|
565
650
|
end
|
566
651
|
|
567
|
-
RegexpSpec.expect_mapping(/\p{Katakana}/, :
|
652
|
+
RegexpSpec.expect_mapping(/\p{Katakana}/, :regexp_katakana_property) do
|
568
653
|
s(:regexp_root_expression,
|
569
|
-
s(:
|
654
|
+
s(:regexp_katakana_property))
|
570
655
|
end
|
571
656
|
|
572
657
|
RegexpSpec.expect_mapping(/foo|bar/, :regexp_sequence_expression) do
|
@@ -28,8 +28,8 @@ RSpec.describe Mutant::Matcher::Method::Instance, '#call' do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
context 'when method is defined inside eval' do
|
31
|
-
let(:scope)
|
32
|
-
let(:method)
|
31
|
+
let(:scope) { base::WithMemoizer }
|
32
|
+
let(:method) { scope.instance_method(:boz) }
|
33
33
|
|
34
34
|
let(:expected_warnings) do
|
35
35
|
[
|
@@ -41,8 +41,8 @@ RSpec.describe Mutant::Matcher::Method::Instance, '#call' do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
context 'when method is defined without source location' do
|
44
|
-
let(:scope)
|
45
|
-
let(:method)
|
44
|
+
let(:scope) { Module }
|
45
|
+
let(:method) { scope.instance_method(:object_id) }
|
46
46
|
|
47
47
|
let(:expected_warnings) do
|
48
48
|
[
|
data/test_app/lib/test_app.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mutant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Markus Schirp
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: abstract_type
|
@@ -198,14 +198,14 @@ dependencies:
|
|
198
198
|
requirements:
|
199
199
|
- - "~>"
|
200
200
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
201
|
+
version: '1.2'
|
202
202
|
type: :runtime
|
203
203
|
prerelease: false
|
204
204
|
version_requirements: !ruby/object:Gem::Requirement
|
205
205
|
requirements:
|
206
206
|
- - "~>"
|
207
207
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
208
|
+
version: '1.2'
|
209
209
|
- !ruby/object:Gem::Dependency
|
210
210
|
name: unparser
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -271,6 +271,7 @@ extensions: []
|
|
271
271
|
extra_rdoc_files:
|
272
272
|
- LICENSE
|
273
273
|
files:
|
274
|
+
- ".circleci/config.yml"
|
274
275
|
- ".gitattributes"
|
275
276
|
- ".gitignore"
|
276
277
|
- ".rspec"
|
@@ -284,7 +285,6 @@ files:
|
|
284
285
|
- README.md
|
285
286
|
- Rakefile
|
286
287
|
- bin/mutant
|
287
|
-
- circle.yml
|
288
288
|
- config/devtools.yml
|
289
289
|
- config/flay.yml
|
290
290
|
- config/flog.yml
|
@@ -311,9 +311,8 @@ files:
|
|
311
311
|
- lib/mutant/ast/nodes.rb
|
312
312
|
- lib/mutant/ast/regexp.rb
|
313
313
|
- lib/mutant/ast/regexp/transformer.rb
|
314
|
-
- lib/mutant/ast/regexp/transformer/alternative.rb
|
315
|
-
- lib/mutant/ast/regexp/transformer/character_set.rb
|
316
314
|
- lib/mutant/ast/regexp/transformer/direct.rb
|
315
|
+
- lib/mutant/ast/regexp/transformer/named_group.rb
|
317
316
|
- lib/mutant/ast/regexp/transformer/options_group.rb
|
318
317
|
- lib/mutant/ast/regexp/transformer/quantifier.rb
|
319
318
|
- lib/mutant/ast/regexp/transformer/recursive.rb
|
@@ -567,7 +566,6 @@ files:
|
|
567
566
|
- spec/unit/mutant/ast/meta/send_spec.rb
|
568
567
|
- spec/unit/mutant/ast/named_children_spec.rb
|
569
568
|
- spec/unit/mutant/ast/regexp/parse_spec.rb
|
570
|
-
- spec/unit/mutant/ast/regexp/supported_predicate_spec.rb
|
571
569
|
- spec/unit/mutant/ast/regexp/transformer/lookup_table/table_spec.rb
|
572
570
|
- spec/unit/mutant/ast/regexp/transformer/lookup_table_spec.rb
|
573
571
|
- spec/unit/mutant/ast/regexp/transformer_spec.rb
|
@@ -670,7 +668,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
670
668
|
requirements:
|
671
669
|
- - ">="
|
672
670
|
- !ruby/object:Gem::Version
|
673
|
-
version: '2.
|
671
|
+
version: '2.5'
|
674
672
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
675
673
|
requirements:
|
676
674
|
- - ">="
|
@@ -700,7 +698,6 @@ test_files:
|
|
700
698
|
- spec/unit/mutant/ast/meta/send_spec.rb
|
701
699
|
- spec/unit/mutant/ast/named_children_spec.rb
|
702
700
|
- spec/unit/mutant/ast/regexp/parse_spec.rb
|
703
|
-
- spec/unit/mutant/ast/regexp/supported_predicate_spec.rb
|
704
701
|
- spec/unit/mutant/ast/regexp/transformer/lookup_table/table_spec.rb
|
705
702
|
- spec/unit/mutant/ast/regexp/transformer/lookup_table_spec.rb
|
706
703
|
- spec/unit/mutant/ast/regexp/transformer_spec.rb
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Mutant
|
4
|
-
module AST
|
5
|
-
module Regexp
|
6
|
-
class Transformer
|
7
|
-
# Transformer for Regexp `alternative` nodes
|
8
|
-
#
|
9
|
-
# This transformer is very similar to the generic recursive mapper
|
10
|
-
# except for the fact that the `Regexp::Expression` class for
|
11
|
-
# `alternative` nodes has a unique constructor
|
12
|
-
class Alternative < self
|
13
|
-
register :regexp_sequence_expression
|
14
|
-
|
15
|
-
# Mapper from `Regexp::Expression` to `Parser::AST::Node`
|
16
|
-
ExpressionToAST = Class.new(Recursive::ExpressionToAST)
|
17
|
-
|
18
|
-
# Mapper from `Parser::AST::Node` to `Regexp::Expression`
|
19
|
-
class ASTToExpression < Transformer::ASTToExpression
|
20
|
-
# Alternative instance with dummy values for `level`, `set_level`,
|
21
|
-
# and `conditional_level`. These values do not affect unparsing
|
22
|
-
ALTERNATIVE = IceNine.deep_freeze(
|
23
|
-
::Regexp::Expression::Alternative.new(0, 0, 0)
|
24
|
-
)
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
# Transform ast into expression
|
29
|
-
#
|
30
|
-
# @return [Regexp::Expression::Alternative]
|
31
|
-
def transform
|
32
|
-
ALTERNATIVE.dup.tap do |alt|
|
33
|
-
alt.expressions = subexpressions
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end # ASTToExpression
|
37
|
-
end # Alternative
|
38
|
-
end # Transformer
|
39
|
-
end # Regexp
|
40
|
-
end # AST
|
41
|
-
end # Mutant
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Mutant
|
4
|
-
module AST
|
5
|
-
module Regexp
|
6
|
-
class Transformer
|
7
|
-
# Transformer for character sets
|
8
|
-
#
|
9
|
-
# The `Regexp::Expression` representation of a character set
|
10
|
-
# is unique due to its usage of the `#members` attribute which
|
11
|
-
# is why it gets its own transformer
|
12
|
-
class CharacterSet < self
|
13
|
-
register :regexp_character_set
|
14
|
-
|
15
|
-
# Mapper from `Regexp::Expression` to `Parser::AST::Node`
|
16
|
-
class ExpressionToAST < Transformer::ExpressionToAST
|
17
|
-
# Transform character set expression into node
|
18
|
-
#
|
19
|
-
# @return [Parser::AST::Node]
|
20
|
-
def call
|
21
|
-
quantify(ast(*expression.members))
|
22
|
-
end
|
23
|
-
end # ExpressionToAST
|
24
|
-
|
25
|
-
# Mapper from `Parser::AST::Node` to `Regexp::Expression`
|
26
|
-
class ASTToExpression < Transformer::ASTToExpression
|
27
|
-
CHARACTER_SET = IceNine.deep_freeze(
|
28
|
-
::Regexp::Expression::CharacterSet.new(
|
29
|
-
::Regexp::Token.new(:set, :character, '[')
|
30
|
-
)
|
31
|
-
)
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
# Transform node into expression
|
36
|
-
#
|
37
|
-
# @return [Regexp::Expression]
|
38
|
-
def transform
|
39
|
-
CHARACTER_SET.dup.tap do |expression|
|
40
|
-
expression.members = node.children
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end # ASTToExpression
|
44
|
-
end # CharacterSet
|
45
|
-
end # Transformer
|
46
|
-
end # Regexp
|
47
|
-
end # AST
|
48
|
-
end # Mutant
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
RSpec.describe Mutant::AST::Regexp, '.supported?' do
|
4
|
-
subject { described_class.supported?(expression) }
|
5
|
-
|
6
|
-
let(:expression) { described_class.parse(regexp) }
|
7
|
-
let(:regexp) { /foo/ }
|
8
|
-
|
9
|
-
it { should be(true) }
|
10
|
-
|
11
|
-
context 'conditional regular expressions' do
|
12
|
-
let(:regexp) { /((?(1)(foo)(bar)))/ }
|
13
|
-
|
14
|
-
it { should be(false) }
|
15
|
-
end
|
16
|
-
end
|