qunited 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +57 -0
- data/lib/qunited/driver/base.rb +56 -0
- data/lib/qunited/driver/phantomjs/phantomjs.rb +69 -0
- data/lib/qunited/driver/phantomjs/support/runner.js +103 -0
- data/lib/qunited/driver/phantomjs/support/tests_page.html.erb +28 -0
- data/lib/qunited/driver/rhino/rhino.rb +51 -0
- data/lib/qunited/{js_runner/rhino/js/qunit-runner.js → driver/rhino/support/runner.js} +12 -8
- data/lib/qunited/driver/support/qunited.js +76 -0
- data/lib/qunited/driver.rb +3 -0
- data/lib/qunited/results.rb +29 -0
- data/lib/qunited/runner.rb +9 -9
- data/lib/qunited/version.rb +1 -1
- data/lib/qunited.rb +2 -2
- data/test/unit/driver_common_tests.rb +70 -0
- data/test/unit/test_phantomjs_driver.rb +15 -0
- data/test/unit/{test_rhino_runner.rb → test_rhino_driver.rb} +10 -54
- metadata +22 -12
- data/lib/qunited/js_runner/base.rb +0 -34
- data/lib/qunited/js_runner/rhino.rb +0 -65
- data/lib/qunited/js_runner.rb +0 -2
- /data/lib/qunited/{js_runner/rhino/js → driver/rhino/support}/env.rhino.js +0 -0
- /data/lib/qunited/{js_runner/rhino/js → driver/rhino/support}/js.jar +0 -0
- /data/lib/qunited/{js_runner/rhino/js → driver/support}/qunit.js +0 -0
- /data/lib/qunited/{js_runner/rhino/js → driver/support}/yaml.js +0 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Aaron Royer
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# QUnited
|
2
|
+
|
3
|
+
QUnited is a tool to run headless JavaScript tests with QUnit.
|
4
|
+
|
5
|
+
Right now it exists in a proof-of-concept phase and only runs tests with Rhino/Envjs. Give it a try and let me know if you have any feedback.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
```
|
10
|
+
$ gem install qunited
|
11
|
+
```
|
12
|
+
|
13
|
+
## Running Tests
|
14
|
+
|
15
|
+
Add the QUnited Rake task to your Rakefile.
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
require 'qunited/rake_task'
|
19
|
+
|
20
|
+
QUnited::RakeTask.new do |t|
|
21
|
+
t.source_files_pattern = 'lib/js/**/*.js'
|
22
|
+
t.test_files_pattern = 'test/js/**/*.js'
|
23
|
+
end
|
24
|
+
```
|
25
|
+
|
26
|
+
Source and test files can also be configured as an array of file names. This may be desirable for source files since the order of their execution is often important. A glob pattern may not order the files correctly but configuring the task with an array can guarantee they are executed in the correct order.
|
27
|
+
|
28
|
+
Note that all JavaScript dependencies will have to be loaded with source files. They will often need to be loaded before your own code so using an array to configure source files may be appropriate.
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require 'qunited/rake_task'
|
32
|
+
|
33
|
+
QUnited::RakeTask.new do |t|
|
34
|
+
t.source_files = ['lib/js/jquery.js', 'lib/js/my_utils.js', 'lib/js/my_app.js']
|
35
|
+
t.test_files = ['test/js/test_my_utils.js', 'test/js/test_my_app.js']
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
Note that you can also use an array to configure the test files but a glob pattern is usually more convenient since test files usually do not need to be loaded in a particular order.
|
40
|
+
|
41
|
+
## Dependencies
|
42
|
+
|
43
|
+
Right now only Rhino is set up to run tests. This means you'll need to have Java (version 1.1 minimum) in your path to use QUnited.
|
44
|
+
|
45
|
+
## Attribution
|
46
|
+
|
47
|
+
QUnited builds on work done on the following projects:
|
48
|
+
|
49
|
+
[QUnit](https://github.com/jquery/qunit/) QUnit is a nice little JavaScript testing library and is, of course, central to what this project does.
|
50
|
+
|
51
|
+
[Rhino](http://www.mozilla.org/rhino/) Rhino is a JavaScript interpreter that runs on the JVM.
|
52
|
+
|
53
|
+
[Envjs](http://www.envjs.com/) Envjs is a simulated browser environment written in JavaScript.
|
54
|
+
|
55
|
+
## License
|
56
|
+
|
57
|
+
QUnited is MIT licensed
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module QUnited
|
2
|
+
module Driver
|
3
|
+
class Base
|
4
|
+
attr_reader :results, :source_files, :test_files
|
5
|
+
|
6
|
+
# Finds an executable on the PATH. Returns the absolute path of the
|
7
|
+
# executable if found, otherwise nil.
|
8
|
+
def self.which(cmd)
|
9
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
10
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
11
|
+
exts.each do |ext|
|
12
|
+
exe = "#{path}/#{cmd}#{ext}"
|
13
|
+
return exe if File.executable? exe
|
14
|
+
end
|
15
|
+
end
|
16
|
+
return nil
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get the path of the common (to all drivers) supporting files directory
|
20
|
+
def self.support_dir
|
21
|
+
@@support_dir = File.expand_path('../support', __FILE__)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Array of file names? Glob pattern?
|
25
|
+
def initialize(source_files, test_files)
|
26
|
+
@source_files = if source_files.is_a? String
|
27
|
+
Dir.glob(source_files)
|
28
|
+
elsif source_files.is_a? Array
|
29
|
+
source_files
|
30
|
+
end
|
31
|
+
|
32
|
+
@test_files = if test_files.is_a? String
|
33
|
+
Dir.glob(test_files)
|
34
|
+
elsif test_files.is_a? Array
|
35
|
+
test_files
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def run
|
40
|
+
raise 'run not implemented'
|
41
|
+
end
|
42
|
+
|
43
|
+
def support_file_path(filename)
|
44
|
+
File.join(self.class.support_dir, filename)
|
45
|
+
end
|
46
|
+
|
47
|
+
def support_file_contents(filename)
|
48
|
+
IO.read(support_file_path(filename))
|
49
|
+
end
|
50
|
+
|
51
|
+
def name
|
52
|
+
self.class.name.split('::')[-1]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'erb'
|
5
|
+
require 'open3'
|
6
|
+
|
7
|
+
module QUnited
|
8
|
+
module Driver
|
9
|
+
class PhantomJs < Base
|
10
|
+
|
11
|
+
# Determines whether this driver available to use.
|
12
|
+
# Checks whether phantomjs is on the PATH.
|
13
|
+
def self.available?
|
14
|
+
!!which('phantomjs')
|
15
|
+
end
|
16
|
+
|
17
|
+
def name
|
18
|
+
"PhantomJS" # Slightly more accurate than our class name
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
self.tests_file = Tempfile.new(['tests_page', '.html'])
|
23
|
+
tests_file.write(tests_page_content)
|
24
|
+
tests_file.close
|
25
|
+
|
26
|
+
results_file = Tempfile.new('qunited_results')
|
27
|
+
results_file.close
|
28
|
+
|
29
|
+
cmd = %{phantomjs "#{File.expand_path('../support/runner.js', __FILE__)}" }
|
30
|
+
cmd << %{#{tests_file.path} #{results_file.path}}
|
31
|
+
|
32
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr|
|
33
|
+
# PhantomJS sometimes puts error messages to stdout - redirect them to stderr
|
34
|
+
[stdout, stderr].each do |io|
|
35
|
+
unless (io_str = io.read).strip.empty? then $stderr.puts(io_str) end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
@results = ::QUnited::Results.from_javascript_produced_yaml(IO.read(results_file))
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_accessor :tests_file
|
45
|
+
|
46
|
+
def tests_page_content
|
47
|
+
ERB.new(IO.read(File.expand_path('../support/tests_page.html.erb', __FILE__))).result(binding)
|
48
|
+
end
|
49
|
+
|
50
|
+
def script_tag(file)
|
51
|
+
js_file_path, tests_file_path = Pathname.new(file).realpath, Pathname.new(tests_file)
|
52
|
+
begin
|
53
|
+
rel_path = js_file_path.relative_path_from(tests_file_path)
|
54
|
+
# Attempt to convert paths to relative URLs if Windows... should really test this
|
55
|
+
return %{<script type="text/javascript" src="#{rel_path.to_s.gsub(/\\/, '/')}"></script>}
|
56
|
+
rescue ArgumentError
|
57
|
+
# If we cannot get a relative path to the js file then just put the contents
|
58
|
+
# of the file inline. This can happen for a few reasons, like if the drive
|
59
|
+
# letter is different on Windows.
|
60
|
+
return <<-SCRIPT_ELEMENT
|
61
|
+
<script type="text/javascript">
|
62
|
+
#{IO.read(file)}
|
63
|
+
</script>
|
64
|
+
SCRIPT_ELEMENT
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
/*
|
2
|
+
Portions of this file are from the PhantomJS project from Ofi Labs.
|
3
|
+
|
4
|
+
Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
5
|
+
Copyright (C) 2011 Ivan De Marino <ivan.de.marino@gmail.com>
|
6
|
+
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
8
|
+
modification, are permitted provided that the following conditions are met:
|
9
|
+
|
10
|
+
* Redistributions of source code must retain the above copyright
|
11
|
+
notice, this list of conditions and the following disclaimer.
|
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.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
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
|
+
*/
|
30
|
+
|
31
|
+
var system = require('system'), fs = require("fs");
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Wait until the test condition is true or a timeout occurs. Useful for waiting
|
35
|
+
* on a server response or for a ui change (fadeIn, etc.) to occur.
|
36
|
+
*
|
37
|
+
* @param testFx javascript condition that evaluates to a boolean,
|
38
|
+
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
|
39
|
+
* as a callback function.
|
40
|
+
* @param onReady what to do when testFx condition is fulfilled,
|
41
|
+
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
|
42
|
+
* as a callback function.
|
43
|
+
* @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
|
44
|
+
*/
|
45
|
+
function waitFor(testFx, onReady, timeOutMillis) {
|
46
|
+
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3001, //< Default Max Timeout is 3s
|
47
|
+
start = new Date().getTime(),
|
48
|
+
condition = false,
|
49
|
+
interval = setInterval(function() {
|
50
|
+
if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
|
51
|
+
// If not time-out yet and condition not yet fulfilled
|
52
|
+
condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
|
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
|
+
|
68
|
+
|
69
|
+
if (system.args.length < 2) {
|
70
|
+
console.log('No tests file specified');
|
71
|
+
phantom.exit(1);
|
72
|
+
} else if (system.args.length < 3) {
|
73
|
+
console.log('No results output file specified');
|
74
|
+
phantom.exit(1);
|
75
|
+
}
|
76
|
+
|
77
|
+
var page = require('webpage').create(),
|
78
|
+
tests_html_file = system.args[1],
|
79
|
+
results_output_file = system.args[2];
|
80
|
+
|
81
|
+
page.open(tests_html_file, function(status) {
|
82
|
+
if (status !== "success") {
|
83
|
+
console.log("Could not open tests file");
|
84
|
+
phantom.exit(1);
|
85
|
+
} else {
|
86
|
+
waitFor(function(){
|
87
|
+
// Done when all tests have run (the results have been rendered)
|
88
|
+
return page.evaluate(function(){
|
89
|
+
var el = document.getElementById('qunit-testresult');
|
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.collectedTestResultsAsYaml(); });
|
99
|
+
fs.write(results_output_file, results, 'a');
|
100
|
+
phantom.exit(0);
|
101
|
+
});
|
102
|
+
}
|
103
|
+
});
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>QUnit Test Suite</title>
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<h1 id="qunit-header">QUnit Test Suite</h1>
|
8
|
+
<h2 id="qunit-banner"></h2>
|
9
|
+
<div id="qunit-testrunner-toolbar"></div>
|
10
|
+
<h2 id="qunit-userAgent"></h2>
|
11
|
+
<ol id="qunit-tests"></ol>
|
12
|
+
</body>
|
13
|
+
<%= script_tag support_file_path('qunit.js') %>
|
14
|
+
<%= script_tag support_file_path('yaml.js') %>
|
15
|
+
<%= script_tag support_file_path('qunited.js') %>
|
16
|
+
|
17
|
+
<script type="text/javascript" charset="utf-8">
|
18
|
+
QUnited.startCollectingTestResults();
|
19
|
+
</script>
|
20
|
+
|
21
|
+
<% source_files.each do |source_file| %>
|
22
|
+
<%= script_tag source_file %>
|
23
|
+
<% end %>
|
24
|
+
<% test_files.each do |test_file| %>
|
25
|
+
<%= script_tag test_file %>
|
26
|
+
<% end %>
|
27
|
+
|
28
|
+
</html>
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'open3'
|
4
|
+
|
5
|
+
module QUnited
|
6
|
+
module Driver
|
7
|
+
class Rhino < Base
|
8
|
+
|
9
|
+
# Determines whether this driver available to use. Checks whether java
|
10
|
+
# is on the PATH and whether Java is version 1.1 or greater.
|
11
|
+
def self.available?
|
12
|
+
java_exe = which('java')
|
13
|
+
if java_exe
|
14
|
+
stdin, stdout, stderr = Open3.popen3('java -version')
|
15
|
+
begin
|
16
|
+
version = Float(stderr.read.split("\n").first[/(\d+\.\d+)/, 1])
|
17
|
+
version >= 1.1
|
18
|
+
rescue
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
support_dir = File.expand_path('../support', __FILE__)
|
26
|
+
js_jar, runner = File.join(support_dir, 'js.jar'), File.join(support_dir, 'runner.js')
|
27
|
+
|
28
|
+
source_files_args = @source_files.map { |sf| %{"#{sf}"} }.join(' ')
|
29
|
+
test_files_args = @test_files.map { |tf| %{"#{tf}"} }.join(' ')
|
30
|
+
|
31
|
+
results_file = Tempfile.new('qunited_results')
|
32
|
+
results_file.close
|
33
|
+
|
34
|
+
cmd = %{java -jar "#{js_jar}" -opt -1 "#{runner}" }
|
35
|
+
cmd << %{"#{QUnited::Driver::Base.support_dir}" "#{support_dir}" "#{results_file.path}"}
|
36
|
+
cmd << " #{source_files_args} -- #{test_files_args}"
|
37
|
+
|
38
|
+
# Swallow stdout but allow stderr to get blasted out to console - if there are uncaught
|
39
|
+
# exceptions or anything else that goes wrong with the JavaScript interpreter the user
|
40
|
+
# will probably want to know but we are not particularly interested in it.
|
41
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr|
|
42
|
+
stdout.each {||} # Ignore; this is just here to make sure we block
|
43
|
+
# while waiting for tests to finish
|
44
|
+
unless (err = stderr.read).strip.empty? then $stderr.puts(err) end
|
45
|
+
end
|
46
|
+
|
47
|
+
@results = ::QUnited::Results.from_javascript_produced_yaml(IO.read(results_file))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,23 +1,27 @@
|
|
1
1
|
// Runs QUnit tests with Envjs and outputs test results as
|
2
2
|
// an array of data serialized in YAML format.
|
3
3
|
//
|
4
|
-
// The first argument should be the lib directory containing
|
5
|
-
// argument is the
|
6
|
-
//
|
4
|
+
// The first argument should be the lib directory containing common QUnited dependencies. The second
|
5
|
+
// argument is the directory containing Rhino driver specific dependencies. The third argument
|
6
|
+
// is the file to use for test results output. The next arguments are source JavaScript files to
|
7
|
+
// test, until "--" is encountered. After the "--" the rest of the arguments are QUnit
|
7
8
|
// test files.
|
8
9
|
//
|
9
10
|
// Example:
|
10
|
-
// java -jar js.jar -opt -1
|
11
|
+
// java -jar js.jar -opt -1 runner.js commonlibdir libdir outfile.yaml source.js -- test1.js test2.js
|
11
12
|
// ^ our args start here
|
12
13
|
|
13
14
|
var QUnited = { sourceFiles: [], testFiles: [] };
|
14
15
|
|
15
16
|
(function(args) {
|
16
|
-
var
|
17
|
+
var commonLibDir = args.shift(),
|
18
|
+
libDir = args.shift();
|
17
19
|
QUnited.outputFile = args.shift();
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
+
load(libDir + '/env.rhino.js');
|
22
|
+
|
23
|
+
['qunit.js', 'yaml.js'].forEach(function(lib) {
|
24
|
+
load(commonLibDir + '/' + lib);
|
21
25
|
});
|
22
26
|
|
23
27
|
var readingSource = true;
|
@@ -94,7 +98,7 @@ QUnited.testFiles.forEach(function(file) {
|
|
94
98
|
// stderr and keeps on going without letting the caller of load() know what happened!
|
95
99
|
//
|
96
100
|
// Another option is to slurp in the file, eval it, and try/catch the errors and handle them
|
97
|
-
// accordingly. But, I found that the slurp and eval approach introduced
|
101
|
+
// accordingly. But, I found that the slurp and eval approach introduced too many subtle
|
98
102
|
// misbehaviors to be worth it.
|
99
103
|
//
|
100
104
|
// The thing is, if a test file crashes and the tests aren't run then the build will succeed and
|
@@ -0,0 +1,76 @@
|
|
1
|
+
var QUnited = QUnited || {};
|
2
|
+
|
3
|
+
(function() {
|
4
|
+
|
5
|
+
QUnited.util = {};
|
6
|
+
QUnited.util.dateToString = function(date) {
|
7
|
+
if (Object.prototype.toString.call(date) === '[object String]') { return date; }
|
8
|
+
function pad(n) { return n < 10 ? '0' + n : n; }
|
9
|
+
return date.getUTCFullYear() + '-' + pad(date.getUTCMonth() + 1)+'-' + pad(date.getUTCDate()) + 'T' +
|
10
|
+
pad(date.getUTCHours()) + ':' + pad(date.getUTCMinutes()) + ':' + pad(date.getUTCSeconds()) + 'Z';
|
11
|
+
};
|
12
|
+
|
13
|
+
QUnited.startCollectingTestResults = function() {
|
14
|
+
// Various state we'll need while running the tests
|
15
|
+
QUnited.modulesMap = {};
|
16
|
+
QUnited.currentTestFile = null; // Set when loading files, see below
|
17
|
+
var currentModule, currentTest;
|
18
|
+
|
19
|
+
///// Listen for QUnit events during tests
|
20
|
+
|
21
|
+
QUnit.testStart(function(data) {
|
22
|
+
currentTest = {
|
23
|
+
name: data.name,
|
24
|
+
assertion_data: [], // Ruby-style, since we'll be reading it with Ruby
|
25
|
+
start: new Date(),
|
26
|
+
assertions: 0,
|
27
|
+
file: QUnited.currentTestFile
|
28
|
+
};
|
29
|
+
|
30
|
+
var moduleName = data.module || "(no module)",
|
31
|
+
module = QUnited.modulesMap[moduleName];
|
32
|
+
if (!module) {
|
33
|
+
module = {name: moduleName, tests: []};
|
34
|
+
QUnited.modulesMap[moduleName] = module;
|
35
|
+
}
|
36
|
+
module.tests.push(currentTest);
|
37
|
+
});
|
38
|
+
|
39
|
+
QUnit.testDone(function(data) {
|
40
|
+
currentTest.duration = ((new Date()).getTime() - currentTest.start.getTime()) / 1000;
|
41
|
+
currentTest.failed = data.failed;
|
42
|
+
currentTest.total = data.total;
|
43
|
+
});
|
44
|
+
|
45
|
+
/*
|
46
|
+
* Called on every assertion AND whenever we have an expect(num) fail. You cannot tell this
|
47
|
+
* apart from an assertion (even though you could make a good guess) with certainty so just
|
48
|
+
* don't worry about it as it will only throw assertions count off on a failing test.
|
49
|
+
*/
|
50
|
+
QUnit.log(function(data) {
|
51
|
+
currentTest.assertions++;
|
52
|
+
currentTest.assertion_data.push(data);
|
53
|
+
});
|
54
|
+
};
|
55
|
+
|
56
|
+
QUnited.collectedTestResultsAsYaml = function() {
|
57
|
+
var modules = [];
|
58
|
+
|
59
|
+
// Make a modules array for outputing results
|
60
|
+
Object.keys(QUnited.modulesMap).forEach(function(key) {
|
61
|
+
var mod = QUnited.modulesMap[key],
|
62
|
+
tests = mod.tests;
|
63
|
+
modules.push(mod);
|
64
|
+
tests.forEach(function(test) {
|
65
|
+
// YAML serializer doesn't seem to do dates; make them strings
|
66
|
+
test.start = QUnited.util.dateToString(test.start);
|
67
|
+
// Convert the duration to a string since the YAML serializer makes them all 0s otherwise
|
68
|
+
test.duration = "" + test.duration;
|
69
|
+
});
|
70
|
+
});
|
71
|
+
|
72
|
+
// Write all the results as YAML
|
73
|
+
return YAML.encode(modules);
|
74
|
+
};
|
75
|
+
|
76
|
+
})();
|
data/lib/qunited/results.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
1
3
|
module QUnited
|
2
4
|
|
3
5
|
# Simple tests results compiler. Takes a raw results hash that was produced by a runner.
|
@@ -79,6 +81,10 @@ module QUnited
|
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
84
|
+
def self.from_javascript_produced_yaml(yaml)
|
85
|
+
self.new clean_up_results(YAML.load(yaml))
|
86
|
+
end
|
87
|
+
|
82
88
|
def initialize(modules_results_array)
|
83
89
|
@data = modules_results_array.freeze
|
84
90
|
@module_results = @data.map { |module_data| ModuleResults.new module_data }
|
@@ -160,5 +166,28 @@ module QUnited
|
|
160
166
|
def errors
|
161
167
|
@errors ||= assertions.select { |assert| assert.error? }
|
162
168
|
end
|
169
|
+
|
170
|
+
# The YAML serializing JavaScript library does not put things into the cleanest form
|
171
|
+
# for us to work with. This turns the String keys into Symbols and converts Strings
|
172
|
+
# representing dates and numbers into their appropriate objects.
|
173
|
+
def self.clean_up_results(results)
|
174
|
+
results.map! { |mod_results| symbolize_keys mod_results }
|
175
|
+
results.each do |mod_results|
|
176
|
+
mod_results[:tests].map! { |test| clean_up_test_results(symbolize_keys(test)) }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def self.clean_up_test_results(test_results)
|
181
|
+
test_results[:start] = DateTime.parse(test_results[:start])
|
182
|
+
test_results[:duration] = Float(test_results[:duration])
|
183
|
+
test_results[:assertion_data].map! { |data| symbolize_keys data }
|
184
|
+
test_results
|
185
|
+
end
|
186
|
+
|
187
|
+
def self.symbolize_keys(hash)
|
188
|
+
new_hash = {}
|
189
|
+
hash.keys.each { |key| new_hash[key.to_sym] = hash[key] }
|
190
|
+
new_hash
|
191
|
+
end
|
163
192
|
end
|
164
193
|
end
|
data/lib/qunited/runner.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
module QUnited
|
2
2
|
class Runner
|
3
|
+
|
4
|
+
# The drivers in order of which to use first when not otherwise specified
|
5
|
+
DRIVERS = [:PhantomJs, :Rhino].map { |driver| ::QUnited::Driver.const_get(driver) }.freeze
|
6
|
+
|
3
7
|
def self.run(js_source_files, js_test_files)
|
4
|
-
|
5
|
-
|
6
|
-
runner = js_runner_klass.new(js_source_files, js_test_files)
|
8
|
+
driver_class = self.best_available_driver
|
9
|
+
runner = driver_class.new(js_source_files, js_test_files)
|
7
10
|
|
8
11
|
puts "\n# Running JavaScript tests with #{runner.name}:\n\n"
|
9
12
|
|
10
|
-
results = runner.run
|
13
|
+
results = runner.run
|
11
14
|
puts results
|
12
15
|
results.to_i
|
13
16
|
end
|
14
17
|
|
15
18
|
# Get the runner that we will be using to run the JavaScript tests.
|
16
|
-
|
17
|
-
|
18
|
-
# determine which one we will used unless explicitly configured.
|
19
|
-
def self.js_runner
|
20
|
-
::QUnited::JsRunner::Rhino
|
19
|
+
def self.best_available_driver
|
20
|
+
DRIVERS.find { |driver| driver.available? }
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
data/lib/qunited/version.rb
CHANGED
data/lib/qunited.rb
CHANGED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Common driver tests that should pass for any implementation of
|
2
|
+
# QUnited::Driver::Base. There are also a few utility methods included.
|
3
|
+
module QUnited::DriverCommonTests
|
4
|
+
def test_driver_available
|
5
|
+
assert driver_class.available?, 'Driver should be available - if it is not then ' +
|
6
|
+
'either the available? method has a bug or you do not have the proper environment ' +
|
7
|
+
"to run the driver; check the available? method in the #{driver_class} driver class " +
|
8
|
+
'to get an idea of whether you should be able to run the driver'
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_running_basic_tests
|
12
|
+
results = run_for_project('basic_project')
|
13
|
+
assert_equal 3, results.total_tests, 'Correct number of tests run'
|
14
|
+
assert_equal 4, results.total_assertions, 'Correct number of assertions executed'
|
15
|
+
assert_equal 0, results.total_failures, 'Correct number of failures given'
|
16
|
+
end
|
17
|
+
|
18
|
+
# Make sure we can run tests with DOM operations
|
19
|
+
def test_running_dom_tests
|
20
|
+
results = run_for_project('dom_project')
|
21
|
+
assert_equal 1, results.total_tests, 'Correct number of tests run'
|
22
|
+
assert_equal 2, results.total_assertions, 'Correct number of assertions executed'
|
23
|
+
assert_equal 0, results.total_failures, 'Correct number of failures given'
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_failures_are_recorded_correctly
|
27
|
+
results = run_for_project('failures_project')
|
28
|
+
assert_equal 4, results.total_tests, 'Correct number of tests run'
|
29
|
+
# QUnit calls the log callback (the same it calls for assertions) every time there
|
30
|
+
# is a failed expect(num). So add one to this total.
|
31
|
+
assert_equal 5 + 1, results.total_assertions, 'Correct number of assertions executed'
|
32
|
+
assert_equal 4, results.total_failures, 'Correct number of failures given'
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_syntax_error_in_test
|
36
|
+
runner = driver_class.new(
|
37
|
+
[File.join(FIXTURES_DIR, 'errors_project/app/assets/javascripts/no_error.js')],
|
38
|
+
[File.join(FIXTURES_DIR, 'errors_project/test/javascripts/this_test_has_syntax_error.js'),
|
39
|
+
File.join(FIXTURES_DIR, 'errors_project/test/javascripts/this_test_has_no_errors_in_it.js')])
|
40
|
+
|
41
|
+
stderr = capture_stderr { runner.run }
|
42
|
+
assert stderr.size > 10, 'Got some stderr output to describe the crash'
|
43
|
+
results = runner.results
|
44
|
+
assert runner.results.failed?, 'Should fail if syntax error in test'
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def driver_class
|
50
|
+
raise 'Must implement driver_class and return the driver class being tested'
|
51
|
+
end
|
52
|
+
|
53
|
+
def run_for_project(project_name)
|
54
|
+
runner = runner_for_project(project_name)
|
55
|
+
runner.run
|
56
|
+
end
|
57
|
+
|
58
|
+
def runner_for_project(project_name)
|
59
|
+
Dir.chdir File.join(FIXTURES_DIR, project_name)
|
60
|
+
driver_class.new("app/assets/javascripts/*.js", "test/javascripts/*.js")
|
61
|
+
end
|
62
|
+
|
63
|
+
def capture_stderr
|
64
|
+
previous_stderr, $stderr = $stderr, StringIO.new
|
65
|
+
yield
|
66
|
+
$stderr.string
|
67
|
+
ensure
|
68
|
+
$stderr = previous_stderr
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
require File.expand_path('../driver_common_tests', __FILE__)
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
# Test running tests with the PhantomJs driver.
|
6
|
+
class TestPhantomJsDriver < MiniTest::Unit::TestCase
|
7
|
+
include QUnited::DriverCommonTests
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def driver_class
|
12
|
+
QUnited::Driver::PhantomJs
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -1,36 +1,13 @@
|
|
1
1
|
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
require File.expand_path('../driver_common_tests', __FILE__)
|
2
3
|
require 'stringio'
|
3
4
|
|
4
|
-
# Test running tests with the Rhino
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def test_running_basic_tests
|
9
|
-
results = runner_for_project('basic_project').run.results
|
10
|
-
assert_equal 3, results.total_tests, 'Correct number of tests run'
|
11
|
-
assert_equal 4, results.total_assertions, 'Correct number of assertions executed'
|
12
|
-
assert_equal 0, results.total_failures, 'Correct number of failures given'
|
13
|
-
end
|
14
|
-
|
15
|
-
# Make sure we can run tests with DOM operations
|
16
|
-
def test_running_dom_tests
|
17
|
-
results = runner_for_project('dom_project').run.results
|
18
|
-
assert_equal 1, results.total_tests, 'Correct number of tests run'
|
19
|
-
assert_equal 2, results.total_assertions, 'Correct number of assertions executed'
|
20
|
-
assert_equal 0, results.total_failures, 'Correct number of failures given'
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_failures_are_recorded_correctly
|
24
|
-
results = runner_for_project('failures_project').run.results
|
25
|
-
assert_equal 4, results.total_tests, 'Correct number of tests run'
|
26
|
-
# QUnit calls the log callback (the same it calls for assertions) every time there
|
27
|
-
# is a failed expect(num). So add one to this total.
|
28
|
-
assert_equal 5 + 1, results.total_assertions, 'Correct number of assertions executed'
|
29
|
-
assert_equal 4, results.total_failures, 'Correct number of failures given'
|
30
|
-
end
|
5
|
+
# Test running tests with the Rhino driver.
|
6
|
+
class TestRhinoDriver < MiniTest::Unit::TestCase
|
7
|
+
include QUnited::DriverCommonTests
|
31
8
|
|
32
9
|
def test_undefined_error_in_source
|
33
|
-
runner = QUnited::
|
10
|
+
runner = QUnited::Driver::Rhino.new(
|
34
11
|
[File.join(FIXTURES_DIR, 'errors_project/app/assets/javascripts/undefined_error.js')],
|
35
12
|
[File.join(FIXTURES_DIR, 'errors_project/test/javascripts/this_test_has_no_errors_in_it.js')])
|
36
13
|
|
@@ -44,7 +21,7 @@ class TestRhinoRunner < MiniTest::Unit::TestCase
|
|
44
21
|
end
|
45
22
|
|
46
23
|
def test_syntax_error_in_source
|
47
|
-
runner = QUnited::
|
24
|
+
runner = QUnited::Driver::Rhino.new(
|
48
25
|
[File.join(FIXTURES_DIR, 'errors_project/app/assets/javascripts/syntax_error.js')],
|
49
26
|
[File.join(FIXTURES_DIR, 'errors_project/test/javascripts/this_test_has_no_errors_in_it.js')])
|
50
27
|
|
@@ -58,7 +35,7 @@ class TestRhinoRunner < MiniTest::Unit::TestCase
|
|
58
35
|
end
|
59
36
|
|
60
37
|
def test_undefined_error_in_test
|
61
|
-
runner = QUnited::
|
38
|
+
runner = QUnited::Driver::Rhino.new(
|
62
39
|
[File.join(FIXTURES_DIR, 'errors_project/app/assets/javascripts/no_error.js')],
|
63
40
|
[File.join(FIXTURES_DIR, 'errors_project/test/javascripts/this_test_has_undefined_error.js')])
|
64
41
|
|
@@ -74,20 +51,8 @@ class TestRhinoRunner < MiniTest::Unit::TestCase
|
|
74
51
|
assert_equal 1, results.total_errors, 'Correct number of errors given'
|
75
52
|
end
|
76
53
|
|
77
|
-
def test_syntax_error_in_test
|
78
|
-
runner = QUnited::JsRunner::Rhino.new(
|
79
|
-
[File.join(FIXTURES_DIR, 'errors_project/app/assets/javascripts/no_error.js')],
|
80
|
-
[File.join(FIXTURES_DIR, 'errors_project/test/javascripts/this_test_has_syntax_error.js'),
|
81
|
-
File.join(FIXTURES_DIR, 'errors_project/test/javascripts/this_test_has_no_errors_in_it.js')])
|
82
|
-
|
83
|
-
stderr = capture_stderr { runner.run }
|
84
|
-
assert stderr.size > 10, 'Got some stderr output to describe the crash'
|
85
|
-
results = runner.results
|
86
|
-
assert runner.results.failed?, 'Should fail if syntax error in test'
|
87
|
-
end
|
88
|
-
|
89
54
|
def test_no_tests_in_test_file_means_failure
|
90
|
-
runner = QUnited::
|
55
|
+
runner = QUnited::Driver::Rhino.new(
|
91
56
|
[File.join(FIXTURES_DIR, 'errors_project/app/assets/javascripts/no_error.js')],
|
92
57
|
[File.join(FIXTURES_DIR, 'errors_project/test/javascripts/this_test_has_no_tests.js')])
|
93
58
|
runner.run
|
@@ -98,17 +63,8 @@ class TestRhinoRunner < MiniTest::Unit::TestCase
|
|
98
63
|
|
99
64
|
private
|
100
65
|
|
101
|
-
def
|
102
|
-
|
103
|
-
QUnited::JsRunner::Rhino.new("app/assets/javascripts/*.js", "test/javascripts/*.js")
|
104
|
-
end
|
105
|
-
|
106
|
-
def capture_stderr
|
107
|
-
previous_stderr, $stderr = $stderr, StringIO.new
|
108
|
-
yield
|
109
|
-
$stderr.string
|
110
|
-
ensure
|
111
|
-
$stderr = previous_stderr
|
66
|
+
def driver_class
|
67
|
+
QUnited::Driver::Rhino
|
112
68
|
end
|
113
69
|
|
114
70
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qunited
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06
|
12
|
+
date: 2012-07-06 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: QUnited runs headless QUnit tests as part of your normal build
|
15
15
|
email:
|
@@ -21,17 +21,23 @@ extra_rdoc_files: []
|
|
21
21
|
files:
|
22
22
|
- .gitignore
|
23
23
|
- Gemfile
|
24
|
+
- MIT-LICENSE
|
25
|
+
- README.md
|
24
26
|
- Rakefile
|
25
27
|
- bin/qunited
|
26
28
|
- lib/qunited.rb
|
27
|
-
- lib/qunited/
|
28
|
-
- lib/qunited/
|
29
|
-
- lib/qunited/
|
30
|
-
- lib/qunited/
|
31
|
-
- lib/qunited/
|
32
|
-
- lib/qunited/
|
33
|
-
- lib/qunited/
|
34
|
-
- lib/qunited/
|
29
|
+
- lib/qunited/driver.rb
|
30
|
+
- lib/qunited/driver/base.rb
|
31
|
+
- lib/qunited/driver/phantomjs/phantomjs.rb
|
32
|
+
- lib/qunited/driver/phantomjs/support/runner.js
|
33
|
+
- lib/qunited/driver/phantomjs/support/tests_page.html.erb
|
34
|
+
- lib/qunited/driver/rhino/rhino.rb
|
35
|
+
- lib/qunited/driver/rhino/support/env.rhino.js
|
36
|
+
- lib/qunited/driver/rhino/support/js.jar
|
37
|
+
- lib/qunited/driver/rhino/support/runner.js
|
38
|
+
- lib/qunited/driver/support/qunit.js
|
39
|
+
- lib/qunited/driver/support/qunited.js
|
40
|
+
- lib/qunited/driver/support/yaml.js
|
35
41
|
- lib/qunited/rake_task.rb
|
36
42
|
- lib/qunited/results.rb
|
37
43
|
- lib/qunited/runner.rb
|
@@ -53,8 +59,10 @@ files:
|
|
53
59
|
- test/fixtures/failures_project/test/javascripts/test_basics.js
|
54
60
|
- test/fixtures/failures_project/test/javascripts/test_math.js
|
55
61
|
- test/test_helper.rb
|
62
|
+
- test/unit/driver_common_tests.rb
|
63
|
+
- test/unit/test_phantomjs_driver.rb
|
56
64
|
- test/unit/test_results.rb
|
57
|
-
- test/unit/
|
65
|
+
- test/unit/test_rhino_driver.rb
|
58
66
|
homepage: https://github.com/aaronroyer/qunited
|
59
67
|
licenses: []
|
60
68
|
post_install_message:
|
@@ -96,5 +104,7 @@ test_files:
|
|
96
104
|
- test/fixtures/failures_project/test/javascripts/test_basics.js
|
97
105
|
- test/fixtures/failures_project/test/javascripts/test_math.js
|
98
106
|
- test/test_helper.rb
|
107
|
+
- test/unit/driver_common_tests.rb
|
108
|
+
- test/unit/test_phantomjs_driver.rb
|
99
109
|
- test/unit/test_results.rb
|
100
|
-
- test/unit/
|
110
|
+
- test/unit/test_rhino_driver.rb
|
@@ -1,34 +0,0 @@
|
|
1
|
-
module QUnited
|
2
|
-
module JsRunner
|
3
|
-
class Base
|
4
|
-
attr_reader :results
|
5
|
-
|
6
|
-
# Array of file names? Glob pattern?
|
7
|
-
def initialize(source_files, test_files)
|
8
|
-
@source_files = if source_files.is_a? String
|
9
|
-
Dir.glob(source_files)
|
10
|
-
elsif source_files.is_a? Array
|
11
|
-
source_files
|
12
|
-
end
|
13
|
-
|
14
|
-
@test_files = if test_files.is_a? String
|
15
|
-
Dir.glob(test_files)
|
16
|
-
elsif test_files.is_a? Array
|
17
|
-
test_files
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def can_run?
|
22
|
-
false
|
23
|
-
end
|
24
|
-
|
25
|
-
def name
|
26
|
-
self.class.name.split('::')[-1]
|
27
|
-
end
|
28
|
-
|
29
|
-
def run
|
30
|
-
raise 'run not implemented'
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'tempfile'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'yaml'
|
4
|
-
require 'open3'
|
5
|
-
|
6
|
-
module QUnited
|
7
|
-
module JsRunner
|
8
|
-
class Rhino < Base
|
9
|
-
def can_run?
|
10
|
-
# TODO: test that you have Java
|
11
|
-
end
|
12
|
-
|
13
|
-
def run
|
14
|
-
js_dir = File.expand_path('../rhino/js', __FILE__)
|
15
|
-
|
16
|
-
js_jar, runner = File.join(js_dir, 'js.jar'), File.join(js_dir, 'qunit-runner.js')
|
17
|
-
|
18
|
-
source_files_args = @source_files.map { |sf| %{"#{sf}"} }.join(' ')
|
19
|
-
test_files_args = @test_files.map { |tf| %{"#{tf}"} }.join(' ')
|
20
|
-
|
21
|
-
tmp_file = Tempfile.new('qunited_results')
|
22
|
-
tmp_file.close
|
23
|
-
|
24
|
-
cmd = %{java -jar "#{js_jar}" -opt -1 "#{runner}" "#{js_dir}" "#{tmp_file.path}"}
|
25
|
-
cmd << " #{source_files_args} -- #{test_files_args}"
|
26
|
-
|
27
|
-
# Swallow stdout but allow stderr to get blasted out to console - if there are uncaught
|
28
|
-
# exceptions or anything else that goes wrong with the JavaScript interpreter the user
|
29
|
-
# will probably want to know but we are not particularly interested in it.
|
30
|
-
Open3.popen3(cmd) do |stdin, stdout, stderr|
|
31
|
-
stdout.each {||} # Ignore; this is just here to make sure we block
|
32
|
-
# while waiting for tests to finish
|
33
|
-
unless (err = stderr.read).strip.empty? then $stderr.puts(err) end
|
34
|
-
end
|
35
|
-
|
36
|
-
@raw_results = clean_up_results(YAML.load(IO.read(tmp_file)))
|
37
|
-
|
38
|
-
@results = ::QUnited::Results.new @raw_results
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def clean_up_results(results)
|
45
|
-
results.map! { |mod_results| symbolize_keys mod_results }
|
46
|
-
results.each do |mod_results|
|
47
|
-
mod_results[:tests].map! { |test| clean_up_test_results(symbolize_keys(test)) }
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def clean_up_test_results(test_results)
|
52
|
-
test_results[:start] = DateTime.parse(test_results[:start])
|
53
|
-
test_results[:duration] = Float(test_results[:duration])
|
54
|
-
test_results[:assertion_data].map! { |data| symbolize_keys data }
|
55
|
-
test_results
|
56
|
-
end
|
57
|
-
|
58
|
-
def symbolize_keys(hash)
|
59
|
-
new_hash = {}
|
60
|
-
hash.keys.each { |key| new_hash[key.to_sym] = hash[key] }
|
61
|
-
new_hash
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
data/lib/qunited/js_runner.rb
DELETED
File without changes
|
File without changes
|
File without changes
|
File without changes
|