forking_test_runner 0.8.0 → 0.9.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: 2ac83a5a2c478db627543f6aa682c2b8ecc32fdd
4
- data.tar.gz: 3c0a8b85d8ee654287f57582027625fbe2ca8a07
3
+ metadata.gz: 989a8330a49520c4aaa7d1a073f5a9ab216793cf
4
+ data.tar.gz: 983e7875d09eb54246efd8f8859d0f1c3a81387c
5
5
  SHA512:
6
- metadata.gz: ee1ca158532118e09bbcfd11e522a69e84cdcfc954f92d8bab55956b24c8e3eb523cf2b042d26b2ea28c3ebc851e73d8e45691fac4b7727243ff868a65964a97
7
- data.tar.gz: 01302ee774cd197531acd520bf228401b6ccc4b0dbfa6a1c5a8dbf8ab98c7f169b6ce0983cb79f1c10ba3fb63a90352d97760f394a2b3e299aeb254cd8e2daa4
6
+ metadata.gz: e691f90b08041be6598d725959951bb7cc475e9cc98563cc32e9fb4f59d452d874c61bd60387b63effd1b4ce35b038dcf5b301282eca69569476755a49aa0ac0
7
+ data.tar.gz: 3e7633c9cbc4f11b946e7f9b6526f8a112faa3811cde9e49135de322fba9e56ad3ca1b4d86ed2b8e97866097a3ae53e073210a5f8a24dd12e51b1b59d9dd4596
@@ -1,3 +1,3 @@
1
1
  module ForkingTestRunner
2
- VERSION = "0.8.0"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require 'benchmark'
2
+ require 'optparse'
2
3
 
3
4
  module ForkingTestRunner
4
5
  CLEAR = "------"
@@ -38,29 +39,18 @@ module ForkingTestRunner
38
39
 
39
40
  class << self
40
41
  def cli(argv)
41
- @rspec = delete_argv("--rspec", argv, arg: false)
42
- @no_fixtures = delete_argv("--no-fixtures", argv, arg: false)
43
- @quiet = delete_argv("--quiet", argv, arg: false)
44
- @merge_coverage = delete_argv("--merge-coverage", argv, arg: false)
45
-
46
- if @merge_coverage
47
- raise "merge_coverage does not work on ruby prior to 2.3" if RUBY_VERSION < "2.3.0"
48
- require 'coverage'
49
- klass = (class << Coverage; self; end)
50
- klass.prepend CoverageCapture
51
- end
42
+ @options, tests = parse_options(argv)
52
43
 
53
44
  disable_test_autorun
54
45
 
55
- load_test_env(delete_argv("--helper", argv))
46
+ load_test_env(@options.fetch(:helper))
56
47
 
57
48
  # figure out what we need to run
58
- record_runtime = delete_argv("--record-runtime", argv)
59
- runtime_log = delete_argv("--runtime-log", argv)
60
- group, group_count, tests = extract_group_args(argv)
49
+ runtime_log = @options.fetch(:runtime_log)
50
+ group, group_count = find_group_args
61
51
  tests = find_tests_for_group(group, group_count, tests, runtime_log)
62
52
 
63
- if @quiet
53
+ if @options.fetch(:quiet)
64
54
  puts "Running #{tests.size} test files"
65
55
  else
66
56
  puts "Running tests #{tests.map(&:first).join(" ")}"
@@ -71,27 +61,27 @@ module ForkingTestRunner
71
61
  ActiveRecord::Base.connection.disconnect!
72
62
  end
73
63
 
74
- Coverage.capture_coverage! if @merge_coverage
64
+ Coverage.capture_coverage! if @options.fetch(:merge_coverage)
75
65
 
76
66
  # run all the tests
77
67
  results = tests.map do |file, expected|
78
68
  puts "#{CLEAR} >>> #{file} "
79
69
  time, success, output = benchmark { run_test(file) }
80
70
 
81
- puts output if !success && @quiet
71
+ puts output if !success && @options.fetch(:quiet)
82
72
 
83
- if runtime_log && !@quiet
73
+ if runtime_log && !@options.fetch(:quiet)
84
74
  puts "Time: expected #{expected.round(2)}, actual #{time.round(2)}"
85
75
  end
86
76
 
