jasmine-headless-webkit 0.2.3 → 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/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
|