mutant 0.12.4 → 0.13.0

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: 1b880a9125609cec0e9516844abe1e3b1f158c1c7d0773ce65600cb9e2738757
4
- data.tar.gz: b451ee917961bd1e09bbc98a7a23db061a92db9b8d8d557bce63216452498c5a
3
+ metadata.gz: 82b061b05d127f9e8c610effc797e56f102504f0494b908c3e0e6e8bfbb468aa
4
+ data.tar.gz: ff8e61e682146e74e9853f2580faed2cac0750333e2bb26a9fffe98ace2fec1f
5
5
  SHA512:
6
- metadata.gz: ad36b6cede53c724b3ac0d9670188ce3df09f817d1bf4137ff779f9152e79dd27a6af59dc9cd934ada0b7bb52baf136e389cd34facb2d6fa2f22996a9df2dad6
7
- data.tar.gz: 825cc31fda1e4b48b8819b0748bdff1d9ab4cc532d5aec550a8c446c03b97aeea0307708738c50f786798add258873a85678de533d5cbbfdc106499f44f56ea8
6
+ metadata.gz: 8a07d644733195d80aea841e88b111f3d7223a22305ab996f5187a362d90db65fab77049bc10b371222e03b7d6c21cf9ea88ba4fe6ac6268ec75726314e74606
7
+ data.tar.gz: 9a5bcdccede3f23359e35129a436d6eab770f146651024a5a4198dd2df9a97087b22b9c010b5f2a2f3d3c53db5e1844854b7005668cc1969d138c23f77545b5a
@@ -20,8 +20,11 @@ module Mutant
20
20
  end
21
21
  end
22
22
 
23
- @targets.each(&method(:print_mutations))
24
- Either::Right.new(nil)
23
+ if @targets.map(&method(:print_mutations)).all?
24
+ Either::Right.new(nil)
25
+ else
26
+ Either::Left.new('Invalid mutation detected!')
27
+ end
25
28
  end
26
29
 
27
30
  private
@@ -70,18 +73,28 @@ module Mutant
70
73
  end
71
74
  end
72
75
 
76
+ # rubocop:disable Metrics/MethodLength
73
77
  def print_mutations(target)
74
78
  world.stdout.puts(target.identification)
75
79
 
80
+ success = true
81
+
76
82
  Mutator::Node.mutate(
77
83
  config: Mutant::Mutation::Config::DEFAULT.with(ignore_patterns: @ignore_patterns),
78
84
  node: target.node
79
85
  ).each do |mutation|
80
- Reporter::CLI::Printer::Mutation.call(
81
- object: Mutant::Mutation::Evil.new(subject: target, node: mutation),
82
- output: world.stdout
86
+ Mutant::Mutation::Evil.from_node(subject: target, node: mutation).either(
87
+ ->(violation) { world.stdout.puts(violation.report); success = false },
88
+ lambda { |object|
89
+ Reporter::CLI::Printer::Mutation.call(
90
+ object:,
91
+ output: world.stdout
92
+ )
93
+ }
83
94
  )
84
95
  end
96
+
97
+ success
85
98
  end
86
99
 
87
100
  def parse_remaining_arguments(arguments)
data/lib/mutant/loader.rb CHANGED
@@ -15,8 +15,8 @@ module Mutant
15
15
  # Call loader
16
16
  #
17
17
  # @return [Result]
18
- def self.call(*arguments)
19
- new(*arguments).call
18
+ def self.call(*)
19
+ new(*).call
20
20
  end
21
21
 
22
22
  # Call loader
@@ -30,8 +30,12 @@ module Mutant
30
30
  end
31
31
  # rubocop:enable Metrics/MethodLength
32
32
 
33
+ TARGET_MEMOIZER = ::Mutant::Adamantium
34
+
35
+ private_constant(*constants(false))
36
+
33
37
  def self.memoized_method?(scope, method_name)
34
- scope.raw < Adamantium && scope.raw.memoized?(method_name)
38
+ scope.raw < TARGET_MEMOIZER && scope.raw.memoized?(method_name)
35
39
  end
36
40
  private_class_method :memoized_method?
37
41
 
@@ -2,20 +2,31 @@
2
2
 
3
3
  module Mutant
4
4
  module Meta
5
+ # rubocop:disable Metrics/ClassLength
5
6
  class Example
6
7
  # Example verification
7
8
  class Verification
8
- include Adamantium, Anima.new(:example, :mutations)
9
+ include Adamantium, Anima.new(:example, :invalid, :valid)
10
+
11
+ def self.from_mutations(example:, mutations:)
12
+ valid, invalid = [], []
13
+
14
+ mutations.each do |mutation|
15
+ mutation.either(invalid.public_method(:<<), valid.public_method(:<<))
16
+ end
17
+
18
+ new(example:, invalid:, valid:)
19
+ end
9
20
 
10
21
  # Test if mutation was verified successfully
11
22
  #
12
23
  # @return [Boolean]
13
24
  def success?
14
25
  [
15
- original_verification,
16
- invalid,
26
+ invalid_report,
17
27
  missing,
18
28
  no_diffs,
29
+ original_verification_report,
19
30
  unexpected
20
31
  ].all?(&:empty?)
21
32
  end
@@ -29,12 +40,12 @@ module Mutant
29
40
 
30
41
  def reports
31
42
  reports = [example.location]
32
- reports.concat(original)
33
- reports.concat(original_verification)
43
+ reports.concat(original_report)
44
+ reports.concat(original_verification_report)
34
45
  reports.concat(make_report('Missing mutations:', missing))
35
46
  reports.concat(make_report('Unexpected mutations:', unexpected))
36
47
  reports.concat(make_report('No-Diff mutations:', no_diffs))
37
- reports.concat(invalid)
48
+ reports.concat(invalid_report)
38
49
  end
39
50
 
40
51
  def make_report(label, mutations)
@@ -52,7 +63,7 @@ module Mutant
52
63
  ]
