mutant 0.11.2 → 0.11.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b75a7265756d1903cb93a5937959a7fca2a38d157eedf9287d1004b7bd5a05a4
4
- data.tar.gz: 96c7945d43c9ba8dd5c9ef362b4bccc5a536eddf91526a9cb1bce4333df542cc
3
+ metadata.gz: 162764a3b1bf798bc41ada84a438c93ff262c1e470bd03ca4577667577f3d12d
4
+ data.tar.gz: 8949ae97fb1af8e30393518cac0c2affd0b962539c048db30ce61ab34ba6ad4c
5
5
  SHA512:
6
- metadata.gz: 53bf6c9d0de1fb8305fa7e7fce7e2072e381c6a088b0f6e08049222f46de4f908466d498c104f72fd19ddcf1cd7fa2f1cbc2beff099bd5529e880b3bf6a4c2ae
7
- data.tar.gz: 3cc43c8eefce22bceb8465c4b475d4e0cc5b1e2c01a29997713e137605483d33ff792e368a37afd66316113f0495ae2ac265ec22af638cb112785da95f2261f9
6
+ metadata.gz: 8328c5f209244d2cee86828cc9923ddf649ccc7fa2ffd921b484468c77b8d8cf0c23ad58605286c25b9a58f98c92a8212eec2641cb00ead46dfaba92aef865f3
7
+ data.tar.gz: 415018adeaea5c01d3ecbda5a8896e66de1facb819336093859cb5dc1b45d70e99e01bae63b355930dfffa22ad9bb23092aee97b14fff0fbe188b817a52783d6
data/LICENSE CHANGED
@@ -5,8 +5,8 @@ END-USER LICENSE AGREEMENT
5
5
  IMPORTANT: THIS SOFTWARE END-USER LICENSE AGREEMENT ("EULA") IS A LEGAL
6
6
  AGREEMENT (“Agreement”) BETWEEN YOU (THE CUSTOMER, EITHER AS AN INDIVIDUAL OR,
7
7
  IF PURCHASED OR OTHERWISE ACQUIRED BY OR FOR AN ENTITY, AS AN ENTITY) AND
8
- CONTRIBUTED SYSTEMS. READ IT CAREFULLY BEFORE COMPLETING THE INSTALLATION
9
- PROCESS AND USING SIDEKIQ PRO AND RELATED SOFTWARE COMPONENTS (“SOFTWARE”).
8
+ SCHIRP DSO LTD. READ IT CAREFULLY BEFORE COMPLETING THE INSTALLATION
9
+ PROCESS AND USING MUTANT AND RELATED SOFTWARE COMPONENTS (“SOFTWARE”).
10
10
 
11
11
  IT PROVIDES A LICENSE TO USE THE SOFTWARE AND CONTAINS WARRANTY INFORMATION
12
12
  AND LIABILITY DISCLAIMERS. BY INSTALLING AND USING THE SOFTWARE, YOU ARE
@@ -110,9 +110,9 @@ module Mutant
110
110
  #
111
111
  # @return [Table]
112
112
  def self.create(*rows)
113
- table = rows.map do |ast_type, token, klass|
113
+ table = rows.to_h do |ast_type, token, klass|
114
114
  [ast_type, Mapping.new(::Regexp::Token.new(*token), klass)]
115
- end.to_h
115
+ end
116
116
 
117
117
  new(table)
118
118
  end
@@ -7,13 +7,13 @@ module Mutant
7
7
  class Run < self
8
8
  NAME = 'run'
9
9
  SHORT_DESCRIPTION = 'Run code analysis'
10
- SLEEP = 60
11
10
  SUBCOMMANDS = EMPTY_ARRAY
12
11
 
13
12
  UNLICENSED = <<~MESSAGE.lines.freeze
14
- Soft fail, continuing in #{SLEEP} seconds
15
- Next major version will enforce the license
16
- See https://github.com/mbj/mutant#licensing
13
+ You are using mutant unlicensed.
14
+
15
+ See https://github.com/mbj/mutant#licensing to aquire a license.
16
+ Note: Its free for opensource use, which is recommended for trials.
17
17
  MESSAGE
18
18
 
19
19
  NO_TESTS_MESSAGE = <<~'MESSAGE'
@@ -40,7 +40,7 @@ module Mutant
40
40
  private
