mutant 0.8.18 → 0.8.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/{circle.yml → .circleci/config.yml} +3 -9
  3. data/.rubocop.yml +1 -1
  4. data/Changelog.md +5 -0
  5. data/Gemfile.lock +6 -6
  6. data/README.md +1 -1
  7. data/config/flay.yml +1 -1
  8. data/lib/mutant.rb +4 -5
  9. data/lib/mutant/ast/regexp.rb +0 -15
  10. data/lib/mutant/ast/regexp/transformer/direct.rb +65 -47
  11. data/lib/mutant/ast/regexp/transformer/named_group.rb +59 -0
  12. data/lib/mutant/ast/regexp/transformer/options_group.rb +22 -7
  13. data/lib/mutant/ast/regexp/transformer/recursive.rb +14 -8
  14. data/lib/mutant/ast/regexp/transformer/root.rb +1 -1
  15. data/lib/mutant/ast/regexp/transformer/text.rb +7 -5
  16. data/lib/mutant/ast/types.rb +29 -6
  17. data/lib/mutant/expression/namespace.rb +1 -1
  18. data/lib/mutant/matcher/method/instance.rb +3 -1
  19. data/lib/mutant/mutator/node/generic.rb +1 -0
  20. data/lib/mutant/mutator/node/literal/regex.rb +0 -1
  21. data/lib/mutant/mutator/node/regexp/character_type.rb +1 -1
  22. data/lib/mutant/version.rb +1 -1
  23. data/lib/mutant/warning_filter.rb +1 -1
  24. data/meta/regexp.rb +3 -0
  25. data/meta/regexp/character_types.rb +1 -1
  26. data/mutant.gemspec +2 -2
  27. data/spec/integrations.yml +2 -4
  28. data/spec/support/warnings.yml +1 -3
  29. data/spec/unit/mutant/ast/regexp_spec.rb +108 -23
  30. data/spec/unit/mutant/matcher/method/instance_spec.rb +4 -4
  31. data/test_app/lib/test_app.rb +1 -1
  32. metadata +7 -10
  33. data/lib/mutant/ast/regexp/transformer/alternative.rb +0 -41
  34. data/lib/mutant/ast/regexp/transformer/character_set.rb +0 -48
  35. 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: e671cfb966debd1654091d93bd356505efdd8c30ed8c440c98b141f40f0e375b
4
- data.tar.gz: 403a97ad6d13f1fd9809b0acc48fcb8e19289b3a01b0aaccb25bb83ea49bc4a3
3
+ metadata.gz: dbaeba3292082f39979c87a1918f1a75a681f4cca1299fee251373779c1f381b
4
+ data.tar.gz: b1e57ca598f25e27d1c74e2b17d2033edb1d3b602742eb0fa62a6a7ac1f1058a
5
5
  SHA512:
6
- metadata.gz: 892d50fd61d110717f60877f1c1249c92d33179b70f44fdbb725dea7b3b34a82a8f8aa8c9b79329dbc74b12b15006a15d0cc2a118727d4732c65095b19421a64
7
- data.tar.gz: 2b2f81d37ba20d4884e168dfe43ad8744e57b9bc0311aeb97f666f0652def83b98df9b71b1855b24070c1cbe16491eecd12f295d65d58bbe6c328041791225e6
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
- ruby_2_3:
9
+ ruby_2_5:
11
10
  <<: *defaults
12
11
  docker:
13
- - image: circleci/ruby:2.3.4
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
- - ruby_2_3
23
- - ruby_2_4
17
+ - ruby_2_5
data/.rubocop.yml CHANGED
@@ -4,4 +4,4 @@ AllCops:
4
4
  - 'test_app/**/*'
5
5
  - 'tmp/**/*'
6
6
  - 'vendor/**/*'
7
- TargetRubyVersion: 2.3
7
+ TargetRubyVersion: 2.5
data/Changelog.md CHANGED
@@ -1,3 +1,8 @@
1
+ # v0.8.19 2018-11-06
2
+
3
+ * Drop support for Ruby < 2.5
4
+ * Fix bug when mutating a module that includes Memoizable
5
+
1
6
  # v0.8.18 2018-10-24
2
7
 
3
8
  * Add support for regexp unicode print nodes https://github.com/mbj/mutant/pull/749
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mutant (0.8.16)
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 (~> 0.4.9)
18
+ regexp_parser (~> 1.2)
19
19
  unparser (~> 0.2.5)