53
64
  end
54
65
 
55
- def original
66
+ def original_report
56
67
  [
57
68
  "Original: (operators: #{example.operators.class.operators_name})",
58
69
  example.node,
@@ -60,7 +71,7 @@ module Mutant
60
71
  ]
61
72
  end
62
73
 
63
- def original_verification
74
+ def original_verification_report
64
75
  validation = Unparser::Validation.from_string(example.original_source)
65
76
  if validation.success?
66
77
  []
@@ -77,30 +88,34 @@ module Mutant
77
88
  end.join
78
89
  end
79
90
 
80
- def invalid
81
- mutations.each_with_object([]) do |mutation, aggregate|
82
- validation = Unparser::Validation.from_node(mutation.node)
83
- aggregate << prefix('[invalid-mutation]', validation.report) unless validation.success?
91
+ def invalid_report
92
+ invalid.map do |validation|
93
+ prefix('[invalid-mutation]', validation.report)
84
94
  end
85
95
  end
86
- memoize :invalid
96
+ memoize :invalid_report
87
97
 
88
98
  def unexpected
89
- mutations.reject do |mutation|
99
+ valid.reject do |mutation|
90
100
  example.expected.any? { |expected| expected.node.eql?(mutation.node) }
91
101
  end
92
102
  end
93
103
  memoize :unexpected
94
104
 
95
105
  def missing
96
- (example.expected.map(&:node) - mutations.map(&:node)).map do |node|
97
- Mutation::Evil.new(subject: example, node:)
106
+ example.expected.each_with_object([]) do |expected, aggregate|
107
+ next if valid.any? { |mutation| expected.node.eql?(mutation.node) }
108
+ aggregate << Mutation::Evil.new(
109
+ node: expected.node,
110
+ source: expected.original_source,
111
+ subject: example
112
+ )
98
113
  end
99
114
  end
100
115
  memoize :missing
101
116
 
102
117
  def no_diffs
103
- mutations.select { |mutation| mutation.source.eql?(example.original_source_generated) }
118
+ valid.select { |mutation| mutation.source.eql?(example.source) }
104
119
  end
105
120
  memoize :no_diffs
106
121
 
@@ -23,7 +23,7 @@ module Mutant
23
23
  #
24
24
  # @return [Verification]
25
25
  def verification
26
- Verification.new(example: self, mutations: generated)
26
+ Verification.from_mutations(example: self, mutations: generated)
27
27
  end
28
28
  memoize :verification
29
29
 
@@ -45,13 +45,13 @@ module Mutant
45
45
  )
46
46
  end
47
47
 
48
- # Original source as generated by unparser
48
+ # Original source
49
49
  #
50
50
  # @return [String]
51
- def original_source_generated
51
+ def source
52
52
  Unparser.unparse(node)
