mutant 0.7.9 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +11 -1
  3. data/README.md +5 -12
  4. data/bin/mutant +17 -1
  5. data/config/flay.yml +1 -1
  6. data/config/flog.yml +1 -1
  7. data/config/reek.yml +4 -4
  8. data/config/rubocop.yml +21 -3
  9. data/lib/mutant.rb +15 -61
  10. data/lib/mutant/cli.rb +1 -7
  11. data/lib/mutant/color.rb +2 -2
  12. data/lib/mutant/config.rb +1 -1
  13. data/lib/mutant/expression/method.rb +1 -1
  14. data/lib/mutant/expression/methods.rb +1 -1
  15. data/lib/mutant/expression/namespace.rb +1 -1
  16. data/lib/mutant/mutator/node/send.rb +18 -18
  17. data/lib/mutant/reporter/cli.rb +1 -6
  18. data/lib/mutant/reporter/cli/format.rb +2 -2
  19. data/lib/mutant/reporter/cli/printer.rb +5 -500
  20. data/lib/mutant/reporter/cli/printer/config.rb +32 -0
  21. data/lib/mutant/reporter/cli/printer/env_progress.rb +66 -0
  22. data/lib/mutant/reporter/cli/printer/env_result.rb +23 -0
  23. data/lib/mutant/reporter/cli/printer/mutation_progress_result.rb +37 -0
  24. data/lib/mutant/reporter/cli/printer/mutation_result.rb +151 -0
  25. data/lib/mutant/reporter/cli/printer/status.rb +60 -0
  26. data/lib/mutant/reporter/cli/printer/status_progressive.rb +52 -0
  27. data/lib/mutant/reporter/cli/printer/subject_progress.rb +90 -0
  28. data/lib/mutant/reporter/cli/printer/subject_result.rb +28 -0
  29. data/lib/mutant/reporter/cli/printer/test_result.rb +33 -0
  30. data/lib/mutant/require_highjack.rb +11 -50
  31. data/lib/mutant/version.rb +1 -1
  32. data/lib/mutant/zombifier.rb +79 -37
  33. data/meta/send.rb +1 -1
  34. data/mutant-rspec.gemspec +1 -1
  35. data/mutant.gemspec +3 -3
  36. data/spec/integration/mutant/corpus_spec.rb +2 -2
  37. data/spec/integration/mutant/rspec_spec.rb +5 -15
  38. data/spec/integrations.yml +3 -3
  39. data/spec/spec_helper.rb +1 -0
  40. data/spec/support/corpus.rb +233 -220
  41. data/spec/support/file_system.rb +60 -0
  42. data/spec/support/rb_bug.rb +1 -1
  43. data/spec/support/ruby_vm.rb +82 -0
  44. data/spec/support/shared_context.rb +19 -10
  45. data/spec/unit/mutant/ast_spec.rb +2 -2
  46. data/spec/unit/mutant/cache_spec.rb +22 -0
  47. data/spec/unit/mutant/cli_spec.rb +1 -30
  48. data/spec/unit/mutant/context_spec.rb +1 -0
  49. data/spec/unit/mutant/expression/method_spec.rb +6 -4
  50. data/spec/unit/mutant/parallel/master_spec.rb +1 -1
  51. data/spec/unit/mutant/reporter/cli/printer/config_spec.rb +33 -0
  52. data/spec/unit/mutant/reporter/cli/printer/env_progress_spec.rb +76 -0
  53. data/spec/unit/mutant/reporter/cli/printer/env_result_spec.rb +35 -0
  54. data/spec/unit/mutant/reporter/cli/printer/mutation_progress_result_spec.rb +23 -0
  55. data/spec/unit/mutant/reporter/cli/printer/mutation_result_spec.rb +110 -0
  56. data/spec/unit/mutant/reporter/cli/printer/status_progressive_spec.rb +51 -0
  57. data/spec/unit/mutant/reporter/cli/printer/status_spec.rb +145 -0
  58. data/spec/unit/mutant/reporter/cli/printer/subject_progress_spec.rb +37 -0
  59. data/spec/unit/mutant/reporter/cli/printer/subject_result_spec.rb +37 -0
  60. data/spec/unit/mutant/reporter/cli/printer/test_result_spec.rb +14 -0
  61. data/spec/unit/mutant/reporter/cli/printer_spec.rb +140 -0
  62. data/spec/unit/mutant/reporter/cli_spec.rb +69 -313
  63. data/spec/unit/mutant/reporter/trace_spec.rb +12 -0
  64. data/spec/unit/mutant/require_highjack_spec.rb +25 -28
  65. data/spec/unit/mutant/warning_filter_spec.rb +7 -0
  66. data/spec/unit/mutant/zombifier_spec.rb +120 -0
  67. data/spec/unit/mutant_spec.rb +0 -43
  68. data/test_app/Gemfile.rspec3.3 +6 -0
  69. metadata +46 -17
  70. data/.travis.yml +0 -20
  71. data/lib/mutant/zombifier/file.rb +0 -100
  72. data/spec/integration/mutant/zombie_spec.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a01c96b2fcfbb344d37ed40dc9773c36d0433bfc
