mutant 0.5.26 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.travis.yml +1 -0
  4. data/Changelog.md +16 -3
  5. data/Gemfile +0 -2
  6. data/Gemfile.devtools +2 -2
  7. data/README.md +9 -15
  8. data/bin/mutant +0 -1
  9. data/config/flay.yml +1 -1
  10. data/config/flog.yml +1 -1
  11. data/config/mutant.yml +1 -1
  12. data/config/reek.yml +14 -11
  13. data/config/rubocop.yml +1 -1
  14. data/lib/mutant.rb +22 -21
  15. data/lib/mutant/ast.rb +47 -0
  16. data/lib/mutant/cli.rb +7 -4
  17. data/lib/mutant/config.rb +1 -0
  18. data/lib/mutant/context.rb +1 -1
  19. data/lib/mutant/diff.rb +38 -7
  20. data/lib/mutant/env.rb +22 -3
  21. data/lib/mutant/expression.rb +15 -4
  22. data/lib/mutant/integration.rb +1 -1
  23. data/lib/mutant/isolation.rb +2 -4
  24. data/lib/mutant/matcher.rb +1 -1
  25. data/lib/mutant/matcher/method.rb +1 -1
  26. data/lib/mutant/matcher/method/singleton.rb +1 -1
  27. data/lib/mutant/matcher/methods.rb +0 -2
  28. data/lib/mutant/meta/example.rb +0 -2
  29. data/lib/mutant/meta/example/dsl.rb +1 -1
  30. data/lib/mutant/mutator.rb +1 -1
  31. data/lib/mutant/mutator/node.rb +3 -3
  32. data/lib/mutant/mutator/node/begin.rb +1 -1
  33. data/lib/mutant/mutator/node/block.rb +16 -3
  34. data/lib/mutant/mutator/node/if.rb +1 -1
  35. data/lib/mutant/mutator/node/literal/fixnum.rb +1 -1
  36. data/lib/mutant/mutator/node/resbody.rb +0 -2
  37. data/lib/mutant/mutator/node/send.rb +17 -7
  38. data/lib/mutant/mutator/node/send/index.rb +0 -2
  39. data/lib/mutant/mutator/registry.rb +1 -1
  40. data/lib/mutant/mutator/util.rb +1 -1
  41. data/lib/mutant/mutator/util/array.rb +1 -1
  42. data/lib/mutant/reporter.rb +13 -3
  43. data/lib/mutant/reporter/cli.rb +54 -8
  44. data/lib/mutant/reporter/cli/format.rb +197 -0
  45. data/lib/mutant/reporter/cli/printer.rb +402 -22
  46. data/lib/mutant/reporter/cli/tput.rb +27 -0
  47. data/lib/mutant/reporter/null.rb +4 -34
  48. data/lib/mutant/reporter/trace.rb +6 -38
  49. data/lib/mutant/result.rb +44 -56
  50. data/lib/mutant/runner.rb +99 -52
  51. data/lib/mutant/runner/collector.rb +134 -0
  52. data/lib/mutant/subject/method/instance.rb +12 -4
  53. data/lib/mutant/version.rb +1 -1
  54. data/lib/mutant/warning_filter.rb +0 -2
  55. data/lib/mutant/zombifier/file.rb +1 -1
  56. data/meta/block.rb +17 -1
  57. data/meta/send.rb +123 -1
  58. data/mutant-rspec.gemspec +3 -3
  59. data/mutant.gemspec +1 -1
  60. data/spec/integration/mutant/corpus_spec.rb +4 -195
  61. data/spec/integration/mutant/null_spec.rb +1 -3
  62. data/spec/integration/mutant/rspec_spec.rb +1 -3
  63. data/spec/integration/mutant/test_mutator_handles_types_spec.rb +1 -3
  64. data/spec/integration/mutant/zombie_spec.rb +1 -3
  65. data/spec/integrations.yml +7 -0
  66. data/spec/shared/method_matcher_behavior.rb +1 -1
  67. data/spec/spec_helper.rb +1 -0
  68. data/spec/support/compress_helper.rb +1 -0
  69. data/spec/support/corpus.rb +239 -0
  70. data/spec/support/mutation_verifier.rb +2 -4
  71. data/spec/unit/mutant/cli_spec.rb +20 -13
  72. data/spec/unit/mutant/context/root_spec.rb +1 -3
  73. data/spec/unit/mutant/context/scope/root_spec.rb +1 -3
  74. data/spec/unit/mutant/context/scope/unqualified_name_spec.rb +1 -3
  75. data/spec/unit/mutant/diff_spec.rb +37 -19
  76. data/spec/unit/mutant/expression/method_spec.rb +5 -7
  77. data/spec/unit/mutant/expression/methods_spec.rb +5 -7
  78. data/spec/unit/mutant/expression/namespace/flat_spec.rb +6 -8
  79. data/spec/unit/mutant/expression/namespace/recursive_spec.rb +6 -7
  80. data/spec/unit/mutant/expression_spec.rb +14 -5
  81. data/spec/unit/mutant/integration_spec.rb +14 -3
  82. data/spec/unit/mutant/isolation_spec.rb +2 -4
  83. data/spec/unit/mutant/loader/eval_spec.rb +1 -3
  84. data/spec/unit/mutant/matcher/chain_spec.rb +1 -3
  85. data/spec/unit/mutant/matcher/compiler/subject_prefix_spec.rb +21 -0
  86. data/spec/unit/mutant/matcher/compiler_spec.rb +28 -3
  87. data/spec/unit/mutant/matcher/filter_spec.rb +1 -3
  88. data/spec/unit/mutant/matcher/method/instance_spec.rb +3 -5
  89. data/spec/unit/mutant/matcher/method/singleton_spec.rb +22 -4
  90. data/spec/unit/mutant/matcher/methods/instance_spec.rb +7 -6
  91. data/spec/unit/mutant/matcher/methods/singleton_spec.rb +4 -6
  92. data/spec/unit/mutant/matcher/namespace_spec.rb +1 -3
  93. data/spec/unit/mutant/matcher/null_spec.rb +1 -3
  94. data/spec/unit/mutant/mutation_spec.rb +1 -3
  95. data/spec/unit/mutant/mutator/node_spec.rb +1 -3
  96. data/spec/unit/mutant/reporter/cli_spec.rb +444 -206
  97. data/spec/unit/mutant/reporter/null_spec.rb +1 -3
  98. data/spec/unit/mutant/require_highjack_spec.rb +1 -3
  99. data/spec/unit/mutant/runner_spec.rb +42 -28
  100. data/spec/unit/mutant/subject/context_spec.rb +1 -3
  101. data/spec/unit/mutant/subject/method/instance_spec.rb +27 -19
  102. data/spec/unit/mutant/subject/method/singleton_spec.rb +49 -17
  103. data/spec/unit/mutant/subject_spec.rb +1 -3
  104. data/spec/unit/mutant/test_spec.rb +1 -3
  105. data/spec/unit/mutant/warning_expectation.rb +1 -3
  106. data/spec/unit/mutant/warning_filter_spec.rb +1 -3
  107. data/spec/unit/mutant_spec.rb +13 -3
  108. data/test_app/Gemfile.devtools +2 -2
  109. data/test_app/spec/unit/test_app/literal/string_spec.rb +1 -1
  110. metadata +10 -21
  111. data/lib/mutant/matcher/method/finder.rb +0 -72
  112. data/lib/mutant/reporter/cli/progress.rb +0 -10
  113. data/lib/mutant/reporter/cli/progress/config.rb +0 -30
  114. data/lib/mutant/reporter/cli/progress/env.rb +0 -30
  115. data/lib/mutant/reporter/cli/progress/noop.rb +0 -27
  116. data/lib/mutant/reporter/cli/progress/result.rb +0 -12
  117. data/lib/mutant/reporter/cli/progress/result/mutation.rb +0 -45
  118. data/lib/mutant/reporter/cli/progress/result/subject.rb +0 -54
  119. data/lib/mutant/reporter/cli/progress/subject.rb +0 -27
  120. data/lib/mutant/reporter/cli/registry.rb +0 -81
  121. data/lib/mutant/reporter/cli/report.rb +0 -10
  122. data/lib/mutant/reporter/cli/report/env.rb +0 -92
  123. data/lib/mutant/reporter/cli/report/mutation.rb +0 -103
  124. data/lib/mutant/reporter/cli/report/subject.rb +0 -32
  125. data/lib/mutant/reporter/cli/report/test.rb +0 -28
  126. data/lib/mutant/walker.rb +0 -53
  127. data/spec/shared/mutator_behavior.rb +0 -55