53
53
  end
54
- memoize :original_source_generated
54
+ memoize :source
55
55
 
56
56
  # Generated mutations on example source
57
57
  #
@@ -61,7 +61,7 @@ module Mutant
61
61
  config: Mutation::Config::DEFAULT.with(operators:),
62
62
  node:
63
63
  ).map do |node|
64
- Mutation::Evil.new(subject: self, node:)
64
+ Mutation::Evil.from_node(subject: self, node:)
65
65
  end
66
66
  end
67
67
  memoize :generated
@@ -4,11 +4,69 @@ module Mutant
4
4
  # Represent a mutated node with its subject
5
5
  class Mutation
6
6
  include AbstractType, Adamantium
7
- include Anima.new(:subject, :node)
7
+ include Anima.new(:subject, :node, :source)
8
8
 
9
9
  CODE_DELIMITER = "\0"
10
10
  CODE_RANGE = (..4)
11
11
 
12
+ class GenerationError
13
+ include Anima.new(:subject, :node, :unparser_validation)
14
+
15
+ MESSAGE = <<~'MESSAGE'
16
+ === Mutation-Generation-Error ===
17
+ This is a mutant internal issue detected by a mutant internal cross check.
18
+ Please report an issue with the details below.
19
+
20
+ Subject: %<subject_identification>s.
21
+
22
+ Mutation-Source-Diff:
23
+ %<mutation_source_diff>s
24
+
25
+ Mutation-Node-Diff:
26
+ %<mutation_node_diff>s
27
+
28
+ Unparser-Validation:
29
+ %<unparser_validation>s
30
+ MESSAGE
31
+
32
+ def report
33
+ MESSAGE % {
34
+ mutation_source_diff:,
35
+ mutation_node_diff:,
36
+ subject_identification: subject.identification,
37
+ unparser_validation: unparser_validation.report
38
+ }
39
+ end
40
+
41
+ private
42
+
43
+ def mutation_source_diff
44
+ mutation = Evil.new(
45
+ subject:,
46
+ node: nil,
47
+ source: unparser_validation.original_source.from_right
48
+ )
49
+
50
+ mutation.diff.colorized_diff
51
+ end
52
+
53
+ def mutation_node_diff
54
+ Unparser::Diff.new(
55
+ subject.node.to_s.lines,
56
+ node.to_s.lines
57
+ ).colorized_diff
58
+ end
59
+ end # GenerationError
60
+
61
+ def self.from_node(subject:, node:)
62
+ ast = Unparser::AST.from_node(node:)
63
+
64
+ Unparser
65
+ .unparse_validate_ast_either(ast:)
66
+ .lmap { |unparser_validation| GenerationError.new(subject:, node:, unparser_validation:) }
67
+ .fmap { |source| new(node:, source:, subject:) }
68
+ end
69
+
12
70
  # Mutation identification code
13
71
  #
14
72
  # @return [String]
@@ -17,14 +75,6 @@ module Mutant
17
75
  end
18
76
  memoize :code
19
77
 
20
- # Normalized mutation source
21
- #
22
- # @return [String]
23
- def source
24
- Unparser.unparse(node)
25
- end
26
- memoize :source
27
-
28
78
  # Identification string
29
79
  #
30
80
  # @return [String]
@@ -75,10 +125,6 @@ module Mutant
75
125
  end
76
126
  end
77
127
 
78
- # Rendered mutation diff
79
- #
80
- # @return [String, nil]
81
- # the diff, if present
82
128
  def diff
83
129
  Unparser::Diff.build(original_source, source)
84
130
  end
@@ -14,10 +14,7 @@ module Mutant
14
14
  private
15
15
 
16
16
  def dispatch
17
- emit_singletons
18
- emit_left_mutations do |node|
19
- !n_self?(node)
20
- end
17
+ emit_left_mutations
21
18
  emit_right_mutations
22
19
  end
23
20
 
@@ -8,24 +8,11 @@ module Mutant
8
8
  class Argument < self
9
9
  handle(:arg, :kwarg)
10
10
 
11
- UNDERSCORE = '_'
12
-
13
11
  children :name
14
12
 
15
13
  private
16
14
 
17
- def dispatch
18
- emit_name_mutation
19
- end
20
-
21
- def emit_name_mutation
22
- return if skip?
23
- emit_name(:"#{UNDERSCORE}#{name}")
24
- end
25
-
26
- def skip?
27
- name.start_with?(UNDERSCORE)
28
- end
15
+ def dispatch; end
29
16
 
