pork 1.0.4 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +22 -0
- data/README.md +15 -1
- data/lib/pork.rb +45 -2
- data/lib/pork/imp.rb +2 -2
- data/lib/pork/isolate.rb +17 -14
- data/lib/pork/mode/parallel.rb +7 -3
- data/lib/pork/mode/shuffle.rb +3 -3
- data/lib/pork/stat.rb +22 -1
- data/lib/pork/test.rb +3 -3
- data/lib/pork/version.rb +1 -1
- data/pork.gemspec +3 -3
- data/test/test_isolate.rb +6 -4
- data/test/test_parallel.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ba32fd4203213a40ab4cc87ef23db9d05e7baa0
|
4
|
+
data.tar.gz: 6079324cc97d94683eda43e837cadabd2141ab40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4cc31b8cfd35a2ed5f66d1f4fa64680a8b32836c605857aa68831300e39b10058494db1c7a0a769e9a293a95c6bc8755282deb09996679325b31dd080753cb7
|
7
|
+
data.tar.gz: 9fe4c8dd306bd73715253f464de164f748e5a2c1596faea8762dd6598c592e0c40d95335de6fe698431688d67487e23e2e5213473dce3501ea964586a45e6282
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## Pork 1.1.0 -- 2015-01-28
|
4
|
+
|
5
|
+
### Bugs fixed
|
6
|
+
|
7
|
+
* Now we can interrupt the tests and still see current report.
|
8
|
+
* Use `exit!` in `at_exit` to avoid issues.
|
9
|
+
* Fixed the description order for nested test cases.
|
10
|
+
|
11
|
+
### Incompatible changes
|
12
|
+
|
13
|
+
* Pork::Parallel.parallel API slightly changed.
|
14
|
+
* Pork::Isolate.isolate API slightly changed.
|
15
|
+
* Pork::Isolate.all_tests format changed.
|
16
|
+
* Mutant::Integration::Pork could be broken now... but it never really works.
|
17
|
+
|
18
|
+
### Enhancement
|
19
|
+
|
20
|
+
* Accept `ENV['PORK_MODE']` for `Pork.execute_mode`
|
21
|
+
* Accept `ENV['PORK_SEED']` for setting up srand.
|
22
|
+
* Accept `ENV['PORK_TEST']` for running a particular test case.
|
23
|
+
* For failure tests, it would now print the replicating command.
|
24
|
+
|
3
25
|
## Pork 1.0.4 -- 2014-12-29
|
4
26
|
|
5
27
|
* Make backtrace easier to read by using `.` and `~`.
|
data/README.md
CHANGED
@@ -796,6 +796,20 @@ Pass the symbol to it to use the mode:
|
|
796
796
|
Pork.execute_mode :shuffle
|
797
797
|
```
|
798
798
|
|
799
|
+
On the other hand, you could also set `ENV['PORK_MODE']` for picking an
|
800
|
+
execution mode. This would be convenient if you just want to switch to a
|
801
|
+
particular mode temporary via command line. For example:
|
802
|
+
|
803
|
+
``` shell
|
804
|
+
env PORK_MODE=shuffle rake test
|
805
|
+
```
|
806
|
+
|
807
|
+
Or:
|
808
|
+
|
809
|
+
``` shell
|
810
|
+
env PORK_MODE=shuffle ruby -Ilib test/test_pork.rb
|
811
|
+
```
|
812
|
+
|
799
813
|
### Pork.inspect_failure_mode
|
800
814
|
|
801
815
|
By default, `Pork.inspect_failure_mode` is set to `:auto`, which would
|
@@ -856,7 +870,7 @@ Then it would always use the mode we specified.
|
|
856
870
|
|
857
871
|
Apache License 2.0
|
858
872
|
|
859
|
-
Copyright (c) 2014, Lin Jen-Shin (godfat)
|
873
|
+
Copyright (c) 2014-2015, Lin Jen-Shin (godfat)
|
860
874
|
|
861
875
|
Licensed under the Apache License, Version 2.0 (the "License");
|
862
876
|
you may not use this file except in compliance with the License.
|
data/lib/pork.rb
CHANGED
@@ -17,14 +17,57 @@ module Pork
|
|
17
17
|
@execute = execute || @execute ||= :execute
|
18
18
|
end
|
19
19
|
|
20
|
+
def self.stat
|
21
|
+
@stat ||= Pork::Stat.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.seed
|
25
|
+
@seed ||= if Random.const_defined?(:DEFAULT)
|
26
|
+
Random::DEFAULT.seed
|
27
|
+
else
|
28
|
+
Thread.current.randomizer.seed # Rubinius (rbx)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.trap sig='SIGINT'
|
33
|
+
Signal.trap(sig) do
|
34
|
+
stat.report
|
35
|
+
puts "\nterminated by signal SIGINT"
|
36
|
+
exit! 255
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.run
|
41
|
+
if ENV['PORK_TEST']
|
42
|
+
require 'pork/isolate'
|
43
|
+
if paths = Executor.all_tests[ENV['PORK_TEST']]
|
44
|
+
case execute_mode
|
45
|
+
when :execute
|
46
|
+
paths.each{ |p| Executor.isolate(p, stat) }
|
47
|
+
else
|
48
|
+
@stat = Executor.public_send(execute_mode, stat, paths)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
puts "Cannot find test: #{ENV['PORK_TEST']}"
|
52
|
+
exit! 254
|
53
|
+
end
|
54
|
+
else
|
55
|
+
@stat = Executor.public_send(execute_mode, stat)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
20
59
|
def self.autorun auto=true
|
21
60
|
@auto = auto
|
22
61
|
@autorun ||= at_exit do
|
23
62
|
next unless @auto
|
63
|
+
Random.srand(ENV['PORK_SEED'].to_i) if ENV['PORK_SEED']
|
64
|
+
execute_mode(ENV['PORK_MODE']) if ENV['PORK_MODE']
|
24
65
|
require "pork/mode/#{execute_mode}" unless execute_mode == :execute
|
25
|
-
|
66
|
+
seed
|
67
|
+
trap
|
68
|
+
run
|
26
69
|
stat.report
|
27
|
-
exit stat.failures.size + stat.errors.size + ($! && 1).to_i
|
70
|
+
exit! stat.failures.size + stat.errors.size + ($! && 1).to_i
|
28
71
|
end
|
29
72
|
end
|
30
73
|
end
|
data/lib/pork/imp.rb
CHANGED
@@ -30,7 +30,7 @@ module Pork
|
|
30
30
|
|
31
31
|
def execute stat=Stat.new
|
32
32
|
if block_given?
|
33
|
-
yield(stat)
|
33
|
+
yield(stat) # XXX: see Isolate#isolate
|
34
34
|
else
|
35
35
|
execute_with_parent(stat)
|
36
36
|
end
|
@@ -97,7 +97,7 @@ module Pork
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def description_for name=''
|
100
|
-
"#{@
|
100
|
+
"#{@super_executor && @super_executor.description_for}#{@desc}#{name}"
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
data/lib/pork/isolate.rb
CHANGED
@@ -5,33 +5,36 @@ require 'pork/executor'
|
|
5
5
|
module Pork
|
6
6
|
module Isolate
|
7
7
|
def all_tests
|
8
|
-
@all_tests ||=
|
8
|
+
@all_tests ||= build_all_tests
|
9
9
|
end
|
10
10
|
|
11
|
-
def isolate
|
11
|
+
def isolate path, stat=Stat.new
|
12
|
+
# XXX: 91152211182a086de20e3e84c96b6befca655975
|
13
|
+
# Executor.execute is a no-op when Should is not loaded,
|
14
|
+
# but if it's loaded, it's essential to call Should#execute to
|
15
|
+
# setup the stat in thread group. Try to come up a better way!
|
12
16
|
execute(stat) do |s|
|
13
|
-
execute_with_isolation(
|
17
|
+
execute_with_isolation(path, s)
|
14
18
|
end
|
15
19
|
end
|
16
20
|
|
17
21
|
protected
|
18
|
-
def build_all_tests
|
19
|
-
@tests.
|
20
|
-
current =
|
22
|
+
def build_all_tests result={}, path=[]
|
23
|
+
@tests.each_with_index.inject(result) do |r, ((type, arg, _), index)|
|
24
|
+
current = path + [index]
|
21
25
|
case type
|
22
26
|
when :describe
|
23
|
-
arg.build_all_tests(current)
|
27
|
+
arg.build_all_tests(r, current)
|
24
28
|
when :would
|
25
|
-
[
|
26
|
-
else
|
27
|
-
[]
|
29
|
+
(r[description_for("would #{arg}")] ||= []) << current
|
28
30
|
end
|
31
|
+
r
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
32
|
-
def execute_with_isolation
|
35
|
+
def execute_with_isolation path, stat, super_env=nil
|
33
36
|
env = Env.new(super_env)
|
34
|
-
idx =
|
37
|
+
idx = path.first
|
35
38
|
|
36
39
|
@tests.first(idx).each do |(type, arg, _)|
|
37
40
|
case type
|
@@ -42,11 +45,11 @@ module Pork
|
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
45
|
-
if
|
48
|
+
if path.size == 1
|
46
49
|
_, desc, test = @tests[idx]
|
47
50
|
run(desc, test, stat, env)
|
48
51
|
else
|
49
|
-
@tests[idx][1].execute_with_isolation(
|
52
|
+
@tests[idx][1].execute_with_isolation(path.drop(1), stat, env)
|
50
53
|
end
|
51
54
|
end
|
52
55
|
end
|
data/lib/pork/mode/parallel.rb
CHANGED
@@ -4,11 +4,15 @@ require 'pork/isolate'
|
|
4
4
|
|
5
5
|
module Pork
|
6
6
|
module Parallel
|
7
|
-
def
|
8
|
-
|
7
|
+
def cores
|
8
|
+
8
|
9
|
+
end
|
10
|
+
|
11
|
+
def parallel stat=Stat.new, paths=all_tests.values.flatten(1)
|
12
|
+
paths.shuffle.each_slice(cores).map do |paths_slice|
|
9
13
|
Thread.new do
|
10
14
|
s = Stat.new
|
11
|
-
|
15
|
+
paths_slice.each{ |p| isolate(p, s) }
|
12
16
|
s
|
13
17
|
end
|
14
18
|
end.map(&:value).inject(stat, &:merge)
|
data/lib/pork/mode/shuffle.rb
CHANGED
@@ -4,9 +4,9 @@ require 'pork/isolate'
|
|
4
4
|
|
5
5
|
module Pork
|
6
6
|
module Shuffle
|
7
|
-
def shuffle stat=Stat.new
|
8
|
-
|
9
|
-
isolate(
|
7
|
+
def shuffle stat=Stat.new, paths=all_tests.values.flatten(1)
|
8
|
+
paths.shuffle.each do |p|
|
9
|
+
isolate(p, stat)
|
10
10
|
end
|
11
11
|
stat
|
12
12
|
end
|
data/lib/pork/stat.rb
CHANGED
@@ -18,7 +18,7 @@ module Pork
|
|
18
18
|
def report
|
19
19
|
io.puts
|
20
20
|
io.puts (failures + errors).map{ |(e, m)|
|
21
|
-
"\n#{m}\n#{e.class}: #{e.message}\n #{backtrace(e)}"
|
21
|
+
"\n#{m}\n#{e.class}: #{e.message}\n #{backtrace(e)}\n#{command(m)}"
|
22
22
|
}
|
23
23
|
io.printf("\nFinished in %f seconds.\n", Time.now - start)
|
24
24
|
io.printf("%d tests, %d assertions, %d failures, %d errors, %d skips\n",
|
@@ -49,5 +49,26 @@ module Pork
|
|
49
49
|
def strip_cwd backtrace
|
50
50
|
backtrace.map{ |path| path.sub(Dir.pwd, '.') }
|
51
51
|
end
|
52
|
+
|
53
|
+
def command name
|
54
|
+
"You can replicate this test with the following command:\n " \
|
55
|
+
"#{env(name)} #{Gem.ruby} -S #{$0} #{ARGV.join(' ')}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def env name
|
59
|
+
"env #{pork(name)} #{pork_mode} #{pork_seed}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def pork name
|
63
|
+
"PORK_TEST='#{name.gsub("'", "\\\\'")}'"
|
64
|
+
end
|
65
|
+
|
66
|
+
def pork_mode
|
67
|
+
"PORK_MODE=#{Pork.execute_mode}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def pork_seed
|
71
|
+
"PORK_SEED=#{Pork.seed}"
|
72
|
+
end
|
52
73
|
end
|
53
74
|
end
|
data/lib/pork/test.rb
CHANGED
@@ -4,9 +4,9 @@ require 'muack'
|
|
4
4
|
|
5
5
|
copy do
|
6
6
|
before do
|
7
|
-
Muack::API.stub(Pork::Executor.all_tests
|
8
|
-
|
9
|
-
|
7
|
+
Muack::API.stub(Pork::Executor).all_tests.peek_return do |tests|
|
8
|
+
tests.reject do |name, _|
|
9
|
+
name =~ /^Pork::(Isolate|Shuffle|Parallel): /
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
data/lib/pork/version.rb
CHANGED
data/pork.gemspec
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: pork 1.0
|
2
|
+
# stub: pork 1.1.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "pork"
|
6
|
-
s.version = "1.0
|
6
|
+
s.version = "1.1.0"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib"]
|
10
10
|
s.authors = ["Lin Jen-Shin (godfat)"]
|
11
|
-
s.date = "
|
11
|
+
s.date = "2015-01-28"
|
12
12
|
s.description = "Pork -- Simple and clean and modular testing library.\n\nInspired by [Bacon][].\n\n[Bacon]: https://github.com/chneukirchen/bacon"
|
13
13
|
s.email = ["godfat (XD) godfat.org"]
|
14
14
|
s.files = [
|
data/test/test_isolate.rb
CHANGED
@@ -4,10 +4,12 @@ require 'pork/isolate'
|
|
4
4
|
|
5
5
|
describe Pork::Isolate do
|
6
6
|
would '#isolate' do
|
7
|
-
Pork::Executor.all_tests.
|
8
|
-
next ok if name.start_with?('Pork::Isolate #isolate
|
9
|
-
|
10
|
-
|
7
|
+
Pork::Executor.all_tests.each do |name, paths|
|
8
|
+
next ok if name.start_with?('Pork::Isolate: would #isolate')
|
9
|
+
paths.each do |p|
|
10
|
+
stat = Pork::Executor.isolate(p, pork_stat)
|
11
|
+
expect(stat.passed?, stat.inspect).eq true
|
12
|
+
end
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
data/test/test_parallel.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pork
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lin Jen-Shin (godfat)
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: muack
|