mutant 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
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