30
17
  # Mutator for optional arguments
31
18
  class Optional < self
@@ -42,7 +29,6 @@ module Mutant
42
29
  private
43
30
 
44
31
  def dispatch
45
- emit_name_mutation
46
32
  emit_required_mutation
47
33
  emit_default_mutations
48
34
  end
@@ -13,36 +13,15 @@ module Mutant
13
13
  private
14
14
 
15
15
  def dispatch
16
- emit_argument_presence
17
16
  emit_argument_mutations
18
17
  emit_mlhs_expansion
19
18
  emit_procarg0_removal
20
19
  end
21
20
 
22
- def emit_argument_presence
23
- emit_type unless removed_block_arg?(EMPTY_ARRAY) || forward_arg?
24
-
25
- children.each_with_index do |removed, index|
26
- new_arguments = children.dup
27
- new_arguments.delete_at(index)
28
- unless forward_type?(removed) || removed_block_arg?(new_arguments) || only_mlhs?(new_arguments)
29
- emit_type(*new_arguments)
30
- end
31
- end
32
- end
33
-
34
21
  def forward_type?(removed)
35
22
  n_forward_arg?(removed) || n_restarg?(removed) || n_kwrestarg?(removed)
36
23
  end
37
24
 
38
- def only_mlhs?(new_arguments)
39
- new_arguments.one? && n_mlhs?(new_arguments.first)
40
- end
41
-
42
- def forward_arg?
43
- children.any?(&method(:forward_type?))
44
- end
45
-
46
25
  def removed_block_arg?(new_arguments)
47
26
  anonymous_block_arg? && new_arguments.none?(&ANONYMOUS_BLOCKARG_PRED)
48
27
  end
@@ -12,9 +12,44 @@ module Mutant
12
12
  private
13
13
 
14
14
  def dispatch
15
- ignore_single = children.any?(&method(:ignore?))
16
- mutate_single_child do |child|
17
- emit(child) unless ignore_single
15
+ children.each_index do |index|
16
+ mutate_child(index)
17
+ delete_child(index)
18
+ end
19
+ end
20
+
21
+ # rubocop:disable Lint/EmptyWhen
22
+ # rubocop:disable Metrics/MethodLength
23
+ def delete_child(index)
24
+ dup_children = children.dup
25
+ child = dup_children.delete_at(index)
26
+ return if contains_lvar_assignment?(child)
27
+ return if ignore?(child)
28
+
29
+ case dup_children.length
30
+ when 0
31
+ when 1
32
+ one = Mutant::Util.one(dup_children)
33
+ return if ignore?(one)
34
+ emit(one)
35
+ else
36
+ emit_type(*dup_children)
37
+ end
38
+ end
39
+
40
+ def contains_lvar_assignment?(node)
41
+ case node.type
42
+ when Unparser::AST::ASSIGN_NODES
43
+ true
44
+ when *Unparser::AST::RESET_NODES
45
+ false
46
+ else
47
+ node.children.each do |child|
48
+ if child.instance_of?(::Parser::AST::Node) && contains_lvar_assignment?(child)
49
+ return true
50
+ end
51
+ end
52
+ false
18
53
  end
19
54
  end
20
55
  end # Begin
@@ -18,9 +18,8 @@ module Mutant
18
18
  private
19
19
 
20
20
  def dispatch
21
- emit_singletons
21
+ emit_singletons unless left_lvasgn?
22
22
  emit_promotions
23
- emit_operator_mutations
24
23
 
25
24
  emit_left_mutations do |mutation|
26
25
  !(n_irange?(mutation) || n_erange?(mutation)) || !mutation.children.fetch(1).nil?
@@ -29,13 +28,13 @@ module Mutant
29
28
  emit_right_mutations
30
29
  end
31
30
 
32
- def emit_operator_mutations
33
- emit(s(INVERSE.fetch(node.type), left, right))
34
- end
35
-
36
31
  def emit_promotions
37
32
  emit(left)
38
- emit(right)
33
+ emit(right) unless left_lvasgn?
34
+ end
35
+
36
+ def left_lvasgn?
37
+ n_lvasgn?(left)
39
38
  end
40
39
 
41
40
  end # Binary
