mutant 0.8.5 → 0.8.6

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
  SHA1:
3
- metadata.gz: 7dd5fae5bb56ceed6c9afc7a06e760f07a4cfefb
4
- data.tar.gz: 5379381863e779bff921ea7f51d0ca55832d4bb8
3
+ metadata.gz: 56b2c2844f22529e172aac6c7042ba32e2213910
4
+ data.tar.gz: 69e3bed5fcbf29655a01aa99b32403bb7523e9d7
5
5
  SHA512:
6
- metadata.gz: 400a2e5a58ee453774f591ca6a4aa81904b07c18203c5cde21cef2bc0f8aae702fb0332dc62e40375476e9aebde7ba273d47716ef2c02a711f6931da7146966b
7
- data.tar.gz: 042ef5b2171ef8a9fc059bb81370a7e6d494f95c826f7fa64e7ce347b6071ad9e45f711832fb0c81c21d37e20e5384456c00a6a4eff0947e392fe616e8f04d22
6
+ metadata.gz: cf95681624f4a5796d0bd5134982084bae1437e3006acc7b43455230429558d8b558eaab5516371e58eb8d23ce4d2ac5cff4d43d0386149e59b26dd144459c10
7
+ data.tar.gz: 1b163c05a8afbaef8d97f3087aeedddd31615b7e7098eab3dbdb48efdd6dfe685eb60e092736ecbd58376cc77474f40a534bdfa4240d8b2992fc484ac76326d6
data/Changelog.md CHANGED
@@ -1,3 +1,9 @@
1
+ # v0.8.6. 2015-10-27
2
+
3
+ * Add mutation from `Date.parse` to more strict parsing methods #448
4
+ * Add mutation from `foo.to_i` to `Integer(foo)` #455
5
+ * Add mutation from `@foo` to `foo` #454
6
+
1
7
  # v0.8.5 2015-09-11
2
8
 
3
9
  * Fix misimplementation of block gluing operator that
data/config/flay.yml CHANGED
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 18
3
- total_score: 1233
3
+ total_score: 1253
data/lib/mutant.rb CHANGED
@@ -26,6 +26,7 @@ Thread.abort_on_exception = true
26
26
  module Mutant
27
27
  EMPTY_STRING = ''.freeze
28
28
  EMPTY_ARRAY = [].freeze
29
+ EMPTY_HASH = {}.freeze
29
30
  SCOPE_OPERATOR = '::'.freeze
30
31
 
31
32
  # Test if CI is detected via environment
@@ -49,6 +50,7 @@ require 'mutant/ast/named_children'
49
50
  require 'mutant/ast/node_predicates'
50
51
  require 'mutant/ast/meta'
51
52
  require 'mutant/ast/meta/send'
53
+ require 'mutant/ast/meta/const'
52
54
  require 'mutant/ast/meta/symbol'
53
55
  require 'mutant/ast/meta/optarg'
54
56
  require 'mutant/ast/meta/resbody'
@@ -0,0 +1,24 @@
1
+ module Mutant
2
+ module AST
3
+ # Node meta information mixin
4
+ module Meta
5
+
6
+ # Metadata for const nodes
7
+ class Const
8
+ include NamedChildren, Concord.new(:node), NodePredicates
9
+
10
+ children :base, :name
11
+
12
+ # Test if AST node is possibly a top level constant
13
+ #
14
+ # @return [Boolean]
15
+ #
16
+ # @api private
17
+ def possible_top_level?
18
+ base.nil? || n_cbase?(base)
19
+ end
20
+
21
+ end # Const
22
+ end # Meta
23
+ end # AST
24
+ end # Mutant
@@ -5,7 +5,7 @@ module Mutant
5
5
 
6
6
  # Metadata for send nodes
7
7
  class Send
8
- include NamedChildren, Concord.new(:node)
8
+ include NamedChildren, Concord.new(:node), NodePredicates
9
9
 
10
10
  children :receiver, :selector