20
- mutant-rspec (0.8.16)
21
- mutant (~> 0.8.16)
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 (0.4.13)
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.16.4
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
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 16
3
- total_score: 1318
3
+ total_score: 1364
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/text'
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/character_set'
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/alternative'
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'
@@ -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
- [:regexp_alpha_property, [:property, :alpha, '\p{Alpha}'], ::Regexp::Expression::UnicodeProperty::Alpha],
42
- [:regexp_alternation_escape, [:escape, :alternation, '\|'], ::Regexp::Expression::EscapeSequence::Literal],
43
- [:regexp_bell_escape, [:escape, :bell, '\a'], ::Regexp::Expression::EscapeSequence::Literal],
44
- [:regexp_bol_anchor, [:anchor, :bol, '^'], ::Regexp::Expression::Anchor::BeginningOfLine],
45
- [:regexp_bol_escape, [:escape, :bol, '\^'], ::Regexp::Expression::EscapeSequence::Literal],
46
- [:regexp_bos_anchor, [:anchor, :bos, '\\A'], ::Regexp::Expression::Anchor::BeginningOfString],
47
- [:regexp_carriage_escape, [:escape, :carriage, '\r'], ::Regexp::Expression::EscapeSequence::Literal],
48
- [:regexp_digit_type, [:type, :digit, '\d'], ::Regexp::Expression::CharacterType::Digit],
49
- [:regexp_dot_escape, [:escape, :dot, '\.'], ::Regexp::Expression::EscapeSequence::Literal],
50
- [:regexp_dot_meta, [:meta, :dot, '.'], ::Regexp::Expression::CharacterType::Any],
51
- [:regexp_eol_anchor, [:anchor, :eol, '$'], ::Regexp::Expression::Anchor::EndOfLine],
52
- [:regexp_eol_escape, [:escape, :eol, '\$'], ::Regexp::Expression::EscapeSequence::Literal],
53
- [:regexp_eos_anchor, [:anchor, :eos, '\\z'], ::Regexp::Expression::Anchor::EndOfString],
54
- [:regexp_eos_ob_eol_anchor, [:anchor, :eos_ob_eol, '\\Z'], ::Regexp::Expression::Anchor::EndOfStringOrBeforeEndOfLine],
55
- [:regexp_escape_escape, [:escape, :escape, '\e'], ::Regexp::Expression::EscapeSequence::AsciiEscape],
56
- [:regexp_form_feed_escape, [:escape, :form_feed, '\f'], ::Regexp::Expression::EscapeSequence::FormFeed],
57
- [:regexp_group_close_escape, [:escape, :group_close, '\)'], ::Regexp::Expression::EscapeSequence::Literal],
58
- [:regexp_group_open_escape, [:escape, :group_open, '\('], ::Regexp::Expression::EscapeSequence::Literal],
59
- [:regexp_hex_type, [:type, :hex, '\h'], ::Regexp::Expression::CharacterType::Hex],
60
- [:regexp_interval_close_escape, [:escape, :interval_close, '\}'], ::Regexp::Expression::EscapeSequence::Literal],
61
- [:regexp_interval_open_escape, [:escape, :interval_open, '\{'], ::Regexp::Expression::EscapeSequence::Literal],
62
- [:regexp_letter_any_property, [:property, :letter_any, '\p{L}'], ::Regexp::Expression::UnicodeProperty::Letter::Any],
63
- [:regexp_mark_keep, [:keep, :mark, '\K'], ::Regexp::Expression::Keep::Mark],
64
- [:regexp_match_start_anchor, [:anchor, :match_start, '\\G'], ::Regexp::Expression::Anchor::MatchStart],
65
- [:regexp_newline_escape, [:escape, :newline, '\n'], ::Regexp::Expression::EscapeSequence::Literal],
66
- [:regexp_nondigit_type, [:type, :nondigit, '\D'], ::Regexp::Expression::CharacterType::NonDigit],
67
- [:regexp_nonhex_type, [:type, :nonhex, '\H'], ::Regexp::Expression::CharacterType::NonHex],
68
- [:regexp_nonspace_type, [:type, :nonspace, '\S'], ::Regexp::Expression::CharacterType::NonSpace],
69
- [:regexp_nonword_boundary_anchor, [:anchor, :nonword_boundary, '\\B'], ::Regexp::Expression::Anchor::NonWordBoundary],
70
- [:regexp_nonword_type, [:type, :nonword, '\W'], ::Regexp::Expression::CharacterType::NonWord],
71
- [:regexp_one_or_more_escape, [:escape, :one_or_more, '\+'], ::Regexp::Expression::EscapeSequence::Literal],
72
- [:regexp_print_nonproperty, [:property, :nonprint, '\P{Print}'], ::Regexp::Expression::UnicodeProperty::Print],
73
- [:regexp_print_property, [:property, :print, '\p{Print}'], ::Regexp::Expression::UnicodeProperty::Print],
74
- [:regexp_script_arabic_property, [:property, :script_arabic, '\p{Arabic}'], ::Regexp::Expression::UnicodeProperty::Script],
75
- [:regexp_script_han_property, [:property, :script_han, '\p{Han}'], ::Regexp::Expression::UnicodeProperty::Script],
76
- [:regexp_script_hangul_property, [:property, :script_hangul, '\p{Hangul}'], ::Regexp::Expression::UnicodeProperty::Script],
77
- [:regexp_script_hiragana_property, [:property, :script_hiragana, '\p{Hiragana}'], ::Regexp::Expression::UnicodeProperty::Script],
78
- [:regexp_script_katakana_property, [:property, :script_katakana, '\p{Katakana}'], ::Regexp::Expression::UnicodeProperty::Script],
79
- [:regexp_set_close_escape, [:escape, :set_close, '\]'], ::Regexp::Expression::EscapeSequence::Literal],
80
- [:regexp_set_open_escape, [:escape, :set_open, '\['], ::Regexp::Expression::EscapeSequence::Literal],
81
- [:regexp_space_type, [:type, :space, '\s'], ::Regexp::Expression::CharacterType::Space],
82
- [:regexp_vertical_tab_escape, [:escape, :vertical_tab, '\v'], ::Regexp::Expression::EscapeSequence::VerticalTab],
83
- [:regexp_word_boundary_anchor, [:anchor, :word_boundary, '\b'], ::Regexp::Expression::Anchor::WordBoundary],
84
- [:regexp_word_type, [:type, :word, '\w'], ::Regexp::Expression::CharacterType::Word],
85
- [:regexp_xgrapheme_type, [:type, :xgrapheme, '\X'], ::Regexp::Expression::CharacterType::ExtendedGrapheme],
86
- [:regexp_zero_or_more_escape, [:escape, :zero_or_more, '\*'], ::Regexp::Expression::EscapeSequence::Literal],
87
- [:regexp_zero_or_one_escape, [:escape, :zero_or_one, '\?'], ::Regexp::Expression::EscapeSequence::Literal]
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.options, *children))
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 :options
27
+ children :option_changes
27
28
 