87
- if !success || !@quiet
77
+ if !success || !@options.fetch(:quiet)
88
78
  puts "#{CLEAR} <<< #{file} ---- #{success ? "OK" : "Failed"}"
89
79
  end
90
80
 
91
81
  [file, time, expected, output, success]
92
82
  end
93
83
 
94
- unless @quiet
84
+ unless @options.fetch(:quiet)
95
85
  # pretty print the results
96
86
  puts "\nResults:"
97
87
  puts results.
@@ -110,10 +100,10 @@ module ForkingTestRunner
110
100
  puts "Time: #{diff.round(2)} diff to expected"
111
101
  end
112
102
 
113
- if record_runtime
103
+ if mode = @options.fetch(:record_runtime)
114
104
  # store runtime log
115
105
  log = runtime_log || 'runtime.log'
116
- record_test_runtime(record_runtime, results, log)
106
+ record_test_runtime(mode, results, log)
117
107
  end
118
108
 
119
109
  # exit with success or failure
@@ -131,7 +121,7 @@ module ForkingTestRunner
131
121
  end
132
122
 
133
123
  def summarize_results(results)
134
- runner = if @rspec
124
+ runner = if @options.fetch(:rspec)
135
125
  require 'parallel_tests/rspec/runner'
136
126
  ParallelTests::RSpec::Runner
137
127
  else
@@ -174,36 +164,29 @@ module ForkingTestRunner
174
164
  end
175
165
  end
176
166
 
177
- def extract_group_args(argv)
178
- if argv.include?("--group")
167
+ def find_group_args
168
+ if @options.fetch(:group) && @options.fetch(:groups)
179
169
  # delete options we want while leaving others as they are (-v / --seed etc)
180
- group, group_count = ['--group', '--groups'].map do |arg|
181
- value = delete_argv(arg, argv) || raise("Did not find option #{arg}")
182
- value.to_i
183
- end
184
- dir = argv.shift
185
- raise "Unable to find directory #{dir.inspect}" unless File.exist?(dir.to_s)
186
- tests = [dir]
170
+ group = @options.fetch(:group)
171
+ group_count = @options.fetch(:groups)
187
172
  else
188
173
  group = 1
189
174
  group_count = 1
190
- size = argv.index { |arg| arg.start_with? "-" } || argv.size
191
- tests = argv.slice!(0, size)
192
175
  end
193
176
 
194
- [group, group_count, tests]
177
+ [group, group_count]
195
178
  end
196
179
 
197
180
  def load_test_env(helper=nil)
198
- require 'rspec' if @rspec
199
- helper = helper || (@rspec ? "spec/spec_helper" : "test/test_helper")
181
+ require 'rspec' if @options.fetch(:rspec)
182
+ helper = helper || (@options.fetch(:rspec) ? "spec/spec_helper" : "test/test_helper")
200
183
  require "./#{helper}"
201
184
  end
202
185
 
203
186
  # This forces Rails to load all fixtures, then prevents it from
204
187
  # "deleting and re-inserting all fixtures" when a new connection is used (forked).
205
188
  def preload_fixtures
206
- return if @no_fixtures
189
+ return if @options.fetch(:no_fixtures)
207
190
 
208
191
  fixtures = (ActiveSupport::VERSION::MAJOR == 3 ? ActiveRecord::Fixtures : ActiveRecord::FixtureSet)
209
192
 
@@ -256,7 +239,7 @@ module ForkingTestRunner
256
239
 
257
240
  def run_test(file)
258
241
  output = change_program_name_to file do
259
- fork_with_captured_output(!@quiet) do
242
+ fork_with_captured_output(!@options.fetch(:quiet)) do
260
243
  SimpleCov.pid = Process.pid if defined?(SimpleCov) && SimpleCov.respond_to?(:pid=) # trick simplecov into reporting in this fork
261
244
  if ar?
262
245
  key = (ActiveRecord::VERSION::STRING >= "4.1.0" ? :test : "test")
@@ -294,16 +277,6 @@ module ForkingTestRunner
294
277
  group.map { |test| [test, (tests[test] if group_by == :runtime)] }
295
278
  end
296
279
 
297
- def delete_argv(name, argv, arg: true)
298
- return unless index = argv.index(name)
299
- argv.delete_at(index)
300
- if arg
301
- argv.delete_at(index) || raise("Missing argument for #{name}")
302
- else
303
- true
304
- end
305
- end
306
-
307
280
  def ar?
