mutant 0.8.18 → 0.8.19
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.
- 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
|