jasmine-headless-webkit 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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|