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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b3309a4342d94a048959287afbbc330bfbcffdd6
4
- data.tar.gz: 90549fc74cc0d7ed04c47d09b7c011001acc5b01
3
+ metadata.gz: 3ba32fd4203213a40ab4cc87ef23db9d05e7baa0
4
+ data.tar.gz: 6079324cc97d94683eda43e837cadabd2141ab40
5
5
  SHA512:
6
- metadata.gz: 7c2c045065fec739b79b34e07f47eb0826123226d08e5b7b5845f9a490be0dfdeaa450468a0c268ed6bce38353e288d30993efcfba58f94b13a98d4d338e325d
7
- data.tar.gz: 5c9d5b7aaa8125292a92183cf524d44dc6328f3f44c23f9991273163fdf178fadf62a626d213c587f0bb30b38977814fa9beb711f83d88f62247e98353b863dc
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
- stat = Executor.public_send(execute_mode)
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
- "#{@desc}#{@super_executor && @super_executor.description_for}#{name}"
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 ||= Hash[build_all_tests]
8
+ @all_tests ||= build_all_tests
9
9
  end
10
10
 
11
- def isolate name, stat=Stat.new
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(all_tests[name], s)
17
+ execute_with_isolation(path, s)
14
18
  end
15
19
  end
16
20
 
17
21
  protected
18
- def build_all_tests paths=[]
19
- @tests.flat_map.with_index do |(type, arg, _), index|
20
- current = paths + [index]
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
- [["#{desc.chomp(': ')} #{arg} ##{current}", current]]
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 paths, stat, super_env=nil
35
+ def execute_with_isolation path, stat, super_env=nil
33
36
  env = Env.new(super_env)
34
- idx = paths.first
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 paths.size == 1
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(paths.drop(1), stat, env)
52
+ @tests[idx][1].execute_with_isolation(path.drop(1), stat, env)
50
53
  end
51
54
  end
52
55
  end
@@ -4,11 +4,15 @@ require 'pork/isolate'
4
4
 
5
5
  module Pork
6
6
  module Parallel
7
- def parallel cores=8, stat=Stat.new
8
- all_tests.keys.shuffle.each_slice(cores).map do |names|
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
- names.each{ |n| isolate(n, s) }
15
+ paths_slice.each{ |p| isolate(p, s) }
12
16
  s
13
17
  end
14
18
  end.map(&:value).inject(stat, &:merge)
@@ -4,9 +4,9 @@ require 'pork/isolate'
4
4
 
5
5
  module Pork
6
6
  module Shuffle
7
- def shuffle stat=Stat.new
8
- all_tests.keys.shuffle.each do |name|
9
- isolate(name, stat)
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).keys.peek_return do |names|
8
- names.reject do |n|
9
- n =~ /^Pork::(Isolate|Shuffle|Parallel) /
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
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Pork
3
- VERSION = '1.0.4'
3
+ VERSION = '1.1.0'
4
4
  end
data/pork.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: pork 1.0.4 ruby lib
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.4"
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 = "2014-12-29"
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.each_key do |name|
8
- next ok if name.start_with?('Pork::Isolate #isolate #')
9
- stat = Pork::Executor.isolate(name, pork_stat)
10
- expect(stat.passed?, stat.inspect).eq true
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
@@ -6,7 +6,7 @@ describe Pork::Parallel do
6
6
  paste
7
7
 
8
8
  would '#parallel' do
9
- stat = Pork::Executor.parallel(8, pork_stat)
9
+ stat = Pork::Executor.parallel(pork_stat)
10
10
  expect(stat.passed?, stat.inspect).eq true
11
11
  end
12
12
  end
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
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: 2014-12-29 00:00:00.000000000 Z
11
+ date: 2015-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: muack