41
41
 
42
42
  def action
43
- soft_fail(License.call(world))
43
+ License.call(world)
44
44
  .bind { bootstrap }
45
45
  .bind(&method(:validate_tests))
46
46
  .bind(&Runner.public_method(:call))
@@ -62,23 +62,6 @@ module Mutant
62
62
  Either::Left.new('Uncovered mutations detected, exiting nonzero!')
63
63
  end
64
64
  end
65
-
66
- def soft_fail(result)
67
- result.either(
68
- lambda do |message|
69
- stderr = world.stderr
70
- stderr.puts(message)
71
- UNLICENSED.each { |line| stderr.puts(unlicensed(line)) }
72
- world.kernel.sleep(SLEEP)
73
- Either::Right.new(nil)
74
- end,
75
- ->(_subscription) { Either::Right.new(nil) }
76
- )
77
- end
78
-
79
- def unlicensed(message)
80
- "[Mutant-License-Error]: #{message}"
81
- end
82
65
  end # Run
83
66
  end # Environment
84
67
  end # Command
@@ -184,9 +184,9 @@ module Mutant
184
184
  end
185
185
 
186
186
  def format_subcommands
187
- commands = subcommands.map do |subcommand|
187
+ commands = subcommands.to_h do |subcommand|
188
188
  [subcommand.command_name, subcommand.short_description]
189
- end.to_h
189
+ end
190
190
 
191
191
  width = commands.each_key.map(&:length).max
192
192
 
data/lib/mutant/env.rb CHANGED
@@ -68,9 +68,9 @@ module Mutant
68
68
  #
69
69
  # @return Hash{Mutation => Enumerable<Test>}
70
70
  def selections
71
- subjects.map do |subject|
71
+ subjects.to_h do |subject|
72
72
  [subject, selector.call(subject)]
73
- end.to_h
73
+ end
74
74
  end
75
75
  memoize :selections
76
76
 
@@ -142,11 +142,10 @@ module Mutant
142
142
  result = mutation.insert(world.kernel)
143
143
  hooks.run(:mutation_insert_post, mutation)
144
144
 
145
- if result.equal?(Loader::Result::VoidValue.instance)
146
- Result::Test::VoidValue.instance
147
- else
148
- integration.call(tests)
149
- end
145
+ result.either(
146
+ ->(_) { Result::Test::VoidValue.instance },
147
+ ->(_) { integration.call(tests) }
148
+ )
150
149
  end
151
150
  end
152
151
 
@@ -36,7 +36,7 @@ module Mutant
36
36
  fail "Unmatched git remote URL: #{input.inspect}"
37
37
  end
38
38
 
39
- new(match[:host], match[:path])
39
+ new(match[:host], match[:path].downcase)
40
40
  end
41
41
  private_class_method :parse_url
42
42
  end
data/lib/mutant/loader.rb CHANGED
@@ -9,17 +9,8 @@ module Mutant
9
9
 
10
10
  private_constant(*constants(false))
11
11
 
12
- class Result
13
- include Singleton
14
-
15
- # Vale returned on successful load
16
- class Success < self
17
- end # Success
18
-
19
- # Vale returned on MRI detecting void value expressions
20
- class VoidValue < self
21
- end # VoidValue
22
- end # Result
12
+ VOID_VALUE = Either::Left.new(nil)
13
+ SUCCESS = Either::Right.new(nil)
23
14
 
24
15
  # Call loader
25
16
  #
@@ -45,12 +36,12 @@ module Mutant
45
36
  rescue SyntaxError => exception
46
37
  # rubocop:disable Style/GuardClause
47
38
  if VOID_VALUE_REGEXP.match?(exception.message)
48
- Result::VoidValue.instance
39
+ VOID_VALUE
49
40
  else
50
41
  raise
51
42
  end
52
43
  else
53
- Result::Success.instance
44
+ SUCCESS
54
45
  end
55
46
  end # Loader
56
47
  end # Mutant
@@ -25,7 +25,7 @@ module Mutant
25
25
 
26
26
  private_constant(*constants(false))
27
27
 
28
- DEFAULT = new(anima.attribute_names.map { |name| [name, []] }.to_h)
28
+ DEFAULT = new(anima.attribute_names.to_h { |name| [name, []] })
29
29
 