@@ -0,0 +1,134 @@
1
+ module Mutant
2
+ class Runner
3
+ # Parallel process collector
4
+ class Collector
5
+ include Concord::Public.new(:env)
6
+
7
+ # Initialize object
8
+ #
9
+ # @return [undefined]
10
+ #
11
+ # @api private
12
+ #
13
+ def initialize(*)
14
+ super
15
+ @start = Time.now
16
+ @aggregate = Hash.new { |hash, key| hash[key] = [] }
17
+ @activity = Hash.new(0)
18
+ @last_mutation_result = nil
19
+ end
20
+
21
+ # Return last mutation result
22
+ #
23
+ # @return [Result::Mutation]
24
+ # if there is a last mutation result
25
+ #
26
+ # @return [nil]
27
+ # otherwise
28
+ #
29
+ # @api private
30
+ #
31
+ attr_reader :last_mutation_result
32
+
33
+ # Return active subject results
34
+ #
35
+ # @return [Array<Result::Subject>]
36
+ #
37
+ # @api private
38
+ #
39
+ def active_subject_results
40
+ active_subjects.map(&method(:subject_result))
41
+ end
42
+
43
+ # Return current result
44
+ #
45
+ # @return [Result::Env]
46
+ #
47
+ # @api private
48
+ #
49
+ def result
50
+ Result::Env.new(
51
+ env: env,
52
+ runtime: Time.now - @start,
53
+ subject_results: subject_results,
54
+ done: false
55
+ )
56
+ end
57
+
58
+ # Handle mutation start
59
+ #
60
+ # @param [Mutation] mutation
61
+ #
62
+ # @return [self]
63
+ #
64
+ # @api private
65
+ #
66
+ def start(mutation)
67
+ @activity[mutation.subject] += 1
68
+ self
69
+ end
70
+
71
+ # Handle mutation finish
72
+ #
73
+ # @param [Result::Mutation] mutation_result
74
+ #
75
+ # @return [self]
76
+ #
77
+ # @api private
78
+ #
79
+ def finish(mutation_result)
80
+ @last_mutation_result = mutation_result
81
+
82
+ subject = mutation_result.mutation.subject
83
+
84
+ @activity[subject] -= 1
85
+ @aggregate[subject] << mutation_result
86
+
87
+ self
88
+ end
89
+
90
+ private
91
+
92
+ # Return current subject results
93
+ #
94
+ # @return [Array<Result::Subject>]
95
+ #
96
+ # @api private
97
+ #
98
+ def subject_results
99
+ env.subjects.map(&method(:subject_result))
100
+ end
101
+
102
+ # Return active subjects
103
+ #
104
+ # @return [Array<Subject>]
105
+ #
106
+ # @api private
107
+ #
108
+ def active_subjects
109
+ @activity.select do |_subject, count|
110
+ count > 0
111
+ end.map(&:first)
112
+ end
113
+
114
+ # Return current subject result
115
+ #
116
+ # @param [Subject] subject
117
+ #
118
+ # @return [Array<Subject::Result>]
119
+ #
120
+ # @api private
121
+ #
122
+ def subject_result(subject)
123
+ mutation_results = @aggregate[subject].sort_by(&:index)
124
+
125
+ Result::Subject.new(
126
+ subject: subject,
127
+ runtime: mutation_results.map(&:runtime).inject(0.0, :+),
128
+ mutation_results: mutation_results
129
+ )
130
+ end
131
+
132
+ end # Collector
133
+ end # Runner
134
+ end # Mutant
@@ -5,7 +5,15 @@ module Mutant
5
5
  class Instance < self