28
29
  private
29
30
 
30
- # Covnert node into expression
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, :options, text)
52
+ ::Regexp::Token.new(:group, type, text)
52
53
  )
53
54
  end
54
55
 
55
- # Flag text constructed from enabled options
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
- flags = options.map { |key, value| key if value }.join
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
- "(?#{flags}-:"
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, :alternation, '|'], ::Regexp::Expression::Alternation],
26
- [:regexp_nlookahead_assertion, [:assertion, :nlookahead, '(?!'], ::Regexp::Expression::Assertion::NegativeLookahead],
27
- [:regexp_passive_group, [:group, :passive, '(?:'], ::Regexp::Expression::Group::Passive],
28
- [:regexp_nlookbehind_assertion, [:assertion, :nlookbehind, '(?<!'], ::Regexp::Expression::Assertion::NegativeLookbehind],
29
- [:regexp_lookbehind_assertion, [:assertion, :lookbehind, '(?<='], ::Regexp::Expression::Assertion::Lookbehind],
30
- [:regexp_lookahead_assertion, [:assertion, :lookahead, '(?='], ::Regexp::Expression::Assertion::Lookahead],
31
- [:regexp_atomic_group, [:group, :atomic, '(?>'], ::Regexp::Expression::Group::Atomic],
32
- [:regexp_capture_group, [:group, :capture, '('], ::Regexp::Expression::Group::Capture]
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
@@ -19,7 +19,7 @@ module Mutant
19
19
  #
20
20
  # @return [Regexp::Expression::Root]
21
21
  def transform
22
- ::Regexp::Expression::Root.new.tap do |root|
22
+ ::Regexp::Expression::Root.build.tap do |root|
23
23
  root.expressions = subexpressions
24
24
  end
25
25
  end
@@ -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::Literal],
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::Literal],
36
- [:regexp_codepoint_escape, %i[escape codepoint], ::Regexp::Expression::EscapeSequence::Literal],
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
@@ -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
- regexp_letter_any_property
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
@@ -44,7 +44,7 @@ module Mutant
44
44
  #
45
45
  # @return [Integer]
46
46
  def match_length(expression)
47
- if @recursion_pattern =~ expression.syntax
47
+ if @recursion_pattern.match?(expression.syntax)
48
48
  scope_name.length
49
49
  else
50
50
  0
@@ -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.include?(Memoizable) && scope.memoized?(name)
20
+ if scope.respond_to?(:memoized?) && scope.memoized?(name)
19
21
  Evaluator::Memoized
20
22
  else
21
23
  Evaluator
@@ -47,6 +47,7 @@ module Mutant
47
47
  regexp_eos_ob_eol_anchor
48
48
  regexp_greedy_zero_or_more
49
49
  regexp_hex_type
50
+ regexp_linebreak_type
50
51
  regexp_nondigit_type
51
52
  regexp_nonhex_type
