mutant 0.7.3 → 0.7.4

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/.travis.yml +3 -2
  4. data/Changelog.md +7 -2
  5. data/Gemfile +0 -1
  6. data/Gemfile.devtools +9 -37
  7. data/README.md +1 -1
  8. data/circle.yml +1 -1
  9. data/config/flay.yml +1 -1
  10. data/config/reek.yml +6 -19
  11. data/config/rubocop.yml +58 -63
  12. data/lib/mutant.rb +8 -4
  13. data/lib/mutant/ast.rb +1 -1
  14. data/lib/mutant/cli.rb +12 -6
  15. data/lib/mutant/env.rb +17 -1
  16. data/lib/mutant/isolation.rb +4 -2
  17. data/lib/mutant/loader.rb +4 -0
  18. data/lib/mutant/matcher/compiler.rb +2 -0
  19. data/lib/mutant/mutation.rb +2 -0
  20. data/lib/mutant/mutator/node/const.rb +1 -1
  21. data/lib/mutant/mutator/node/generic.rb +1 -1
  22. data/lib/mutant/mutator/node/if.rb +2 -0
  23. data/lib/mutant/parallel.rb +93 -0
  24. data/lib/mutant/{runner → parallel}/master.rb +90 -45
  25. data/lib/mutant/parallel/source.rb +73 -0
  26. data/lib/mutant/{runner → parallel}/worker.rb +13 -30
  27. data/lib/mutant/reporter/cli.rb +8 -11
  28. data/lib/mutant/reporter/cli/printer.rb +14 -8
  29. data/lib/mutant/result.rb +0 -10
  30. data/lib/mutant/runner.rb +49 -43
  31. data/lib/mutant/runner/{scheduler.rb → sink.rb} +9 -68
  32. data/lib/mutant/version.rb +1 -1
  33. data/lib/mutant/zombifier/file.rb +28 -9
  34. data/meta/if.rb +8 -0
  35. data/meta/match_current_line.rb +1 -0
  36. data/spec/integration/mutant/corpus_spec.rb +1 -1
  37. data/spec/integration/mutant/null_spec.rb +1 -1
  38. data/spec/integration/mutant/rspec_spec.rb +1 -1
  39. data/spec/integration/mutant/test_mutator_handles_types_spec.rb +1 -1
  40. data/spec/integration/mutant/zombie_spec.rb +1 -1
  41. data/spec/support/corpus.rb +2 -0
  42. data/spec/support/fake_actor.rb +20 -10
  43. data/spec/support/mutation_verifier.rb +2 -0
  44. data/spec/support/shared_context.rb +12 -19
  45. data/spec/unit/mutant/env_spec.rb +20 -2
  46. data/spec/unit/mutant/expression_spec.rb +4 -1
  47. data/spec/unit/mutant/parallel/master_spec.rb +339 -0
  48. data/spec/unit/mutant/parallel/source/array_spec.rb +47 -0
  49. data/spec/unit/mutant/{runner → parallel}/worker_spec.rb +23 -26
  50. data/spec/unit/mutant/parallel_spec.rb +16 -0
  51. data/spec/unit/mutant/reporter/cli_spec.rb +1 -1
  52. data/spec/unit/mutant/reporter/trace_spec.rb +9 -0
  53. data/spec/unit/mutant/result/env_spec.rb +0 -55
  54. data/spec/unit/mutant/runner/driver_spec.rb +26 -0
  55. data/spec/unit/mutant/runner/sink_spec.rb +162 -0
  56. data/spec/unit/mutant/runner_spec.rb +60 -63
  57. data/spec/unit/mutant/warning_filter_spec.rb +2 -1
  58. data/test_app/Gemfile.devtools +9 -37
  59. metadata +21 -11
  60. data/spec/unit/mutant/runner/master_spec.rb +0 -199
  61. data/spec/unit/mutant/runner/scheduler_spec.rb +0 -161
@@ -54,7 +54,7 @@ RSpec.describe Mutant::WarningFilter do
54
54
  it 'executes block with warning filter enabled' do
55
55
  found = false
56
56
  object.use do
