mutant 0.7.8 → 0.7.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/Changelog.md +5 -0
  4. data/README.md +11 -29
  5. data/config/flay.yml +1 -1
  6. data/config/reek.yml +1 -0
  7. data/lib/mutant.rb +3 -3
  8. data/lib/mutant/cli.rb +12 -9
  9. data/lib/mutant/integration.rb +13 -0
  10. data/lib/mutant/meta/example.rb +2 -2
  11. data/lib/mutant/reporter/cli.rb +3 -2
  12. data/lib/mutant/reporter/cli/printer.rb +2 -2
  13. data/lib/mutant/reporter/cli/tput.rb +29 -11
  14. data/lib/mutant/result.rb +0 -2
  15. data/lib/mutant/version.rb +1 -1
  16. data/meta/and.rb +0 -2
  17. data/meta/and_asgn.rb +0 -2
  18. data/meta/array.rb +0 -2
  19. data/meta/begin.rb +0 -2
  20. data/meta/block.rb +0 -2
  21. data/meta/block_pass.rb +0 -2
  22. data/meta/blockarg.rb +0 -2
  23. data/meta/boolean.rb +0 -2
  24. data/meta/break.rb +0 -2
  25. data/meta/case.rb +0 -2
  26. data/meta/casgn.rb +0 -2
  27. data/meta/cbase.rb +0 -2
  28. data/meta/const.rb +0 -2
  29. data/meta/cvar.rb +0 -2
  30. data/meta/cvasgn.rb +0 -2
  31. data/meta/def.rb +0 -2
  32. data/meta/defined.rb +0 -2
  33. data/meta/dstr.rb +0 -2
  34. data/meta/dsym.rb +0 -2
  35. data/meta/ensure.rb +0 -2
  36. data/meta/false.rb +0 -2
  37. data/meta/float.rb +0 -2
  38. data/meta/gvar.rb +0 -2
  39. data/meta/gvasgn.rb +0 -2
  40. data/meta/hash.rb +0 -2
  41. data/meta/if.rb +0 -2
  42. data/meta/int.rb +0 -2
  43. data/meta/ivasgn.rb +0 -2
  44. data/meta/kwbegin.rb +0 -2
  45. data/meta/lvar.rb +0 -2
  46. data/meta/lvasgn.rb +0 -2
  47. data/meta/masgn.rb +0 -2
  48. data/meta/match_current_line.rb +0 -2
  49. data/meta/next.rb +0 -2
  50. data/meta/nil.rb +0 -2
  51. data/meta/nthref.rb +0 -2
  52. data/meta/op_assgn.rb +0 -2
  53. data/meta/or.rb +0 -2
  54. data/meta/or_asgn.rb +0 -2
  55. data/meta/range.rb +0 -2
  56. data/meta/redo.rb +0 -2
  57. data/meta/regex.rb +0 -2
  58. data/meta/rescue.rb +0 -2
  59. data/meta/restarg.rb +0 -2
  60. data/meta/return.rb +0 -2
  61. data/meta/self.rb +0 -2
  62. data/meta/send.rb +0 -2
  63. data/meta/str.rb +0 -2
  64. data/meta/super.rb +0 -2
  65. data/meta/symbol.rb +0 -2
  66. data/meta/true.rb +0 -2
  67. data/meta/until.rb +0 -2
  68. data/meta/while.rb +0 -2
  69. data/meta/yield.rb +0 -2
  70. data/mutant-rspec.gemspec +1 -1
  71. data/mutant.gemspec +3 -3
  72. data/spec/integration/mutant/rspec_spec.rb +3 -39
  73. data/spec/shared/framework_integration_behavior.rb +35 -0
  74. data/spec/unit/mutant/cli_spec.rb +34 -1
  75. data/spec/unit/mutant/env_spec.rb +0 -1
  76. data/spec/unit/mutant/integration/rspec_spec.rb +193 -0
  77. data/spec/unit/mutant/loader/eval_spec.rb +1 -1
  78. data/spec/unit/mutant/matcher/methods/instance_spec.rb +22 -21
  79. data/spec/unit/mutant/matcher/methods/singleton_spec.rb +21 -19
  80. data/spec/unit/mutant/parallel/worker_spec.rb +0 -2
  81. data/spec/unit/mutant/reporter/cli/tput_spec.rb +48 -0
  82. data/spec/unit/mutant/reporter/cli_spec.rb +29 -9
  83. data/test_app/Gemfile.rspec3.0 +1 -0
  84. data/test_app/Gemfile.rspec3.1 +1 -0
  85. data/test_app/Gemfile.rspec3.2 +1 -0
  86. data/test_app/lib/test_app.rb +1 -1
  87. data/test_app/lib/test_app/literal.rb +0 -2
  88. data/test_app/spec/spec_helper.rb +0 -2
  89. data/test_app/spec/unit/test_app/literal_spec.rb +22 -0
  90. metadata +15 -5
  91. data/test_app/spec/unit/test_app/literal/command_spec.rb +0 -11
  92. data/test_app/spec/unit/test_app/literal/string_spec.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 28fdf0f67547fa2e8afe911daeb9c18e188f4e7d