52
53
  regexp_nonspace_type
@@ -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: :regexp_space_type
15
+ regexp_xgrapheme_type: :regexp_linebreak_type
16
16
  }
17
17
 
18
18
  MAP = IceNine.deep_freeze(map.merge(map.invert))
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Mutant
4
4
  # Current mutant version
5
- VERSION = '0.8.18'.freeze
5
+ VERSION = '0.8.19'.freeze
6
6
  end # Mutant
@@ -36,7 +36,7 @@ module Mutant
36
36
  #
37
37
  # @return [self]
38
38
  def write(message)
39
- if WARNING_PATTERN =~ message
39
+ if WARNING_PATTERN.match?(message)
40
40
  warnings << message
41
41
  else
42
42
  target.write(message)
data/meta/regexp.rb CHANGED
@@ -71,6 +71,9 @@ Mutant::Meta::Example.add :regexp do
71
71
 
72
72
  singleton_mutations
73
73
  regexp_mutations
74
+
75
+ mutation '/(?(1)(?:foo)(bar))/'
76
+ mutation '/(?(1)(foo)(?:bar))/'
74
77
  end
75
78
 
76
79
  Pathname
@@ -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/'] => [:regexp_space_type, '/\s/']
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.3'
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', '~> 0.4.9')
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')
@@ -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: 'v0.4.4'
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
@@ -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:1675: warning: assigned but unused variable - testEof'
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, 'a', 'b')))
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, 'a', 'b'))
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, 'a-j'))
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-: # comment
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, 'a', 'b')))
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/, :regexp_hex_type) do
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}/, :regexp_letter_any_property) do
417
+ RegexpSpec.expect_mapping(/\p{L}/, :regexp_letter_property) do
370
418
  s(:regexp_root_expression,
371
- s(:regexp_letter_any_property))
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>)/, :regexp_named_group) do
475
+ RegexpSpec.expect_mapping(/(?<foo>a)+/, :regexp_named_group) do
428
476
  s(:regexp_root_expression,
429
- s(:regexp_named_group, '(?<foo>'))
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, '(?<a>'),
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-:a)+/, :regexp_options_group) do
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-: #{"\n"} )/, :regexp_whitespace_free_space) do
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}/, :regexp_script_arabic_property) do
632
+ RegexpSpec.expect_mapping(/\p{Arabic}/, :regexp_arabic_property) do
548
633
  s(:regexp_root_expression,
549
- s(:regexp_script_arabic_property))
634
+ s(:regexp_arabic_property))
550
635
  end
551
636
 
552
- RegexpSpec.expect_mapping(/\p{Han}/, :regexp_script_han_property) do
637
+ RegexpSpec.expect_mapping(/\p{Han}/, :regexp_han_property) do
553
638
  s(:regexp_root_expression,
554
- s(:regexp_script_han_property))
639
+ s(:regexp_han_property))
555
640
  end
556
641
 
557
- RegexpSpec.expect_mapping(/\p{Hangul}/, :regexp_script_hangul_property) do
642
+ RegexpSpec.expect_mapping(/\p{Hangul}/, :regexp_hangul_property) do
558
643
  s(:regexp_root_expression,
559
- s(:regexp_script_hangul_property))
644
+ s(:regexp_hangul_property))
560
645
  end
561
646
 
562
- RegexpSpec.expect_mapping(/\p{Hiragana}/, :regexp_script_hiragana_property) do
647
+ RegexpSpec.expect_mapping(/\p{Hiragana}/, :regexp_hiragana_property) do
563
648
  s(:regexp_root_expression,
564
- s(:regexp_script_hiragana_property))
649
+ s(:regexp_hiragana_property))
565
650
  end
566
651
 
567
- RegexpSpec.expect_mapping(/\p{Katakana}/, :regexp_script_katakana_property) do
652
+ RegexpSpec.expect_mapping(/\p{Katakana}/, :regexp_katakana_property) do
568
653
  s(:regexp_root_expression,
569
- s(:regexp_script_katakana_property))
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) { base::WithMemoizer }
32
- let(:method) { scope.instance_method(:boz) }
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) { Module }
45
- let(:method) { scope.instance_method(:object_id) }
44
+ let(:scope) { Module }
45
+ let(:method) { scope.instance_method(:object_id) }
46
46
 
47
47
  let(:expected_warnings) do
48
48
  [
@@ -7,7 +7,7 @@ $VERBOSE = false
7
7
  # Namespace for test application
8
8
  module TestApp
9
9
  module InstanceMethodTests
10
- class WithMemoizer
10
+ module WithMemoizer
11
11
  include Adamantium
12
12
 
13
13
  def bar; end; def baz; end
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.18
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-09-24 00:00:00.000000000 Z
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: 0.4.9
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: 0.4.9
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.3'
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