11
11
 
@@ -56,6 +56,17 @@ module Mutant
56
56
  Types::BINARY_METHOD_OPERATORS.include?(selector)
57
57
  end
58
58
 
59
+ # Test if receiver is possibly a top level constant
60
+ #
61
+ # @return [Boolean]
62
+ #
63
+ # @api private
64
+ def receiver_possible_top_level_const?
65
+ return false unless receiver && n_const?(receiver)
66
+
67
+ Const.new(receiver).possible_top_level?
68
+ end
69
+
59
70
  end # Send
60
71
  end # Meta
61
72
  end # AST
@@ -6,7 +6,7 @@ module Mutant
6
6
  # Mutation emitter to handle named value access nodes
7
7
  class Access < Node
8
8
 
9
- handle(:gvar, :cvar, :ivar, :lvar, :self)
9
+ handle(:gvar, :cvar, :lvar, :self)
10
10
 
11
11
  private
12
12
 
@@ -19,6 +19,45 @@ module Mutant
19
19
  emit_singletons
20
20
  end
21
21
 
22
+ # Named value access emitter for instance variables
23
+ class Ivar < Access
24
+ NAME_RANGE = (1..-1).freeze
25
+
26
+ handle(:ivar)
27
+
28
+ children :name
29
+
30
+ # Emit mutations
31
+ #
32
+ # @return [undefined]
33
+ #
34
+ # @api private
35
+ def dispatch
36
+ emit_attribute_read
37
+ super()
38
+ end
39
+
40
+ private
41
+
42
+ # Emit instance variable as attribute send
43
+ #
44
+ # @return [undefined]
45
+ #
46
+ # @api private
47
+ def emit_attribute_read
48
+ emit(s(:send, nil, attribute_name))
49
+ end
50
+
51
+ # Variable name without leading '@'
52
+ #
53
+ # @return [Symbol]
54
+ #
55
+ # @api private
56
+ def attribute_name
57
+ name.slice(NAME_RANGE).to_sym
58
+ end
59
+ end
60
+
22
61
  end # Access
23
62
  end # NamedValue
24
63
  end # Node
@@ -3,6 +3,7 @@ module Mutant
3
3
  class Node
4
4
 
5
5
  # Namespace for send mutators
6
+ # rubocop:disable ClassLength
6
7
  class Send < self
7
8
  include AST::Types
8
9
 
@@ -34,6 +35,12 @@ module Mutant
34
35
  :< => %i[== <= eql? equal?]
35
36
  )
36
37
 
38
+ RECEIVER_SELECTOR_REPLACEMENTS = IceNine.deep_freeze(
39
+ Date: {
40
+ parse: %i[jd civil strptime iso8601 rfc3339 xmlschema rfc2822 rfc822 httpdate jisx0301]
41
+ }
42
+ )
43
+
37
44
  private
38
45
 
39
46
  # Perform dispatch
@@ -90,12 +97,48 @@ module Mutant
90
97
  def normal_dispatch
91
98
  emit_naked_receiver
92
99
  emit_selector_replacement
93
- emit_const_get_mutation
100
+ emit_selector_specific_mutations
94
101
  emit_argument_propagation
102
+ emit_receiver_selector_mutations
95
103
  mutate_receiver
96
104
  mutate_arguments
97
105
  end
98
106
 
107
+ # Emit mutations which only correspond to one selector
108
+ #
109
+ # @return [undefined]
110
+ #
111
+ # @api private
112
+ def emit_selector_specific_mutations
113
+ emit_const_get_mutation
114
+ emit_integer_mutation
115
+ end
116
+
117
+ # Emit selector mutations specific to top level constants
118
+ #
119
+ # @return [undefined]
120
+ #
121
+ # @api private
122
+ def emit_receiver_selector_mutations
123
+ return unless meta.receiver_possible_top_level_const?
124
+
125
+ RECEIVER_SELECTOR_REPLACEMENTS
126
+ .fetch(receiver.children.last, EMPTY_HASH)
127
+ .fetch(selector, EMPTY_ARRAY)
128
+ .each(&method(:emit_selector))
129
+ end
130
+
131
+ # Emit mutation from `to_i` to `Integer(...)`
132
+ #
133
+ # @return [undefined]
134
+ #
135
+ # @api private
136
+ def emit_integer_mutation
137
+ return unless selector.equal?(:to_i)
138
+
139
+ emit(s(:send, nil, :Integer, receiver))
140
+ end
141
+
99
142
  # Emit mutation from `const_get` to const literal
