class QUnited::Driver::ResultsCollector

Collects test results from lines of JavaScript interpreter output.

QUnited test running drivers may run a JavaScript interpreter in a separate process and observe the output (say, on stdout) for text containing test results. These results may be delimited by tokens that allow ResultsCollector to recognize the beginning and end of JSON test results. The test running driver must be properly configured to emit the correct tokens, matching TEST_RESULT_START_TOKEN and TEST_RESULT_END_TOKEN before and after strings of test results serialized as valid JSON.

If everything is set up correctly the recognized results are parsed and QUnitTestResult objects are produced for each.

To use, initialize with the IO object that provides the output from the test running process. Then call on_test_result with a block to be called when a test is collected. A QUnited::QUnitTestResult object will be passed to the block for each test.

rc = ResultsCollector.new(stdout_from_test_runner)
rc.on_test_result {|test_result| puts "I've got a result: #{test_result.inspect}" }

If you need to capture output that is not part of any test result, you can call on_non_test_result_line with another block to do this. Each line of output that is not part of test result JSON is passed to the block.

rc.on_non_test_result_line {|line| puts "This line is not part of a test result: #{line}"}

Constants

ONE_LINE_TEST_RESULT_REGEX
TEST_RESULT_END_TOKEN
TEST_RESULT_START_TOKEN

Public Class Methods

new(io) click to toggle source
# File lib/qunited/driver/results_collector.rb, line 35
def initialize(io)
  @io = io
  @results = []
  @on_test_result_block = nil
  @on_non_test_result_line_block = nil
  @partial_test_result = ''
end

Public Instance Methods

collect_next_line() click to toggle source

Read the next line from the IO and parse results from it, if applicable. If blocks have been set with on_test_result and/or on_non_test_result_line they will be called when appropriate.

Usually collect_results should be used unless lines need to be read one at a time for some reason.

# File lib/qunited/driver/results_collector.rb, line 69
def collect_next_line
  line = @io.gets
  return nil unless line

  if line =~ ONE_LINE_TEST_RESULT_REGEX
    process_test_result $1

  elsif line.include? TEST_RESULT_START_TOKEN
    @partial_test_result << line.sub(TEST_RESULT_START_TOKEN, '')

  elsif line.include? TEST_RESULT_END_TOKEN
    @partial_test_result << line.sub(TEST_RESULT_END_TOKEN, '')
    process_test_result @partial_test_result
    @partial_test_result = ''

  elsif !@partial_test_result.empty?
    # Middle of a test result
    @partial_test_result << line

  else
    @on_non_test_result_line_block.call(line) if @on_non_test_result_line_block

  end

  line
end
collect_results() click to toggle source

Read all available lines from the IO and parse results from it. If blocks have been set with on_test_result and/or on_non_test_result_line they will be called when appropriate.

# File lib/qunited/driver/results_collector.rb, line 59
def collect_results
  while collect_next_line; end
end
on_non_test_result_line(&block) click to toggle source

Set a block to be called when a line of output is read from the IO object that is not part of a test result. The block is passed the line of output.

# File lib/qunited/driver/results_collector.rb, line 52
def on_non_test_result_line(&block)
  raise ArgumentError.new('must provide a block') unless block_given?
  @on_non_test_result_line_block = block
end
on_test_result(&block) click to toggle source

Set a block to be called when a test result has been parsed. The block is passed a QUnitTestResult object.

# File lib/qunited/driver/results_collector.rb, line 45
def on_test_result(&block)
  raise ArgumentError.new('must provide a block') unless block_given?
  @on_test_result_block = block
end

Private Instance Methods

process_test_result(test_result_json) click to toggle source
# File lib/qunited/driver/results_collector.rb, line 98
def process_test_result(test_result_json)
  result = ::QUnited::QUnitTestResult.from_json(test_result_json)
  @results << result
  @on_test_result_block.call(result) if @on_test_result_block
end