57
- found = $stderr.is_a?(described_class)
57
+ found = $stderr.instance_of?(described_class)
58
58
  end
59
59
  expect(found).to be(true)
60
60
  end
@@ -71,6 +71,7 @@ RSpec.describe Mutant::WarningFilter do
71
71
 
72
72
  it 'returns warnings generated within block' do
73
73
  warnings = object.use do
74
+ # rubocop:disable Lint/Eval
74
75
  eval(<<-RUBY)
75
76
  Class.new do
76
77
  def foo
@@ -1,65 +1,37 @@
1
- # encoding: utf-8
2
-
3
1
  group :development do
4
- gem 'rake', '~> 10.3.2'
5
- gem 'rspec', '~> 3.1.0'
6
- gem 'rspec-its', '~> 1.0.1'
7
- gem 'yard', '~> 0.8.7.4'
8
-
9
2
  platform :rbx do
10
3
  gem 'rubysl-singleton', '~> 2.0.0'
11
- gem 'rubinius-coverage', '~> 2.0.1'
12
4
  end
13
5
  end
14
6
 
15
- group :yard do
16
- gem 'kramdown', '~> 1.3.3'
17
- end
18
-
19
7
  group :guard do
20
- gem 'guard', '~> 2.6.1'
21
- gem 'guard-bundler', '~> 2.0.0'
22
- gem 'guard-rspec', '~> 4.2.9'
23
- gem 'guard-rubocop', '~> 1.1.0'
8
+ gem 'guard', '~> 2.10.3'
9
+ gem 'guard-bundler', '~> 2.1.0'
10
+ gem 'guard-rspec', '~> 4.5.0'
11
+ gem 'guard-rubocop', '~> 1.2.0'
24
12
 
25
13
  # file system change event handling
26
- gem 'listen', '~> 2.7.7'
14
+ gem 'listen', '~> 2.8.4'
27
15
  gem 'rb-fchange', '~> 0.0.6', require: false
28
16
  gem 'rb-fsevent', '~> 0.9.4', require: false
29
17
  gem 'rb-inotify', '~> 0.9.5', require: false
30
18
 
31
19
  # notification handling
32
- gem 'libnotify', '~> 0.8.3', require: false
20
+ gem 'libnotify', '~> 0.9.0', require: false
33
21
  gem 'rb-notifu', '~> 0.0.4', require: false
34
- gem 'terminal-notifier-guard', '~> 1.5.3', require: false
22
+ gem 'terminal-notifier-guard', '~> 1.6.4', require: false
35
23
  end
36
24
 
37
25
  group :metrics do
38
- gem 'coveralls', '~> 0.7.0'
39
- gem 'flay', '~> 2.5.0'
40
- gem 'flog', '~> 4.2.1'
41
- gem 'reek', '~> 1.3.7'
42
- gem 'rubocop', '~> 0.26.0'
43
- gem 'simplecov', '~> 0.7.1'
44
- gem 'yardstick', '~> 0.9.9'
45
-
46
- platforms :ruby_19, :ruby_20 do
47
- gem 'yard-spellcheck', '~> 0.1.5'
48
- end
49
-
50
26
  platform :rbx do
51
27
  gem 'json', '~> 1.8.1'
52
- gem 'racc', '~> 1.4.11'
53
- gem 'rubysl-logger', '~> 2.0.0'
28
+ gem 'racc', '~> 1.4.12'
29
+ gem 'rubysl-logger', '~> 2.1.0'
54
30
  gem 'rubysl-open-uri', '~> 2.0.0'
55
31
  gem 'rubysl-prettyprint', '~> 2.0.3'
56
32
  end
57
33
  end
58
34
 
59
- group :benchmarks do
60
- gem 'rbench', '~> 0.2.3'
61
- end
62
-
63
35
  platform :jruby do
64
36
  group :jruby do
65
37
  gem 'jruby-openssl', '~> 0.9.4'
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.7.3
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-08 00:00:00.000000000 Z
11
+ date: 2014-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -378,6 +378,10 @@ files:
378
378
  - lib/mutant/mutator/util.rb
379
379
  - lib/mutant/mutator/util/array.rb