@@ -25,7 +25,9 @@ module Mutant
25
25
  emit_body(N_RAISE)
26
26
 
27
27
  return unless body
28
- emit(body) unless body_has_control?
28
+
29
+ emit_body_promotion
30
+
29
31
  emit_body_mutations do |node|
30
32
  !(n_nil?(node) && unconditional_loop?)
31
33
  end
@@ -45,8 +47,17 @@ module Mutant
45
47
  false
46
48
  end
47
49
 
50
+ def emit_body_promotion
51
+ emit(body) if empty_block_argument? && !body_has_control?
52
+ end
53
+
54
+ def empty_block_argument?
55
+ arguments.children.empty?
56
+ end
57
+
48
58
  def mutate_body_receiver
49
59
  return if n_lambda?(send) || !n_send?(body)
60
+ return unless empty_block_argument?
50
61
 
51
62
  body_meta = AST::Meta::Send.new(node: body)
52
63
 
@@ -21,10 +21,7 @@ module Mutant
21
21
  end
22
22
 
23
23
  def mutate_condition
24
- emit_condition_mutations do |node|
25
- !n_self?(node)
26
- end
27
- emit_type(n_not(condition), if_branch, else_branch) unless n_match_current_line?(condition)
24
+ emit_condition_mutations
28
25
  emit_type(N_TRUE, if_branch, else_branch)
29
26
  emit_type(N_FALSE, if_branch, else_branch)
30
27
  end
@@ -44,7 +44,6 @@ module Mutant
44
44
 
45
45
  def mutate_indices
46
46
  children_indices(index_range).each do |index|
47
- emit_propagation(children.fetch(index)) unless left_op_assignment?
48
47
  delete_child(index)
49
48
  mutate_child(index)
50
49
  end
@@ -3,9 +3,8 @@
3
3
  module Mutant
4
4
  class Mutator
5
5
  class Node
6
-
7
6
  # Mutation emitter to handle multiple assignment nodes
8
- class MultipleAssignment < self
7
+ class Masgn < self
9
8
 
10
9
  handle(:masgn)
11
10
 
@@ -14,10 +13,10 @@ module Mutant
14
13
  private
15
14
 
16
15
  def dispatch
17
- emit_singletons
16
+ emit_right_mutations
18
17
  end
19
18
 
20
- end # MultipleAssignment
19
+ end # Masgn
21
20
  end # Node
22
21
  end # Mutator
23
22
  end # Mutant
@@ -10,11 +10,7 @@ module Mutant
10
10
 
11
11
  private
12
12
 
13
- def dispatch
14
- mutate_single_child do |_child, index|
15
- delete_child(index)
16
- end
17
- end
13
+ def dispatch; end
18
14
 
19
15
  end # MLHS
20
16
  end # Node
@@ -26,19 +26,8 @@ module Mutant
26
26
  private
27
27
 
28
28
  def dispatch
29
- emit_singletons
30
- mutate_name
31
29
  emit_value_mutations if value # op asgn!
32
30
  end
33
-
34
- def mutate_name
35
- prefix, regexp = MAP.fetch(node.type)
36
- stripped = name.to_s.sub(regexp, EMPTY_STRING)
37
-
38
- Util::Symbol.call(input: stripped, parent: nil).each do |name|
39
- emit_name(:"#{prefix}#{name}")
40
- end
41
- end
42
31
  end # VariableAssignment
43
32
  end # NamedValue
44
33
  end # Node
@@ -14,8 +14,6 @@ module Mutant
14
14
  private
15
15
 
16
16
  def dispatch
17
- emit_singletons
18
-
19
17
  left_mutations
20
18
 
21
19
  emit_right_mutations
@@ -25,7 +23,6 @@ module Mutant
25
23
  emit_left_mutations do |node|
26
24
  !n_self?(node)
27
25
  end
28
-
29
26
  emit_left_promotion if n_send?(left)
30
27
  end
31
28
 
@@ -13,7 +13,6 @@ module Mutant
13
13
  private
14
14
 
15
15
  def dispatch
16
- emit_assignment(nil)
17
16
  emit_body_mutations if body
18
17
  end
19
18
  end # Resbody
@@ -25,8 +25,10 @@ module Mutant
25
25
  def mutate_rescue_bodies
26
26
  children_indices(RESCUE_INDICES).each do |index|
27
27
  mutate_child(index)