6
6
 
7
7
  NAME_INDEX = 0
8
- SYMBOL = '#'.freeze
8
+ SYMBOL = '#'.freeze
9
+
10
+ # A list of methods that will warn when they are undefined
11
+ WARN_METHODS_UNDEFINED =
12
+ if RUBY_ENGINE.eql?('ruby')
13
+ [:initialize, :__send__, :object_id].freeze
14
+ else
15
+ EMPTY_ARRAY
16
+ end
9
17
 
10
18
  # Test if method is public
11
19
  #
@@ -26,10 +34,10 @@ module Mutant
26
34
  #
27
35
  def prepare
28
36
  expected_warnings =
29
- if RUBY_ENGINE.eql?('ruby') && name.equal?(:initialize)
30
- ["#{__FILE__}:#{__LINE__ + 5}: warning: undefining `initialize' may cause serious problems\n"]
37
+ if WARN_METHODS_UNDEFINED.include?(name)
38
+ ["#{__FILE__}:#{__LINE__ + 5}: warning: undefining `#{name}' may cause serious problems\n"]
31
39
  else
32
- []
40
+ EMPTY_ARRAY
33
41
  end
34
42
  WarningExpectation.new(expected_warnings).execute do
35
43
  scope.send(:undef_method, name)
@@ -1,4 +1,4 @@
1
1
  module Mutant
