pork 1.0.4 → 1.1.0

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.
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