4
- data.tar.gz: c74f5ce7f161105ef8e039d7a3b0a003778f7e80
3
+ metadata.gz: a01c96b2fcfbb344d37ed40dc9773c36d0433bfc
4
+ data.tar.gz: f4ef32cec5591667c75a1e1e31200d51529a7b50
5
5
  SHA512:
6
- metadata.gz: 3ab26532273554b8a11a72e91206af5d5562e9ef721a84a83629f725411deb46d5483a0b2bcb5edb2fed19b5d619f4c293b8809982d3b2a71b69753cdddc8c73
7
- data.tar.gz: 0352702fea3d37bafcecac59840bc205c4a0310f46ba5c0574a1b15f18339713ec72720976d0957c2c0f6ba1780ed485a799e6accbe51857573804d80fedc4c8
6
+ metadata.gz: 6aa3c28aeffad6471ced7ab755d34cab8b0c6d986c4d6739245b9706e3608fd18fbfed75287f94ac5d337e5078f4e711e94aee748ff9508b439689ad24417a2b
7
+ data.tar.gz: 36c0f9f971e94f602299f785a7d28a1f56b7e566a6ec3717f46905c7f7e306b574d028a7cd10e32f35b6455b742c0f5538b327fa4360e91c392a8dd76f6cc732
@@ -4,7 +4,6 @@ script: "bundle exec rake ci"
4
4
  env:
5
5
  - TRAVIS=true
6
6
  rvm:
7
- - '1.9'
8
7
  - '2.0'
9
8
  - '2.1'
10
9
  - '2.2'
@@ -12,6 +11,7 @@ rvm:
12
11
  matrix:
13
12
  allow_failures:
14
13
  - rvm: rbx
14
+ - rvm: '2.0'
15
15
  notifications:
16
16
  irc:
17
17
  channels:
@@ -1,3 +1,8 @@
1
+ # v0.7.9 pending
2
+
3
+ * Deprecate `--score` flag replace with `--expected-coverage`
4
+ * Set default job count to 4 under CI environments.
5
+
1
6
  # v0.7.8 2015-03-8
2
7
 
3
8
  * Kill imperfect float rounding for exact coverage expectations.
data/README.md CHANGED
@@ -45,26 +45,6 @@ Blog-Posts
45
45
  * http://www.sitepoint.com/mutation-testing-mutant/
46
46
  * http://solnic.eu/2013/01/23/mutation-testing-with-mutant.html
47
47
 