2
2
  # The current mutant version
3
- VERSION = '0.5.26'.freeze
3
+ VERSION = '0.6.0'.freeze
4
4
  end # Mutant
@@ -1,5 +1,3 @@
1
- # encoding: UTF-8
2
-
3
1
  module Mutant
4
2
  # Stream filter for warnings
5
3
  class WarningFilter
@@ -1,6 +1,6 @@
1
1
  module Mutant
2
2
  class Zombifier
3
- # File containing source beeing zombified
3
+ # File containing source being zombified
4
4
  class File
5
5
  include Adamantium::Flat, Concord::Public.new(:path), AST::Sexp
6
6
 
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  Mutant::Meta::Example.add do
4
- source 'foo() { a; b }'
4
+ source 'foo { a; b }'
5
5
 
6
6
  singleton_mutations
7
7
  mutation 'foo { a }'
@@ -13,6 +13,7 @@ Mutant::Meta::Example.add do
13
13
  mutation 'foo { nil; b }'
14
14
  mutation 'foo { self; b }'
15
15
  mutation 'foo'
16
+ mutation 'a; b'
16
17
  end
17
18
 
18
19
  Mutant::Meta::Example.add do
@@ -45,6 +46,21 @@ Mutant::Meta::Example.add do
45
46
  mutation 'foo'
46
47
  end
47
48
 
49
+ Mutant::Meta::Example.add do
50
+ source 'foo(a, b) {}'
51
+
52
+ singleton_mutations
53
+ mutation 'foo(a, nil) {}'
54
+ mutation 'foo(nil, b) {}'
55
+ mutation 'foo(self, b) {}'
56
+ mutation 'foo(a, self) {}'
57
+ mutation 'foo(a, b)'
58
+ mutation 'foo(a, b) { raise }'
59
+ mutation 'foo(a) {}'
60
+ mutation 'foo(b) {}'
61
+ mutation 'foo {}'
62
+ end
63
+
48
64
  Mutant::Meta::Example.add do
49
65
  source 'foo { |(a)| }'
50
66
 
@@ -1,5 +1,67 @@
1
1
  # encoding: utf-8
2
2
 
3
+ Mutant::Meta::Example.add do
4
+ source 'a > b'
5
+
6
+ singleton_mutations
7
+ mutation 'a == b'
8
+ mutation 'a.eql?(b)'
9
+ mutation 'a.equal?(b)'
10
+ mutation 'nil > b'
11
+ mutation 'self > b'
12
+ mutation 'a > nil'
13
+ mutation 'a > self'
14
+ mutation 'a'
15
+ mutation 'b'
16
+ end
17
+
18
+ Mutant::Meta::Example.add do
19
+ source 'a >= b'
20
+
21
+ singleton_mutations
22
+ mutation 'a > b'
23
+ mutation 'a == b'
24
+ mutation 'a.eql?(b)'
25
+ mutation 'a.equal?(b)'
26
+ mutation 'nil >= b'
27
+ mutation 'self >= b'
28
+ mutation 'a >= nil'
29
+ mutation 'a >= self'
30
+ mutation 'a'
31
+ mutation 'b'
32
+ end
33
+
34
+ Mutant::Meta::Example.add do
35
+ source 'a <= b'
36
+
37
+ singleton_mutations
38
+ mutation 'a < b'
39
+ mutation 'a == b'
40
+ mutation 'a.eql?(b)'
41
+ mutation 'a.equal?(b)'
42
+ mutation 'nil <= b'
43
+ mutation 'self <= b'
44
+ mutation 'a <= nil'
45
+ mutation 'a <= self'
46
+ mutation 'a'
47
+ mutation 'b'
48
+ end
49
+
50
+ Mutant::Meta::Example.add do
51
+ source 'a < b'
52
+
53
+ singleton_mutations
54
+ mutation 'a == b'
55
+ mutation 'a.eql?(b)'
56
+ mutation 'a.equal?(b)'
57
+ mutation 'nil < b'
58
+ mutation 'self < b'
59
+ mutation 'a < nil'
60
+ mutation 'a < self'
61
+ mutation 'a'
62
+ mutation 'b'
63
+ end
64
+
3
65
  Mutant::Meta::Example.add do