30
30
  expression = Transform::Block.capture(:expression) do |input|
31
31
  Mutant::Config::DEFAULT.expression_parser.call(input)
@@ -74,8 +74,7 @@ module Mutant
74
74
  def merge(other)
75
75
  self.class.new(
76
76
  to_h
77
- .map { |name, value| [name, value + other.public_send(name)] }
78
- .to_h
77
+ .to_h { |name, value| [name, value + other.public_send(name)] }
79
78
  )
80
79
  end
81
80
 
@@ -41,6 +41,16 @@ module Mutant
41
41
  node.children.fetch(NAME_INDEX).equal?(method_name)
42
42
  end
43
43
 
44
+ def visibility
45
+ if scope.private_instance_methods.include?(method_name)
46
+ :private
47
+ elsif scope.protected_instance_methods.include?(method_name)
48
+ :protected
49
+ else
50
+ :public
51
+ end
52
+ end
53
+
44
54
  # Evaluator specialized for memoized instance methods
45
55
  class Memoized < self
46
56
  SUBJECT_CLASS = Subject::Method::Instance::Memoized
@@ -99,16 +99,40 @@ module Mutant
99
99
  node = matched_node_path.last || return
100
100
 
101
101
  self.class::SUBJECT_CLASS.new(
102
- context: context,
103
- node: node
102
+ context: context,
103
+ node: node,
104
+ visibility: visibility
104
105
  )
105
106
  end
106
- memoize :subject
107
107
 
108
108
  def matched_node_path
109
109
  AST.find_last_path(ast, &method(:match?))
110
110
  end
111
111
  memoize :matched_node_path
112
+
113
+ def visibility
114
+ # This can be cleaned up once we are on >ruby-3.0
115
+ # Method#{public,private,protected}? exists there.
116
+ #
117
+ # On Ruby 3.1 this can just be:
118
+ #
119
+ # if target_method.private?
120
+ # :private
121
+ # elsif target_method.protected?
122
+ # :protected
123
+ # else
124
+ # :public
125
+ # end
126
+ #
127
+ # Change to this once 3.0 is EOL.
128
+ if scope.private_methods.include?(method_name)
129
+ :private
130
+ elsif scope.protected_methods.include?(method_name)
131
+ :protected
132
+ else
133
+ :public
134
+ end
135
+ end
112
136
  end # Evaluator
113
137
 
114
138
  private_constant(*constants(false))
@@ -93,7 +93,9 @@ module Mutant
93
93
 
94
94
  Object: %<scope>s
95
95
  Method: %<method_name>s
96
- Exception: %<exception>s
96
+ Exception:
97
+
98
+ %<exception>s
97
99
 
98
100
  See: https://github.com/mbj/mutant/issues/1273
99
101
  MESSAGE
@@ -69,7 +69,10 @@ module Mutant
69
69
  kernel: kernel,
70
70
  source: monkeypatch,
71
71
  subject: subject
72
- )
72
+ ).fmap do
73
+ subject.post_insert
74
+ nil
75
+ end
73
76
  end
74
77
 
75
78
  # Rendered mutation diff
@@ -6,6 +6,8 @@ module Mutant
6
6
  # Mutator for arguments node
7
7
  class Arguments < self
8
8
 
9
+ ANONYMOUS_BLOCKARG_PRED = ::Parser::AST::Node.new(:blockarg, [nil]).method(:eql?)
10
+
9
11
  handle(:args)
10
12
 
11
13
  private
@@ -17,15 +19,24 @@ module Mutant
17
19
  end
18
20
 
19
21
  def emit_argument_presence
20
- emit_type
22
+ emit_type unless removed_block_arg?(EMPTY_ARRAY)
21
23
 
22
24
  Util::Array::Presence.call(children).each do |children|
23
- unless children.one? && n_mlhs?(children.first)
25
+ unless removed_block_arg?(children) || (children.one? && n_mlhs?(children.first))
24
26
  emit_type(*children)
25
27
  end
26
28
  end
27
29
  end
28
30
 
31
+ def removed_block_arg?(children)
32
+ anonymous_block_arg? && children.none?(&ANONYMOUS_BLOCKARG_PRED)
33
+ end
34
+
35
+ def anonymous_block_arg?
36
+ children.any?(&ANONYMOUS_BLOCKARG_PRED)
37
+ end
38
+ memoize :anonymous_block_arg?
39
+
29
40
  def emit_argument_mutations