4
- data.tar.gz: f4ef32cec5591667c75a1e1e31200d51529a7b50
3
+ metadata.gz: fa063e8c2f6e2cf17858c47e1725f315e64c4c0b
4
+ data.tar.gz: b96166a5788f2de7088b36033ed7dc0198295b8f
5
5
  SHA512:
6
- metadata.gz: 6aa3c28aeffad6471ced7ab755d34cab8b0c6d986c4d6739245b9706e3608fd18fbfed75287f94ac5d337e5078f4e711e94aee748ff9508b439689ad24417a2b
7
- data.tar.gz: 36c0f9f971e94f602299f785a7d28a1f56b7e566a6ec3717f46905c7f7e306b574d028a7cd10e32f35b6455b742c0f5538b327fa4360e91c392a8dd76f6cc732
6
+ metadata.gz: a4f4038557d14c1da74122005c6dce8e510d3808cc01efec45f3bbcc6e53ece5430b2b1ce0b65d45f4e7234143881e14b21581a66a4f80c89c093b64c4c16dc9
7
+ data.tar.gz: f31d6f38605ba70960779c66ff5fa8767c508a9e87b2ed49c0ff3033635ad210a2a79040458bca86188e733d0e6cde77902e45f6f6b995e0ea6239e7f66ff5c3
data/Changelog.md CHANGED
@@ -1,7 +1,17 @@
1
- # v0.7.9 pending
1
+ # v0.8.0 2015-06-15
2
+
3
+ * Drop support for ruby < 2.1
4
+ * Remove broken `--code` option
5
+ * Remove deprecated `--score` option
6
+ * Add support for rspec-3.3
7
+ * End support for rspec-3.{0,1}
8
+ * Internal quality improvements
9
+
10
+ # v0.7.9 2015-05-30
2
11
 
3
12
  * Deprecate `--score` flag replace with `--expected-coverage`
4
13
  * Set default job count to 4 under CI environments.
14
+ * Relax parser dependency to ~>2.2.2
5
15
 
6
16
  # v0.7.8 2015-03-8
7
17
 
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  mutant
2
2
  ======
3
3
 