4
66
  source 'reverse_each'
5
67
 
@@ -7,6 +69,13 @@ Mutant::Meta::Example.add do
7
69
  mutation 'each'
8
70
  end
9
71
 
72
+ Mutant::Meta::Example.add do
73
+ source 'reverse_merge'
74
+
75
+ singleton_mutations
76
+ mutation 'merge'
77
+ end
78
+
10
79
  Mutant::Meta::Example.add do
11
80
  source 'reverse_map'
12
81
 
@@ -22,6 +91,33 @@ Mutant::Meta::Example.add do
22
91
  mutation 'each'
23
92
  end
24
93
 
94
+ Mutant::Meta::Example.add do
95
+ source 'foo.to_s'
96
+
97
+ singleton_mutations
98
+ mutation 'foo'
99
+ mutation 'self.to_s'
100
+ mutation 'foo.to_str'
101
+ end
102
+
103
+ Mutant::Meta::Example.add do
104
+ source 'foo.to_a'
105
+
106
+ singleton_mutations
107
+ mutation 'foo'
108
+ mutation 'self.to_a'
109
+ mutation 'foo.to_ary'
110
+ end
111
+
112
+ Mutant::Meta::Example.add do
113
+ source 'foo.to_i'
114
+
115
+ singleton_mutations
116
+ mutation 'foo'
117
+ mutation 'self.to_i'
118
+ mutation 'foo.to_int'
119
+ end
120
+
25
121
  Mutant::Meta::Example.add do
26
122
  source 'foo == bar'
27
123
 
@@ -36,6 +132,32 @@ Mutant::Meta::Example.add do
36
132
  mutation 'foo.equal?(bar)'
37
133
  end
38
134
 
135
+ Mutant::Meta::Example.add do
136
+ source 'foo.is_a?(bar)'
137
+
138
+ singleton_mutations
139
+ mutation 'foo'
140
+ mutation 'bar'
141
+ mutation 'foo.is_a?'
142
+ mutation 'foo.is_a?(nil)'
143
+ mutation 'foo.is_a?(self)'
144
+ mutation 'self.is_a?(bar)'
145
+ mutation 'foo.instance_of?(bar)'
146
+ end
147
+
148
+ Mutant::Meta::Example.add do
149
+ source 'foo.kind_of?(bar)'
150
+
151
+ singleton_mutations
152
+ mutation 'foo'
153
+ mutation 'bar'
154
+ mutation 'foo.kind_of?'
155
+ mutation 'foo.kind_of?(nil)'
156
+ mutation 'foo.kind_of?(self)'
157
+ mutation 'self.kind_of?(bar)'
158
+ mutation 'foo.instance_of?(bar)'
159
+ end
160
+
39
161
  Mutant::Meta::Example.add do
40
162
  source 'foo.gsub(a, b)'
41
163
 
@@ -259,7 +381,7 @@ Mutant::Meta::Example.add do
259
381
  mutation 'self[*bar]'
260
382
  end
261
383
 
262
- (Mutant::AST::Types::BINARY_METHOD_OPERATORS - [:==, :eql?]).each do |operator|
384
+ (Mutant::AST::Types::BINARY_METHOD_OPERATORS - [:<=, :>=, :<, :>, :==, :eql?]).each do |operator|
263
385
  Mutant::Meta::Example.add do
264
386
  source "true #{operator} false"
265
387
 
@@ -13,12 +13,12 @@ Gem::Specification.new do |gem|
13
13
  gem.license = 'MIT'
14
14
 
15
15
  gem.require_paths = %w[lib]