48
- Projects using Mutant
49
- ---------------------
50
-
51
- The following projects adopted mutant, and aim for 100% mutation coverage:
52
-
53
- * [axiom](https://github.com/dkubb/axiom)
54
- * [axiom-types](https://github.com/dkubb/axiom-types)
55
- * [rom-mapper](https://github.com/rom-rb/rom-mapper)
56
- * [rom-session](https://github.com/rom-rb/rom-session)
57
- * [event_bus](https://github.com/kevinrutherford/event_bus)
58
- * [virtus](https://github.com/solnic/virtus)
59
- * [quacky](https://github.com/benmoss/quacky)
60
- * [substation](https://github.com/snusnu/substation)
61
- * [large_binomials](https://github.com/filipvanlaenen/large_binomials)
62
- * [promise.rb](https://github.com/lgierth/promise.rb)
63
- * [full_name](https://github.com/AGILiDEE/full_name)
64
- * various small/minor stuff under https://github.com/mbj
65
-
66
- Feel free to ping me to add your project to the list!
67
-
68
48
  Installation
69
49
  ------------
70
50
 
@@ -87,10 +67,8 @@ The Crash / Stuck Problem (MRI)
87
67
  -------------------------------
88
68
 
89
69
  Mutations generated by mutant can cause MRI to enter VM states its not prepared for.
90
- All MRI versions above 1.9 are affected by this depending on your compiler flags, compiler version,
91
- and OS scheduling behavior.
92
-
93
- It seems that https://github.com/ruby/ruby/commit/8fe95fea9d238a6deb70c8953ceb3a28a67f4636 fixes the problem (unlreleased). So in doubht you have currently to run muant against latest head / trunk.
70
+ All MRI versions > 1.9 and < 2.2.1 are affected by this depending on your compiler flags,
71
+ compiler version, and OS scheduling behavior.
94
72
 
95
73
  This can have the following unintended effects:
96
74
 
@@ -107,8 +85,11 @@ This can have the following unintended effects:
107
85
 
108
86
  References:
109
87
 
110
- * Mutant bug: https://github.com/mbj/mutant/issues/265
111
- * Upstream bug: https://bugs.ruby-lang.org/issues/10460
88
+ * [MRI fix](https://github.com/ruby/ruby/commit/8fe95fea9d238a6deb70c8953ceb3a28a67f4636)
89
+ * [MRI backport to 2.2.1](https://github.com/ruby/ruby/commit/8fe95fea9d238a6deb70c8953ceb3a28a67f4636)
90
+ * [Mutant issue](https://github.com/mbj/mutant/issues/265)
91
+ * [Upstream bug redmine](https://bugs.ruby-lang.org/issues/10460)
92
+ * [Upstream bug github](https://github.com/ruby/ruby/pull/822)
112
93
 
113
94
  Examples
114
95
  --------
@@ -152,7 +133,7 @@ Assuming you are using rspec, you can mutation test Rails models by adding the f
152
133
  group :test do
153
134
  gem 'mutant'
154
135
  gem 'mutant-rspec'
155
- end
136
+ end
156
137
  ```
157
138
 
158
139
  Next, run bundle and comment out ```require 'rspec/autorun'``` from your spec_helper.rb file. Having done so you should be able to use commands like the following:
@@ -171,8 +152,9 @@ Your options:
171
152
  * [GitHub Issues](https://github.com/mbj/mutant/issues)
172
153
  * Ping me on [twitter](https://twitter.com/_m_b_j_)
173
154
 
174
- There is also the [#mutant] channel on freenode. As my OSS time budged is very limited I cannot
175
- join it often. Please prefer to use GitHub issues with a 'Question: ' prefix in title.
155
+ There is also the [#mutant](http://irclog.whitequark.org/mutant) channel on freenode.
156
+ As my OSS time budged is very limited I cannot join it often. Please prefer to use GitHub issues with
157
+ a 'Question: ' prefix in title.
176
158
 
177
159
  Credits
178
160
  -------
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 18
3
- total_score: 1215
3
+ total_score: 1241
@@ -132,4 +132,5 @@ UtilityFunction:
132
132
  - Mutant::Meta::Example::Verification#format_mutation
133
133
  - Mutant::Reporter::CLI::Format::Progressive#new_buffer
134
134
  - Mutant::Reporter::CLI::Printer::StatusProgressive#object # False positive calls super
135
+ - Mutant::Integration::Rspec#parse_expression # intentional, private
135
136
  max_helper_calls: 0
@@ -7,9 +7,9 @@ require 'diff/lcs'
7
7
  require 'diff/lcs/hunk'
8
8
  require 'equalizer'
9
9
  require 'ice_nine'
10
- require 'ice_nine'
11
10
  require 'morpher'
12
11
  require 'open3'
12
+ require 'optparse'
13
13
  require 'parallel'
14
14
  require 'parser'
15
15
  require 'parser/current'
@@ -178,7 +178,6 @@ require 'mutant/mutator/node/splat'
178
178
  require 'mutant/mutator/node/resbody'
179
179
  require 'mutant/mutator/node/rescue'
180
180
  require 'mutant/mutator/node/match_current_line'
181
- require 'mutant/config'
182
181
  require 'mutant/loader'
183
182
  require 'mutant/context'
184
183
  require 'mutant/context/scope'
@@ -206,6 +205,7 @@ require 'mutant/test'
206
205
  require 'mutant/integration'
207
206
  require 'mutant/selector'
208
207
  require 'mutant/selector/expression'
208
+ require 'mutant/config'
209
209
  require 'mutant/cli'
210
210
  require 'mutant/color'
211
211
  require 'mutant/diff'
@@ -225,7 +225,7 @@ require 'mutant/zombifier/file'
225
225
  module Mutant
226
226
  # Reopen class to initialize constant to avoid dep circle
227
227
  class Config
228
- CI_DEFAULT_PROCESSOR_COUNT = 2
228
+ CI_DEFAULT_PROCESSOR_COUNT = 4
229
229
 
230
230
  DEFAULT = new(
231
231
  debug: false,
@@ -1,5 +1,3 @@
1
- require 'optparse'
2
-
3
1
  module Mutant
4
2
 
5
3
  # Commandline parser
@@ -68,13 +66,13 @@ module Mutant
68
66
  opts = OptionParser.new do |builder|
69
67
  builder.banner = 'usage: mutant [options] MATCH_EXPRESSION ...'
70
68
  %w[add_environment_options add_mutation_options add_filter_options add_debug_options].each do |name|
71
- send(name, builder)
69
+ __send__(name, builder)
72
70
  end
73
71
  end
74
72
 
75
73
  parse_match_expressions(opts.parse!(arguments))
76
74
  rescue OptionParser::ParseError => error
77
- raise(Error, error.message, error.backtrace)
75
+ raise(Error, error)
78
76
  end
79
77
 
80
78
  # Parse matchers
@@ -128,8 +126,7 @@ module Mutant
128
126
  # @api private
129
127
  #
130
128
  def setup_integration(name)
131
- require "mutant/integration/#{name}"
132
- update(integration: Integration.lookup(name))
129
+ update(integration: Integration.setup(name))
133
130
  rescue LoadError
134
131
  raise Error, "Could not load integration #{name.inspect} (you may want to try installing the gem mutant-#{name})"
135
132
  end
@@ -143,10 +140,16 @@ module Mutant
143
140
  # @api private
144
141
  #
145
142
  def add_mutation_options(opts)
146
- opts.separator(EMPTY_STRING)
143
+ opts.separator(nil)
147
144
  opts.separator('Options:')
148
145
 
149
- opts.on('--score COVERAGE', 'Fail unless COVERAGE is not reached exactly') do |coverage|
146
+ opts.on(
147
+ '--expected-coverage COVERAGE',
148
+ 'Fail unless COVERAGE is not reached exactly, parsed via Rational()'
149
+ ) do |coverage|
150
+ update(expected_coverage: Rational(coverage))
151
+ end
152
+ opts.on('--score COVERAGE', 'Fail unless COVERAGE is not reached exactly [deprecated]') do |coverage|
150
153
  update(expected_coverage: Rational(coverage, 100))
151
154
  end
152
155
  opts.on('--use STRATEGY', 'Use STRATEGY for killing mutations', &method(:setup_integration))
@@ -182,7 +185,7 @@ module Mutant
182
185
  update(fail_fast: true)
183
186
  end
184
187
  opts.on('--version', 'Print mutants version') do
185
- puts("mutant-#{Mutant::VERSION}")
188
+ puts("mutant-#{VERSION}")
186
189
  Kernel.exit(EXIT_SUCCESS)
187
190
  end
188
191
  opts.on('-d', '--debug', 'Enable debugging output') do
@@ -6,6 +6,19 @@ module Mutant
6
6
 
7
7
  REGISTRY = {}
8
8
 
9
+ # Setup integration
10
+ #
11
+ # @param [String] name
12
+ #
13
+ # @return [Integration]
14
+ #
15
+ # @api private
16
+ #
17
+ def self.setup(name)
18
+ require "mutant/integration/#{name}"
19
+ lookup(name)
20
+ end
21
+
9
22
  # Lookup integration for name
10
23
  #
11
24
  # @param [String] name
@@ -31,8 +31,8 @@ module Mutant
31
31
  # @api private
32
32
  #
33
33
  def generated
34
- Mutant::Mutator.each(node).map do |node|
35
- Mutant::Mutation::Evil.new(self, node)
34
+ Mutator.each(node).map do |node|
35
+ Mutation::Evil.new(self, node)
36
36
  end
37
37
  end
38
38
  memoize :generated
@@ -13,9 +13,10 @@ module Mutant
13
13
  # @api private
14
14
  #
15
15
  def self.build(output)
16
+ tput = Tput.detect
16
17
  tty = output.respond_to?(:tty?) && output.tty?
17
- format = if !Mutant.ci? && tty && Tput::INSTANCE.available
18
- Format::Framed.new(tty: tty, tput: Tput::INSTANCE)
18
+ format = if !Mutant.ci? && tty && tput
19
+ Format::Framed.new(tty: tty, tput: tput)
19
20
  else
20
21
  Format::Progressive.new(tty: tty)
21
22
  end
@@ -176,7 +176,7 @@ module Mutant
176
176
  # @api private
177
177
  #
178
178
  def active_subject_results
179
- active_mutation_jobs = active_jobs.select { |job| job.payload.kind_of?(Mutant::Mutation) }
179
+ active_mutation_jobs = active_jobs.select { |job| job.payload.kind_of?(Mutation) }
180
180
  active_subjects = active_mutation_jobs.map(&:payload).flat_map(&:subject).to_set
181
181
 
182
182
  payload.subject_results.select do |subject_result|
@@ -258,7 +258,7 @@ module Mutant
258
258
  # @api private
259
259
  #
260
260
  def coverage_percent
261
- (coverage * 100).to_f
261
+ coverage * 100
262
262
  end
263
263
 
264
264
  # Return overhead percent
@@ -3,23 +3,41 @@ module Mutant
3
3
  class CLI
4
4
  # Interface to the optionally present tput binary
5
5
  class Tput
6
- include Adamantium, Concord::Public.new(:available, :prepare, :restore)
6
+ include Adamantium, Concord::Public.new(:prepare, :restore)
7
7
 
8
8
  private_class_method :new
9
9
 
10
- capture = lambda do |command|
10
+ # Return detected tput support
11
+ #
12
+ # @return [Tput]
13
+ # if tput support is present
14
+ #
15
+ # @return [nil]
16
+ # otherwise
17
+ def self.detect
18
+ reset = capture('tput reset')
19
+ save = capture('tput sc') if reset
20
+ restore = capture('tput rc') if save
21
+ clean = capture('tput ed') || capture('tput cd') if restore
22
+ new(reset + save, restore + clean) if clean
23
+ end
24
+
25
+ # Capture output
26
+ #
27
+ # @param [String] command
28
+ # command to run
29
+ #
30
+ # @return [String]
31
+ # stdout of command on success
32
+ #
33
+ # @return [nil]
34
+ # otherwise
35
+ #
36
+ def self.capture(command)
11
37
  stdout, _stderr, exitstatus = Open3.capture3(command)
12
38
  stdout if exitstatus.success?
13
39
  end
14
-
15
- reset = capture.('tput reset')
16
- save = capture.('tput sc') if reset
17
- restore = capture.('tput rc') if save
18
- clean = capture.('tput ed') if restore
19
-
20
- UNAVAILABLE = new(false, nil, nil)
21
-
22
- INSTANCE = clean ? new(true, reset + save, restore + clean) : UNAVAILABLE
40
+ private_class_method :capture
23
41
 
24
42
  end # TPUT
25
43
  end # CLI
@@ -85,8 +85,6 @@ module Mutant
85
85
  class Env
86
86
  include Coverage, Result, Anima.new(:runtime, :env, :subject_results)
87
87
 
88
- COVERAGE_PRECISION = 1
89
-
90
88
  # Test if run is successful
91
89
  #
92
90
  # @return [Boolean]
@@ -1,4 +1,4 @@
1
1
  module Mutant
2
2
  # The current mutant version
3
- VERSION = '0.7.8'.freeze
3
+ VERSION = '0.7.9'.freeze
4
4
  end # Mutant
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source 'true and false'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source 'a &&= 1'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source '[true]'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
 
5
3
  source 'true; false'
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source 'foo { a; b }'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source 'foo(&bar)'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source 'foo { |&bar| }'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source 'true'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source 'break true'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source <<-RUBY
5
3
  case
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source 'A = true'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source '::A'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source 'A::B::C'
5
3
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  Mutant::Meta::Example.add do
4
2
  source '@@a'
5
3