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
@@ -1,8 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This contains code that may be placed, by a QUnited driver, on the same page or context where
|
3
|
+
* QUnit tests are run. QUnit events are listened for and test results are collected for easier
|
4
|
+
* retrieval by other driver code.
|
5
|
+
*/
|
6
|
+
|
1
7
|
var QUnited = QUnited || {};
|
2
8
|
|
3
9
|
(function() {
|
4
10
|
|
5
11
|
QUnited.util = {};
|
12
|
+
|
6
13
|
QUnited.util.dateToString = function(date) {
|
7
14
|
if (Object.prototype.toString.call(date) === '[object String]') { return date; }
|
8
15
|
function pad(n) { return n < 10 ? '0' + n : n; }
|
@@ -10,6 +17,60 @@ QUnited.util.dateToString = function(date) {
|
|
10
17
|
pad(date.getUTCHours()) + ':' + pad(date.getUTCMinutes()) + ':' + pad(date.getUTCSeconds()) + 'Z';
|
11
18
|
};
|
12
19
|
|
20
|
+
/*
|
21
|
+
* Converts the given serializable JavaScript object to a JSON string. Uses the native JSON.stringify.
|
22
|
+
*/
|
23
|
+
QUnited.util.jsonStringify = function(object) {
|
24
|
+
var jsonString,
|
25
|
+
stringifiableTypes,
|
26
|
+
toJSONFunctions,
|
27
|
+
i;
|
28
|
+
|
29
|
+
// Hack to work around toJSON functions breaking JSON serialization. This most notably can happen
|
30
|
+
// when the Prototype library is used. As much as we'd like to just delete these we have to
|
31
|
+
// save them to restore them later since tests may be run after this and user code may depend on
|
32
|
+
// this stuff.
|
33
|
+
stringifiableTypes = [Object, Array, String];
|
34
|
+
if (typeof Hash !== 'undefined' && Hash.prototype) { stringifiableTypes.push(Hash); }
|
35
|
+
toJSONFunctions = [];
|
36
|
+
|
37
|
+
for (i = 0; i < stringifiableTypes.length; i++) {
|
38
|
+
if (stringifiableTypes[i].prototype.toJSON) {
|
39
|
+
toJSONFunctions[i] = stringifiableTypes[i].prototype.toJSON;
|
40
|
+
delete stringifiableTypes[i].prototype.toJSON;
|
41
|
+
} else {
|
42
|
+
toJSONFunctions[i] = undefined;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
// The 3rd argument here adds spaces to the generated JSON string. This is necessary
|
47
|
+
// for YAML parsers that are not compliant with YAML 1.2 (the version where YAML became
|
48
|
+
// a true superset of JSON).
|
49
|
+
jsonString = JSON.stringify(object, null, 1);
|
50
|
+
|
51
|
+
// Restore any toJSON functions we removed earlier
|
52
|
+
for (i = 0; i < toJSONFunctions.length; i++) {
|
53
|
+
if (toJSONFunctions[i]) {
|
54
|
+
stringifiableTypes[i].prototype.toJSON = toJSONFunctions[i];
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
return jsonString;
|
59
|
+
};
|
60
|
+
|
61
|
+
|
62
|
+
/* Test results that should be output to be picked up by the formatter, for live result updates
|
63
|
+
* while tests are still running. Not all runners may be able to do live updates but keeping this
|
64
|
+
* up to date enables that in case they are able to.
|
65
|
+
*/
|
66
|
+
QUnited.testResultsPendingOutput = [];
|
67
|
+
|
68
|
+
/*
|
69
|
+
* Flag to indicate whether all of the QUnit tests have completed. This is set to true with the
|
70
|
+
* QUnit.done callback.
|
71
|
+
*/
|
72
|
+
QUnited.testsHaveCompleted = false;
|
73
|
+
|
13
74
|
QUnited.startCollectingTestResults = function() {
|
14
75
|
// Various state we'll need while running the tests
|
15
76
|
QUnited.modulesMap = {};
|
@@ -19,16 +80,18 @@ QUnited.startCollectingTestResults = function() {
|
|
19
80
|
///// Listen for QUnit events during tests
|
20
81
|
|
21
82
|
QUnit.testStart(function(data) {
|
83
|
+
var moduleName = data.module || "(no module)",
|
84
|
+
module = QUnited.modulesMap[moduleName];
|
85
|
+
|
22
86
|
currentTest = {
|
23
87
|
name: data.name,
|
24
|
-
|
88
|
+
module_name: moduleName,
|
89
|
+
assertion_data: [],
|
25
90
|
start: new Date(),
|
26
91
|
assertions: 0,
|
27
92
|
file: QUnited.currentTestFile
|
28
93
|
};
|
29
94
|
|
30
|
-
var moduleName = data.module || "(no module)",
|
31
|
-
module = QUnited.modulesMap[moduleName];
|
32
95
|
if (!module) {
|
33
96
|
module = {name: moduleName, tests: []};
|
34
97
|
QUnited.modulesMap[moduleName] = module;
|
@@ -40,6 +103,8 @@ QUnited.startCollectingTestResults = function() {
|
|
40
103
|
currentTest.duration = ((new Date()).getTime() - currentTest.start.getTime()) / 1000;
|
41
104
|
currentTest.failed = data.failed;
|
42
105
|
currentTest.total = data.total;
|
106
|
+
|
107
|
+
QUnited.testResultsPendingOutput.push(currentTest);
|
43
108
|
});
|
44
109
|
|
45
110
|
/*
|
@@ -51,6 +116,10 @@ QUnited.startCollectingTestResults = function() {
|
|
51
116
|
currentTest.assertions++;
|
52
117
|
currentTest.assertion_data.push(data);
|
53
118
|
});
|
119
|
+
|
120
|
+
QUnit.done(function() {
|
121
|
+
QUnited.testsHaveCompleted = true;
|
122
|
+
});
|
54
123
|
};
|
55
124
|
|
56
125
|
/* Results as an Array of modules */
|
@@ -62,20 +131,7 @@ QUnited.collectedTestResults = function() {
|
|
62
131
|
|
63
132
|
/* Module results as a JSON string */
|
64
133
|
QUnited.collectedTestResultsAsJson = function() {
|
65
|
-
|
66
|
-
// rid of the bad bits if they are present.
|
67
|
-
// http://stackoverflow.com/questions/710586/json-stringify-bizarreness
|
68
|
-
if (window.Prototype) {
|
69
|
-
delete Object.prototype.toJSON;
|
70
|
-
delete Array.prototype.toJSON;
|
71
|
-
delete Hash.prototype.toJSON;
|
72
|
-
delete String.prototype.toJSON;
|
73
|
-
}
|
74
|
-
|
75
|
-
// The 3rd argument here adds spaces to the generated JSON string. This is necessary
|
76
|
-
// for YAML parsers that are not compliant with YAML 1.2 (the version where YAML became
|
77
|
-
// a true superset of JSON).
|
78
|
-
return JSON.stringify(QUnited.collectedTestResults(), null, 1);
|
134
|
+
return QUnited.util.jsonStringify(QUnited.collectedTestResults());
|
79
135
|
};
|
80
136
|
|
81
137
|
})();
|
data/lib/qunited/driver.rb
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
module QUnited
|
2
|
+
module Formatter
|
3
|
+
class Base
|
4
|
+
attr_reader :driver_name, :output, :test_results
|
5
|
+
|
6
|
+
def initialize(options={})
|
7
|
+
@driver_name = options[:driver_name]
|
8
|
+
@output = options[:output] || $stdout
|
9
|
+
@test_results = []
|
10
|
+
end
|
11
|
+
|
12
|
+
# Called before we start running tests
|
13
|
+
def start
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_passed(result)
|
17
|
+
@test_results << result
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_failed(result)
|
21
|
+
@test_results << result
|
22
|
+
end
|
23
|
+
|
24
|
+
# Send arbitrary messages to the output stream
|
25
|
+
def message
|
26
|
+
output.puts message
|
27
|
+
end
|
28
|
+
|
29
|
+
# Called after all tests have run, before we summarize results
|
30
|
+
def stop
|
31
|
+
end
|
32
|
+
|
33
|
+
# Called after we have stopped running tests
|
34
|
+
def summarize
|
35
|
+
end
|
36
|
+
|
37
|
+
def close
|
38
|
+
output.close if IO === output && output != $stdout
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module QUnited
|
2
|
+
module Formatter
|
3
|
+
class Dots < Base
|
4
|
+
def start
|
5
|
+
super
|
6
|
+
output.print "\n# Running JavaScript tests with #{driver_name}:\n\n"
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_passed(result)
|
10
|
+
super result
|
11
|
+
output.print '.'
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_failed(result)
|
15
|
+
super result
|
16
|
+
output.print(result.error? ? 'E' : 'F')
|
17
|
+
end
|
18
|
+
|
19
|
+
def summarize
|
20
|
+
output.print "\n\n#{times_line}\n"
|
21
|
+
output.print failure_output
|
22
|
+
output.print "\n#{bottom_line}\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def failure_output
|
28
|
+
return '' unless total_failures > 0
|
29
|
+
|
30
|
+
all_failure_output = ''
|
31
|
+
count = 1
|
32
|
+
failures.each do |test|
|
33
|
+
test.assertions.reject { |a| a.passed? }.each do |assertion|
|
34
|
+
file_name_output = (test.file && !test.file.strip.empty?) ? " [#{test.file}]" : ''
|
35
|
+
msg = "\n " + (count ? "#{count.to_s}) " : "")
|
36
|
+
msg << "#{assertion.error? ? 'Error' : 'Failure'}:\n"
|
37
|
+
msg << "#{test.name} (#{test.module_name})#{file_name_output}\n"
|
38
|
+
msg << "#{assertion.message || 'Failed assertion, no message given.'}\n"
|
39
|
+
|
40
|
+
if assertion.data.key? :expected
|
41
|
+
msg << "Expected: #{assertion.expected.nil? ? 'null' : assertion.expected.inspect}\n"
|
42
|
+
msg << " Actual: #{assertion.actual.nil? ? 'null' : assertion.actual.inspect}\n"
|
43
|
+
end
|
44
|
+
all_failure_output << msg
|
45
|
+
count += 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
all_failure_output
|
50
|
+
end
|
51
|
+
|
52
|
+
def times_line
|
53
|
+
total_time = test_results.inject(0) { |total, result| total += result.duration }
|
54
|
+
|
55
|
+
tests_per = (total_time > 0) ? (total_tests / total_time) : total_tests
|
56
|
+
assertions_per = (total_time > 0) ? (total_assertions / total_time) : total_assertions
|
57
|
+
|
58
|
+
"Finished in #{"%.6g" % total_time} seconds, #{"%.6g" % tests_per} tests/s, " +
|
59
|
+
"#{"%.6g" % assertions_per} assertions/s."
|
60
|
+
end
|
61
|
+
|
62
|
+
def bottom_line
|
63
|
+
"#{total_tests} tests, #{total_assertions} assertions, " +
|
64
|
+
"#{total_failures} failures, #{total_errors} errors"
|
65
|
+
end
|
66
|
+
|
67
|
+
def failures
|
68
|
+
test_results.select { |tr| tr.failed? }
|
69
|
+
end
|
70
|
+
|
71
|
+
def total_tests
|
72
|
+
test_results.size
|
73
|
+
end
|
74
|
+
|
75
|
+
# Test failures, not assertion failures
|
76
|
+
def total_failures
|
77
|
+
failures.size
|
78
|
+
end
|
79
|
+
|
80
|
+
# Test errors, not assertion errors
|
81
|
+
def total_errors
|
82
|
+
test_results.select { |tr| tr.error? }.size
|
83
|
+
end
|
84
|
+
|
85
|
+
def total_assertions
|
86
|
+
test_results.inject(0) { |total, result| total += result.assertions.size}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module QUnited
|
2
|
+
|
3
|
+
# Contains results data from a QUnit JavaScript test. Useful for passing data
|
4
|
+
# to formatters.
|
5
|
+
class QUnitTestResult
|
6
|
+
class AssertionResult
|
7
|
+
attr_accessor :data
|
8
|
+
|
9
|
+
def initialize(assertion_data)
|
10
|
+
@data = assertion_data
|
11
|
+
end
|
12
|
+
|
13
|
+
def message
|
14
|
+
data[:message] || 'Failed assertion, no message given.'
|
15
|
+
end
|
16
|
+
|
17
|
+
def result
|
18
|
+
if data[:result]
|
19
|
+
:passed
|
20
|
+
else
|
21
|
+
data[:message] =~ /^Died on test/ ? :error : :failed
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def passed?; result == :passed end
|
26
|
+
def failed?; result == :failed end
|
27
|
+
def error?; result == :error end
|
28
|
+
|
29
|
+
[:expected, :actual].each do |prop|
|
30
|
+
define_method(prop) do
|
31
|
+
data[prop]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.from_json(json)
|
37
|
+
self.new clean_up_result(YAML.load(json))
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_accessor :data
|
41
|
+
|
42
|
+
def initialize(test_data)
|
43
|
+
@data = test_data
|
44
|
+
end
|
45
|
+
|
46
|
+
def passed?; result == :passed end
|
47
|
+
def failed?; result == :failed end
|
48
|
+
def error?; result == :error end
|
49
|
+
|
50
|
+
def result
|
51
|
+
@result ||= if assertions.find { |a| a.error? }
|
52
|
+
:error
|
53
|
+
else
|
54
|
+
assertions.find { |a| a.failed? } ? :failed : :passed
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def assertions
|
59
|
+
@assertions ||= data[:assertion_data].map { |assertion_data| AssertionResult.new assertion_data }
|
60
|
+
end
|
61
|
+
|
62
|
+
[:name, :module_name, :duration, :file].each do |prop|
|
63
|
+
define_method(prop) do
|
64
|
+
data[prop]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# Turn String keys into Symbols and convert Strings representing dates
|
71
|
+
# and numbers into their appropriate objects.
|
72
|
+
def self.clean_up_result(test_result)
|
73
|
+
test_result = symbolize_keys(test_result)
|
74
|
+
test_result[:start] = DateTime.parse(test_result[:start])
|
75
|
+
test_result[:assertion_data].map! { |data| symbolize_keys data }
|
76
|
+
test_result
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.symbolize_keys(hash)
|
80
|
+
new_hash = {}
|
81
|
+
hash.keys.each { |key| new_hash[key.to_sym] = hash[key] }
|
82
|
+
new_hash
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/qunited/rake_task.rb
CHANGED
@@ -8,21 +8,23 @@ module QUnited
|
|
8
8
|
# :qunited
|
9
9
|
attr_accessor :name
|
10
10
|
|
11
|
-
#
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
# <b>DEPRECATED:</b> Please use <tt>source_files=</tt>, which now takes either an array of files
|
12
|
+
# or a glob pattern string.
|
13
|
+
def source_files_pattern=(pattern)
|
14
|
+
warn 'source_files_pattern= is deprecated in QUnited rake task config, use source_files= with a pattern'
|
15
|
+
@source_files = pattern
|
16
|
+
end
|
17
17
|
|
18
18
|
# Array of JavaScript source files (and any dependencies). These will be loaded in order
|
19
19
|
# before loading the QUnit tests.
|
20
20
|
attr_accessor :source_files
|
21
21
|
|
22
|
-
#
|
23
|
-
#
|
24
|
-
|
25
|
-
|
22
|
+
# <b>DEPRECATED:</b> Please use <tt>test_files=</tt>, which now takes either an array of files
|
23
|
+
# or a glob pattern string.
|
24
|
+
def test_files_pattern=(pattern)
|
25
|
+
warn 'test_files_pattern= is deprecated in QUnited rake task config, use test_files= with a pattern'
|
26
|
+
@test_files = pattern
|
27
|
+
end
|
26
28
|
|
27
29
|
# Array of QUnit test files.
|
28
30
|
attr_accessor :test_files
|
@@ -36,6 +38,12 @@ module QUnited
|
|
36
38
|
# true
|
37
39
|
attr_accessor :verbose
|
38
40
|
|
41
|
+
# Fail rake task when tests fail.
|
42
|
+
#
|
43
|
+
# default:
|
44
|
+
# true
|
45
|
+
attr_accessor :fail_on_test_failure
|
46
|
+
|
39
47
|
# The port to use if running the server.
|
40
48
|
#
|
41
49
|
# default:
|
@@ -45,6 +53,7 @@ module QUnited
|
|
45
53
|
def initialize(*args)
|
46
54
|
@name = args.shift || :qunited
|
47
55
|
@verbose = true
|
56
|
+
@fail_on_test_failure = true
|
48
57
|
@server_port = nil
|
49
58
|
|
50
59
|
yield self if block_given?
|
@@ -60,12 +69,19 @@ module QUnited
|
|
60
69
|
elsif test_files_to_run.empty?
|
61
70
|
puts "No QUnit test files matching #{test_files_pattern} could be found"
|
62
71
|
else
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
72
|
+
command = test_command
|
73
|
+
puts command if verbose
|
74
|
+
success = system(command)
|
75
|
+
|
76
|
+
unless success
|
77
|
+
if $?.exitstatus == 10
|
78
|
+
# 10 is our test failure status code
|
79
|
+
fail 'QUnit tests failed' if @fail_on_test_failure
|
80
|
+
else
|
81
|
+
# Other status codes should mean unexpected crashes
|
82
|
+
fail 'Something went wrong when running tests with QUnited'
|
83
|
+
end
|
67
84
|
end
|
68
|
-
raise "#{command} failed" unless success
|
69
85
|
end
|
70
86
|
end
|
71
87
|
end
|
@@ -85,18 +101,23 @@ module QUnited
|
|
85
101
|
|
86
102
|
private
|
87
103
|
|
88
|
-
def
|
104
|
+
def test_command
|
89
105
|
cmd = 'qunited'
|
90
106
|
cmd << " --driver #{driver}" if driver
|
91
107
|
cmd << " #{source_files_to_include.join(' ')} -- #{test_files_to_run.join(' ')}"
|
92
108
|
end
|
93
109
|
|
94
110
|
def source_files_to_include
|
95
|
-
source_files
|
111
|
+
files_array source_files
|
96
112
|
end
|
97
113
|
|
98
114
|
def test_files_to_run
|
99
|
-
test_files
|
115
|
+
files_array test_files
|
116
|
+
end
|
117
|
+
|
118
|
+
# Force convert to array of files if glob pattern
|
119
|
+
def files_array(files)
|
120
|
+
files.is_a?(Array) ? files : pattern_to_filelist(files.to_s)
|
100
121
|
end
|
101
122
|
|
102
123
|
def pattern_to_filelist(pattern)
|
data/lib/qunited/runner.rb
CHANGED
@@ -11,14 +11,13 @@ module QUnited
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def run
|
14
|
-
driver_class = resolve_driver_class
|
14
|
+
driver_class, formatter_class = resolve_driver_class, resolve_formatter_class
|
15
15
|
driver = driver_class.new(js_source_files, js_test_files)
|
16
|
-
|
17
|
-
puts "\n# Running JavaScript tests with #{driver.name}:\n\n"
|
16
|
+
driver.formatter = formatter_class.new({:driver_name => driver.name})
|
18
17
|
|
19
18
|
results = driver.run
|
20
|
-
|
21
|
-
results.
|
19
|
+
|
20
|
+
results.all? { |r| r.passed? }
|
22
21
|
end
|
23
22
|
|
24
23
|
def resolve_driver_class
|
@@ -34,7 +33,6 @@ module QUnited
|
|
34
33
|
elsif !driver_class.available?
|
35
34
|
raise UsageError, "#{driver_class} driver specified, but not available"
|
36
35
|
end
|
37
|
-
driver_class
|
38
36
|
end
|
39
37
|
|
40
38
|
driver_class ||= best_available_driver
|
@@ -42,13 +40,32 @@ module QUnited
|
|
42
40
|
driver_class
|
43
41
|
end
|
44
42
|
|
43
|
+
def resolve_formatter_class
|
44
|
+
if options[:formatter]
|
45
|
+
begin
|
46
|
+
formatter_class = get_formatter(options[:formatter])
|
47
|
+
rescue NameError
|
48
|
+
raise UsageError, "#{options[:formatter].to_s} does not exist"
|
49
|
+
end
|
50
|
+
|
51
|
+
raise UsageError, "#{formatter_class} formatter not found" unless formatter_class
|
52
|
+
end
|
53
|
+
|
54
|
+
formatter_class || ::QUnited::Formatter::Dots
|
55
|
+
end
|
56
|
+
|
45
57
|
def get_driver(klass)
|
46
58
|
if ::QUnited::Driver.constants.reject { |d| d == :Base }.include?(klass.to_s)
|
47
59
|
::QUnited::Driver.const_get(klass.to_s)
|
48
60
|
end
|
49
61
|
end
|
50
62
|
|
51
|
-
|
63
|
+
def get_formatter(klass)
|
64
|
+
if ::QUnited::Formatter.constants.reject { |d| d == :Base }.include?(klass.to_s)
|
65
|
+
::QUnited::Formatter.const_get(klass.to_s)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
52
69
|
def best_available_driver
|
53
70
|
DRIVERS_PRIORITY.map { |driver| get_driver(driver) }.find { |driver| driver.available? }
|
54
71
|
end
|
data/lib/qunited/version.rb
CHANGED
data/lib/qunited.rb
CHANGED
@@ -3,7 +3,7 @@ module("Math");
|
|
3
3
|
test("Addition is hard", function() {
|
4
4
|
expect(2);
|
5
5
|
equal(1 + 1, 3, "This math is wrong");
|
6
|
-
equal(2 + 2,
|
6
|
+
equal(2 + 2, null, "This expected null");
|
7
7
|
});
|
8
8
|
|
9
9
|
test("This expects the wrong number of assertions", function() {
|