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.
Files changed (36) hide show
  1. data/Gemfile +1 -0
  2. data/Guardfile +1 -1
  3. data/bin/jasmine-headless-webkit +5 -98
  4. data/ext/jasmine-webkit-specrunner/specrunner.cpp +39 -16
  5. data/jasmine/jasmine.headless-reporter.coffee +3 -3
  6. data/jasmine/jasmine.headless-reporter.js +4 -5
  7. data/lib/jasmine/files_list.rb +122 -0
  8. data/lib/jasmine/headless/cli.rb +17 -0
  9. data/lib/jasmine/headless/errors.rb +7 -0
  10. data/lib/jasmine/headless/options.rb +76 -0
  11. data/lib/jasmine/headless/railtie.rb +29 -0
  12. data/lib/jasmine/headless/runner.rb +75 -0
  13. data/lib/jasmine/headless/task.rb +9 -1
  14. data/lib/jasmine/template_writer.rb +50 -0
  15. data/lib/jasmine-headless-webkit/version.rb +1 -1
  16. data/spec/bin/jasmine-headless-webkit_spec.rb +40 -20
  17. data/spec/jasmine/coffeescript_error/coffeescript_error.yml +10 -0
  18. data/spec/jasmine/coffeescript_error/spec.coffee +2 -0
  19. data/spec/jasmine/coffeescript_error/src.coffee +2 -0
  20. data/spec/jasmine/filtered_failure/failure_spec.js +6 -0
  21. data/spec/jasmine/filtered_failure/filtered_failure.yml +10 -0
  22. data/spec/jasmine/filtered_failure/src.js +0 -0
  23. data/spec/jasmine/filtered_failure/success_spec.js +6 -0
  24. data/spec/jasmine/filtered_success/filtered_success.yml +10 -0
  25. data/spec/jasmine/filtered_success/src.js +0 -0
  26. data/spec/jasmine/filtered_success/success_one_spec.js +6 -0
  27. data/spec/jasmine/filtered_success/success_two_spec.js +6 -0
  28. data/spec/lib/jasmine/files_list_spec.rb +198 -0
  29. data/spec/lib/jasmine/headless/cli_spec.rb +1 -0
  30. data/spec/lib/jasmine/headless/options_spec.rb +69 -0
  31. data/spec/lib/jasmine/headless/runner_spec.rb +72 -0
  32. data/spec/lib/jasmine/template_writer_spec.rb +37 -0
  33. data/spec/spec_helper.rb +15 -0
  34. metadata +42 -7
  35. data/lib/jasmine/cli.rb +0 -78
  36. data/spec/lib/jasmine/cli_spec.rb +0 -89
data/Gemfile CHANGED
@@ -11,3 +11,4 @@ gem 'guard-shell'
11
11
  gem 'guard-coffeescript'
12
12
  gem 'growl'
13
13
  gem 'rake', '0.8.7'
14
+ gem 'mocha', '0.9.12'
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" }
@@ -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
- files = %w{jasmine jasmine-html}.collect { |name| File.join(Jasmine.root, "lib/#{name}.js") }
68
- files << File.join(gem_dir, 'jasmine/jasmine.headless-reporter.js')
69
-
70
- [ [ 'src_files', 'src_dir' ], [ 'stylesheets', 'src_dir' ], [ 'helpers', 'spec_dir' ], [ 'spec_files', 'spec_dir' ] ].each do |searches, root|
71
- if data[searches] ||= DEFAULTS[searches]
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 &note, 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::load(const QString &spec)
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
- QApplication::instance()->exit(exitCode);
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
- bool filenameFound = false;
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] SpecRunner.html" << std::endl;
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
- runner.load(QString::fromLocal8Bit(filename));
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 Exception("jasmine not laoded!")
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 Exception("jasmine not laoded!");
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,7 @@
1
+ module Jasmine
2
+ module Headless
3
+ class NoRunnerError < StandardError
4
+ end
5
+ end
6
+ end
7
+
@@ -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
- system %{jasmine-headless-webkit #{@colors ? "-c" : "--no-colors"} #{@keep_on_error ? "--keep" : ""} #{@jasmine_config ? "-j #{@jasmine_config}" : ""}}
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