Class: QUnited::Driver::ResultsCollector

Inherits:
Object
  • Object
show all
Defined in:
lib/qunited/driver/results_collector.rb

Overview

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}"}

Constant Summary collapse

TEST_RESULT_START_TOKEN =
'QUNITED_TEST_RESULT_START_TOKEN'
TEST_RESULT_END_TOKEN =
'QUNITED_TEST_RESULT_END_TOKEN'
ONE_LINE_TEST_RESULT_REGEX =
/#{TEST_RESULT_START_TOKEN}(.*?)#{TEST_RESULT_END_TOKEN}/

Instance Method Summary collapse

Constructor Details

#initialize(io) ⇒ ResultsCollector

Returns a new instance of ResultsCollector.



35
36
37
38
39
40
41
# 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

Instance Method Details

#collect_next_lineObject

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.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# 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_resultsObject

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.



59
60
61
# File 'lib/qunited/driver/results_collector.rb', line 59

def collect_results
  while collect_next_line; end
end

#on_non_test_result_line(&block) ⇒ Object

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.

Raises:

  • (ArgumentError)


52
53
54
55
# 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) ⇒ Object

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

Raises:

  • (ArgumentError)


45
46
47
48
# 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