16
- gem.files = `git ls-files -- lib/mutant/integration/rspec{,2,3}.rb`.split("\n")
17
- gem.test_files = `git ls-files -- spec/{unit/mutant/rspec,integration/rspec}`.split("\n")
16
+ gem.files = `git ls-files -- lib/mutant/integration/rspec.rb`.split("\n")
17
+ gem.test_files = `git ls-files -- spec/{unit,integration}/mutant/rspec/**/*.rb}`.split("\n")
18
18
  gem.extra_rdoc_files = %w[TODO LICENSE]
19
19
 
20
20
  gem.add_runtime_dependency('mutant', "~> #{gem.version}")
21
- gem.add_runtime_dependency('rspec-core', '>= 2.14.1', '<= 3.0.0')
21
+ gem.add_runtime_dependency('rspec-core', '>= 2.14.1', '< 3.1.0')
22
22
 
23
23
  gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5')
24
24
  end
@@ -37,7 +37,7 @@ Gem::Specification.new do |gem|
37
37
  gem.add_runtime_dependency('inflecto', '~> 0.0.2')
38
38
  gem.add_runtime_dependency('anima', '~> 0.2.0')
39
39
  gem.add_runtime_dependency('concord', '~> 0.1.5')
40
- gem.add_runtime_dependency('parallel', '~> 1.0.0')
40
+ gem.add_runtime_dependency('parallel', '~> 1.2.0')
41
41
 
42
42
  gem.add_development_dependency('bundler', '~> 1.3', '>= 1.3.5')
43
43
  end
@@ -1,209 +1,18 @@
1
- # encoding: UTF-8
2
-
3
- require 'parallel'
4
- require 'spec_helper'
5
-
6
- describe 'Mutant on ruby corpus' do
7
-
8
- ROOT = Pathname.new(__FILE__).parent.parent.parent.parent
9
-
10
- TMP = ROOT.join('tmp').freeze
1
+ RSpec.describe 'Mutant on ruby corpus' do
11
2
 
12
3
  before do
13
4
  skip 'Corpus test is deactivated on 1.9.3' if RUBY_VERSION.eql?('1.9.3')
14
5
  skip 'Corpus test is deactivated on RBX' if RUBY_ENGINE.eql?('rbx')
15
6
  end
16
7
 
