def run(pattern: '*', max_threads: 8, max_tests: 0)
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
@results = File.expand_path('results.log')
max_threads = 1000 if max_threads.to_i == 0
c = Doing::Color
c.coloring = true
shuffle = false
unless pattern =~ /shuffle/i
pattern = "test/doing_*#{pattern}*_test.rb"
else
pattern = "test/doing_*_test.rb"
shuffle = true
end
tests = Dir.glob(pattern)
tests.shuffle! if shuffle
if max_tests.to_i > 0
tests = tests.slice(0, max_tests.to_i - 1)
end
puts "#{tests.count} test files".boldcyan
banner = [
'Running tests '.bold.white,
'['.black,
':bar'.boldcyan,
'] '.black,
'T'.green,
'/'.white,
'A'.cyan,
' ('.white,
max_threads.to_s.bold.magenta,
' threads)'.white
].join('')
progress = TTY::ProgressBar::Multi.new(banner,
width: 12,
clear: true,
hide_cursor: true)
@children = []
tests.each do |t|
test_name = File.basename(t, '.rb').sub(/doing_(.*?)_test/, '\1')
new_sp = progress.register("[#{':bar'.cyan}] #{test_name.bold.white}:status",
total: tests.count + 8,
width: 1,
head: ' ',
unknown: ' ',
hide_cursor: true,
clear: true)
status = ': waiting'.dark.yellow.reset
@children.push([test_name, new_sp, status])
end
@elapsed = 0.0
@test_total = 0
@assrt_total = 0
@error_out = []
@threads = []
@running_tests = []
begin
finish_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
while @children.count.positive?
slices = @children.slice!(0, max_threads)
slices.each { |c| c[1].start }
slices.each do |s|
@threads << Thread.new do
run_test(s)
finish_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
end
end
@threads.each { |t| t.join }
end
finish_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
progress.finish
rescue
progress.stop
ensure
msg = @running_tests.map { |t| t[1].format.uncolor.sub(/^\[:bar\] (.*?):status/, "#{c.bold}#{c.white}\\1#{c.reset}#{t[2]}") }.join("\n")
Doing::Prompt.clear_screen(msg)
output = []
output << if @error_out.count.positive?
c.boldred("#{@error_out.count} Issues")
else
c.green('Success')
end
output << c.green("#{@test_total} tests")
output << c.cyan("#{@assrt_total} assertions")
output << c.yellow("#{(finish_time - start_time).round(3)}s")
puts output.join(', ')
if @error_out.count.positive?
res = Doing::Prompt.yn('Display error report?', default_response: false)
Doing::Pager.paginate = true
Doing::Pager.page(@error_out.join("\n----\n".boldwhite)) if res
Process.exit 1
end
end
end