jasmine-headless-webkit 0.7.1 → 0.7.2

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.
@@ -3,165 +3,229 @@
3
3
  if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
4
4
  throw new Error("jasmine not laoded!");
5
5
  }
6
- getSplitName = function(parts) {
7
- parts.push(String(this.description).replace(/[\n\r]/g, ' '));
8
- return parts;
9
- };
10
- jasmine.Suite.prototype.getSuiteSplitName = function() {
11
- return this.getSplitName(this.parentSuite ? this.parentSuite.getSuiteSplitName() : []);
12
- };
13
- jasmine.Spec.prototype.getSpecSplitName = function() {
14
- return this.getSplitName(this.suite.getSuiteSplitName());
15
- };
16
- jasmine.Suite.prototype.getSplitName = getSplitName;
17
- jasmine.Spec.prototype.getSplitName = getSplitName;
18
- jasmine.Spec.prototype.getJHWSpecInformation = function() {
19
- var parts, specLineInfo;
20
- parts = this.getSpecSplitName();
21
- specLineInfo = HeadlessReporterResult.findSpecLine(parts);
22
- if (specLineInfo.file) {
23
- parts.push("" + specLineInfo.file + ":" + specLineInfo.lineNumber);
24
- } else {
25
- parts.push('');
26
- }
27
- return parts.join("||");
28
- };
29
- if (!jasmine.WaitsBlock.prototype._execute) {
30
- jasmine.WaitsBlock.prototype._execute = jasmine.WaitsBlock.prototype.execute;
31
- jasmine.WaitsForBlock.prototype._execute = jasmine.WaitsForBlock.prototype.execute;
32
- pauseAndRun = function(onComplete) {
33
- JHW.timerPause();
34
- return this._execute(function() {
35
- JHW.timerDone();
36
- return onComplete();
37
- });
6
+ if (window.JHW) {
7
+ getSplitName = function(parts) {
8
+ parts.push(String(this.description).replace(/[\n\r]/g, ' '));
9
+ return parts;
38
10
  };
39
- jasmine.WaitsBlock.prototype.execute = pauseAndRun;
40
- jasmine.WaitsForBlock.prototype.execute = pauseAndRun;
41
- }
42
- window.HeadlessReporterResult = (function() {
43
- function HeadlessReporterResult(name, splitName) {
44
- this.name = name;
45
- this.splitName = splitName;
46
- this.results = [];
47
- }
48
- HeadlessReporterResult.prototype.addResult = function(message) {
49
- return this.results.push(message);
11
+ jasmine.Suite.prototype.getSuiteSplitName = function() {
12
+ return this.getSplitName(this.parentSuite ? this.parentSuite.getSuiteSplitName() : []);
50
13
  };
51
- HeadlessReporterResult.prototype.print = function() {
52
- var bestChoice, output, result, _i, _len, _ref, _results;
53
- output = this.name;
54
- bestChoice = HeadlessReporterResult.findSpecLine(this.splitName);
55
- if (bestChoice.file) {
56
- output += " (" + bestChoice.file + ":" + bestChoice.lineNumber + ")";
57
- }
58
- JHW.printName(output);
59
- _ref = this.results;
60
- _results = [];
61
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
62
- result = _ref[_i];
63
- _results.push(JHW.printResult(result));
14
+ jasmine.Spec.prototype.getSpecSplitName = function() {
15
+ return this.getSplitName(this.suite.getSuiteSplitName());
16
+ };
17
+ jasmine.Suite.prototype.getSplitName = getSplitName;
18
+ jasmine.Spec.prototype.getSplitName = getSplitName;
19
+ jasmine.Spec.prototype.getJHWSpecInformation = function() {
20
+ var parts, specLineInfo;
21
+ parts = this.getSpecSplitName();
22
+ specLineInfo = HeadlessReporterResult.findSpecLine(parts);
23
+ if (specLineInfo.file) {
24
+ parts.push("" + specLineInfo.file + ":" + specLineInfo.lineNumber);
25
+ } else {
26
+ parts.push('');
64
27
  }
65
- return _results;
28
+ return parts.join("||");
66
29
  };
67
- HeadlessReporterResult.findSpecLine = function(splitName) {
68
- var bestChoice, file, index, lastLine, line, lineNumber, lines, newLineNumberInfo, _i, _len, _ref;
69
- bestChoice = {
70
- accuracy: 0,
71
- file: null,
72
- lineNumber: null
73
- };
74
- _ref = HeadlessReporterResult.specLineNumbers;
75
- for (file in _ref) {
76
- lines = _ref[file];
77
- index = 0;
78
- lineNumber = 0;
79
- while (newLineNumberInfo = lines[splitName[index]]) {
80
- if (newLineNumberInfo.length === 0) {
81
- lineNumber = newLineNumberInfo[0];
82
- } else {
83
- lastLine = null;
84
- for (_i = 0, _len = newLineNumberInfo.length; _i < _len; _i++) {
85
- line = newLineNumberInfo[_i];
86
- lastLine = line;
87
- if (line > lineNumber) {
88
- break;
89
- }
90
- }
91
- lineNumber = lastLine;
92
- }
93
- index++;
94
- }
95
- if (index > bestChoice.accuracy) {
96
- bestChoice = {
97
- accuracy: index,
98
- file: file,
99
- lineNumber: lineNumber
30
+ jasmine.Spec.prototype.fail = function(e) {
31
+ var expectationResult, filename, realFilename;
32
+ if (e && e.sourceURL && window.CoffeeScriptToFilename) {
33
+ filename = e.sourceURL.split('/').pop();
34
+ if (realFilename = window.CoffeeScriptToFilename[filename]) {
35
+ e = {
36
+ name: e.name,
37
+ message: e.message,
38
+ lineNumber: "~" + String(e.line),
39
+ sourceURL: realFilename
100
40
  };
101
41
  }
102
42
  }
103
- return bestChoice;
43
+ expectationResult = new jasmine.ExpectationResult({
44
+ passed: false,
45
+ message: e ? jasmine.util.formatException(e) : 'Exception',
46
+ trace: {
47
+ stack: e.stack
48
+ }
49
+ });
50
+ return this.results_.addResult(expectationResult);
104
51
  };
105
- return HeadlessReporterResult;
106
- })();
107
- jasmine.HeadlessReporter = (function() {
108
- function HeadlessReporter(callback) {
109
- this.callback = callback != null ? callback : null;
110
- this.results = [];
111
- this.failedCount = 0;
112
- this.length = 0;
113
- }
114
- HeadlessReporter.prototype.reportRunnerResults = function(runner) {
115
- var result, _i, _len, _ref;
116
- if (this.hasError()) {
117
- return;
118
- }
119
- _ref = this.results;
52
+ jasmine.NestedResults.isValidSpecLine = function(line) {
53
+ return line.match(/^\s*expect/) !== null || line.match(/^\s*return\s*expect/) !== null;
54
+ };
55
+ jasmine.NestedResults.parseFunction = function(func) {
56
+ var line, lineCount, lines, _i, _len, _ref;
57
+ lines = [];
58
+ lineCount = 0;
59
+ _ref = func.split("\n");
120
60
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
121
- result = _ref[_i];
122
- result.print();
123
- }
124
- if (this.callback) {
125
- this.callback();
61
+ line = _ref[_i];
62
+ if (jasmine.NestedResults.isValidSpecLine(line)) {
63
+ line = line.replace(/^\s*/, '').replace(/\s*$/, '').replace(/^return\s*/, '');
64
+ lines.push([line, lineCount]);
65
+ }
66
+ lineCount += 1;
126
67
  }
127
- return JHW.finishSuite((new Date() - this.startTime) / 1000.0, this.length, this.failedCount);
68
+ return lines;
128
69
  };
129
- HeadlessReporter.prototype.reportRunnerStarting = function(runner) {
130
- return this.startTime = new Date();
70
+ jasmine.NestedResults.parseAndStore = function(func) {
71
+ if (!jasmine.NestedResults.ParsedFunctions[func]) {
72
+ jasmine.NestedResults.ParsedFunctions[func] = jasmine.NestedResults.parseFunction(func);
73
+ }
74
+ return jasmine.NestedResults.ParsedFunctions[func];
131
75
  };
132
- HeadlessReporter.prototype.reportSpecResults = function(spec) {
133
- var failureResult, result, results, _i, _len, _ref;
134
- if (this.hasError()) {
135
- return;
76
+ jasmine.NestedResults.ParsedFunctions = [];
77
+ if (!jasmine.WaitsBlock.prototype._execute) {
78
+ jasmine.WaitsBlock.prototype._execute = jasmine.WaitsBlock.prototype.execute;
79
+ jasmine.WaitsForBlock.prototype._execute = jasmine.WaitsForBlock.prototype.execute;
80
+ pauseAndRun = function(onComplete) {
81
+ JHW.timerPause();
82
+ return this._execute(function() {
83
+ JHW.timerDone();
84
+ return onComplete();
85
+ });
86
+ };
87
+ jasmine.WaitsBlock.prototype.execute = pauseAndRun;
88
+ jasmine.WaitsForBlock.prototype.execute = pauseAndRun;
89
+ jasmine.NestedResults.prototype.addResult_ = jasmine.NestedResults.prototype.addResult;
90
+ jasmine.NestedResults.prototype.addResult = function(result) {
91
+ result.expectations = [];
92
+ result.expectations = jasmine.NestedResults.parseAndStore(arguments.callee.caller.caller.caller.toString());
93
+ return this.addResult_(result);
94
+ };
95
+ }
96
+ window.HeadlessReporterResult = (function() {
97
+ function HeadlessReporterResult(name, splitName) {
98
+ this.name = name;
99
+ this.splitName = splitName;
100
+ this.results = [];
136
101
  }
137
- results = spec.results();
138
- this.length++;
139
- if (results.passed()) {
140
- return JHW.specPassed(spec.getJHWSpecInformation());
141
- } else {
142
- JHW.specFailed(spec.getJHWSpecInformation());
143
- this.failedCount++;
144
- failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName());
145
- _ref = results.getItems();
102
+ HeadlessReporterResult.prototype.addResult = function(message) {
103
+ return this.results.push(message);
104
+ };
105
+ HeadlessReporterResult.prototype.print = function() {
106
+ var bestChoice, output, result, _i, _len, _ref, _results;
107
+ output = this.name;
108
+ bestChoice = HeadlessReporterResult.findSpecLine(this.splitName);
109
+ if (bestChoice.file) {
110
+ output += " (" + bestChoice.file + ":" + bestChoice.lineNumber + ")";
111
+ }
112
+ JHW.printName(output);
113
+ _ref = this.results;
114
+ _results = [];
146
115
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
147
116
  result = _ref[_i];
148
- if (result.type === 'expect' && !result.passed_) {
149
- failureResult.addResult(result.message);
117
+ output = result.message;
118
+ if (result.lineNumber) {
119
+ output += " (line ~" + (bestChoice.lineNumber + result.lineNumber) + ")\n " + result.line;
150
120
  }
121
+ _results.push(JHW.printResult(output));
151
122
  }
152
- return this.results.push(failureResult);
153
- }
154
- };
155
- HeadlessReporter.prototype.reportSpecStarting = function(spec) {
156
- if (this.hasError()) {
157
- spec.finish();
158
- return spec.suite.finish();
123
+ return _results;
124
+ };
125
+ HeadlessReporterResult.findSpecLine = function(splitName) {
126
+ var bestChoice, file, index, lastLine, line, lineNumber, lines, newLineNumberInfo, _i, _len, _ref;
127
+ bestChoice = {
128
+ accuracy: 0,
129
+ file: null,
130
+ lineNumber: null
131
+ };
132
+ _ref = HeadlessReporterResult.specLineNumbers;
133
+ for (file in _ref) {
134
+ lines = _ref[file];
135
+ index = 0;
136
+ lineNumber = 0;
137
+ while (newLineNumberInfo = lines[splitName[index]]) {
138
+ if (newLineNumberInfo.length === 0) {
139
+ lineNumber = newLineNumberInfo[0];
140
+ } else {
141
+ lastLine = null;
142
+ for (_i = 0, _len = newLineNumberInfo.length; _i < _len; _i++) {
143
+ line = newLineNumberInfo[_i];
144
+ lastLine = line;
145
+ if (line > lineNumber) {
146
+ break;
147
+ }
148
+ }
149
+ lineNumber = lastLine;
150
+ }
151
+ index++;
152
+ }
153
+ if (index > bestChoice.accuracy) {
154
+ bestChoice = {
155
+ accuracy: index,
156
+ file: file,
157
+ lineNumber: lineNumber
158
+ };
159
+ }
160
+ }
161
+ return bestChoice;
162
+ };
163
+ return HeadlessReporterResult;
164
+ })();
165
+ jasmine.HeadlessReporter = (function() {
166
+ function HeadlessReporter(callback) {
167
+ this.callback = callback != null ? callback : null;
168
+ this.results = [];
169
+ this.failedCount = 0;
170
+ this.length = 0;
159
171
  }
160
- };
161
- HeadlessReporter.prototype.reportSuiteResults = function(suite) {};
162
- HeadlessReporter.prototype.hasError = function() {
163
- return JHW.hasError();
164
- };
165
- return HeadlessReporter;
166
- })();
172
+ HeadlessReporter.prototype.reportRunnerResults = function(runner) {
173
+ var result, _i, _len, _ref;
174
+ if (this.hasError()) {
175
+ return;
176
+ }
177
+ _ref = this.results;
178
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
179
+ result = _ref[_i];
180
+ result.print();
181
+ }
182
+ if (this.callback) {
183
+ this.callback();
184
+ }
185
+ return JHW.finishSuite((new Date() - this.startTime) / 1000.0, this.length, this.failedCount);
186
+ };
187
+ HeadlessReporter.prototype.reportRunnerStarting = function(runner) {
188
+ return this.startTime = new Date();
189
+ };
190
+ HeadlessReporter.prototype.reportSpecResults = function(spec) {
191
+ var failureResult, foundLine, result, results, testCount, _i, _len, _ref;
192
+ if (this.hasError()) {
193
+ return;
194
+ }
195
+ results = spec.results();
196
+ this.length++;
197
+ if (results.passed()) {
198
+ return JHW.specPassed(spec.getJHWSpecInformation());
199
+ } else {
200
+ JHW.specFailed(spec.getJHWSpecInformation());
201
+ this.failedCount++;
202
+ failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName());
203
+ testCount = 1;
204
+ _ref = results.getItems();
205
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
206
+ result = _ref[_i];
207
+ if (result.type === 'expect' && !result.passed_) {
208
+ if (foundLine = result.expectations[testCount - 1]) {
209
+ result.line = foundLine[0], result.lineNumber = foundLine[1];
210
+ }
211
+ failureResult.addResult(result);
212
+ }
213
+ testCount += 1;
214
+ }
215
+ return this.results.push(failureResult);
216
+ }
217
+ };
218
+ HeadlessReporter.prototype.reportSpecStarting = function(spec) {
219
+ if (this.hasError()) {
220
+ spec.finish();
221
+ return spec.suite.finish();
222
+ }
223
+ };
224
+ HeadlessReporter.prototype.reportSuiteResults = function(suite) {};
225
+ HeadlessReporter.prototype.hasError = function() {
226
+ return JHW.hasError();
227
+ };
228
+ return HeadlessReporter;
229
+ })();
230
+ }
167
231
  }).call(this);
@@ -1,6 +1,6 @@
1
1
  require 'jasmine-core'
2
- require 'iconv'
3
2
  require 'time'
3
+ require 'multi_json'
4
4
 
5
5
  module Jasmine
6
6
  class FilesList
@@ -9,9 +9,10 @@ module Jasmine
9
9
  DEFAULT_FILES = [
10
10
  File.join(Jasmine::Core.path, "jasmine.js"),
11
11
  File.join(Jasmine::Core.path, "jasmine-html.js"),
12
- File.expand_path('../../../jasmine/jasmine.headless-reporter.js', __FILE__),
13
- File.expand_path('../../../js-lib/jsDump.js', __FILE__),
14
- File.expand_path('../../../js-lib/beautify-html.js', __FILE__)
12
+ File.join(Jasmine::Core.path, "jasmine.css"),
13
+ Jasmine::Headless.root.join('jasmine/jasmine.headless-reporter.js').to_s,
14
+ Jasmine::Headless.root.join('js-lib/jsDump.js').to_s,
15
+ Jasmine::Headless.root.join('js-lib/beautify-html.js').to_s
15
16
  ]
16
17
 
17
18
  PLEASE_WAIT_IM_WORKING_TIME = 2
@@ -63,10 +64,24 @@ module Jasmine
63
64
  alert_time = nil
64
65
  end
65
66
 
66
- case File.extname(file)
67
+ source = nil
68
+
69
+ result = case File.extname(file)
67
70
  when '.coffee'
68
71
  begin
69
- %{<script type="text/javascript">#{Jasmine::Headless::CoffeeScriptCache.for(file)}</script>}
72
+ cache = Jasmine::Headless::CoffeeScriptCache.new(file)
73
+ source = cache.handle
74
+ if cache.cached?
75
+ %{
76
+ <script type="text/javascript" src="#{cache.cache_file}"></script>S
77
+ <script type="text/javascript">
78
+ window.CoffeeScriptToFilename = window.CoffeeScriptToFilename || {};
79
+ window.CoffeeScriptToFilename['#{File.split(cache.cache_file).last}'] = '#{file}';
80
+ </script>
81
+ }
82
+ else
83
+ %{<script type="text/javascript">#{source}</script>}
84
+ end
70
85
  rescue CoffeeScript::CompilationError => ne
71
86
  puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), file.color(:yellow), ne.message.to_s.color(:white) ]
72
87
  raise ne
@@ -79,38 +94,58 @@ module Jasmine
79
94
  when '.css'
80
95
  %{<link rel="stylesheet" href="#{file}" type="text/css" />}
81
96
  end
97
+
98
+ result
82
99
  }.flatten.compact.reject(&:empty?)
83
100
  end
84
101
 
85
102
  def spec_filter
86
- @spec_filter ||= (@options[:only] ? @options[:only].collect { |path| Dir[path] }.flatten : [])
103
+ return @spec_filter if @spec_filter
104
+
105
+ @spec_filter = begin
106
+ if @options[:only]
107
+ @options[:only].collect { |path| expanded_dir(path) }.flatten
108
+ else
109
+ []
110
+ end
111
+ end
87
112
  end
88
113
 
89
114
  def use_config!
90
115
  @filtered_files = @files.dup
91
116
 
92
117
  data = @options[:config].dup
93
- [ [ 'src_files', 'src_dir' ], [ 'stylesheets', 'src_dir' ], [ 'helpers', 'spec_dir' ], [ 'spec_files', 'spec_dir' ] ].each do |searches, root|
118
+ [ [ 'src_files', 'src_dir' ], [ 'stylesheets', 'src_dir' ], [ 'vendored_helpers' ], [ 'helpers', 'spec_dir' ], [ 'spec_files', 'spec_dir' ] ].each do |searches, root|
94
119
  if data[searches]
95
- data[searches].flatten.collect do |search|
96
- path = search
97
- path = File.join(data[root], path) if data[root]
98
- found_files = Dir[path] - @files
99
-
100
- @files += found_files
120
+ case searches
121
+ when 'vendored_helpers'
122
+ data[searches].each do |name|
123
+ found_files = self.class.find_vendored_asset_path(name)
101
124
 
102
- if searches == 'spec_files'
103
- @spec_files += spec_filter.empty? ? found_files : (found_files & spec_filter)
125
+ @files += found_files
126
+ @filtered_files += found_files
104
127
  end
105
-
106
- @filtered_files += begin
107
- if searches == 'spec_files'
108
- @spec_outside_scope = ((spec_filter | found_files).sort != found_files.sort)
109
- spec_filter.empty? ? found_files : (spec_filter || found_files)
110
- else
111
- found_files
128
+ else
129
+ data[searches].flatten.collect do |search|
130
+ path = search
131
+ path = File.join(data[root], path) if data[root]
132
+ found_files = expanded_dir(path) - @files
133
+
134
+ @files += found_files
135
+
136
+ if searches == 'spec_files'
137
+ @spec_files += spec_filter.empty? ? found_files : (found_files & spec_filter)
138
+ end
139
+
140
+ @filtered_files += begin
141
+ if searches == 'spec_files'
142
+ @spec_outside_scope = ((spec_filter | found_files).sort != found_files.sort)
143
+ spec_filter.empty? ? found_files : (spec_filter || found_files)
144
+ else
145
+ found_files
146
+ end
112
147
  end
113
- end
148
+ end
114
149
  end
115
150
  end
116
151
  end
@@ -119,6 +154,23 @@ module Jasmine
119
154
  def config?
120
155
  @options[:config]
121
156
  end
157
+
158
+ def expanded_dir(path)
159
+ Dir[path].collect { |file| File.expand_path(file) }
160
+ end
161
+
162
+ def self.find_vendored_asset_path(name)
163
+ require 'rubygems'
164
+
165
+ raise StandardError.new("A newer version of Rubygems is required to use vendored assets. Please upgrade.") if !Gem::Specification.respond_to?(:map)
166
+ all_spec_files.find_all { |file| file["vendor/assets/javascripts/#{name}.js"] }
167
+ end
168
+
169
+ def self.all_spec_files
170
+ @all_spec_files ||= Gem::Specification.map { |spec| spec.files.find_all { |file|
171
+ file["vendor/assets/javascripts"]
172
+ }.compact.collect { |file| File.join(spec.gem_dir, file) } }.flatten
173
+ end
122
174
  end
123
175
  end
124
176
 
@@ -56,11 +56,15 @@ module Jasmine::Headless
56
56
  end
57
57
 
58
58
  def cache_file
59
- @cache_file ||= File.join(self.class.cache_dir, self.class.cache_type, Digest::SHA1.hexdigest(file))
59
+ @cache_file ||= File.join(self.class.cache_dir, self.class.cache_type, Digest::SHA1.hexdigest(file)) + '.js'
60
60
  end
61
61
 
62
62
  def fresh?
63
- File.exist?(cache_file) && (File.mtime(file) < File.mtime(cache_file))
63
+ cached? && (File.mtime(file) < File.mtime(cache_file))
64
+ end
65
+
66
+ def cached?
67
+ File.exist?(cache_file)
64
68
  end
65
69
 
66
70
  def action
@@ -11,6 +11,7 @@ module Jasmine
11
11
  DEFAULT_OPTIONS = {
12
12
  :colors => false,
13
13
  :remove_html_file => true,
14
+ :runner_output_filename => false,
14
15
  :jasmine_config => 'spec/javascripts/support/jasmine.yml',
15
16
  :report => false,
16
17
  :do_list => false,
@@ -20,7 +21,7 @@ module Jasmine
20
21
  }
21
22
 
22
23
  DEFAULTS_FILE = File.join(Dir.pwd, '.jasmine-headless-webkit')
23
- GLOBAL_DEFAULTS_FILE = File.expand_path("~/#{DEFAULTS_FILE}")
24
+ GLOBAL_DEFAULTS_FILE = File.expand_path('~/.jasmine-headless-webkit')
24
25
 
25
26
  def self.from_command_line
26
27
  options = new
@@ -51,6 +52,8 @@ module Jasmine
51
52
  @options[:remove_html_file] = false
52
53
  when '--report'
53
54
  @options[:report] = arg
55
+ when '--runner-out'
56
+ @options[:runner_output_filename] = arg
54
57
  when '--jasmine-config', '-j'
55
58
  @options[:jasmine_config] = arg
56
59
  when '--no-full-run'
@@ -75,6 +78,7 @@ module Jasmine
75
78
  [ '--cache', GetoptLong::NO_ARGUMENT ],
76
79
  [ '--no-t stcache', GetoptLong::NO_ARGUMENT ],
77
80
  [ '--keep', GetoptLong::NO_ARGUMENT ],
81
+ [ '--runner-out', GetoptLong::REQUIRED_ARGUMENT ],
78
82
  [ '--report', GetoptLong::REQUIRED_ARGUMENT ],
79
83
  [ '--jasmine-config', '-j', GetoptLong::REQUIRED_ARGUMENT ],
80
84
  [ '--no-full-run', GetoptLong::NO_ARGUMENT ],
@@ -14,7 +14,8 @@ module Jasmine
14
14
  'spec_dir' => 'spec/javascripts',
15
15
  'src_dir' => nil,
16
16
  'stylesheets' => [],
17
- 'src_files' => []
17
+ 'src_files' => [],
18
+ 'backtrace' => []
18
19
  }
19
20
 
20
21
  RUNNER_DIR = File.expand_path('../../../../ext/jasmine-webkit-specrunner', __FILE__)
@@ -39,6 +40,10 @@ module Jasmine
39
40
  @options = options
40
41
  end
41
42
 
43
+ def template_writer
44
+ @template_writer ||= TemplateWriter.new(self)
45
+ end
46
+
42
47
  def jasmine_config
43
48
  raise JasmineConfigNotFound.new("Jasmine config not found. I tried #{@options[:jasmine_config]}.") if !File.file?(@options[:jasmine_config])
44
49
 
@@ -62,18 +67,26 @@ module Jasmine
62
67
  :only => @options[:files]
63
68
  )
64
69
 
65
- targets = Jasmine::TemplateWriter.write!(files_list)
66
- run_targets = targets.dup
70
+ @_targets = template_writer.write!(files_list)
71
+ run_targets = @_targets.dup
67
72
  run_targets.pop if (!@options[:full_run] && files_list.filtered?) || files_list.has_spec_outside_scope?
68
73
 
69
74
  system jasmine_command(run_targets)
70
- status = $?.exitstatus
71
-
72
- if @options[:remove_html_file] || (status == 0)
73
- targets.each { |target| FileUtils.rm_f target }
75
+ @_status = $?.exitstatus
76
+ ensure
77
+ if @_targets && !runner_filename && (@options[:remove_html_file] || (@_status == 0))
78
+ @_targets.each { |target| FileUtils.rm_f target }
74
79
  end
80
+ end
75
81
 
76
- status
82
+ def runner_filename
83
+ options[:runner_output_filename] || begin
84
+ if (runner_output = jasmine_config['runner_output']) && !runner_output.empty?
85
+ runner_output
86
+ else
87
+ false
88
+ end
89
+ end
77
90
  end
78
91
  end
79
92
  end
@@ -1,4 +1,3 @@
1
- require 'iconv'
2
1
  require 'multi_json'
3
2
 
4
3
  module Jasmine::Headless
@@ -12,8 +11,16 @@ module Jasmine::Headless
12
11
  def action
13
12
  line_numbers = {}
14
13
 
15
- ic = Iconv.new('UTF-8//IGNORE', 'US-ASCII')
16
- data = ic.iconv(File.read(file) + ' ')[0..-2]
14
+ data = File.read(file)
15
+
16
+ if data.respond_to?(:encode)
17
+ data.encode!('US-ASCII', 'UTF-8', :invalid => :replace)
18
+ else
19
+ require 'iconv'
20
+ ic = Iconv.new('UTF-8//IGNORE', 'US-ASCII')
21
+ data = ic.iconv(File.read(file) + ' ')[0..-2]
22
+ end
23
+
17
24
  data.force_encoding('US-ASCII') if data.respond_to?(:force_encoding)
18
25
 
19
26
  data.lines.each_with_index.each { |line, index|