17
- MUTEX = Mutex.new
18
-
19
- class Project
20
- include Adamantium, Anima.new(
21
- :name,
22
- :repo_uri,
23
- :exclude,
24
- :mutation_coverage,
25
- :mutation_generation,
26
- :namespace,
27
- :expect_coverage
28
- )
29
-
30
- # Verify mutation coverage
31
- #
32
- # @return [self]
33
- # if successufl
34
- #
35
- # @raise [Exception]
36
- #
37
- def verify_mutation_coverage
38
- checkout
39
- Dir.chdir(repo_path) do
40
- relative = ROOT.relative_path_from(repo_path)
41
- devtools = ROOT.join('Gemfile.devtools').read
42
- devtools << "gem 'mutant', path: '#{relative}'\n"
43
- devtools << "gem 'mutant-rspec', path: '#{relative}'\n"
44
- File.write(repo_path.join('Gemfile.devtools'), devtools)
45
- lockfile = repo_path.join('Gemfile.lock')
46
- lockfile.delete if lockfile.exist?
47
- Bundler.with_clean_env do
48
- system('bundle install')
49
- system(%W[bundle exec mutant -I lib -r #{name} --score #{expect_coverage} --use rspec #{namespace}*])
50
- end
51
- end
52
- end
53
-
54
- # Verify mutation generation
55
- #
56
- # @return [self]
57
- # if successful
58
- #
59
- # @raise [Exception]
60
- # otherwise
61
- #
62
- # rubocop:disable MethodLength
63
- def verify_mutation_generation
64
- checkout
65
- start = Time.now
66
- paths = Pathname.glob(repo_path.join('**/*.rb')).sort_by(&:size).reverse
67
- total = Parallel.map(paths, finish: method(:finish), start: method(:start)) do |path|
68
- count = 0
69
- node =
70
- begin
71
- Parser::CurrentRuby.parse(path.read)
72
- rescue EncodingError, ArgumentError
73
- nil # Make rubocop happy
74
- end
75
- if node
76
- Mutant::Mutator::Node.each(node) do
77
- count += 1
78
- end
79
- end
80
- count
81
- end.inject(0, :+)
82
- took = Time.now - start
83
- puts format(
84
- 'Total Mutations/Time/Parse-Errors: %s/%0.2fs - %0.2f/s',
85
- total,
86
- took,
87
- total / took
88
- )
89
- self
90
- end
91
-
92
- # Checkout repository
93
- #
94
- # @return [self]
95
- #
96
- # @api private
97
- #
98
- def checkout
99
- TMP.mkdir unless TMP.directory?
100
- if repo_path.exist?
101
- Dir.chdir(repo_path) do
102
- system(%w[git pull -f origin master])
103
- system(%w[git clean -f -d -x])
104
- end
105
- else
106
- system(%W[git clone #{repo_uri} #{repo_path}])
107
- end
108
- self
109
- end
110
- memoize :checkout
111
-
112
- private
113
-
114
- # Return repository path
115
- #
116
- # @return [Pathname]
117
- #
118
- # @api private
119
- #
120
- def repo_path
121
- TMP.join(name)
122
- end
123
-
124
- # Print start progress
125
- #
126
- # @param [Pathname] path
127
- # @param [Fixnum] _index
128
- # @param [Fixnum] count
129
- #
130
- # @return [undefined]
131
- #
132
- def start(path, _index)
133
- MUTEX.synchronize do
134
- puts format('Starting - %s', path)
135
- end
136
- end
137
-
138
- # Print finish progress
139
- #
140
- # @param [Pathname] path
141
- # @param [Fixnum] _index
142
- # @param [Fixnum] count
143
- #
144
- # @return [undefined]
145
- #
146
- def finish(path, _index, count)
147
- MUTEX.synchronize do
148
- puts format('Mutations - %4i - %s', count, path)
149
- end
150
- end
151
-
152
- # Helper method to execute system commands
153
- #
154
- # @param [Array<String>] arguments
155
- #
156
- # @api private
157
- #
158
- def system(arguments)
159
- return if Kernel.system(*arguments)
160
- if block_given?
161
- yield
162
- else
163
- fail 'System command failed!'
164
- end
165
- end
166
-
167
- LOADER = Morpher.build do
168
- s(:block,
169
- s(:guard, s(:primitive, Array)),
170
- s(:map,
171
- s(:block,
172
- s(:guard, s(:primitive, Hash)),
173
- s(:hash_transform,
174
- s(:key_symbolize, :repo_uri, s(:guard, s(:primitive, String))),
175
- s(:key_symbolize, :name, s(:guard, s(:primitive, String))),
176
- s(:key_symbolize, :namespace, s(:guard, s(:primitive, String))),
177
- s(:key_symbolize, :expect_coverage, s(:guard, s(:primitive, Float))),
178
- s(:key_symbolize, :mutation_coverage,
179
- s(:guard, s(:or, s(:primitive, TrueClass), s(:primitive, FalseClass)))),
180
- s(:key_symbolize, :mutation_generation,
181
- s(:guard, s(:or, s(:primitive, TrueClass), s(:primitive, FalseClass)))),
182
- s(:key_symbolize, :exclude, s(:map, s(:guard, s(:primitive, String))))
183
- ),
184
- s(:load_attribute_hash,
185
- # NOTE: The domain param has no DSL currently!
186
- Morpher::Evaluator::Transformer::Domain::Param.new(
187
- Project,
188
- [:repo_uri, :name, :exclude, :mutation_coverage, :mutation_generation]
189
- )
190
- )
191
- )
192
- )
193
- )
194
- end
195
-
196
- ALL = LOADER.call(YAML.load_file(ROOT.join('spec', 'integrations.yml')))
197
- end
198
-
199
- Project::ALL.select(&:mutation_generation).each do |project|
8
+ Corpus::Project::ALL.select(&:mutation_generation).each do |project|
200
9
  specify "#{project.name} does not fail on mutation generation" do
201
10
  project.verify_mutation_generation
202
11
  end
203
12
  end
204
13
 
205
- Project::ALL.select(&:mutation_coverage).each do |project|
206
- specify "#{project.name} does have expected mutaiton coverage" do
14
+ Corpus::Project::ALL.select(&:mutation_coverage).each do |project|
15
+ specify "#{project.name} does have expected mutation coverage" do
207
16
  project.verify_mutation_coverage
208
17
  end
209
18
  end