380
380
  - lib/mutant/mutator/util/symbol.rb
381
+ - lib/mutant/parallel.rb
382
+ - lib/mutant/parallel/master.rb
383
+ - lib/mutant/parallel/source.rb
384
+ - lib/mutant/parallel/worker.rb
381
385
  - lib/mutant/reporter.rb
382
386
  - lib/mutant/reporter/cli.rb
383
387
  - lib/mutant/reporter/cli/format.rb
@@ -388,9 +392,7 @@ files:
388
392
  - lib/mutant/require_highjack.rb
389
393
  - lib/mutant/result.rb
390
394
  - lib/mutant/runner.rb
391
- - lib/mutant/runner/master.rb
392
- - lib/mutant/runner/scheduler.rb
393
- - lib/mutant/runner/worker.rb
395
+ - lib/mutant/runner/sink.rb
394
396
  - lib/mutant/subject.rb
395
397
  - lib/mutant/subject/method.rb
396
398
  - lib/mutant/subject/method/instance.rb
@@ -510,14 +512,18 @@ files:
510
512
  - spec/unit/mutant/mutation_spec.rb
511
513
  - spec/unit/mutant/mutator/node_spec.rb
512
514
  - spec/unit/mutant/mutator/registry_spec.rb
515
+ - spec/unit/mutant/parallel/master_spec.rb
516
+ - spec/unit/mutant/parallel/source/array_spec.rb
517
+ - spec/unit/mutant/parallel/worker_spec.rb
518
+ - spec/unit/mutant/parallel_spec.rb
513
519
  - spec/unit/mutant/reporter/cli_spec.rb
514
520
  - spec/unit/mutant/reporter/null_spec.rb
521
+ - spec/unit/mutant/reporter/trace_spec.rb
515
522
  - spec/unit/mutant/require_highjack_spec.rb
516
523
  - spec/unit/mutant/result/env_spec.rb
517
524
  - spec/unit/mutant/result/subject_spec.rb
518
- - spec/unit/mutant/runner/master_spec.rb
519
- - spec/unit/mutant/runner/scheduler_spec.rb
520
- - spec/unit/mutant/runner/worker_spec.rb
525
+ - spec/unit/mutant/runner/driver_spec.rb
526
+ - spec/unit/mutant/runner/sink_spec.rb
521
527
  - spec/unit/mutant/runner_spec.rb
522
528
  - spec/unit/mutant/subject/context_spec.rb
523
529
  - spec/unit/mutant/subject/method/instance_spec.rb
@@ -600,14 +606,18 @@ test_files:
600
606
  - spec/unit/mutant/mutation_spec.rb
601
607
  - spec/unit/mutant/mutator/node_spec.rb
602
608
  - spec/unit/mutant/mutator/registry_spec.rb
609
+ - spec/unit/mutant/parallel/master_spec.rb
610
+ - spec/unit/mutant/parallel/source/array_spec.rb
611
+ - spec/unit/mutant/parallel/worker_spec.rb
612
+ - spec/unit/mutant/parallel_spec.rb
603
613
  - spec/unit/mutant/reporter/cli_spec.rb
604
614
  - spec/unit/mutant/reporter/null_spec.rb
615
+ - spec/unit/mutant/reporter/trace_spec.rb
605
616
  - spec/unit/mutant/require_highjack_spec.rb
606
617
  - spec/unit/mutant/result/env_spec.rb
607
618
  - spec/unit/mutant/result/subject_spec.rb
608
- - spec/unit/mutant/runner/master_spec.rb
609
- - spec/unit/mutant/runner/scheduler_spec.rb
610
- - spec/unit/mutant/runner/worker_spec.rb
619
+ - spec/unit/mutant/runner/driver_spec.rb
620
+ - spec/unit/mutant/runner/sink_spec.rb
611
621
  - spec/unit/mutant/runner_spec.rb
612
622
  - spec/unit/mutant/subject/context_spec.rb
613
623
  - spec/unit/mutant/subject/method/instance_spec.rb