100
143
  #
101
144
  # @return [undefined]
@@ -1,4 +1,4 @@
1
1
  module Mutant
2
2
  # Current mutant version
3
- VERSION = '0.8.5'.freeze
3
+ VERSION = '0.8.6'.freeze
4
4
  end # Mutant
data/meta/date.rb ADDED
@@ -0,0 +1,57 @@
1
+ Mutant::Meta::Example.add do
2
+ source 'Date.parse(nil)'
3
+
4
+ singleton_mutations
5
+ mutation 'Date.parse'
6
+ mutation 'self.parse(nil)'
7
+ mutation 'Date'
8
+ mutation 'Date.jd(nil)'
9
+ mutation 'Date.civil(nil)'
10
+ mutation 'Date.strptime(nil)'
11
+ mutation 'Date.iso8601(nil)'
12
+ mutation 'Date.rfc3339(nil)'
13
+ mutation 'Date.xmlschema(nil)'
14
+ mutation 'Date.rfc2822(nil)'
15
+ mutation 'Date.rfc822(nil)'
16
+ mutation 'Date.httpdate(nil)'
17
+ mutation 'Date.jisx0301(nil)'
18
+ end
19
+
20
+ Mutant::Meta::Example.add do
21
+ source '::Date.parse(nil)'
22
+
23
+ singleton_mutations
24
+ mutation '::Date.parse'
25
+ mutation 'Date.parse(nil)'
26
+ mutation 'self.parse(nil)'
27
+ mutation '::Date'
28
+ mutation '::Date.jd(nil)'
29
+ mutation '::Date.civil(nil)'
30
+ mutation '::Date.strptime(nil)'
31
+ mutation '::Date.iso8601(nil)'
32
+ mutation '::Date.rfc3339(nil)'
33
+ mutation '::Date.xmlschema(nil)'
34
+ mutation '::Date.rfc2822(nil)'
35
+ mutation '::Date.rfc822(nil)'
36
+ mutation '::Date.httpdate(nil)'
37
+ mutation '::Date.jisx0301(nil)'
38
+ end
39
+
40
+ Mutant::Meta::Example.add do
41
+ source 'Date.iso8601(nil)'
42
+
43
+ singleton_mutations
44
+ mutation 'Date.iso8601'
45
+ mutation 'self.iso8601(nil)'
46
+ mutation 'Date'
47
+ end
48
+
49
+ Mutant::Meta::Example.add do
50
+ source 'Foo::Date.parse(nil)'
51
+
52
+ singleton_mutations
53
+ mutation 'Foo::Date.parse'
54
+ mutation 'Foo::Date'
55
+ mutation 'Date.parse(nil)'
56
+ mutation 'self.parse(nil)'
57
+ end
data/meta/ivar.rb ADDED
@@ -0,0 +1,6 @@
1
+ Mutant::Meta::Example.add do
2
+ source '@foo'
3
+
4
+ singleton_mutations
5
+ mutation 'foo'
6
+ end
data/meta/op_assgn.rb CHANGED
@@ -2,6 +2,7 @@ Mutant::Meta::Example.add do
2
2
  source '@a.b += 1'
3
3
 
4
4
  singleton_mutations
5
+ mutation 'a.b += 1'
5
6
  mutation '@a.b += -1'
6
7
  mutation '@a.b += 2'
7
8
  mutation '@a.b += 0'
