mutant 0.7.8 → 0.7.9

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.
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