class ThreadedTests
Public Instance Methods
next_test()
click to toggle source
# File lib/helpers/threaded_tests.rb, line 195 def next_test if @children.count.positive? t = Thread.new do s = @children.shift # s[1].start # s[1].advance(status: ": #{'running'.green}") run_test(s) end t.join end end
run(pattern: '*', max_threads: 8, max_tests: 0)
click to toggle source
# File lib/helpers/threaded_tests.rb, line 17 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]) # new_sp.advance(status: ': waiting'.dark.yellow.reset) end @elapsed = 0.0 @test_total = 0 @assrt_total = 0 @error_out = [] # progress.start @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 end end end
run_test(s)
click to toggle source
# File lib/helpers/threaded_tests.rb, line 129 def run_test(s) bar = s[1] s[2] = ": #{'running'.green}" bar.advance(status: s[2]) if @running_tests.count.positive? @running_tests.each do |b| prev_bar = b[1] if prev_bar.complete? prev_bar.reset prev_bar.advance(status: b[2]) prev_bar.finish else prev_bar.update(head: ' ', unfinished: ' ') prev_bar.advance(status: b[2]) end end end @running_tests.push(s) out, _err, status = Open3.capture3(ENV, 'rake', "test:#{s[0]}", stdin_data: nil) time = out.match(/^Finished in (?<time>\d+\.\d+) seconds\./) count = out.match(/^(?<tests>\d+) tests, (?<assrt>\d+) assertions, (?<fails>\d+) failures, (?<errs>\d+) errors/) unless status.success? && !count['fails'].to_i.positive? && !count['errs'].to_i.positive? s[2] = if count ": #{count['fails'].bold.red} #{'failures'.red}, #{count['errs'].bold.red} #{'errors'.red}" else ": #{'Unknown Error'.bold.red}" end bar.update(head: '✖'.boldred) bar.advance(head: '✖'.boldred, status: s[2]) # errs = out.scan(/(?:Failure|Error): [\w_]+\((?:.*?)\):(?:.*?)(?=\n=======)/m) @error_out.push(out.highlight_errors) bar.finish next_test Thread.exit end s[2] = [ ': ', count['tests'].green, '/', count['assrt'].cyan, # ' (', # count['fails'].to_i == 0 ? '-'.dark.white.reset : count['fails'].bold.red, # '/', # count['errs'].to_i == 0 ? '-'.dark.white.reset : count['errs'].bold.red, # ') ', ' ', time['time'].to_f.round(3).to_s.yellow, 's' ].join('') bar.update(head: '✔'.boldgreen) bar.advance(head: '✔'.boldgreen, status: s[2]) @test_total += count['tests'].to_i @assrt_total += count['assrt'].to_i @elapsed += time['time'].to_f bar.finish next_test end