qunited 0.3.1 → 0.4.0
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/lib/qunited/application.rb +5 -7
- data/lib/qunited/driver/base.rb +11 -0
- data/lib/qunited/driver/phantomjs/phantomjs.rb +26 -9
- data/lib/qunited/driver/phantomjs/support/runner.js +79 -84
- data/lib/qunited/driver/phantomjs/support/tests_page.html.erb +3 -0
- data/lib/qunited/driver/results_collector.rb +105 -0
- data/lib/qunited/driver/rhino/rhino.rb +19 -9
- data/lib/qunited/driver/rhino/support/runner.js +37 -23
- data/lib/qunited/driver/support/qunited.js +73 -17
- data/lib/qunited/driver.rb +1 -0
- data/lib/qunited/formatter/base.rb +42 -0
- data/lib/qunited/formatter/dots.rb +90 -0
- data/lib/qunited/formatter.rb +2 -0
- data/lib/qunited/qunit_test_result.rb +85 -0
- data/lib/qunited/rake_task.rb +39 -18
- data/lib/qunited/runner.rb +24 -7
- data/lib/qunited/version.rb +1 -1
- data/lib/qunited.rb +2 -1
- data/test/fixtures/failures_project/test/javascripts/test_math.js +1 -1
- data/test/test_helper.rb +1 -0
- data/test/unit/driver/test_results_collector.rb +186 -0
- data/test/unit/driver_common_tests.rb +87 -26
- data/test/unit/formatter/test_dots.rb +250 -0
- data/test/unit/test_phantomjs_driver.rb +1 -2
- data/test/unit/test_rhino_driver.rb +31 -31
- metadata +11 -5
- data/lib/qunited/results.rb +0 -195
- data/test/unit/test_results.rb +0 -338
data/lib/qunited/application.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'optparse'
|
2
|
-
require 'ostruct'
|
3
2
|
|
4
3
|
module QUnited
|
5
4
|
class Application
|
@@ -12,7 +11,8 @@ module QUnited
|
|
12
11
|
|
13
12
|
def run_tests
|
14
13
|
js_source_files, js_test_files = ARGV.join(' ').split('--').map { |file_list| file_list.split(' ') }
|
15
|
-
|
14
|
+
passed = QUnited::Runner.new(js_source_files, js_test_files, options).run
|
15
|
+
exit (passed ? 0 : 10)
|
16
16
|
end
|
17
17
|
|
18
18
|
# Client options generally parsed from the command line
|
@@ -80,21 +80,19 @@ Options:
|
|
80
80
|
def handle_exceptions
|
81
81
|
begin
|
82
82
|
yield
|
83
|
-
rescue SystemExit
|
84
|
-
exit
|
85
83
|
rescue UsageError => ex
|
86
84
|
$stderr.puts ex.message
|
87
85
|
exit 1
|
88
86
|
rescue OptionParser::InvalidOption => ex
|
89
87
|
$stderr.puts ex.message
|
90
88
|
exit 1
|
91
|
-
rescue
|
92
|
-
|
89
|
+
rescue StandardError => ex
|
90
|
+
display_crash_message ex
|
93
91
|
exit 1
|
94
92
|
end
|
95
93
|
end
|
96
94
|
|
97
|
-
def
|
95
|
+
def display_crash_message(ex)
|
98
96
|
msg = <<MSG
|
99
97
|
QUnited has aborted! If this is unexpected, you may want to open an issue at
|
100
98
|
github.com/aaronroyer/qunited to get a possible bug fixed. If you do, please
|
data/lib/qunited/driver/base.rb
CHANGED
@@ -4,7 +4,12 @@ module QUnited
|
|
4
4
|
# Path of the common (to all drivers) supporting files directory
|
5
5
|
SUPPORT_DIR = File.expand_path('../support', __FILE__)
|
6
6
|
|
7
|
+
TEST_RESULT_START_TOKEN = 'QUNITED_TEST_RESULT_START_TOKEN'
|
8
|
+
TEST_RESULT_END_TOKEN = 'QUNITED_TEST_RESULT_END_TOKEN'
|
9
|
+
TEST_RESULT_REGEX = /#{TEST_RESULT_START_TOKEN}(.*?)#{TEST_RESULT_END_TOKEN}/m
|
10
|
+
|
7
11
|
attr_reader :results, :source_files, :test_files
|
12
|
+
attr_accessor :formatter
|
8
13
|
|
9
14
|
# Finds an executable on the PATH. Returns the absolute path of the
|
10
15
|
# executable if found, otherwise nil.
|
@@ -49,6 +54,12 @@ module QUnited
|
|
49
54
|
def name
|
50
55
|
self.class.name.split('::')[-1]
|
51
56
|
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
def send_to_formatter(method, *args)
|
61
|
+
formatter.send(method, *args) if formatter
|
62
|
+
end
|
52
63
|
end
|
53
64
|
end
|
54
65
|
end
|
@@ -16,7 +16,7 @@ module QUnited
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def name
|
19
|
-
|
19
|
+
'PhantomJS'
|
20
20
|
end
|
21
21
|
|
22
22
|
def run
|
@@ -24,20 +24,37 @@ module QUnited
|
|
24
24
|
tests_file.write(tests_page_content)
|
25
25
|
tests_file.close
|
26
26
|
|
27
|
-
|
28
|
-
results_file.close
|
27
|
+
send_to_formatter(:start)
|
29
28
|
|
30
|
-
cmd =
|
31
|
-
|
29
|
+
cmd = %|phantomjs "#{File.join(SUPPORT_DIR, 'runner.js')}" "#{tests_file.path}"|
|
30
|
+
|
31
|
+
@results = []
|
32
32
|
|
33
33
|
Open3.popen3(cmd) do |stdin, stdout, stderr|
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
results_collector = ResultsCollector.new(stdout)
|
35
|
+
|
36
|
+
results_collector.on_test_result do |result|
|
37
|
+
@results << result
|
38
|
+
method = result.passed? ? :test_passed : :test_failed
|
39
|
+
send_to_formatter(method, result)
|
40
|
+
end
|
41
|
+
|
42
|
+
results_collector.on_non_test_result_line do |line|
|
43
|
+
# PhantomJS sometimes puts error messages to stdout. If we are not reading
|
44
|
+
# a test result then redirect any output to stderr
|
45
|
+
$stderr.puts(line)
|
37
46
|
end
|
47
|
+
|
48
|
+
results_collector.collect_results
|
49
|
+
|
50
|
+
err = stderr.read
|
51
|
+
unless err.nil? || err.strip.empty? then $stderr.puts(err) end
|
38
52
|
end
|
39
53
|
|
40
|
-
|
54
|
+
send_to_formatter(:stop)
|
55
|
+
send_to_formatter(:summarize)
|
56
|
+
|
57
|
+
@results
|
41
58
|
end
|
42
59
|
|
43
60
|
private
|
@@ -1,102 +1,97 @@
|
|
1
1
|
/*
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
2
|
+
* Runs QUnit tests in PhantomJS and outputs test result data, in JSON format, to stdout.
|
3
|
+
*
|
4
|
+
* Tokens are placed around each test result to allow them to be parsed individually. The tokens
|
5
|
+
* match the constants in QUnited::Driver::ResultsCollector.
|
6
|
+
*
|
7
|
+
* Usage:
|
8
|
+
* phantomjs runner.js PATH_TO_TESTS_HTML_PAGE
|
9
|
+
*/
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
* Redistributions in binary form must reproduce the above copyright
|
13
|
-
notice, this list of conditions and the following disclaimer in the
|
14
|
-
documentation and/or other materials provided with the distribution.
|
15
|
-
* Neither the name of the <organization> nor the
|
16
|
-
names of its contributors may be used to endorse or promote products
|
17
|
-
derived from this software without specific prior written permission.
|
11
|
+
var system = require('system'),
|
12
|
+
webpage = require('webpage');
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
24
|
-
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
25
|
-
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
26
|
-
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
27
|
-
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
28
|
-
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
-
*/
|
14
|
+
if (system.args.length < 2) {
|
15
|
+
console.log('No tests file specified');
|
16
|
+
phantom.exit(1);
|
17
|
+
}
|
30
18
|
|
31
|
-
var
|
19
|
+
var page = webpage.create(),
|
20
|
+
testsHtmlFile = system.args[1],
|
21
|
+
config = {
|
22
|
+
resultsCheckInterval: 200, // Check for new results at this interval
|
23
|
+
testsCompletedCheckInterval: 100, // Check for all tests completing at this interval
|
24
|
+
testsTimeout: 10001 // Time out and indicate error after this many millis
|
25
|
+
};
|
32
26
|
|
33
|
-
|
34
|
-
*
|
35
|
-
*
|
27
|
+
/*
|
28
|
+
* Writes any collected QUnit results that are pending output to stdout (this is done with
|
29
|
+
* console.log in PhantomJS).
|
36
30
|
*
|
37
|
-
*
|
38
|
-
*
|
39
|
-
*
|
40
|
-
*
|
41
|
-
* it
|
42
|
-
* as
|
43
|
-
*
|
31
|
+
* Tokens are placed around each test result to allow them to be parsed out later. Note that the
|
32
|
+
* tokens must match the constants in QUnited::Driver::ResultsCollector.
|
33
|
+
*
|
34
|
+
* JSON.stringify must be called in the context of the page to properly serialize null values in
|
35
|
+
* results. If it is called here in the PhantomJS interpreter code then null values are serialized
|
36
|
+
* as empty strings. Finding out exactly why this happens would take more investigation. For now
|
37
|
+
* it seems that stringifying on the page is a decent solution, though it is slightly less robust
|
38
|
+
* since JSON serialization may be tampered with in user code.
|
44
39
|
*/
|
45
|
-
function
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
} else {
|
54
|
-
if (!condition) {
|
55
|
-
// If condition still not fulfilled (timeout but condition is 'false')
|
56
|
-
console.log("ERROR: Timeout waiting for tests to complete");
|
57
|
-
phantom.exit(1);
|
58
|
-
} else {
|
59
|
-
// Condition fulfilled (timeout and/or condition is 'true')
|
60
|
-
//console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
|
61
|
-
typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
|
62
|
-
clearInterval(interval); //< Stop this interval
|
63
|
-
}
|
64
|
-
}
|
65
|
-
}, 100);
|
66
|
-
};
|
67
|
-
|
40
|
+
function writePendingTestResults() {
|
41
|
+
var serializedResults = page.evaluate(function() {
|
42
|
+
var pendingResults = [];
|
43
|
+
while (QUnited.testResultsPendingOutput.length > 0) {
|
44
|
+
pendingResults.push(QUnited.util.jsonStringify(QUnited.testResultsPendingOutput.shift()));
|
45
|
+
}
|
46
|
+
return pendingResults;
|
47
|
+
});
|
68
48
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
49
|
+
var i, output;
|
50
|
+
for (i = 0; i < serializedResults.length; i++) {
|
51
|
+
output = 'QUNITED_TEST_RESULT_START_TOKEN';
|
52
|
+
output += serializedResults[i];
|
53
|
+
output += 'QUNITED_TEST_RESULT_END_TOKEN';
|
54
|
+
console.log(output);
|
55
|
+
}
|
75
56
|
}
|
76
57
|
|
77
|
-
|
78
|
-
|
79
|
-
|
58
|
+
/*
|
59
|
+
* Executes the given function once all tests have completed. If a timeout occurs then exit
|
60
|
+
* with a status code of 1.
|
61
|
+
*/
|
62
|
+
function whenTestsHaveCompleted(fn) {
|
63
|
+
var start = new Date().getTime(),
|
64
|
+
testsHaveCompleted = false,
|
65
|
+
interval = setInterval(function() {
|
66
|
+
if ( (new Date().getTime() - start < config.testsTimeout) && !testsHaveCompleted ) {
|
67
|
+
testsHaveCompleted = page.evaluate(function() { return QUnited.testsHaveCompleted; });
|
68
|
+
} else {
|
69
|
+
if (testsHaveCompleted) {
|
70
|
+
fn();
|
71
|
+
clearInterval(interval);
|
72
|
+
} else {
|
73
|
+
// Tests took too long
|
74
|
+
console.log("ERROR: Timeout waiting for tests to complete");
|
75
|
+
phantom.exit(1);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}, config.testsCompletedCheckInterval);
|
79
|
+
};
|
80
80
|
|
81
|
-
|
81
|
+
/*
|
82
|
+
* Open the HTML page that contains all of our QUnit tests. As it is running, check for collected
|
83
|
+
* test results and output them if we have any. Also check whether tests have completed. Once they
|
84
|
+
* have completed, output any remaining results and exit.
|
85
|
+
*/
|
86
|
+
page.open(testsHtmlFile, function(status) {
|
82
87
|
if (status !== "success") {
|
83
88
|
console.log("Could not open tests file");
|
84
89
|
phantom.exit(1);
|
85
90
|
} else {
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
if (el && el.innerText.match('completed')) {
|
91
|
-
return true;
|
92
|
-
}
|
93
|
-
return false;
|
94
|
-
});
|
95
|
-
}, function(){
|
96
|
-
// Results should have been collected with code in qunited.js. Check that file
|
97
|
-
// for more details. Grab the YAML it outputs and write it to the results file.
|
98
|
-
var results = page.evaluate(function() { return QUnited.collectedTestResultsAsJson(); });
|
99
|
-
fs.write(results_output_file, results, 'a');
|
91
|
+
setInterval(writePendingTestResults, config.resultsCheckInterval);
|
92
|
+
|
93
|
+
whenTestsHaveCompleted(function() {
|
94
|
+
writePendingTestResults();
|
100
95
|
phantom.exit(0);
|
101
96
|
});
|
102
97
|
}
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module QUnited
|
2
|
+
module Driver
|
3
|
+
|
4
|
+
# Collects test results from lines of JavaScript interpreter output.
|
5
|
+
#
|
6
|
+
# QUnited test running drivers may run a JavaScript interpreter in a separate process and
|
7
|
+
# observe the output (say, on stdout) for text containing test results. These results may
|
8
|
+
# be delimited by tokens that allow ResultsCollector to recognize the beginning and end of
|
9
|
+
# JSON test results. The test running driver must be properly configured to emit the correct
|
10
|
+
# tokens, matching TEST_RESULT_START_TOKEN and TEST_RESULT_END_TOKEN before and after strings
|
11
|
+
# of test results serialized as valid JSON.
|
12
|
+
#
|
13
|
+
# If everything is set up correctly the recognized results are parsed and QUnitTestResult
|
14
|
+
# objects are produced for each.
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# To use, initialize with the IO object that provides the output from the test running
|
18
|
+
# process. Then call on_test_result with a block to be called when a test is collected.
|
19
|
+
# A QUnited::QUnitTestResult object will be passed to the block for each test.
|
20
|
+
#
|
21
|
+
# rc = ResultsCollector.new(stdout_from_test_runner)
|
22
|
+
# rc.on_test_result {|test_result| puts "I've got a result: #{test_result.inspect}" }
|
23
|
+
#
|
24
|
+
# If you need to capture output that is not part of any test result, you can call
|
25
|
+
# on_non_test_result_line with another block to do this. Each line of output that is not part
|
26
|
+
# of test result JSON is passed to the block.
|
27
|
+
#
|
28
|
+
# rc.on_non_test_result_line {|line| puts "This line is not part of a test result: #{line}"}
|
29
|
+
#
|
30
|
+
class ResultsCollector
|
31
|
+
TEST_RESULT_START_TOKEN = 'QUNITED_TEST_RESULT_START_TOKEN'
|
32
|
+
TEST_RESULT_END_TOKEN = 'QUNITED_TEST_RESULT_END_TOKEN'
|
33
|
+
ONE_LINE_TEST_RESULT_REGEX = /#{TEST_RESULT_START_TOKEN}(.*?)#{TEST_RESULT_END_TOKEN}/
|
34
|
+
|
35
|
+
def initialize(io)
|
36
|
+
@io = io
|
37
|
+
@results = []
|
38
|
+
@on_test_result_block = nil
|
39
|
+
@on_non_test_result_line_block = nil
|
40
|
+
@partial_test_result = ''
|
41
|
+
end
|
42
|
+
|
43
|
+
# Set a block to be called when a test result has been parsed. The block is passed a
|
44
|
+
# QUnitTestResult object.
|
45
|
+
def on_test_result(&block)
|
46
|
+
raise ArgumentError.new('must provide a block') unless block_given?
|
47
|
+
@on_test_result_block = block
|
48
|
+
end
|
49
|
+
|
50
|
+
# Set a block to be called when a line of output is read from the IO object that is not
|
51
|
+
# part of a test result. The block is passed the line of output.
|
52
|
+
def on_non_test_result_line(&block)
|
53
|
+
raise ArgumentError.new('must provide a block') unless block_given?
|
54
|
+
@on_non_test_result_line_block = block
|
55
|
+
end
|
56
|
+
|
57
|
+
# Read all available lines from the IO and parse results from it. If blocks have been set
|
58
|
+
# with on_test_result and/or on_non_test_result_line they will be called when appropriate.
|
59
|
+
def collect_results
|
60
|
+
while collect_next_line; end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Read the next line from the IO and parse results from it, if applicable. If blocks have
|
64
|
+
# been set with on_test_result and/or on_non_test_result_line they will be called when
|
65
|
+
# appropriate.
|
66
|
+
#
|
67
|
+
# Usually collect_results should be used unless lines need to be read one at a time for
|
68
|
+
# some reason.
|
69
|
+
def collect_next_line
|
70
|
+
line = @io.gets
|
71
|
+
return nil unless line
|
72
|
+
|
73
|
+
if line =~ ONE_LINE_TEST_RESULT_REGEX
|
74
|
+
process_test_result $1
|
75
|
+
|
76
|
+
elsif line.include? TEST_RESULT_START_TOKEN
|
77
|
+
@partial_test_result << line.sub(TEST_RESULT_START_TOKEN, '')
|
78
|
+
|
79
|
+
elsif line.include? TEST_RESULT_END_TOKEN
|
80
|
+
@partial_test_result << line.sub(TEST_RESULT_END_TOKEN, '')
|
81
|
+
process_test_result @partial_test_result
|
82
|
+
@partial_test_result = ''
|
83
|
+
|
84
|
+
elsif !@partial_test_result.empty?
|
85
|
+
# Middle of a test result
|
86
|
+
@partial_test_result << line
|
87
|
+
|
88
|
+
else
|
89
|
+
@on_non_test_result_line_block.call(line) if @on_non_test_result_line_block
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
line
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def process_test_result(test_result_json)
|
99
|
+
result = ::QUnited::QUnitTestResult.from_json(test_result_json)
|
100
|
+
@results << result
|
101
|
+
@on_test_result_block.call(result) if @on_test_result_block
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -28,23 +28,33 @@ module QUnited
|
|
28
28
|
source_files_args = @source_files.map { |sf| %{"#{sf}"} }.join(' ')
|
29
29
|
test_files_args = @test_files.map { |tf| %{"#{tf}"} }.join(' ')
|
30
30
|
|
31
|
-
|
32
|
-
results_file.close
|
31
|
+
send_to_formatter(:start)
|
33
32
|
|
34
33
|
cmd = %{java -jar "#{js_jar}" -opt -1 "#{runner}" }
|
35
|
-
cmd << %{"#{QUnited::Driver::Base::SUPPORT_DIR}" "#{SUPPORT_DIR}"
|
34
|
+
cmd << %{"#{QUnited::Driver::Base::SUPPORT_DIR}" "#{SUPPORT_DIR}"}
|
36
35
|
cmd << " #{source_files_args} -- #{test_files_args}"
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
# will probably want to know but we are not particularly interested in it.
|
37
|
+
@results = []
|
38
|
+
|
41
39
|
Open3.popen3(cmd) do |stdin, stdout, stderr|
|
42
|
-
|
43
|
-
|
40
|
+
results_collector = ResultsCollector.new(stdout)
|
41
|
+
results_collector.on_test_result do |result|
|
42
|
+
@results << result
|
43
|
+
method = result.passed? ? :test_passed : :test_failed
|
44
|
+
send_to_formatter(method, result)
|
45
|
+
end
|
46
|
+
|
47
|
+
results_collector.collect_results
|
48
|
+
|
49
|
+
# Allow stderr to get blasted out to console - if there are uncaught exceptions or
|
50
|
+
# anything else that goes wrong with Rhino the user will probably want to know.
|
44
51
|
unless (err = stderr.read).strip.empty? then $stderr.puts(err) end
|
45
52
|
end
|
46
53
|
|
47
|
-
|
54
|
+
send_to_formatter(:stop)
|
55
|
+
send_to_formatter(:summarize)
|
56
|
+
|
57
|
+
@results
|
48
58
|
end
|
49
59
|
end
|
50
60
|
end
|
@@ -1,22 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
/*
|
2
|
+
* Runs QUnit tests on Rhino with Envjs and outputs test result data, in JSON format, to stdout.
|
3
|
+
*
|
4
|
+
* Tokens are placed around each test result to allow them to be parsed individually. The tokens
|
5
|
+
* match the constants in QUnited::Driver::ResultsCollector.
|
6
|
+
*
|
7
|
+
* When run, the first argument is the lib directory containing common QUnited dependencies. The
|
8
|
+
* second argument is the directory containing Rhino driver specific dependencies. The next
|
9
|
+
* arguments are source JavaScript files to test, until "--" is encountered. After the "--" the
|
10
|
+
* rest of the arguments are QUnit test files.
|
11
|
+
*
|
12
|
+
* Example:
|
13
|
+
* java -jar js.jar -opt -1 runner.js commonlibdir libdir source.js -- test1.js test2.js
|
14
|
+
* ^ our args start here
|
15
|
+
*/
|
13
16
|
|
14
17
|
var QUnited = { sourceFiles: [], testFiles: [] };
|
15
18
|
|
19
|
+
// Process command line arguments
|
16
20
|
(function(args) {
|
17
21
|
var commonLibDir = args.shift(),
|
18
22
|
libDir = args.shift();
|
19
|
-
QUnited.outputFile = args.shift();
|
20
23
|
|
21
24
|
load(libDir + '/env.rhino.js');
|
22
25
|
|
@@ -90,21 +93,32 @@ QUnited.testFiles.forEach(function(file) {
|
|
90
93
|
QUnited.modulesMap[defaultModuleName] = module;
|
91
94
|
}
|
92
95
|
|
93
|
-
//
|
94
|
-
|
95
|
-
name: "Nonexistent
|
96
|
+
// Put our failed test data into the default module
|
97
|
+
var failingTest = {
|
98
|
+
name: "Nonexistent tests",
|
96
99
|
assertion_data: [{
|
97
100
|
result: false, message: "Test file did not contain any tests (or there was an error loading it)"
|
98
101
|
}],
|
99
102
|
start: new Date(), duration: 0,
|
100
103
|
assertions: 1, failed: 1, total: 1,
|
101
104
|
file: file
|
102
|
-
}
|
105
|
+
}
|
106
|
+
|
107
|
+
module.tests.push(failingTest);
|
108
|
+
QUnited.testResultsPendingOutput.push(failingTest);
|
103
109
|
}
|
104
|
-
});
|
105
110
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
+
var results = [];
|
112
|
+
while (QUnited.testResultsPendingOutput.length > 0) {
|
113
|
+
results.push(QUnited.testResultsPendingOutput.shift());
|
114
|
+
}
|
115
|
+
|
116
|
+
var i, output;
|
117
|
+
for (i = 0; i < results.length; i++) {
|
118
|
+
// Beginning and end tokens should match the constants in QUnited::Driver::ResultsCollector
|
119
|
+
output = 'QUNITED_TEST_RESULT_START_TOKEN\n';
|
120
|
+
output += JSON.stringify(results[i], null, 1);
|
121
|
+
output += '\nQUNITED_TEST_RESULT_END_TOKEN';
|
122
|
+
java.lang.System.out.println(output);
|
123
|
+
}
|
124
|
+
});
|