parallelized_specs 0.0.5 → 0.0.6
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.
- data/Gemfile +0 -10
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/parallelized_spec +94 -1
- data/lib/parallelized_specs.rb +161 -17
- data/lib/{parallelized_tests → parallelized_specs}/grouper.rb +1 -1
- data/lib/{parallelized_tests → parallelized_specs}/railtie.rb +2 -2
- data/lib/parallelized_specs/runtime_logger.rb +26 -0
- data/lib/{parallelized_tests → parallelized_specs}/tasks.rb +17 -19
- data/lib/tasks/parallelized_specs.rake +1 -0
- data/parallelized_specs.gemspec +8 -16
- metadata +11 -30
- data/bin/parallelized_test +0 -96
- data/lib/parallelized_tests.rb +0 -163
- data/lib/parallelized_tests/runtime_logger.rb +0 -78
- data/lib/tasks/parallelized_tests.rake +0 -1
- data/spec/integration_spec.rb +0 -132
- data/spec/parallelized_tests/runtime_logger_spec.rb +0 -74
- data/spec/parallelized_tests_spec.rb +0 -229
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "/../parallelized_specs/tasks")
|
data/parallelized_specs.gemspec
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "parallelized_specs"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jake Sorce, Bryan Madsen"]
|
12
|
-
s.date = "2012-04-
|
12
|
+
s.date = "2012-04-19"
|
13
13
|
s.email = "jake@instructure.com"
|
14
|
-
s.executables = ["parallelized_spec"
|
14
|
+
s.executables = ["parallelized_spec"]
|
15
15
|
s.files = [
|
16
16
|
"Gemfile",
|
17
17
|
"Gemfile.lock",
|
@@ -19,8 +19,10 @@ Gem::Specification.new do |s|
|
|
19
19
|
"Readme.md",
|
20
20
|
"VERSION",
|
21
21
|
"bin/parallelized_spec",
|
22
|
-
"bin/parallelized_test",
|
23
22
|
"lib/parallelized_specs.rb",
|
23
|
+
"lib/parallelized_specs/grouper.rb",
|
24
|
+
"lib/parallelized_specs/railtie.rb",
|
25
|
+
"lib/parallelized_specs/runtime_logger.rb",
|
24
26
|
"lib/parallelized_specs/spec_error_count_logger.rb",
|
25
27
|
"lib/parallelized_specs/spec_error_logger.rb",
|
26
28
|
"lib/parallelized_specs/spec_failures_logger.rb",
|
@@ -28,20 +30,13 @@ Gem::Specification.new do |s|
|
|
28
30
|
"lib/parallelized_specs/spec_runtime_logger.rb",
|
29
31
|
"lib/parallelized_specs/spec_start_finish_logger.rb",
|
30
32
|
"lib/parallelized_specs/spec_summary_logger.rb",
|
31
|
-
"lib/
|
32
|
-
"lib/
|
33
|
-
"lib/parallelized_tests/railtie.rb",
|
34
|
-
"lib/parallelized_tests/runtime_logger.rb",
|
35
|
-
"lib/parallelized_tests/tasks.rb",
|
36
|
-
"lib/tasks/parallelized_tests.rake",
|
33
|
+
"lib/parallelized_specs/tasks.rb",
|
34
|
+
"lib/tasks/parallelized_specs.rake",
|
37
35
|
"parallelized_specs.gemspec",
|
38
|
-
"spec/integration_spec.rb",
|
39
36
|
"spec/parallelized_specs/spec_failure_logger_spec.rb",
|
40
37
|
"spec/parallelized_specs/spec_runtime_logger_spec.rb",
|
41
38
|
"spec/parallelized_specs/spec_summary_logger_spec.rb",
|
42
39
|
"spec/parallelized_specs_spec.rb",
|
43
|
-
"spec/parallelized_tests/runtime_logger_spec.rb",
|
44
|
-
"spec/parallelized_tests_spec.rb",
|
45
40
|
"spec/spec_helper.rb"
|
46
41
|
]
|
47
42
|
s.homepage = "http://github.com/jakesorce/parallelized_specs"
|
@@ -53,12 +48,9 @@ Gem::Specification.new do |s|
|
|
53
48
|
s.specification_version = 3
|
54
49
|
|
55
50
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
56
|
-
s.add_runtime_dependency(%q<parallel>, [">= 0"])
|
57
51
|
else
|
58
|
-
s.add_dependency(%q<parallel>, [">= 0"])
|
59
52
|
end
|
60
53
|
else
|
61
|
-
s.add_dependency(%q<parallel>, [">= 0"])
|
62
54
|
end
|
63
55
|
end
|
64
56
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallelized_specs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 6
|
10
|
+
version: 0.0.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jake Sorce, Bryan Madsen
|
@@ -15,27 +15,13 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-04-
|
19
|
-
dependencies:
|
20
|
-
|
21
|
-
name: parallel
|
22
|
-
prerelease: false
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
-
none: false
|
25
|
-
requirements:
|
26
|
-
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 3
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
version: "0"
|
32
|
-
type: :runtime
|
33
|
-
version_requirements: *id001
|
18
|
+
date: 2012-04-19 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
34
21
|
description:
|
35
22
|
email: jake@instructure.com
|
36
23
|
executables:
|
37
24
|
- parallelized_spec
|
38
|
-
- parallelized_test
|
39
25
|
extensions: []
|
40
26
|
|
41
27
|
extra_rdoc_files: []
|
@@ -47,8 +33,10 @@ files:
|
|
47
33
|
- Readme.md
|
48
34
|
- VERSION
|
49
35
|
- bin/parallelized_spec
|
50
|
-
- bin/parallelized_test
|
51
36
|
- lib/parallelized_specs.rb
|
37
|
+
- lib/parallelized_specs/grouper.rb
|
38
|
+
- lib/parallelized_specs/railtie.rb
|
39
|
+
- lib/parallelized_specs/runtime_logger.rb
|
52
40
|
- lib/parallelized_specs/spec_error_count_logger.rb
|
53
41
|
- lib/parallelized_specs/spec_error_logger.rb
|
54
42
|
- lib/parallelized_specs/spec_failures_logger.rb
|
@@ -56,20 +44,13 @@ files:
|
|
56
44
|
- lib/parallelized_specs/spec_runtime_logger.rb
|
57
45
|
- lib/parallelized_specs/spec_start_finish_logger.rb
|
58
46
|
- lib/parallelized_specs/spec_summary_logger.rb
|
59
|
-
- lib/
|
60
|
-
- lib/
|
61
|
-
- lib/parallelized_tests/railtie.rb
|
62
|
-
- lib/parallelized_tests/runtime_logger.rb
|
63
|
-
- lib/parallelized_tests/tasks.rb
|
64
|
-
- lib/tasks/parallelized_tests.rake
|
47
|
+
- lib/parallelized_specs/tasks.rb
|
48
|
+
- lib/tasks/parallelized_specs.rake
|
65
49
|
- parallelized_specs.gemspec
|
66
|
-
- spec/integration_spec.rb
|
67
50
|
- spec/parallelized_specs/spec_failure_logger_spec.rb
|
68
51
|
- spec/parallelized_specs/spec_runtime_logger_spec.rb
|
69
52
|
- spec/parallelized_specs/spec_summary_logger_spec.rb
|
70
53
|
- spec/parallelized_specs_spec.rb
|
71
|
-
- spec/parallelized_tests/runtime_logger_spec.rb
|
72
|
-
- spec/parallelized_tests_spec.rb
|
73
54
|
- spec/spec_helper.rb
|
74
55
|
homepage: http://github.com/jakesorce/parallelized_specs
|
75
56
|
licenses: []
|
data/bin/parallelized_test
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require 'rubygems'
|
3
|
-
require 'optparse'
|
4
|
-
require 'parallel'
|
5
|
-
raise "please ' gem install parallel '" if Gem::Version.new(Parallel::VERSION) < Gem::Version.new('0.4.2')
|
6
|
-
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
7
|
-
require "parallelized_tests"
|
8
|
-
|
9
|
-
options = {}
|
10
|
-
OptionParser.new do |opts|
|
11
|
-
opts.banner = <<BANNER
|
12
|
-
Run all tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...)
|
13
|
-
|
14
|
-
[optional] Only run selected files & folders:
|
15
|
-
parallelized_test test/bar test/baz/xxx_text.rb
|
16
|
-
|
17
|
-
Options are:
|
18
|
-
BANNER
|
19
|
-
opts.on("-n [PROCESSES]", Integer, "How many processes to use, default: available CPUs"){|n| options[:count] = n }
|
20
|
-
opts.on("-p", '--pattern [PATTERN]', "run tests matching this pattern"){|pattern| options[:pattern] = pattern }
|
21
|
-
opts.on("--no-sort", "do not sort files before running them"){ |no_sort| options[:no_sort] = no_sort }
|
22
|
-
opts.on("-m [FLOAT]", "--multiply-processes [FLOAT]", Float, "use given number as a multiplier of processes to run"){ |multiply| options[:multiply] = multiply }
|
23
|
-
opts.on("-r", '--root [PATH]', "execute test commands from this path"){|path| options[:root] = path }
|
24
|
-
opts.on("-s [PATTERN]", "--single [PATTERN]", "Run all matching files in only one process") do |pattern|
|
25
|
-
options[:single_process] ||= []
|
26
|
-
options[:single_process] << /#{pattern}/
|
27
|
-
end
|
28
|
-
opts.on("-e", '--exec [COMMAND]', "execute this code parallel and with ENV['TEST_ENV_NUM']"){|path| options[:execute] = path }
|
29
|
-
opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options"){|arg| options[:test_options] = arg }
|
30
|
-
opts.on("-t", "--type [TYPE]", "which type of tests to run? test, spec or features"){|type| options[:type] = type }
|
31
|
-
opts.on("--non-parallel", "execute same commands but do not in parallel, needs --exec"){ options[:non_parallel] = true }
|
32
|
-
opts.on("--chunk-timeout [TIMEOUT]", "timeout before re-printing the output of a child-process"){|timeout| options[:chunk_timeout] = timeout.to_f }
|
33
|
-
opts.on('-v', '--version', 'Show Version'){ puts ParallelizedTests::VERSION; exit}
|
34
|
-
opts.on("-h", "--help", "Show this.") { puts opts; exit }
|
35
|
-
end.parse!
|
36
|
-
|
37
|
-
raise "--no-sort and --single-process are not supported" if options[:no_sort] and options[:single_process]
|
38
|
-
|
39
|
-
# get files to run from arguments
|
40
|
-
options[:files] = ARGV if ARGV.size > 0
|
41
|
-
|
42
|
-
num_processes = options[:count] || Parallel.processor_count
|
43
|
-
num_processes = num_processes * (options[:multiply] || 1)
|
44
|
-
|
45
|
-
if options[:execute]
|
46
|
-
runs = (0...num_processes).to_a
|
47
|
-
results = if options[:non_parallel]
|
48
|
-
runs.map do |i|
|
49
|
-
ParallelizedTests.execute_command(options[:execute], i, options)
|
50
|
-
end
|
51
|
-
else
|
52
|
-
Parallel.map(runs, :in_processes => num_processes) do |i|
|
53
|
-
ParallelizedTests.execute_command(options[:execute], i, options)
|
54
|
-
end
|
55
|
-
end.flatten
|
56
|
-
abort if results.any?{|r| r[:exit_status] != 0 }
|
57
|
-
else
|
58
|
-
lib, name, task = {
|
59
|
-
'test' => ["tests", "test", "test"],
|
60
|
-
'spec' => ["specs", "spec", "spec"],
|
61
|
-
}[options[:type]||'test']
|
62
|
-
|
63
|
-
require "parallelized_#{lib}"
|
64
|
-
klass = eval("Parallelized#{lib.capitalize}")
|
65
|
-
|
66
|
-
start = Time.now
|
67
|
-
|
68
|
-
tests_folder = task
|
69
|
-
tests_folder = File.join(options[:root], tests_folder) unless options[:root].to_s.empty?
|
70
|
-
|
71
|
-
groups = klass.tests_in_groups(options[:files] || tests_folder, num_processes, options)
|
72
|
-
num_processes = groups.size
|
73
|
-
|
74
|
-
#adjust processes to groups
|
75
|
-
abort "no #{name}s found!" if groups.size == 0
|
76
|
-
|
77
|
-
num_tests = groups.inject(0){|sum,item| sum + item.size }
|
78
|
-
puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{num_tests / groups.size} #{name}s per process"
|
79
|
-
|
80
|
-
test_results = Parallel.map(groups, :in_processes => num_processes) do |group|
|
81
|
-
klass.run_tests(group, groups.index(group), options)
|
82
|
-
end
|
83
|
-
|
84
|
-
#parse and print results
|
85
|
-
results = klass.find_results(test_results.map{|result| result[:stdout] }*"")
|
86
|
-
puts ""
|
87
|
-
puts klass.summarize_results(results)
|
88
|
-
|
89
|
-
#report total time taken
|
90
|
-
puts ""
|
91
|
-
puts "Took #{Time.now - start} seconds"
|
92
|
-
|
93
|
-
#exit with correct status code so rake parallel:test && echo 123 works
|
94
|
-
failed = test_results.any?{|result| result[:exit_status] != 0 }
|
95
|
-
abort "#{name.capitalize}s Failed" if failed
|
96
|
-
end
|
data/lib/parallelized_tests.rb
DELETED
@@ -1,163 +0,0 @@
|
|
1
|
-
require 'parallel'
|
2
|
-
require 'parallelized_tests/grouper'
|
3
|
-
require 'parallelized_tests/railtie'
|
4
|
-
|
5
|
-
class ParallelizedTests
|
6
|
-
VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
|
7
|
-
|
8
|
-
# parallel:spec[:count, :pattern, :options]
|
9
|
-
def self.parse_rake_args(args)
|
10
|
-
# order as given by user
|
11
|
-
args = [args[:count], args[:pattern], args[:options]]
|
12
|
-
|
13
|
-
# count given or empty ?
|
14
|
-
# parallel:spec[2,models,options]
|
15
|
-
# parallel:spec[,models,options]
|
16
|
-
count = args.shift if args.first.to_s =~ /^\d*$/
|
17
|
-
num_processes = count.to_i unless count.to_s.empty?
|
18
|
-
num_processes ||= ENV['PARALLEL_TEST_PROCESSORS'].to_i if ENV['PARALLEL_TEST_PROCESSORS']
|
19
|
-
num_processes ||= Parallel.processor_count
|
20
|
-
|
21
|
-
pattern = args.shift
|
22
|
-
options = args.shift
|
23
|
-
|
24
|
-
[num_processes.to_i, pattern.to_s, options.to_s]
|
25
|
-
end
|
26
|
-
|
27
|
-
# finds all tests and partitions them into groups
|
28
|
-
def self.tests_in_groups(root, num_groups, options={})
|
29
|
-
tests = find_tests(root, options)
|
30
|
-
if options[:no_sort] == true
|
31
|
-
Grouper.in_groups(tests, num_groups)
|
32
|
-
else
|
33
|
-
tests = with_runtime_info(tests)
|
34
|
-
Grouper.in_even_groups_by_size(tests, num_groups, options)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.run_tests(test_files, process_number, options)
|
39
|
-
require_list = test_files.map { |filename| %{"#{File.expand_path filename}"} }.join(",")
|
40
|
-
cmd = "ruby -Itest -e '[#{require_list}].each {|f| require f }' -- #{options[:test_options]}"
|
41
|
-
execute_command(cmd, process_number, options)
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.execute_command(cmd, process_number, options)
|
45
|
-
cmd = "TEST_ENV_NUMBER=#{test_env_number(process_number)} ; export TEST_ENV_NUMBER; #{cmd}"
|
46
|
-
f = open("|#{cmd}", 'r')
|
47
|
-
output = fetch_output(f, options)
|
48
|
-
f.close
|
49
|
-
{:stdout => output, :exit_status => $?.exitstatus}
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.find_results(test_output)
|
53
|
-
test_output.split("\n").map {|line|
|
54
|
-
line = line.gsub(/\.|F|\*/,'')
|
55
|
-
next unless line_is_result?(line)
|
56
|
-
line
|
57
|
-
}.compact
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.test_env_number(process_number)
|
61
|
-
process_number == 0 ? '' : process_number + 1
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.runtime_log
|
65
|
-
'tmp/parallelized_runtime_test.log'
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.summarize_results(results)
|
69
|
-
results = results.join(' ').gsub(/s\b/,'') # combine and singularize results
|
70
|
-
counts = results.scan(/(\d+) (\w+)/)
|
71
|
-
sums = counts.inject(Hash.new(0)) do |sum, (number, word)|
|
72
|
-
sum[word] += number.to_i
|
73
|
-
sum
|
74
|
-
end
|
75
|
-
sums.sort.map{|word, number| "#{number} #{word}#{'s' if number != 1}" }.join(', ')
|
76
|
-
end
|
77
|
-
|
78
|
-
protected
|
79
|
-
|
80
|
-
# read output of the process and print in in chucks
|
81
|
-
def self.fetch_output(process, options)
|
82
|
-
all = ''
|
83
|
-
buffer = ''
|
84
|
-
timeout = options[:chunk_timeout] || 0.2
|
85
|
-
flushed = Time.now.to_f
|
86
|
-
|
87
|
-
while char = process.getc
|
88
|
-
char = (char.is_a?(Fixnum) ? char.chr : char) # 1.8 <-> 1.9
|
89
|
-
all << char
|
90
|
-
|
91
|
-
# print in chunks so large blocks stay together
|
92
|
-
now = Time.now.to_f
|
93
|
-
buffer << char
|
94
|
-
if flushed + timeout < now
|
95
|
-
print buffer
|
96
|
-
STDOUT.flush
|
97
|
-
buffer = ''
|
98
|
-
flushed = now
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# print the remainder
|
103
|
-
print buffer
|
104
|
-
STDOUT.flush
|
105
|
-
|
106
|
-
all
|
107
|
-
end
|
108
|
-
|
109
|
-
# copied from http://github.com/carlhuda/bundler Bundler::SharedHelpers#find_gemfile
|
110
|
-
def self.bundler_enabled?
|
111
|
-
return true if Object.const_defined?(:Bundler)
|
112
|
-
|
113
|
-
previous = nil
|
114
|
-
current = File.expand_path(Dir.pwd)
|
115
|
-
|
116
|
-
until !File.directory?(current) || current == previous
|
117
|
-
filename = File.join(current, "Gemfile")
|
118
|
-
return true if File.exists?(filename)
|
119
|
-
current, previous = File.expand_path("..", current), current
|
120
|
-
end
|
121
|
-
|
122
|
-
false
|
123
|
-
end
|
124
|
-
|
125
|
-
def self.line_is_result?(line)
|
126
|
-
line =~ /\d+ failure/
|
127
|
-
end
|
128
|
-
|
129
|
-
def self.test_suffix
|
130
|
-
"_test.rb"
|
131
|
-
end
|
132
|
-
|
133
|
-
def self.with_runtime_info(tests)
|
134
|
-
lines = File.read(runtime_log).split("\n") rescue []
|
135
|
-
|
136
|
-
# use recorded test runtime if we got enough data
|
137
|
-
if lines.size * 1.5 > tests.size
|
138
|
-
puts "Using recorded test runtime"
|
139
|
-
times = Hash.new(1)
|
140
|
-
lines.each do |line|
|
141
|
-
test, time = line.split(":")
|
142
|
-
next unless test and time
|
143
|
-
times[File.expand_path(test)] = time.to_f
|
144
|
-
end
|
145
|
-
tests.sort.map{|test| [test, times[test]] }
|
146
|
-
else # use file sizes
|
147
|
-
tests.sort.map{|test| [test, File.stat(test).size] }
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def self.find_tests(root, options={})
|
152
|
-
if root.is_a?(Array)
|
153
|
-
root
|
154
|
-
else
|
155
|
-
# follow one symlink and direct children
|
156
|
-
# http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob
|
157
|
-
files = Dir["#{root}/**{,/*/**}/*#{test_suffix}"].uniq
|
158
|
-
files = files.map{|f| f.sub(root+'/','') }
|
159
|
-
files = files.grep(/#{options[:pattern]}/)
|
160
|
-
files.map{|f| "#{root}/#{f}" }
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
class ParallelizedTests::RuntimeLogger
|
2
|
-
@@has_started = false
|
3
|
-
|
4
|
-
def self.log(test, start_time, end_time)
|
5
|
-
return if test.is_a? Test::Unit::TestSuite # don't log for suites-of-suites
|
6
|
-
|
7
|
-
if !@@has_started # make empty log file
|
8
|
-
File.open(ParallelizedTests.runtime_log, 'w') do end
|
9
|
-
@@has_started = true
|
10
|
-
end
|
11
|
-
|
12
|
-
File.open(ParallelizedTests.runtime_log, 'a') do |output|
|
13
|
-
begin
|
14
|
-
output.flock File::LOCK_EX
|
15
|
-
output.puts(self.message(test, start_time, end_time))
|
16
|
-
ensure
|
17
|
-
output.flock File::LOCK_UN
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.message(test, start_time, end_time)
|
23
|
-
delta="%.2f" % (end_time.to_f-start_time.to_f)
|
24
|
-
filename=class_directory(test.class) + class_to_filename(test.class) + ".rb"
|
25
|
-
message="#{filename}:#{delta}"
|
26
|
-
end
|
27
|
-
|
28
|
-
# Note: this is a best guess at conventional test directory structure, and may need
|
29
|
-
# tweaking / post-processing to match correctly for any given project
|
30
|
-
def self.class_directory(suspect)
|
31
|
-
result = "test/"
|
32
|
-
|
33
|
-
if defined?(Rails)
|
34
|
-
result += case suspect.superclass.name
|
35
|
-
when "ActionDispatch::IntegrationTest"
|
36
|
-
"integration/"
|
37
|
-
when "ActionDispatch::PerformanceTest"
|
38
|
-
"performance/"
|
39
|
-
when "ActionController::TestCase"
|
40
|
-
"functional/"
|
41
|
-
when "ActionView::TestCase"
|
42
|
-
"unit/helpers/"
|
43
|
-
else
|
44
|
-
"unit/"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
result
|
48
|
-
end
|
49
|
-
|
50
|
-
# based on https://github.com/grosser/single_test/blob/master/lib/single_test.rb#L117
|
51
|
-
def self.class_to_filename(suspect)
|
52
|
-
word = suspect.to_s.dup
|
53
|
-
return word unless word.match /^[A-Z]/ and not word.match %r{/[a-z]}
|
54
|
-
|
55
|
-
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
56
|
-
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
57
|
-
word.gsub!(/\:\:/,'/')
|
58
|
-
word.tr!("-", "_")
|
59
|
-
word.downcase!
|
60
|
-
word
|
61
|
-
end
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
require 'test/unit/testsuite'
|
66
|
-
class Test::Unit::TestSuite
|
67
|
-
|
68
|
-
alias :run_without_timing :run unless defined? @@timing_installed
|
69
|
-
|
70
|
-
def run(result, &progress_block)
|
71
|
-
start_time=Time.now
|
72
|
-
run_without_timing(result, &progress_block)
|
73
|
-
end_time=Time.now
|
74
|
-
ParallelizedTests::RuntimeLogger.log(self.tests.first, start_time, end_time)
|
75
|
-
end
|
76
|
-
@@timing_installed = true
|
77
|
-
|
78
|
-
end
|