30
41
  children.each_with_index do |child, index|
31
42
  Mutator.mutate(child).each do |mutant|
@@ -12,6 +12,7 @@ module Mutant
12
12
  private
13
13
 
14
14
  def dispatch
15
+ return unless argument
15
16
  emit_argument_mutations
16
17
  emit_symbol_to_proc_mutations
17
18
  end
@@ -50,7 +50,7 @@ module Mutant
50
50
  Mutant
51
51
  .traverse(->(line) { parse_line(root, line) }, lines)
52
52
  .fmap do |paths|
53
- paths.map { |path| [path.path, path] }.to_h
53
+ paths.to_h { |path| [path.path, path] }
54
54
  end
55
55
  end
56
56
  end
@@ -17,6 +17,11 @@ module Mutant
17
17
  self
18
18
  end
19
19
 
20
+ def post_insert
21
+ scope.__send__(visibility, name)
22
+ self
23
+ end
24
+
20
25
  # Mutator for memoizable memoized instance methods
21
26
  class Memoized < self
22
27
  include AST::Sexp
@@ -17,6 +17,11 @@ module Mutant
17
17
  self
18
18
  end
19
19
 
20
+ def post_insert
21
+ scope.singleton_class.__send__(visibility, name)
22
+ self
23
+ end
24
+
20
25
  end # Singleton
21
26
  end # Method
22
27
  end # Subject
@@ -4,6 +4,7 @@ module Mutant
4
4
  class Subject
5
5
  # Abstract base class for method subjects
6
6
  class Method < self
7
+ include anima.add(:visibility)
7
8
 
8
9
  # Method name
9
10
  #
@@ -33,6 +33,13 @@ module Mutant
33
33
  self
34
34
  end
35
35
 
36
+ # Perform post insert cleanup
37
+ #
38
+ # @return [self]
39
+ def post_insert
40
+ self
41
+ end
42
+
36
43
  # Source line range
37
44
  #
38
45
  # @return [Range<Integer>]
@@ -351,7 +351,7 @@ module Mutant
351
351
  def transform_keys(keys, input)
352
352
  success(
353
353
  keys
354
- .map do |key|
354
+ .to_h do |key|
355
355
  [
356
356
  key.value,
357
357
  coerce_key(key, input).from_right do |error|
@@ -359,7 +359,6 @@ module Mutant
359
359
  end
360
360
  ]
361
361
  end
362
- .to_h
363
362
  )
364
363
  end
365
364
  # rubocop:enable Metrics/MethodLength
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Mutant
4
4
  # Current mutant version
5
- VERSION = '0.11.2'
5
+ VERSION = '0.11.5'
6
6
  end # Mutant
@@ -17,10 +17,7 @@ module Mutant
17
17
 
18
18
  include AST::Sexp
19
19
 
20
- # rubocop:disable Lint/InheritException
21
20
  LoadError = Class.new(::LoadError)
22
- # rubocop:enable Lint/InheritException
23
-
24
21
  # Initialize object
25
22
  #
26
23
  # @param [Symbol] namespace
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.11.2
4
+ version: 0.11.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-15 00:00:00.000000000 Z
11
+ date: 2022-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 3.0.0
33
+ version: 3.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 3.0.0
40
+ version: 3.1.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: regexp_parser
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -78,14 +78,14 @@ dependencies:
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: 0.6.2
81
+ version: 0.6.4
82
82
  type: :runtime
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: 0.6.2
88
+ version: 0.6.4
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: parallel
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -368,7 +368,8 @@ files:
368
368
  homepage: https://github.com/mbj/mutant
369
369
  licenses:
370
370
  - Nonstandard
371
- metadata: {}
371
+ metadata:
372
+ rubygems_mfa_required: 'true'
372
373
  post_install_message:
373
374
  rdoc_options: []
374
375
  require_paths:
@@ -377,7 +378,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
377
378
  requirements:
378
379
  - - ">="
379
380
  - !ruby/object:Gem::Version
380
- version: '2.6'
381
+ version: '2.7'
381
382
  required_rubygems_version: !ruby/object:Gem::Requirement
382
383
  requirements:
383
384
  - - ">="