jasmine-headless-webkit 0.2.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Guardfile +1 -1
- data/bin/jasmine-headless-webkit +5 -98
- data/ext/jasmine-webkit-specrunner/specrunner.cpp +39 -16
- data/jasmine/jasmine.headless-reporter.coffee +3 -3
- data/jasmine/jasmine.headless-reporter.js +4 -5
- data/lib/jasmine/files_list.rb +122 -0
- data/lib/jasmine/headless/cli.rb +17 -0
- data/lib/jasmine/headless/errors.rb +7 -0
- data/lib/jasmine/headless/options.rb +76 -0
- data/lib/jasmine/headless/railtie.rb +29 -0
- data/lib/jasmine/headless/runner.rb +75 -0
- data/lib/jasmine/headless/task.rb +9 -1
- data/lib/jasmine/template_writer.rb +50 -0
- data/lib/jasmine-headless-webkit/version.rb +1 -1
- data/spec/bin/jasmine-headless-webkit_spec.rb +40 -20
- data/spec/jasmine/coffeescript_error/coffeescript_error.yml +10 -0
- data/spec/jasmine/coffeescript_error/spec.coffee +2 -0
- data/spec/jasmine/coffeescript_error/src.coffee +2 -0
- data/spec/jasmine/filtered_failure/failure_spec.js +6 -0
- data/spec/jasmine/filtered_failure/filtered_failure.yml +10 -0
- data/spec/jasmine/filtered_failure/src.js +0 -0
- data/spec/jasmine/filtered_failure/success_spec.js +6 -0
- data/spec/jasmine/filtered_success/filtered_success.yml +10 -0
- data/spec/jasmine/filtered_success/src.js +0 -0
- data/spec/jasmine/filtered_success/success_one_spec.js +6 -0
- data/spec/jasmine/filtered_success/success_two_spec.js +6 -0
- data/spec/lib/jasmine/files_list_spec.rb +198 -0
- data/spec/lib/jasmine/headless/cli_spec.rb +1 -0
- data/spec/lib/jasmine/headless/options_spec.rb +69 -0
- data/spec/lib/jasmine/headless/runner_spec.rb +72 -0
- data/spec/lib/jasmine/template_writer_spec.rb +37 -0
- data/spec/spec_helper.rb +15 -0
- metadata +42 -7
- data/lib/jasmine/cli.rb +0 -78
- data/spec/lib/jasmine/cli_spec.rb +0 -89
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -9,7 +9,7 @@ end
|
|
9
9
|
# A sample Guardfile
|
10
10
|
# More info at https://github.com/guard/guard#readme
|
11
11
|
|
12
|
-
guard 'rspec', :version => 2 do
|
12
|
+
guard 'rspec', :version => 2, :all_on_start => false do
|
13
13
|
watch(%r{^spec/.+_spec\.rb})
|
14
14
|
watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
15
15
|
watch(%r{^bin/(.+)}) { |m| "spec/bin/#{m[1]}_spec.rb" }
|
data/bin/jasmine-headless-webkit
CHANGED
@@ -8,105 +8,12 @@ end
|
|
8
8
|
|
9
9
|
$:.unshift(File.join(gem_dir, 'lib'))
|
10
10
|
|
11
|
-
require 'yaml'
|
12
|
-
require 'fileutils'
|
13
|
-
require 'getoptlong'
|
14
|
-
|
15
|
-
require 'jasmine/base'
|
16
|
-
require 'coffee-script'
|
17
|
-
require 'rainbow'
|
18
|
-
|
19
|
-
require 'jasmine/cli'
|
20
|
-
include Jasmine::CLI
|
21
|
-
|
22
|
-
if !File.file?(File.join(gem_dir, RUNNER))
|
23
|
-
puts "The Qt WebKit widget is not compiled! Try re-installing this gem."
|
24
|
-
exit 1
|
25
|
-
end
|
26
|
-
|
27
|
-
opts = GetoptLong.new(
|
28
|
-
[ '--colors', '-c', GetoptLong::NO_ARGUMENT ],
|
29
|
-
[ '--no-colors', GetoptLong::NO_ARGUMENT ],
|
30
|
-
[ '--keep', GetoptLong::NO_ARGUMENT ],
|
31
|
-
[ '--report', GetoptLong::REQUIRED_ARGUMENT ],
|
32
|
-
[ '--jasmine-config', '-j', GetoptLong::REQUIRED_ARGUMENT ]
|
33
|
-
)
|
34
|
-
|
35
|
-
options = {
|
36
|
-
:colors => false,
|
37
|
-
:remove_html_file => true,
|
38
|
-
:jasmine_config => 'spec/javascripts/support/jasmine.yml',
|
39
|
-
:report => false
|
40
|
-
}
|
41
|
-
|
42
|
-
@process_options = lambda { |*args|
|
43
|
-
opt, arg = args.flatten[0..1]
|
44
|
-
|
45
|
-
case opt
|
46
|
-
when '--colors', '-c'
|
47
|
-
options[:colors] = true
|
48
|
-
when '--no-colors', '-nc'
|
49
|
-
options[:colors] = false
|
50
|
-
when '--keep'
|
51
|
-
options[:remove_html_file] = false
|
52
|
-
when '--report'
|
53
|
-
options[:report] = arg
|
54
|
-
when '--jasmine-config', '-j'
|
55
|
-
options[:jasmine_config] = arg
|
56
|
-
end
|
57
|
-
}
|
58
|
-
|
59
|
-
read_defaults_files!
|
60
|
-
opts.each(&@process_options)
|
61
|
-
@spec_filter = ARGV.dup
|
62
|
-
|
63
|
-
data = YAML.load_file(options[:jasmine_config])
|
64
|
-
|
65
11
|
puts "Running Jasmine specs..."
|
66
12
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
data[root] ||= DEFAULTS[root]
|
73
|
-
|
74
|
-
data[searches].collect do |search|
|
75
|
-
path = search
|
76
|
-
path = File.join(data[root], path) if data[root]
|
77
|
-
found_files = Dir[path]
|
78
|
-
if searches == 'spec_files'
|
79
|
-
found_files = found_files.find_all { |file| use_spec?(file) }
|
80
|
-
end
|
81
|
-
files += found_files
|
82
|
-
end
|
83
|
-
end
|
13
|
+
require 'jasmine/headless/cli'
|
14
|
+
begin
|
15
|
+
exit Jasmine::Headless::CLI.run
|
16
|
+
rescue StandardError => e
|
17
|
+
exit 1
|
84
18
|
end
|
85
19
|
|
86
|
-
files = files.collect { |file|
|
87
|
-
case File.extname(file)
|
88
|
-
when '.js'
|
89
|
-
%{<script type="text/javascript" src="#{file}"></script>}
|
90
|
-
when '.coffee'
|
91
|
-
begin
|
92
|
-
%{<script type="text/javascript">#{CoffeeScript.compile(fh = File.open(file))}</script>}
|
93
|
-
rescue CoffeeScript::CompilationError => e
|
94
|
-
puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), file.color(:yellow), e.message.to_s.color(:white) ]
|
95
|
-
exit 1
|
96
|
-
ensure
|
97
|
-
fh.close
|
98
|
-
end
|
99
|
-
when '.css'
|
100
|
-
%{<link rel="stylesheet" href="#{file}" type="text/css" />}
|
101
|
-
end
|
102
|
-
}
|
103
|
-
|
104
|
-
output = jasmine_html_template(files)
|
105
|
-
|
106
|
-
File.open(target = "specrunner.#{$$}.html", 'w') { |fh| fh.print output }
|
107
|
-
system jasmine_command(options, target)
|
108
|
-
status = $?.exitstatus
|
109
|
-
FileUtils.rm_f target if options[:remove_html_file] || (status == 0)
|
110
|
-
|
111
|
-
exit status
|
112
|
-
|
@@ -26,6 +26,7 @@
|
|
26
26
|
#include <QFile>
|
27
27
|
#include <QTextStream>
|
28
28
|
#include <iostream>
|
29
|
+
#include <QQueue>
|
29
30
|
|
30
31
|
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
|
31
32
|
#error Use Qt 4.7 or later version
|
@@ -64,9 +65,10 @@ class HeadlessSpecRunner: public QObject
|
|
64
65
|
Q_OBJECT
|
65
66
|
public:
|
66
67
|
HeadlessSpecRunner();
|
67
|
-
void load(const QString &spec);
|
68
68
|
void setColors(bool colors);
|
69
69
|
void reportFile(const QString &file);
|
70
|
+
void addFile(const QString &spec);
|
71
|
+
void go();
|
70
72
|
public slots:
|
71
73
|
void log(const QString &msg);
|
72
74
|
void specPassed();
|
@@ -78,6 +80,7 @@ private slots:
|
|
78
80
|
void watch(bool ok);
|
79
81
|
void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
|
80
82
|
void internalLog(const QString ¬e, const QString &msg);
|
83
|
+
void addJHW();
|
81
84
|
protected:
|
82
85
|
bool hasElement(const char *select);
|
83
86
|
void timerEvent(QTimerEvent *event);
|
@@ -91,12 +94,14 @@ private:
|
|
91
94
|
bool isFinished;
|
92
95
|
bool didFail;
|
93
96
|
bool consoleNotUsedThisRun;
|
97
|
+
QQueue<QString> runnerFiles;
|
94
98
|
QString reportFilename;
|
95
99
|
|
96
100
|
void red();
|
97
101
|
void green();
|
98
102
|
void yellow();
|
99
103
|
void clear();
|
104
|
+
void loadSpec();
|
100
105
|
};
|
101
106
|
|
102
107
|
HeadlessSpecRunner::HeadlessSpecRunner()
|
@@ -113,14 +118,30 @@ HeadlessSpecRunner::HeadlessSpecRunner()
|
|
113
118
|
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
|
114
119
|
connect(&m_page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(errorLog(QString, int, QString)));
|
115
120
|
connect(&m_page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
|
121
|
+
connect(m_page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW()));
|
116
122
|
}
|
117
123
|
|
118
|
-
void HeadlessSpecRunner::
|
124
|
+
void HeadlessSpecRunner::addFile(const QString &spec)
|
125
|
+
{
|
126
|
+
runnerFiles.enqueue(spec);
|
127
|
+
}
|
128
|
+
|
129
|
+
void HeadlessSpecRunner::go()
|
119
130
|
{
|
120
131
|
m_ticker.stop();
|
121
|
-
m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
|
122
|
-
m_page.mainFrame()->load(spec);
|
123
132
|
m_page.setPreferredContentsSize(QSize(1024, 600));
|
133
|
+
addJHW();
|
134
|
+
loadSpec();
|
135
|
+
}
|
136
|
+
void HeadlessSpecRunner::addJHW()
|
137
|
+
{
|
138
|
+
m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
|
139
|
+
}
|
140
|
+
|
141
|
+
void HeadlessSpecRunner::loadSpec()
|
142
|
+
{
|
143
|
+
m_page.mainFrame()->load(runnerFiles.dequeue());
|
144
|
+
m_ticker.start(200, this);
|
124
145
|
}
|
125
146
|
|
126
147
|
void HeadlessSpecRunner::watch(bool ok)
|
@@ -298,7 +319,12 @@ void HeadlessSpecRunner::timerEvent(QTimerEvent *event)
|
|
298
319
|
}
|
299
320
|
}
|
300
321
|
|
301
|
-
|
322
|
+
if ((exitCode == 0 && runnerFiles.count() == 0) || (exitCode != 0)) {
|
323
|
+
QApplication::instance()->exit(exitCode);
|
324
|
+
} else {
|
325
|
+
isFinished = false;
|
326
|
+
loadSpec();
|
327
|
+
}
|
302
328
|
}
|
303
329
|
|
304
330
|
if (m_runs > 30) {
|
@@ -311,7 +337,6 @@ void HeadlessSpecRunner::timerEvent(QTimerEvent *event)
|
|
311
337
|
|
312
338
|
int main(int argc, char** argv)
|
313
339
|
{
|
314
|
-
char *filename = NULL;
|
315
340
|
char *reporter = NULL;
|
316
341
|
char showColors = false;
|
317
342
|
|
@@ -328,16 +353,9 @@ int main(int argc, char** argv)
|
|
328
353
|
}
|
329
354
|
}
|
330
355
|
|
331
|
-
|
332
|
-
|
333
|
-
for (index = optind; index < argc; index++) {
|
334
|
-
filename = argv[index];
|
335
|
-
filenameFound = true;
|
336
|
-
}
|
337
|
-
|
338
|
-
if (!filenameFound) {
|
356
|
+
if (optind == argc) {
|
339
357
|
std::cerr << "Run Jasmine's SpecRunner headlessly" << std::endl << std::endl;
|
340
|
-
std::cerr << " specrunner [-c]
|
358
|
+
std::cerr << " specrunner [-c] [-r <report file>] specrunner.html ..." << std::endl;
|
341
359
|
return 1;
|
342
360
|
}
|
343
361
|
|
@@ -345,7 +363,12 @@ int main(int argc, char** argv)
|
|
345
363
|
HeadlessSpecRunner runner;
|
346
364
|
runner.setColors(true);
|
347
365
|
runner.reportFile(reporter);
|
348
|
-
|
366
|
+
|
367
|
+
for (index = optind; index < argc; index++) {
|
368
|
+
runner.addFile(QString::fromLocal8Bit(argv[index]));
|
369
|
+
}
|
370
|
+
runner.go();
|
371
|
+
|
349
372
|
return app.exec();
|
350
373
|
}
|
351
374
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
if !jasmine?
|
2
|
-
throw new
|
2
|
+
throw new Error("jasmine not laoded!")
|
3
3
|
|
4
4
|
class HeadlessReporterResult
|
5
5
|
constructor: (name) ->
|
@@ -28,17 +28,17 @@ class jasmine.HeadlessReporter
|
|
28
28
|
@startTime = new Date()
|
29
29
|
reportSpecResults: (spec) ->
|
30
30
|
results = spec.results()
|
31
|
+
@length++
|
31
32
|
if results.passed()
|
32
33
|
JHW.specPassed()
|
33
34
|
else
|
34
35
|
JHW.specFailed()
|
36
|
+
@failedCount++
|
35
37
|
failureResult = new HeadlessReporterResult(spec.getFullName())
|
36
38
|
for result in results.getItems()
|
37
39
|
do (result) =>
|
38
40
|
if result.type == 'expect' and !result.passed_
|
39
|
-
@failedCount += 1
|
40
41
|
failureResult.addResult(result.message)
|
41
42
|
@results.push(failureResult)
|
42
43
|
reportSpecStarting: (spec) ->
|
43
44
|
reportSuiteResults: (suite) ->
|
44
|
-
@length += suite.specs().length
|
@@ -2,7 +2,7 @@
|
|
2
2
|
var HeadlessReporterResult;
|
3
3
|
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
4
4
|
if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
|
5
|
-
throw new
|
5
|
+
throw new Error("jasmine not laoded!");
|
6
6
|
}
|
7
7
|
HeadlessReporterResult = (function() {
|
8
8
|
function HeadlessReporterResult(name) {
|
@@ -51,15 +51,16 @@
|
|
51
51
|
HeadlessReporter.prototype.reportSpecResults = function(spec) {
|
52
52
|
var failureResult, result, results, _fn, _i, _len, _ref;
|
53
53
|
results = spec.results();
|
54
|
+
this.length++;
|
54
55
|
if (results.passed()) {
|
55
56
|
return JHW.specPassed();
|
56
57
|
} else {
|
57
58
|
JHW.specFailed();
|
59
|
+
this.failedCount++;
|
58
60
|
failureResult = new HeadlessReporterResult(spec.getFullName());
|
59
61
|
_ref = results.getItems();
|
60
62
|
_fn = __bind(function(result) {
|
61
63
|
if (result.type === 'expect' && !result.passed_) {
|
62
|
-
this.failedCount += 1;
|
63
64
|
return failureResult.addResult(result.message);
|
64
65
|
}
|
65
66
|
}, this);
|
@@ -71,9 +72,7 @@
|
|
71
72
|
}
|
72
73
|
};
|
73
74
|
HeadlessReporter.prototype.reportSpecStarting = function(spec) {};
|
74
|
-
HeadlessReporter.prototype.reportSuiteResults = function(suite) {
|
75
|
-
return this.length += suite.specs().length;
|
76
|
-
};
|
75
|
+
HeadlessReporter.prototype.reportSuiteResults = function(suite) {};
|
77
76
|
return HeadlessReporter;
|
78
77
|
})();
|
79
78
|
}).call(this);
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'jasmine'
|
2
|
+
|
3
|
+
module Jasmine
|
4
|
+
class FilesList
|
5
|
+
attr_reader :files, :filtered_files
|
6
|
+
|
7
|
+
DEFAULT_FILES = [
|
8
|
+
File.join(Jasmine.root, "lib/jasmine.js"),
|
9
|
+
File.join(Jasmine.root, "lib/jasmine-html.js"),
|
10
|
+
File.expand_path('../../../jasmine/jasmine.headless-reporter.js', __FILE__)
|
11
|
+
]
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@options = options
|
15
|
+
@files = DEFAULT_FILES.dup
|
16
|
+
@filtered_files = @files.dup
|
17
|
+
use_config! if config?
|
18
|
+
|
19
|
+
@code_for_file = {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def use_spec?(file)
|
23
|
+
spec_filter.empty? || spec_filter.include?(file)
|
24
|
+
end
|
25
|
+
|
26
|
+
def filtered?
|
27
|
+
files != filtered_files
|
28
|
+
end
|
29
|
+
|
30
|
+
def files_to_html
|
31
|
+
to_html(files)
|
32
|
+
end
|
33
|
+
|
34
|
+
def filtered_files_to_html
|
35
|
+
to_html(filtered_files)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def to_html(files)
|
40
|
+
coffeescript_run = []
|
41
|
+
|
42
|
+
files.collect { |file|
|
43
|
+
next @code_for_file[file] if @code_for_file[file]
|
44
|
+
|
45
|
+
coffeescript_run << file if (ext = File.extname(file)) == '.coffee'
|
46
|
+
|
47
|
+
output = []
|
48
|
+
if (files.last == file or ext != '.coffee') and !coffeescript_run.empty?
|
49
|
+
output << ensure_coffeescript_run!(coffeescript_run)
|
50
|
+
end
|
51
|
+
|
52
|
+
if ext != '.coffee'
|
53
|
+
output << case File.extname(file)
|
54
|
+
when '.js'
|
55
|
+
%{<script type="text/javascript" src="#{file}"></script>}
|
56
|
+
when '.css'
|
57
|
+
%{<link rel="stylesheet" href="#{file}" type="text/css" />}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
@code_for_file[file] = output if output.length == 1
|
62
|
+
|
63
|
+
output
|
64
|
+
}.flatten.reject(&:empty?)
|
65
|
+
end
|
66
|
+
|
67
|
+
def ensure_coffeescript_run!(files)
|
68
|
+
data = StringIO.new
|
69
|
+
files.each { |file| data << File.read(file) }
|
70
|
+
data.rewind
|
71
|
+
|
72
|
+
%{<script type="text/javascript">#{CoffeeScript.compile(data)}</script>}
|
73
|
+
rescue CoffeeScript::CompilationError => e
|
74
|
+
files.each do |file|
|
75
|
+
begin
|
76
|
+
CoffeeScript.compile(fh = File.open(file))
|
77
|
+
rescue CoffeeScript::CompilationError => ne
|
78
|
+
puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), file.color(:yellow), ne.message.to_s.color(:white) ]
|
79
|
+
raise ne
|
80
|
+
ensure
|
81
|
+
fh.close
|
82
|
+
end
|
83
|
+
end
|
84
|
+
rescue StandardError => e
|
85
|
+
puts "[%s] Error in compiling one of the followng: %s" % [ 'coffeescript'.color(:red), files.join(' ').color(:yellow) ]
|
86
|
+
raise e
|
87
|
+
ensure
|
88
|
+
files.clear
|
89
|
+
end
|
90
|
+
|
91
|
+
def spec_filter
|
92
|
+
@options[:only] || []
|
93
|
+
end
|
94
|
+
|
95
|
+
def use_config!
|
96
|
+
@filtered_files = @files.dup
|
97
|
+
|
98
|
+
data = @options[:config].dup
|
99
|
+
[ [ 'src_files', 'src_dir' ], [ 'stylesheets', 'src_dir' ], [ 'helpers', 'spec_dir' ], [ 'spec_files', 'spec_dir' ] ].each do |searches, root|
|
100
|
+
if data[searches]
|
101
|
+
data[searches].collect do |search|
|
102
|
+
path = search
|
103
|
+
path = File.join(data[root], path) if data[root]
|
104
|
+
found_files = Dir[path] - @files
|
105
|
+
|
106
|
+
@files += found_files
|
107
|
+
|
108
|
+
if searches == 'spec_files'
|
109
|
+
found_files = found_files.find_all { |file| use_spec?(file) }
|
110
|
+
end
|
111
|
+
@filtered_files += found_files
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def config?
|
118
|
+
@options[:config]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'jasmine/headless/runner'
|
2
|
+
require 'jasmine/headless/options'
|
3
|
+
require 'getoptlong'
|
4
|
+
|
5
|
+
module Jasmine
|
6
|
+
module Headless
|
7
|
+
class CLI
|
8
|
+
def self.run
|
9
|
+
Runner.run(Options.from_command_line)
|
10
|
+
rescue NoRunnerError
|
11
|
+
puts "The Qt WebKit widget is not compiled! Try re-installing this gem."
|
12
|
+
1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Jasmine
|
4
|
+
module Headless
|
5
|
+
class Options
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
def_delegators :@options, :[], :[]=
|
9
|
+
|
10
|
+
DEFAULT_OPTIONS = {
|
11
|
+
:colors => false,
|
12
|
+
:remove_html_file => true,
|
13
|
+
:jasmine_config => 'spec/javascripts/support/jasmine.yml',
|
14
|
+
:report => false,
|
15
|
+
:full_run => true,
|
16
|
+
:files => []
|
17
|
+
}
|
18
|
+
|
19
|
+
DEFAULTS_FILE = '.jasmine-headless-webkit'
|
20
|
+
GLOBAL_DEFAULTS_FILE = File.expand_path("~/#{DEFAULTS_FILE}")
|
21
|
+
|
22
|
+
def self.from_command_line
|
23
|
+
options = new
|
24
|
+
options.process_command_line_args
|
25
|
+
options[:files] = ARGV
|
26
|
+
options
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(opts = {})
|
30
|
+
@options = DEFAULT_OPTIONS.dup
|
31
|
+
opts.each { |k, v| @options[k] = v if v }
|
32
|
+
end
|
33
|
+
|
34
|
+
def process_option(*args)
|
35
|
+
opt, arg = args.flatten[0..1]
|
36
|
+
|
37
|
+
case opt
|
38
|
+
when '--colors', '-c'
|
39
|
+
@options[:colors] = true
|
40
|
+
when '--no-colors', '-nc'
|
41
|
+
@options[:colors] = false
|
42
|
+
when '--keep'
|
43
|
+
@options[:remove_html_file] = false
|
44
|
+
when '--report'
|
45
|
+
@options[:report] = arg
|
46
|
+
when '--jasmine-config', '-j'
|
47
|
+
@options[:jasmine_config] = arg
|
48
|
+
when '--no-full-run'
|
49
|
+
@options[:full_run] = false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def read_defaults_files
|
54
|
+
[ GLOBAL_DEFAULTS_FILE, DEFAULTS_FILE ].each do |file|
|
55
|
+
if File.file?(file)
|
56
|
+
File.readlines(file).collect { |line| line.strip.split(' ', 2) }.each { |*args| process_option(*args) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def process_command_line_args
|
62
|
+
command_line_args = GetoptLong.new(
|
63
|
+
[ '--colors', '-c', GetoptLong::NO_ARGUMENT ],
|
64
|
+
[ '--no-colors', GetoptLong::NO_ARGUMENT ],
|
65
|
+
[ '--keep', GetoptLong::NO_ARGUMENT ],
|
66
|
+
[ '--report', GetoptLong::REQUIRED_ARGUMENT ],
|
67
|
+
[ '--jasmine-config', '-j', GetoptLong::REQUIRED_ARGUMENT ],
|
68
|
+
[ '--no-full-run', GetoptLong::NO_ARGUMENT ]
|
69
|
+
)
|
70
|
+
|
71
|
+
command_line_args.each { |*args| process_option(*args) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
@@ -1,5 +1,25 @@
|
|
1
1
|
require 'jasmine/headless/task'
|
2
2
|
|
3
|
+
module Digest
|
4
|
+
class JasmineTest
|
5
|
+
def self.file(file)
|
6
|
+
new
|
7
|
+
end
|
8
|
+
|
9
|
+
def file(file)
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def hexdigest
|
14
|
+
'test'
|
15
|
+
end
|
16
|
+
|
17
|
+
def update(prefix)
|
18
|
+
self
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
3
23
|
module Jasmine
|
4
24
|
module Headless
|
5
25
|
class Railtie < Rails::Railtie
|
@@ -7,6 +27,15 @@ module Jasmine
|
|
7
27
|
Jasmine::Headless::Task.new do |t|
|
8
28
|
t.colors = true
|
9
29
|
end
|
30
|
+
|
31
|
+
if Rails.version >= "3.1.0"
|
32
|
+
desc 'Force generate static assets without an MD5 hash, all assets end with -test.<ext>'
|
33
|
+
task 'assets:precompile:for_testing' => :environment do
|
34
|
+
Rails.application.assets.digest_class = Digest::JasmineTest
|
35
|
+
|
36
|
+
Rake::Task['assets:precompile'].invoke
|
37
|
+
end
|
38
|
+
end
|
10
39
|
end
|
11
40
|
end
|
12
41
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'jasmine/headless/errors'
|
2
|
+
require 'jasmine/headless/options'
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
require 'jasmine/base'
|
7
|
+
require 'coffee-script'
|
8
|
+
require 'rainbow'
|
9
|
+
|
10
|
+
require 'jasmine/files_list'
|
11
|
+
require 'jasmine/template_writer'
|
12
|
+
|
13
|
+
module Jasmine
|
14
|
+
module Headless
|
15
|
+
class Runner
|
16
|
+
JASMINE_DEFAULTS = {
|
17
|
+
'spec_files' => [ '**/*[sS]pec.js' ],
|
18
|
+
'helpers' => [ 'helpers/**/*.js' ],
|
19
|
+
'spec_dir' => 'spec/javascripts',
|
20
|
+
'src_dir' => nil,
|
21
|
+
'stylesheets' => [],
|
22
|
+
'src_files' => []
|
23
|
+
}
|
24
|
+
|
25
|
+
RUNNER = File.expand_path('../../../../ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner', __FILE__)
|
26
|
+
|
27
|
+
attr_reader :options
|
28
|
+
|
29
|
+
def self.run(options = {})
|
30
|
+
options = Options.new(options) if !options.kind_of?(Options)
|
31
|
+
new(options).run
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(options)
|
35
|
+
raise NoRunnerError if !File.file?(RUNNER)
|
36
|
+
|
37
|
+
@options = options
|
38
|
+
end
|
39
|
+
|
40
|
+
def jasmine_config
|
41
|
+
@jasmine_config ||= JASMINE_DEFAULTS.dup.merge(YAML.load_file(@options[:jasmine_config]))
|
42
|
+
end
|
43
|
+
|
44
|
+
def jasmine_command(*targets)
|
45
|
+
[
|
46
|
+
RUNNER,
|
47
|
+
@options[:colors] ? '-c' : nil,
|
48
|
+
@options[:report] ? "-r #{@options[:report]}" : nil,
|
49
|
+
*targets
|
50
|
+
].compact.join(" ")
|
51
|
+
end
|
52
|
+
|
53
|
+
def run
|
54
|
+
files_list = Jasmine::FilesList.new(
|
55
|
+
:config => jasmine_config,
|
56
|
+
:only => @options[:files]
|
57
|
+
)
|
58
|
+
|
59
|
+
targets = Jasmine::TemplateWriter.write!(files_list)
|
60
|
+
run_targets = targets.dup
|
61
|
+
run_targets.pop if !@options[:full_run] && files_list.filtered?
|
62
|
+
|
63
|
+
system jasmine_command(run_targets)
|
64
|
+
status = $?.exitstatus
|
65
|
+
|
66
|
+
if @options[:remove_html_file] || (status == 0)
|
67
|
+
targets.each { |target| FileUtils.rm_f target }
|
68
|
+
end
|
69
|
+
|
70
|
+
status
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
@@ -1,6 +1,10 @@
|
|
1
|
+
require 'jasmine/headless/runner'
|
2
|
+
|
1
3
|
module Jasmine
|
2
4
|
module Headless
|
3
5
|
class Task
|
6
|
+
include Rake::DSL if defined?(Rake::DSL)
|
7
|
+
|
4
8
|
attr_accessor :colors, :keep_on_error, :jasmine_config
|
5
9
|
|
6
10
|
def initialize(name = 'jasmine:headless')
|
@@ -12,7 +16,11 @@ module Jasmine
|
|
12
16
|
|
13
17
|
desc 'Run Jasmine specs headlessly'
|
14
18
|
task name do
|
15
|
-
|
19
|
+
Jasmine::Headless::Runner.run(
|
20
|
+
:colors => colors,
|
21
|
+
:remove_html_file => !@keep_on_error,
|
22
|
+
:jasmine_config => @jasmine_config
|
23
|
+
)
|
16
24
|
end
|
17
25
|
end
|
18
26
|
end
|