308
281
  defined?(ActiveRecord::Base)
309
282
  end
@@ -323,7 +296,7 @@ module ForkingTestRunner
323
296
  end
324
297
 
325
298
  def toggle_test_autorun(value, file=nil)
326
- if @rspec
299
+ if @options.fetch(:rspec)
327
300
  if value
328
301
  exit(RSpec::Core::Runner.run([file] + ARGV))
329
302
  else
@@ -342,5 +315,84 @@ module ForkingTestRunner
342
315
  end
343
316
  end
344
317
  end
318
+
319
+ # we remove the args we understand and leave the rest alone
320
+ # so minitest / rspec can read their own options (--seed / -v ...)
321
+ # - keep our options clear / unambiguous to avoid overriding
322
+ # - read all serial non-flag arguments as tests and leave only unknown options behind
323
+ # - use .fetch everywhere to make sure nothing is misspelled
324
+ # GOOD: test --ours --theirs
325
+ # OK: --ours test --theirs
326
+ # BAD: --theirs test --ours
327
+ def parse_options(argv)
328
+ arguments = [
329
+ [:rspec, "--rspec", "RSpec mode"],
330
+ [:helper, "--helper", "Helper file to load before tests start", String],
331
+ [:quiet, "--quiet", "Quiet"],
332
+ [:no_fixtures, "--no-fixtures", "Do not load fixtures"],
333
+ [:merge_coverage, "--merge-coverage", "Merge base code coverage into indvidual files coverage, great for SingleCov"],
334
+ [
335
+ :record_runtime,
336
+ "--record-runtime=MODE",
337
+ "\n Record test runtime:\n" <<
338
+ " simple = write to disk at --runtime-log)\n" <<
339
+ " amend = write from multiple remote workers via http://github.com/grosser/amend, needs TRAVIS_REPO_SLUG & TRAVIS_BUILD_NUMBER",
340
+ String
341
+ ],
342
+ [:runtime_log, "--runtime-log=FILE", "File to store runtime log in or runtime.log", String],
343
+ [:group, "--group=NUM", "What group this is (use with --groups / starts at 1)", Integer],
344
+ [:groups, "--groups=NUM", "How many groups there are in total (use with --group)", Integer],
345
+ [:version, "--version", "Show version"],
346
+ [:help, "--help", "Show help"]
347
+ ]
348
+
349
+ options = arguments.each_with_object({}) do |(setting, flag, _, type), all|
350
+ all[setting] = delete_argv(flag.split('=', 2)[0], argv, type: type)
351
+ end
352
+
353
+ # show version
354
+ if options.fetch(:version)
355
+ puts VERSION
356
+ exit 0
357
+ end
358
+
359
+ # # show help
360
+ if options[:help]
361
+ parser = OptionParser.new("forking-test-runner folder [options]", 32, '') do |opts|
362
+ arguments.each do |_, flag, desc, type|
363
+ opts.on(flag, desc, type)
364
+ end
365
+ end
366
+ puts parser
367
+ exit 0
368
+ end
369
+
370
+ # check if we can use merge_coverage
371
+ if options.fetch(:merge_coverage)
372
+ abort "merge_coverage does not work on ruby prior to 2.3" if RUBY_VERSION < "2.3.0"
373
+ require 'coverage'
374
+ klass = (class << Coverage; self; end)
375
+ klass.prepend CoverageCapture
376
+ end
377
+
378
+ # all remaining non-flag options until the next flag must be tests
379
+ next_flag = argv.index { |arg| arg.start_with?("-") } || argv.size
380
+ tests = argv.slice!(0, next_flag)
381
+ abort "No tests or folders found in arguments" if tests.empty?
382
+ tests.each { |t| abort "Unable to find #{t}" unless File.exist?(t) }
383
+
384
+ [options, tests]
385
+ end
386
+
387
+ def delete_argv(name, argv, type: nil)
388
+ return unless index = argv.index(name)
389
+ argv.delete_at(index)
390
+ if type
391
+ found = argv.delete_at(index) || raise("Missing argument for #{name}")
392
+ send(type.name, found) # case found
393
+ else
394
+ true
395
+ end
396
+ end
345
397
  end
346
398
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forking_test_runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-06 00:00:00.000000000 Z
11
+ date: 2017-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parallel_tests