4
- [![Build Status](https://secure.travis-ci.org/mbj/mutant.png?branch=master)](http://travis-ci.org/mbj/mutant)
4
+ [![Build Status](https://circleci.com/gh/mbj/mutant.svg?style=shield&circle-token=1afd77e8f0f9d0a11fd8f15f5d7b10270f4665e2)](https://circleci.com/gh/mbj/mutant/tree/master)
5
5
  [![Dependency Status](https://gemnasium.com/mbj/mutant.png)](https://gemnasium.com/mbj/mutant)
6
6
  [![Code Climate](https://codeclimate.com/github/mbj/mutant.png)](https://codeclimate.com/github/mbj/mutant)
7
7
  [![Inline docs](http://inch-ci.org/github/mbj/mutant.png)](http://inch-ci.org/github/mbj/mutant)
@@ -13,7 +13,7 @@ Mutant is a mutation testing tool for Ruby.
13
13
  The idea is that if code can be changed and your tests do not notice, either that code isn't being covered
14
14
  or it does not have a speced side effect.
15
15
 
16
- Mutant supports MRI and RBX 2.0 and 2.1, while support for JRuby is planned.
16
+ Mutant supports ruby >= 2.1, while support for JRuby is planned.
17
17
  It should also work under any Ruby engine that supports POSIX-fork(2) semantics.
18
18
 
19
19
  Mutant uses a pure Ruby [parser](https://github.com/whitequark/parser) and an [unparser](https://github.com/mbj/unparser)
@@ -48,20 +48,14 @@ Blog-Posts
48
48
  Installation
49
49
  ------------
50
50
 
51
- Install the gem `mutant` via your preferred method.
52
-
53
- ```ruby
54
- gem install mutant
55
- ```
56
-
57
- If you plan to use the RSpec integration you'll have to install `mutant-rspec` also.
58
- Please add an explicit dependency to `rspec-core` for the RSpec version you want to use.
51
+ As mutant right now only supports rspec, install the gem `mutant-rspec` via your preferred method.
52
+ It'll pull the `mutant` gem (in correct version), that contains the main engine.
59
53
 
60
54
  ```ruby
61
55
  gem install mutant-rspec
62
56
  ```
63
57
 
64
- The minitest integration is still in the works.
58
+ The minitest integration is still in the [works](https://github.com/mbj/mutant/pull/330).
65
59
 
66
60
  The Crash / Stuck Problem (MRI)
67
61
  -------------------------------
@@ -131,7 +125,6 @@ Assuming you are using rspec, you can mutation test Rails models by adding the f
131
125
 
132
126
  ```ruby
133
127
  group :test do
134
- gem 'mutant'
135
128
  gem 'mutant-rspec'
136
129
  end
137
130
  ```
data/bin/mutant CHANGED
@@ -10,7 +10,23 @@ require 'mutant'
10
10
  namespace =
11
11
  if ARGV.include?('--zombie')
12
12
  $stderr.puts('Running mutant zombified!')
13
- Mutant.zombify
13
+ Mutant::Zombifier.call(
14
+ namespace: :Zombie,
15
+ load_path: $LOAD_PATH,
16
+ kernel: Kernel,
17
+ pathname: Pathname,
18
+ require_highjack: Mutant::RequireHighjack.method(:call).to_proc.curry.call(Kernel),
19
+ root_require: 'mutant',
20
+ includes: %w[
21
+ mutant
22
+ unparser
23
+ morpher
24
+ adamantium
25
+ equalizer
26
+ anima
27
+ concord
28
+ ]
29
+ )
14
30
  Zombie::Mutant
15
31
  else
16
32
  Mutant
data/config/flay.yml CHANGED
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 18
3
- total_score: 1241
3
+ total_score: 1227
data/config/flog.yml CHANGED
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 30.9
2
+ threshold: 29.3
data/config/reek.yml CHANGED
@@ -24,13 +24,14 @@ DuplicateMethodCall:
24
24
  allow_calls: []
25
25
  FeatureEnvy:
26
26
  enabled: false
27
+ # Buggy smell detector
27
28
  IrresponsibleModule:
28
- enabled: true
29
+ enabled: false
29
30
  exclude: []
30
31
  LongParameterList:
31
32
  enabled: true
32
33
  exclude:
33
- - Mutant::Matcher::Method::Instance#self.build?
34
+ - Mutant::Matcher::Method::Instance#self.build
34
35
  max_params: 2
35
36
  LongYieldList:
36
37
  enabled: true
@@ -45,8 +46,7 @@ NestedIterators:
45
46
  - Mutant::Mutator::Util::Array::Element#dispatch
46
47
  - Mutant::Mutator::Node::Resbody#mutate_captures
47
48
  - Mutant::Mutator::Node::Arguments#emit_argument_mutations
48
- - Mutant::RequireHighjack#infect
49
- - Mutant::RequireHighjack#disinfect
49
+ - Mutant::RequireHighjack#self.call
50
50
  - Mutant::Selector::Expression#call
51
51
  - Mutant::Parallel::Master#run
52
52
  - Parser::Lexer#self.new
data/config/rubocop.yml CHANGED
@@ -87,6 +87,10 @@ PercentLiteralDelimiters:
87
87
  '%W': '[]'
88
88
  '%x': ()
89
89
 
90
+ # Use %i[...] for arrays of symbols
91
+ SymbolArray:
92
+ Enabled: true
93
+
90
94
  # Align if/else blocks with the variable assignment
91
95
  EndAlignment:
92
96
  AlignWith: variable
@@ -106,11 +110,25 @@ UnneededPercentQ:
106
110
 
107
111
  # Allow a maximum ABC score
108
112
  Metrics/AbcSize:
109
- Max: 18.00
113
+ Max: 21.02
110
114
 
111
115
  # Do not prefer lambda.call(...) over lambda.(...)
112
116
  LambdaCall:
113
117
  Enabled: false
114
118
 
115
- Style/RegexpLiteral:
116
- MaxSlashes: 0
119
+ # Buggy cop, returns false positive for our code base
120
+ NonLocalExitFromIterator:
121
+ Enabled: false
122
+
123
+ # To allow alignment of similar expressions we want to allow more than one
124
+ # space around operators:
125
+ #
126
+ # let(:a) { bar + something }
127
+ # let(:b) { foobar + something }
128
+ #
129
+ SpaceAroundOperators:
130
+ Enabled: false
131
+
132
+ # We use parallel assignments with great success
133
+ ParallelAssignment:
134
+ Enabled: false
data/lib/mutant.rb CHANGED
@@ -24,11 +24,8 @@ Thread.abort_on_exception = true
24
24
 
25
25
  # Library namespace
26
26
  module Mutant
27
- # The frozen empty string used within mutant
28
- EMPTY_STRING = ''.freeze
29
- # The frozen empty array used within mutant
30
- EMPTY_ARRAY = [].freeze
31
-
27
+ EMPTY_STRING = ''.freeze
28
+ EMPTY_ARRAY = [].freeze
32
29
  SCOPE_OPERATOR = '::'.freeze
33
30
 
34
31
  # Test if CI is detected via environment
@@ -40,58 +37,6 @@ module Mutant
40
37
  def self.ci?
41
38
  ENV.key?('CI')
42
39
  end
43
-
44
- # Lookup constant for location
45
- #
46
- # @param [String] location
47
- #
48
- # @return [Object]
49
- #
50
- # @api private
51
- #
52
- def self.constant_lookup(location)
53
- location.split(SCOPE_OPERATOR).reduce(Object) do |parent, name|
54
- parent.const_get(name, nil)
55
- end
56
- end
57
-
58
- # Perform self zombification
59
- #
60
- # @return [self]
61
- #
62
- # @api private
63
- #
64
- def self.zombify
65
- Zombifier.run('mutant', :Zombie)
66
- self
67
- end
68
-
69
- # Define instance of subclassed superclass as constant
70
- #
71
- # @param [Class] superclass
72
- # @param [Symbol] name
73
- #
74
- # @return [self]
75
- #
76
- # @api private
77
- #
78
- # rubocop:disable MethodLength
79
- #
80
- def self.singleton_subclass_instance(name, superclass, &block)
81
- klass = Class.new(superclass) do
82
- def inspect
83
- self.class.name
84
- end
85
-
86
- define_singleton_method(:name) do
87
- "#{superclass.name}::#{name}".freeze
88
- end
89
- end
90
- klass.class_eval(&block)
91
- superclass.const_set(name, klass.new)
92
- self
93
- end
94
-
95
40
  end # Mutant
96
41
 
97
42
  require 'mutant/version'
@@ -109,15 +54,15 @@ require 'mutant/actor/receiver'
109
54
  require 'mutant/actor/sender'
110
55
  require 'mutant/actor/mailbox'
111
56
  require 'mutant/actor/env'
57
+ require 'mutant/cache'
58
+ require 'mutant/delegator'
59
+ require 'mutant/isolation'
112
60
  require 'mutant/parallel'
113
61
  require 'mutant/parallel/master'
114
62
  require 'mutant/parallel/worker'
115
63
  require 'mutant/parallel/source'
116
- require 'mutant/cache'
117
- require 'mutant/delegator'
118
64
  require 'mutant/warning_filter'
119
65
  require 'mutant/require_highjack'
120
- require 'mutant/isolation'
121
66
  require 'mutant/mutator'
122
67
  require 'mutant/mutation'
123
68
  require 'mutant/mutator/registry'
@@ -217,10 +162,19 @@ require 'mutant/reporter/null'
217
162
  require 'mutant/reporter/trace'
218
163
  require 'mutant/reporter/cli'
219
164
  require 'mutant/reporter/cli/printer'
165
+ require 'mutant/reporter/cli/printer/config'
166
+ require 'mutant/reporter/cli/printer/env_result'
167
+ require 'mutant/reporter/cli/printer/env_progress'
168
+ require 'mutant/reporter/cli/printer/mutation_result'
169
+ require 'mutant/reporter/cli/printer/mutation_progress_result'
170
+ require 'mutant/reporter/cli/printer/subject_progress'
171
+ require 'mutant/reporter/cli/printer/subject_result'
172
+ require 'mutant/reporter/cli/printer/status'
173
+ require 'mutant/reporter/cli/printer/status_progressive'
174
+ require 'mutant/reporter/cli/printer/test_result'
220
175
  require 'mutant/reporter/cli/tput'
221
176
  require 'mutant/reporter/cli/format'
222
177
  require 'mutant/zombifier'
223
- require 'mutant/zombifier/file'
224
178
 
225
179
  module Mutant
226
180
  # Reopen class to initialize constant to avoid dep circle
data/lib/mutant/cli.rb CHANGED
@@ -149,10 +149,7 @@ module Mutant
149
149
  ) do |coverage|
150
150
  update(expected_coverage: Rational(coverage))
151
151
  end
152
- opts.on('--score COVERAGE', 'Fail unless COVERAGE is not reached exactly [deprecated]') do |coverage|
153
- update(expected_coverage: Rational(coverage, 100))
154
- end
155
- opts.on('--use STRATEGY', 'Use STRATEGY for killing mutations', &method(:setup_integration))
152
+ opts.on('--use INTEGRATION', 'Use INTEGRATION to kill mutations', &method(:setup_integration))
156
153
  end
157
154
 
158
155
  # Add filter options
@@ -167,9 +164,6 @@ module Mutant
167
164
  opts.on('--ignore-subject PATTERN', 'Ignore subjects that match PATTERN') do |pattern|
168
165
  add_matcher(:subject_ignores, Expression.parse(pattern))
169
166
  end
170
- opts.on('--code CODE', 'Scope execution to subjects with CODE') do |code|
171
- add_matcher(:subject_selects, [:code, code])
172
- end
173
167
  end
174
168
 
175
169
  # Add debug options
data/lib/mutant/color.rb CHANGED
@@ -15,7 +15,7 @@ module Mutant
15
15
  "\e[#{@code}m#{text}\e[0m"
16
16
  end
17
17
 
18
- Mutant.singleton_subclass_instance('NONE', self) do
18
+ NONE = Class.new(self) do
19
19
 
20
20
  # Format null color
21
21
  #
@@ -41,7 +41,7 @@ module Mutant
41
41
  def initialize
42
42
  end
43
43
 
44
- end
44
+ end.new
45
45
 
46
46
  RED = Color.new(31)
47
47
  GREEN = Color.new(32)
data/lib/mutant/config.rb CHANGED
@@ -15,7 +15,7 @@ module Mutant
15
15
  :expected_coverage
16
16
  )
17
17
 
18
- [:fail_fast, :zombie, :debug].each do |name|
18
+ %i[fail_fast zombie debug].each do |name|
19
19
  define_method(:"#{name}?") { public_send(name) }
20
20
  end
21
21
 
@@ -48,7 +48,7 @@ module Mutant
48
48
  # @api private
49
49
  #
50
50
  def scope
51
- Mutant.constant_lookup(scope_name)
51
+ Object.const_get(scope_name)
52
52
  end
53
53
 
54
54
  # Return method name
@@ -60,7 +60,7 @@ module Mutant
60
60
  # @api private
61
61
  #
62
62
  def scope
63
- Mutant.constant_lookup(scope_name)
63
+ Object.const_get(scope_name)
64
64
  end
65
65
 
66
66
  # Return scope symbol
@@ -81,7 +81,7 @@ module Mutant
81
81
  # @api private
82
82
  #
83
83
  def matcher(env)
84
- Matcher::Scope.new(env, Mutant.constant_lookup(namespace), self)
84
+ Matcher::Scope.new(env, Object.const_get(namespace), self)
85
85
  end
86
86
 
87
87
  end # Exact
@@ -11,24 +11,24 @@ module Mutant
11
11
  children :receiver, :selector
12
12
 
13
13
  SELECTOR_REPLACEMENTS = IceNine.deep_freeze(
14
- reverse_map: [:map, :each],
15
- kind_of?: [:instance_of?],
16
- is_a?: [:instance_of?],
17
- reverse_each: [:each],
18
- reverse_merge: [:merge],
19
- map: [:each],
20
- send: [:public_send, :__send__],
21
- __send__: [:public_send],
22
- gsub: [:sub],
23
- eql?: [:equal?],
24
- to_s: [:to_str],
25
- to_i: [:to_int],
26
- to_a: [:to_ary],
27
- :== => [:eql?, :equal?],
28
- :>= => [:>, :==, :eql?, :equal?],
29
- :<= => [:<, :==, :eql?, :equal?],
30
- :> => [:==, :>=, :eql?, :equal?],
31
- :< => [:==, :<=, :eql?, :equal?]
14
+ reverse_map: %i[map each],
15
+ kind_of?: %i[instance_of?],
16
+ is_a?: %i[instance_of?],
17
+ reverse_each: %i[each],
18
+ reverse_merge: %i[merge],
19
+ map: %i[each],
20
+ send: %i[public_send __send__],
21
+ __send__: %i[public_send],
22
+ gsub: %i[sub],
23
+ eql?: %i[equal?],
24
+ to_s: %i[to_str],
25
+ to_i: %i[to_int],
26
+ to_a: %i[to_ary],
27
+ :== => %i[eql? equal?],
28
+ :>= => %i[> == eql? equal?],
29
+ :<= => %i[< == eql? equal?],
30
+ :> => %i[== >= eql? equal?],
31
+ :< => %i[== <= eql? equal?]
32
32
  )
33
33
 
34
34
  private
@@ -53,11 +53,6 @@ module Mutant
53
53
  #
54
54
  # TODO: Move this to a callback registration
55
55
  #
56
- # Reporters other than CLI that might exist in future
57
- # may only need the final report. So providing a noop callback
58
- # registration makes more sense for these.
59
- # As only CLI reporters exist currently I do not really care right now.
60
- #
61
56
  # @return [Float]
62
57
  #
63
58
  # @api private
@@ -88,7 +83,7 @@ module Mutant
88
83
  # @api private
89
84
  #
90
85
  def report(env)
91
- Printer::EnvResult.run(output, env)
86
+ Printer::EnvResult.call(output, env)
92
87
  self
93
88
  end
94
89