data/meta/send.rb CHANGED
@@ -142,6 +142,7 @@ Mutant::Meta::Example.add do
142
142
  mutation 'foo'
143
143
  mutation 'self.to_i'
144
144
  mutation 'foo.to_int'
145
+ mutation 'Integer(foo)'
145
146
  end
146
147
 
147
148
  Mutant::Meta::Example.add do
@@ -0,0 +1,37 @@
1
+ RSpec.describe Mutant::AST::Meta::Send, '#receiver_possible_top_level_const?' do
2
+ subject { described_class.new(node).receiver_possible_top_level_const? }
3
+
4
+ def parse(source)
5
+ Parser::CurrentRuby.parse(source)
6
+ end
7
+
8
+ context 'when implicit top level const' do
9
+ let(:node) { parse('Foo.bar') }
10
+
11
+ it { should be true }
12
+ end
13
+
14
+ context 'when cbase' do
15
+ let(:node) { parse('::Foo.bar') }
16
+
17
+ it { should be true }
18
+ end
19
+
20
+ context 'when nested const' do
21
+ let(:node) { parse('Baz::Foo.bar') }
22
+
23
+ it { should be false }
24
+ end
25
+
26
+ context 'when no receiver' do
27
+ let(:node) { parse('bar') }
28
+
29
+ it { should be false }
30
+ end
31
+
32
+ context 'when send receiver' do
33
+ let(:node) { parse('foo.bar') }
34
+
35
+ it { should be false }
36
+ end
37
+ 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.5
4
+ version: 0.8.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-11 00:00:00.000000000 Z
11
+ date: 2015-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -287,6 +287,7 @@ files:
287
287
  - lib/mutant/actor/sender.rb
288
288
  - lib/mutant/ast.rb
289
289
  - lib/mutant/ast/meta.rb
290
+ - lib/mutant/ast/meta/const.rb
290
291
  - lib/mutant/ast/meta/optarg.rb
291
292
  - lib/mutant/ast/meta/resbody.rb
292
293
  - lib/mutant/ast/meta/restarg.rb
@@ -441,6 +442,7 @@ files:
441
442
  - meta/const.rb
442
443
  - meta/cvar.rb
443
444
  - meta/cvasgn.rb
445
+ - meta/date.rb
444
446
  - meta/def.rb
445
447
  - meta/defined.rb
446
448
  - meta/dstr.rb
@@ -453,6 +455,7 @@ files:
453
455
  - meta/hash.rb
454
456
  - meta/if.rb
455
457
  - meta/int.rb
458
+ - meta/ivar.rb
456
459
  - meta/ivasgn.rb
457
460
  - meta/kwbegin.rb
458
461
  - meta/lvar.rb
@@ -508,6 +511,7 @@ files:
508
511
  - spec/unit/mutant/actor/receiver_spec.rb
509
512
  - spec/unit/mutant/actor/sender_spec.rb
510
513
  - spec/unit/mutant/ast/meta/optarg_spec.rb
514
+ - spec/unit/mutant/ast/meta/send/receiver_possible_top_level_const_predicate_spec.rb
511
515
  - spec/unit/mutant/ast/meta/send_spec.rb
512
516
  - spec/unit/mutant/ast/named_children_spec.rb
513
517
  - spec/unit/mutant/ast/sexp_spec.rb
@@ -624,6 +628,7 @@ test_files:
624
628
  - spec/unit/mutant/actor/receiver_spec.rb
625
629
  - spec/unit/mutant/actor/sender_spec.rb
626
630
  - spec/unit/mutant/ast/meta/optarg_spec.rb
631
+ - spec/unit/mutant/ast/meta/send/receiver_possible_top_level_const_predicate_spec.rb
627
632
  - spec/unit/mutant/ast/meta/send_spec.rb
628
633
  - spec/unit/mutant/ast/named_children_spec.rb
629
634
  - spec/unit/mutant/ast/sexp_spec.rb