28
- resbody_body = AST::Meta::Resbody.new(node: children.fetch(index)).body
29
- emit_concat(resbody_body) if resbody_body
28
+ resbody = AST::Meta::Resbody.new(node: children.fetch(index))
29
+ if resbody.body && !resbody.assignment
30
+ emit_concat(resbody.body)
31
+ end
30
32
  end
31
33
  end
32
34
 
@@ -206,7 +206,8 @@ module Mutant
206
206
  emit(receiver) if receiver && !left_op_assignment?
207
207
  end
208
208
 
209
- # rubocop:disable Style/HashEachMethods - its not a hash ;)
209
+ # rubocop:disable Style/HashEachMethods
210
+ # - its not a hash ;)
210
211
  def mutate_arguments
211
212
  emit_type(receiver, selector)
212
213
  remaining_children_with_index.each do |_node, index|
data/lib/mutant/parser.rb CHANGED
@@ -24,11 +24,11 @@ module Mutant
24
24
  private
25
25
 
26
26
  def parse(source)
27
- node, comments = Unparser.parse_with_comments(source)
27
+ ast = Unparser.parse_ast_either(source).from_right
28
28
 
29
29
  AST.new(
30
- node:,
31
- comment_associations: ::Parser::Source::Comment.associate_by_identity(node, comments)
30
+ comment_associations: ::Parser::Source::Comment.associate_by_identity(ast.node, ast.comments),
31
+ node: ast.node
32
32
  )
33
33
  end
34
34
 
data/lib/mutant/procto.rb CHANGED
@@ -15,8 +15,8 @@ module Mutant
15
15
  end
16
16
 
17
17
  module ClassMethods
18
- def call(*arguments)
19
- new(*arguments).call
18
+ def call(*)
19
+ new(*).call
20
20
  end
21
21
  end
22
22
  end # Procto
@@ -10,13 +10,21 @@ module Mutant
10
10
  #
11
11
  # @return [Enumerable<Mutation>]
12
12
  # @return [undefined]
13
+ #
14
+ # mutant:disable
15
+ # rubocop:disable Metrics/MethodLength
13
16
  def mutations
14
17
  [neutral_mutation].concat(
15
18
  Mutator::Node.mutate(
16
19
  config: config.mutation,
17
20
  node:
18
- ).map do |mutant|
19
- Mutation::Evil.new(subject: self, node: wrap_node(mutant))
21
+ ).each_with_object([]) do |mutant, aggregate|
22
+ Mutation::Evil
23
+ .from_node(subject: self, node: wrap_node(mutant))
24
+ .either(
25
+ ->(validation) {},
26
+ aggregate.public_method(:<<)
27
+ )
20
28
  end
21
29
  )
22
30
  end
@@ -92,7 +100,9 @@ module Mutant
92
100
  private
93
101
 
94
102
  def neutral_mutation
95
- Mutation::Neutral.new(subject: self, node: wrap_node(node))
103
+ Mutation::Neutral
104
+ .from_node(subject: self, node: wrap_node(node))
105
+ .from_right
96
106
  end
97
107
 
98
108
  def wrap_node(node)
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Mutant
4
4
  # Current mutant version
5
- VERSION = '0.12.4'
5
+ VERSION = '0.13.0'
6
6
  end # Mutant
@@ -32,8 +32,8 @@ module Mutant
32
32
  # Call zombifier
33
33
  #
34
34
  # @return [self]
35
- def self.call(*args)
36
- new(*args).__send__(:call)
35
+ def self.call(*)
36
+ new(*).__send__(:call)
37
37
  self
38
38
  end
39
39
 
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.12.4
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-30 00:00:00.000000000 Z
11
+ date: 2025-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.6.14
75
+ version: 0.7.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.6.14
82
+ version: 0.7.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -355,14 +355,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
355
355
  requirements:
356
356
  - - ">="
357
357
  - !ruby/object:Gem::Version
358
- version: '3.1'
358
+ version: '3.2'
359
359
  required_rubygems_version: !ruby/object:Gem::Requirement
360
360
  requirements:
361
361
  - - ">="
362
362
  - !ruby/object:Gem::Version
363
363
  version: '0'
364
364
  requirements: []
365
- rubygems_version: 3.5.9
365
+ rubygems_version: 3.5.22
366
366
  signing_key:
367
367
  specification_version: 4
368
368
  summary: ''