@@ -1,199 +0,0 @@
1
- RSpec.describe Mutant::Runner::Master do
2
- setup_shared_context
3
-
4
- describe 'object initialization' do
5
- subject { described_class.__send__(:new, env, double('actor')) }
6
-
7
- it 'initialized instance variables' do
8
- expect(subject.instance_variable_get(:@stop)).to be(false)
9
- expect(subject.instance_variable_get(:@stopping)).to be(false)
10
- end
11
- end
12
-
13
- describe '.call' do
14
- let(:actor_names) { [:master, :worker_a] }
15
- let(:worker_a) { actor_env.mailbox(:worker_a).sender }
16
- let(:worker_b) { actor_env.mailbox(:worker_b).sender }
17
- let(:parent) { actor_env.mailbox(:parent).sender }
18
-
19
- let(:job) { double('Job') }
20
-
21
- before do
22
- expect(Time).to receive(:now).and_return(Time.at(0)).at_most(5).times
23
- expect(Mutant::Runner::Worker).to receive(:run).with(
24
- id: 0,
25
- config: env.config,
26
- parent: actor_env.mailbox(:master).sender
27
- ).and_return(worker_a)
28
- end
29
-
30
- subject { described_class.call(env) }
31
-
32
- context 'jobs done before external stop' do
33
- before do
34
- message_sequence.add(:master, :ready, worker_a)
35
- message_sequence.add(:worker_a, :job, job_a)
36
- message_sequence.add(:master, :result, job_a_result)
37
-
38
- message_sequence.add(:master, :ready, worker_a)
39
- message_sequence.add(:worker_a, :job, job_b)
40
- message_sequence.add(:master, :result, job_b_result)
41
-
42
- message_sequence.add(:master, :ready, worker_a)
43
- message_sequence.add(:worker_a, :stop)
44
-
45
- message_sequence.add(:master, :stop, parent)
46
- message_sequence.add(:parent, :stop)
47
- end
48
-
49
- it { should eql(actor_env.mailbox(:master).sender) }
50
-
51
- it 'consumes all messages' do
52
- expect { subject }.to change(&message_sequence.method(:consumed?)).from(false).to(true)
53
- end
54
- end
55
-
56
- context 'stop by fail fast trigger first' do
57
- update(:config) { { fail_fast: true } }
58
- update(:mutation_b_test_result) { { passed: true } }
59
-
60
- before do
61
- message_sequence.add(:master, :ready, worker_a)
62
- message_sequence.add(:worker_a, :job, job_a)
63
- message_sequence.add(:master, :result, job_a_result)
64
-
65
- message_sequence.add(:master, :ready, worker_a)
66
- message_sequence.add(:worker_a, :job, job_b)
67
- message_sequence.add(:master, :result, job_b_result)
68
-
69
- message_sequence.add(:master, :ready, worker_a)
70
- message_sequence.add(:worker_a, :stop)
71
-
72
- message_sequence.add(:master, :stop, parent)
73
- message_sequence.add(:parent, :stop)
74
- end
75
-
76
- it { should eql(actor_env.mailbox(:master).sender) }
77
-
78
- it 'consumes all messages' do
79
- expect { subject }.to change(&message_sequence.method(:consumed?)).from(false).to(true)
80
- end
81
- end
82
-
83
- context 'stop by fail fast trigger last' do
84
- update(:config) { { fail_fast: true } }
85
- update(:mutation_a_test_result) { { passed: true } }
86
-
87
- before do
88
- message_sequence.add(:master, :ready, worker_a)
89
- message_sequence.add(:worker_a, :job, job_a)
90
- message_sequence.add(:master, :result, job_a_result)
91
-
92
- message_sequence.add(:master, :ready, worker_a)
93
- message_sequence.add(:worker_a, :stop)
94
-
95
- message_sequence.add(:master, :stop, parent)
96
- message_sequence.add(:parent, :stop)
97
- end
98
-
99
- it { should eql(actor_env.mailbox(:master).sender) }
100
-
101
- it 'consumes all messages' do
102
- expect { subject }.to change(&message_sequence.method(:consumed?)).from(false).to(true)
103
- end
104
- end
105
-
106
- context 'jobs active while external stop' do
107
- before do
108
- message_sequence.add(:master, :ready, worker_a)
109
- message_sequence.add(:worker_a, :job, job_a)
110
- message_sequence.add(:master, :stop, parent)
111
- message_sequence.add(:master, :result, job_a_result)
112
-
113
- message_sequence.add(:master, :status, parent)
114
- message_sequence.add(:parent, :status, empty_status.update(active_jobs: [job_a].to_set))
115
-
116
- message_sequence.add(:master, :ready, worker_a)
117
- message_sequence.add(:worker_a, :stop)
118
-
119
- message_sequence.add(:parent, :stop)
120
- end
121
-
122
- it { should eql(actor_env.mailbox(:master).sender) }
123
-
124
- it 'consumes all messages' do
125
- expect { subject }.to change(&message_sequence.method(:consumed?)).from(false).to(true)
126
- end
127
- end
128
-
129
- context 'stop with pending jobs' do
130
- before do
131
- message_sequence.add(:master, :stop, parent)
132
- message_sequence.add(:master, :ready, worker_a)
133
- message_sequence.add(:worker_a, :stop)
134
- message_sequence.add(:parent, :stop)
135
- end
136
-
137
- it { should eql(actor_env.mailbox(:master).sender) }
138
-
139
- it 'consumes all messages' do
140
- expect { subject }.to change(&message_sequence.method(:consumed?)).from(false).to(true)
141
- end
142
- end
143
-
144
- context 'unhandled message received' do
145
- before do
146
- message_sequence.add(:master, :foo, parent)
147
- end
148
-
149
- it 'raises message' do
150
- expect { subject }.to raise_error(Mutant::Actor::ProtocolError, 'Unexpected message: :foo')
151
- end
152
- end
153
-
154
- context 'request status late' do
155
- let(:expected_status) { status.update(env_result: env_result.update(runtime: 0.0)) }
156
-
157
- before do
158
- message_sequence.add(:master, :ready, worker_a)
159
- message_sequence.add(:worker_a, :job, job_a)
160
- message_sequence.add(:master, :result, job_a_result)
161
-
162
- message_sequence.add(:master, :ready, worker_a)
163
- message_sequence.add(:worker_a, :job, job_b)
164
- message_sequence.add(:master, :result, job_b_result)
165
-
166
- message_sequence.add(:master, :ready, worker_a)
167
- message_sequence.add(:worker_a, :stop)
168
-
169
- message_sequence.add(:master, :status, parent)
170
- message_sequence.add(:parent, :status, expected_status)
171
- message_sequence.add(:master, :stop, parent)
172
- message_sequence.add(:parent, :stop)
173
- end
174
-
175
- it { should eql(actor_env.mailbox(:master).sender) }
176
-
177
- it 'consumes all messages' do
178
- expect { subject }.to change(&message_sequence.method(:consumed?)).from(false).to(true)
179
- end
180
- end
181
-
182
- context 'request status early' do
183
- before do
184
- message_sequence.add(:master, :status, parent)
185
- message_sequence.add(:parent, :status, empty_status)
186
- message_sequence.add(:master, :stop, parent)
187
- message_sequence.add(:master, :ready, worker_a)
188
- message_sequence.add(:worker_a, :stop)
189
- message_sequence.add(:parent, :stop)
190
- end
191
-
192
- it { should eql(actor_env.mailbox(:master).sender) }
193
-
194
- it 'consumes all messages' do
195
- expect { subject }.to change(&message_sequence.method(:consumed?)).from(false).to(true)
196
- end
197
- end
198
- end
199
- end
@@ -1,161 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Mutant::Runner::Scheduler do
4
- let(:object) { described_class.new(env) }
5
-
6
- before do
7
- allow(Time).to receive(:now).and_return(Time.now)
8
- end
9
-
10
- setup_shared_context
11
-
12
- let(:active_subject_a_result) do
13
- subject_a_result.update(mutation_results: [])
14
- end
15
-
16
- describe '#job_result' do
17
- subject { object.job_result(job_a_result) }
18
-
19
- before do
20
- expect(object.next_job).to eql(job_a)
21
- end
22
-
23
- it 'removes the tracking of job as active' do
24
- expect { subject }.to change { object.status.active_jobs }.from([job_a].to_set).to(Set.new)
25
- end
26
-
27
- it 'aggregates results in #status' do
28
- subject
29
- object.job_result(job_b_result)
30
- expect(object.status.env_result).to eql(
31
- Mutant::Result::Env.new(
32
- env: env,
33
- runtime: 0.0,
34
- subject_results: [subject_a_result]
35
- )
36
- )
37
- end
38
-
39
- it_should_behave_like 'a command method'
40
- end
41
-
42
- describe '#next_job' do
43
- subject { object.next_job }
44
-
45
- context 'when there is a next job' do
46
- let(:mutations) { [mutation_a, mutation_b] }
47
-
48
- it { should eql(job_a) }
49
-
50
- it 'does not return the same job again' do
51
- subject
52
- expect(object.next_job).to eql(job_b)
53
- expect(object.next_job).to be(nil)
54
- end
55
-
56
- it 'does record job as active' do
57
- expect { subject }.to change { object.status.active_jobs }.from(Set.new).to([job_a].to_set)
58
- end
59
- end
60
-
61
- context 'when there is no next job' do
62
- let(:mutations) { [] }
63
- it { should be(nil) }
64
- end
65
- end
66
-
67
- describe '#status' do
68
- subject { object.status }
69
-
70
- context 'when empty' do
71
- let(:expected_status) do
72
- Mutant::Runner::Status.new(
73
- env_result: Mutant::Result::Env.new(env: env, runtime: 0.0, subject_results: []),
74
- active_jobs: Set.new,
75
- done: false
76
- )
77
- end
78
-
79
- it { should eql(expected_status) }
80
- end
81
-
82
- context 'when jobs are active' do
83
- before do
84
- object.next_job
85
- object.next_job
86
- end
87
-
88
- let(:expected_status) do
89
- Mutant::Runner::Status.new(
90
- env_result: Mutant::Result::Env.new(env: env, runtime: 0.0, subject_results: []),
91
- active_jobs: [job_a, job_b].to_set,
92
- done: false
93
- )
94
- end
95
-
96
- it { should eql(expected_status) }
97
- end
98
-
99
- context 'remaining jobs are active' do
100
- before do
101
- object.next_job
102
- object.next_job
103
- object.job_result(job_a_result)
104
- end
105
-
106
- update(:subject_a_result) { { mutation_results: [mutation_a_result] } }
107
-
108
- let(:expected_status) do
109
- Mutant::Runner::Status.new(
110
- env_result: Mutant::Result::Env.new(env: env, runtime: 0.0, subject_results: [subject_a_result]),
111
- active_jobs: [job_b].to_set,
112
- done: false
113
- )
114
- end
115
-
116
- it { should eql(expected_status) }
117
- end
118
-
119
- context 'under fail fast config with failed result' do
120
- before do
121
- object.next_job
122
- object.next_job
123
- object.job_result(job_a_result)
124
- end
125
-
126
- update(:subject_a_result) { { mutation_results: [mutation_a_result] } }
127
- update(:mutation_a_test_result) { { passed: true } }
128
- update(:config) { { fail_fast: true } }
129
-
130
- let(:expected_status) do
131
- Mutant::Runner::Status.new(
132
- env_result: Mutant::Result::Env.new(env: env, runtime: 0.0, subject_results: [subject_a_result]),
133
- active_jobs: [job_b].to_set,
134
- done: true
135
- )
136
- end
137
-
138
- it { should eql(expected_status) }
139
- end
140
-
141
- context 'when done' do
142
- before do
143
- object.next_job
144
- object.next_job
145
- object.status
146
- object.job_result(job_a_result)
147
- object.job_result(job_b_result)
148
- end
149
-
150
- let(:expected_status) do
151
- Mutant::Runner::Status.new(
152
- env_result: Mutant::Result::Env.new(env: env, runtime: 0.0, subject_results: [subject_a_result]),
153
- active_jobs: Set.new,
154
- done: true
155
- )
156
- end
157
-
158
- it { should eql(expected_status) }
159
- end
160
- end
161
- end