guard-jasmine 1.3.0 → 1.19.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.
@@ -0,0 +1,246 @@
1
+ (function() {
2
+ var currentSpecId, errors, fs, getXmlResults, jasmineAvailable, jasmineMissing, jasmineReady, logs, options, overloadPageEvaluate, page, replaceFunctionPlaceholders, resultsKey, setupWriteFileFunction, specsDone, specsReady, specsTimedout, waitFor;
3
+
4
+ phantom.injectJs('lib/result.js');
5
+
6
+ options = {
7
+ url: phantom.args[0] || 'http://127.0.0.1:3000/jasmine',
8
+ timeout: parseInt(phantom.args[1] || 10000),
9
+ specdoc: phantom.args[2] || 'failure',
10
+ focus: /true/i.test(phantom.args[3]),
11
+ console: phantom.args[4] || 'failure',
12
+ errors: phantom.args[5] || 'failure',
13
+ junit: /true/i.test(phantom.args[6]),
14
+ junit_consolidate: /true/i.test(phantom.args[7]),
15
+ junit_save_path: phantom.args[8] || ''
16
+ };
17
+
18
+ page = require('webpage').create();
19
+
20
+ currentSpecId = -1;
21
+
22
+ logs = {};
23
+
24
+ errors = {};
25
+
26
+ resultsKey = "__jr" + Math.ceil(Math.random() * 1000000);
27
+
28
+ fs = require("fs");
29
+
30
+ page.onError = function(msg, trace) {
31
+ if (currentSpecId) {
32
+ errors[currentSpecId] || (errors[currentSpecId] = []);
33
+ return errors[currentSpecId].push({
34
+ msg: msg,
35
+ trace: trace
36
+ });
37
+ }
38
+ };
39
+
40
+ page.onConsoleMessage = function(msg, line, source) {
41
+ var result;
42
+
43
+ if (/^RUNNER_END$/.test(msg)) {
44
+ result = page.evaluate(function() {
45
+ return window.reporter.runnerResult;
46
+ });
47
+ console.log(JSON.stringify(new Result(result, logs, errors, options).process()));
48
+ return page.evaluate(function() {
49
+ return window.resultReceived = true;
50
+ });
51
+ } else if (/^SPEC_START: (\d+)$/.test(msg)) {
52
+ return currentSpecId = Number(RegExp.$1);
53
+ } else {
54
+ logs[currentSpecId] || (logs[currentSpecId] = []);
55
+ return logs[currentSpecId].push(msg);
56
+ }
57
+ };
58
+
59
+ page.onInitialized = function() {
60
+ var setupReporters;
61
+
62
+ overloadPageEvaluate(page);
63
+ setupWriteFileFunction(page, resultsKey, fs.separator);
64
+ page.injectJs('lib/console.js');
65
+ page.injectJs('lib/reporter.js');
66
+ page.injectJs('lib/junit_reporter.js');
67
+ setupReporters = function() {
68
+ return window.onload = function() {
69
+ window.onload = null;
70
+ window.resultReceived = false;
71
+ window.reporter = new ConsoleReporter();
72
+ if (window.jasmine) {
73
+ jasmine.getEnv().addReporter(new JUnitXmlReporter("%save_path%", "%consolidate%"));
74
+ return jasmine.getEnv().addReporter(window.reporter);
75
+ }
76
+ };
77
+ };
78
+ return page.evaluate(setupReporters, {
79
+ save_path: options.junit_save_path,
80
+ consolidate: options.junit_consolidate
81
+ });
82
+ };
83
+
84
+ getXmlResults = function(page, key) {
85
+ var getWindowObj;
86
+
87
+ getWindowObj = function() {
88
+ return window["%resultsObj%"] || {};
89
+ };
90
+ return page.evaluate(getWindowObj, {
91
+ resultsObj: key
92
+ });
93
+ };
94
+
95
+ replaceFunctionPlaceholders = function(fn, replacements) {
96
+ var match, p;
97
+
98
+ if (replacements && typeof replacements === 'object') {
99
+ fn = fn.toString();
100
+ for (p in replacements) {
101
+ if (replacements.hasOwnProperty(p)) {
102
+ match = new RegExp("%" + p + "%", "g");
103
+ while (true) {
104
+ fn = fn.replace(match, replacements[p]);
105
+ if (fn.indexOf(match) === -1) {
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+ return fn;
113
+ };
114
+
115
+ overloadPageEvaluate = function(page) {
116
+ page._evaluate = page.evaluate;
117
+ page.evaluate = function(fn, replacements) {
118
+ return page._evaluate(replaceFunctionPlaceholders(fn, replacements));
119
+ };
120
+ return page;
121
+ };
122
+
123
+ setupWriteFileFunction = function(page, key, path_separator) {
124
+ var saveData;
125
+
126
+ saveData = function() {
127
+ window["%resultsObj%"] = {};
128
+ window.fs_path_separator = "%fs_path_separator%";
129
+ return window.__phantom_writeFile = function(filename, text) {
130
+ return window["%resultsObj%"][filename] = text;
131
+ };
132
+ };
133
+ return page.evaluate(saveData, {
134
+ resultsObj: key,
135
+ fs_path_separator: path_separator
136
+ });
137
+ };
138
+
139
+ page.open(options.url, function(status) {
140
+ page.onLoadFinished = function() {};
141
+ if (status !== 'success') {
142
+ console.log(JSON.stringify({
143
+ error: "Unable to access Jasmine specs at " + options.url
144
+ }));
145
+ return phantom.exit();
146
+ } else {
147
+ return waitFor(jasmineReady, jasmineAvailable, options.timeout, jasmineMissing);
148
+ }
149
+ });
150
+
151
+ jasmineReady = function() {
152
+ return page.evaluate(function() {
153
+ return window.jasmine;
154
+ });
155
+ };
156
+
157
+ jasmineAvailable = function() {
158
+ return waitFor(specsReady, specsDone, options.timeout, specsTimedout);
159
+ };
160
+
161
+ jasmineMissing = function() {
162
+ var error, text;
163
+
164
+ text = page.evaluate(function() {
165
+ var _ref;
166
+
167
+ return (_ref = document.getElementsByTagName('body')[0]) != null ? _ref.innerText : void 0;
168
+ });
169
+ if (text) {
170
+ error = "The Jasmine reporter is not available!\n\n" + text;
171
+ return console.log(JSON.stringify({
172
+ error: error
173
+ }));
174
+ } else {
175
+ return console.log(JSON.stringify({
176
+ error: 'The Jasmine reporter is not available!'
177
+ }));
178
+ }
179
+ };
180
+
181
+ specsReady = function() {
182
+ return page.evaluate(function() {
183
+ return window.resultReceived;
184
+ });
185
+ };
186
+
187
+ specsTimedout = function() {
188
+ var error, text;
189
+
190
+ text = page.evaluate(function() {
191
+ var _ref;
192
+
193
+ return (_ref = document.getElementsByTagName('body')[0]) != null ? _ref.innerText : void 0;
194
+ });
195
+ if (text) {
196
+ error = "Timeout waiting for the Jasmine test results!\n\n" + text;
197
+ return console.log(JSON.stringify({
198
+ error: error
199
+ }));
200
+ } else {
201
+ return console.log(JSON.stringify({
202
+ error: 'Timeout for the Jasmine test results!'
203
+ }));
204
+ }
205
+ };
206
+
207
+ specsDone = function() {
208
+ var filename, output, xml_results;
209
+
210
+ if (options.junit === true) {
211
+ xml_results = getXmlResults(page, resultsKey);
212
+ for (filename in xml_results) {
213
+ if (xml_results.hasOwnProperty(filename) && (output = xml_results[filename]) && typeof output === 'string') {
214
+ fs.write(filename, output, 'w');
215
+ }
216
+ }
217
+ }
218
+ return phantom.exit();
219
+ };
220
+
221
+ waitFor = function(test, ready, timeout, timeoutFunction) {
222
+ var condition, interval, start, wait;
223
+
224
+ if (timeout == null) {
225
+ timeout = 10000;
226
+ }
227
+ start = Date.now();
228
+ condition = false;
229
+ interval = void 0;
230
+ wait = function() {
231
+ if ((Date.now() - start < timeout) && !condition) {
232
+ return condition = test();
233
+ } else {
234
+ clearInterval(interval);
235
+ if (condition) {
236
+ return ready();
237
+ } else {
238
+ timeoutFunction();
239
+ return phantom.exit(1);
240
+ }
241
+ }
242
+ };
243
+ return interval = setInterval(wait, 250);
244
+ };
245
+
246
+ }).call(this);
@@ -3,32 +3,37 @@
3
3
  __slice = [].slice;
4
4
 
5
5
  Console = (function() {
6
-
7
6
  function Console(console) {
8
7
  var log;
8
+
9
9
  log = console.log;
10
10
  console.log = function() {
11
11
  var args;
12
+
12
13
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
13
14
  return log.call(console, Console.format.apply(Console, args));
14
15
  };
15
16
  console.info = function() {
16
17
  var args;
18
+
17
19
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
18
20
  return log.call(console, "INFO: " + (Console.format.apply(Console, args)));
19
21
  };
20
22
  console.warn = function() {
21
23
  var args;
24
+
22
25
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
23
26
  return log.call(console, "WARN: " + (Console.format.apply(Console, args)));
24
27
  };
25
28
  console.error = function() {
26
29
  var args;
30
+
27
31
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
28
32
  return log.call(console, "ERROR: " + (Console.format.apply(Console, args)));
29
33
  };
30
34
  console.debug = function() {
31
35
  var args;
36
+
32
37
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
33
38
  return log.call(console, "DEBUG: " + (Console.format.apply(Console, args)));
34
39
  };
@@ -39,6 +44,7 @@
39
44
  Console.format = function() {
40
45
  var arg, args, result, _i, _len,
41
46
  _this = this;
47
+
42
48
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
43
49
  result = [];
44
50
  if (typeof args[0] === 'string' && /%[sdifo]/gi.test(args[0])) {
@@ -56,6 +62,7 @@
56
62
 
57
63
  Console.inspect = function(object, type) {
58
64
  var match, result;
65
+
59
66
  switch (type) {
60
67
  case '%s':
61
68
  result = String(object);
@@ -93,6 +100,7 @@
93
100
 
94
101
  Console.pp = function(object, depth) {
95
102
  var key, result, type, value, _i, _len;
103
+
96
104
  if (depth == null) {
97
105
  depth = 0;
98
106
  }
@@ -0,0 +1,224 @@
1
+ (function() {
2
+ function elapsed(startTime, endTime) {
3
+ return (endTime - startTime)/1000;
4
+ }
5
+
6
+ function ISODateString(d) {
7
+ function pad(n) { return n < 10 ? '0'+n : n; }
8
+
9
+ return d.getFullYear() + '-' +
10
+ pad(d.getMonth()+1) + '-' +
11
+ pad(d.getDate()) + 'T' +
12
+ pad(d.getHours()) + ':' +
13
+ pad(d.getMinutes()) + ':' +
14
+ pad(d.getSeconds());
15
+ }
16
+
17
+ function trim(str) {
18
+ return str.replace(/^\s+/, "" ).replace(/\s+$/, "" );
19
+ }
20
+
21
+ function escapeInvalidXmlChars(str) {
22
+ return str.replace(/\&/g, "&amp;")
23
+ .replace(/</g, "&lt;")
24
+ .replace(/\>/g, "&gt;")
25
+ .replace(/\"/g, "&quot;")
26
+ .replace(/\'/g, "&apos;");
27
+ }
28
+
29
+ /**
30
+ * Generates JUnit XML for the given spec run.
31
+ * Allows the test results to be used in java based CI
32
+ * systems like CruiseControl and Hudson.
33
+ *
34
+ * @param {string} savePath where to save the files
35
+ * @param {boolean} consolidate whether to save nested describes within the
36
+ * same file as their parent; default: true
37
+ * @param {boolean} useDotNotation whether to separate suite names with
38
+ * dots rather than spaces (ie "Class.init" not
39
+ * "Class init"); default: true
40
+ */
41
+ var JUnitXmlReporter = function(savePath, consolidate, useDotNotation) {
42
+ this.savePath = savePath || '';
43
+ this.consolidate = consolidate === jasmine.undefined ? true : consolidate;
44
+ this.useDotNotation = useDotNotation === jasmine.undefined ? true : useDotNotation;
45
+ };
46
+ JUnitXmlReporter.finished_at = null; // will be updated after all files have been written
47
+
48
+ JUnitXmlReporter.prototype = {
49
+ reportSpecStarting: function(spec) {
50
+ spec.startTime = new Date();
51
+
52
+ if (!spec.suite.startTime) {
53
+ spec.suite.startTime = spec.startTime;
54
+ }
55
+ },
56
+
57
+ reportSpecResults: function(spec) {
58
+ var results = spec.results();
59
+ spec.didFail = !results.passed();
60
+ spec.duration = elapsed(spec.startTime, new Date());
61
+ spec.output = '<testcase classname="' + this.getFullName(spec.suite) +
62
+ '" name="' + escapeInvalidXmlChars(spec.description) + '" time="' + spec.duration + '">';
63
+ if(results.skipped) {
64
+ spec.output = spec.output + "<skipped />";
65
+ }
66
+
67
+ var failure = "";
68
+ var failures = 0;
69
+ var resultItems = results.getItems();
70
+ for (var i = 0; i < resultItems.length; i++) {
71
+ var result = resultItems[i];
72
+
73
+ if (result.type == 'expect' && result.passed && !result.passed()) {
74
+ failures += 1;
75
+ failure += '<failure type="' + result.type + '" message="' + trim(escapeInvalidXmlChars(result.message)) + '">';
76
+ failure += escapeInvalidXmlChars(result.trace.stack || result.message);
77
+ failure += "</failure>";
78
+ }
79
+ }
80
+ if (failure) {
81
+ spec.output += failure;
82
+ }
83
+ spec.output += "</testcase>";
84
+ },
85
+
86
+ reportSuiteResults: function(suite) {
87
+ var results = suite.results();
88
+ var specs = suite.specs();
89
+ var specOutput = "";
90
+ // for JUnit results, let's only include directly failed tests (not nested suites')
91
+ var failedCount = 0;
92
+
93
+ suite.status = results.passed() ? 'Passed.' : 'Failed.';
94
+ if (results.totalCount === 0) { // todo: change this to check results.skipped
95
+ suite.status = 'Skipped.';
96
+ }
97
+
98
+ // if a suite has no (active?) specs, reportSpecStarting is never called
99
+ // and thus the suite has no startTime -- account for that here
100
+ suite.startTime = suite.startTime || new Date();
101
+ suite.duration = elapsed(suite.startTime, new Date());
102
+
103
+ for (var i = 0; i < specs.length; i++) {
104
+ failedCount += specs[i].didFail ? 1 : 0;
105
+ specOutput += "\n " + specs[i].output;
106
+ }
107
+ suite.output = '\n<testsuite name="' + this.getFullName(suite) +
108
+ '" errors="0" tests="' + specs.length + '" failures="' + failedCount +
109
+ '" time="' + suite.duration + '" timestamp="' + ISODateString(suite.startTime) + '">';
110
+ suite.output += specOutput;
111
+ suite.output += "\n</testsuite>";
112
+ },
113
+
114
+ reportRunnerResults: function(runner) {
115
+ var suites = runner.suites();
116
+ for (var i = 0; i < suites.length; i++) {
117
+ var suite = suites[i];
118
+ var fileName = 'TEST-' + this.getFullName(suite, true) + '.xml';
119
+ var output = '<?xml version="1.0" encoding="UTF-8" ?>';
120
+ // if we are consolidating, only write out top-level suites
121
+ if (this.consolidate && suite.parentSuite) {
122
+ continue;
123
+ }
124
+ else if (this.consolidate) {
125
+ output += "\n<testsuites>";
126
+ output += this.getNestedOutput(suite);
127
+ output += "\n</testsuites>";
128
+ this.writeFile(this.savePath, fileName, output);
129
+ }
130
+ else {
131
+ output += suite.output;
132
+ this.writeFile(this.savePath, fileName, output);
133
+ }
134
+ }
135
+ // When all done, make it known on JUnitXmlReporter
136
+ JUnitXmlReporter.finished_at = (new Date()).getTime();
137
+ },
138
+
139
+ getNestedOutput: function(suite) {
140
+ var output = suite.output;
141
+ for (var i = 0; i < suite.suites().length; i++) {
142
+ output += this.getNestedOutput(suite.suites()[i]);
143
+ }
144
+ return output;
145
+ },
146
+
147
+ writeFile: function(path, filename, text) {
148
+ function getQualifiedFilename(separator) {
149
+ if (path && path.substr(-1) !== separator && filename.substr(0) !== separator) {
150
+ path += separator;
151
+ }
152
+ return path + filename;
153
+ }
154
+
155
+ // Rhino
156
+ try {
157
+ // turn filename into a qualified path
158
+ if (path) {
159
+ filename = getQualifiedFilename(java.lang.System.getProperty("file.separator"));
160
+ // create parent dir and ancestors if necessary
161
+ var file = java.io.File(filename);
162
+ var parentDir = file.getParentFile();
163
+ if (!parentDir.exists()) {
164
+ parentDir.mkdirs();
165
+ }
166
+ }
167
+ // finally write the file
168
+ var out = new java.io.BufferedWriter(new java.io.FileWriter(filename));
169
+ out.write(text);
170
+ out.close();
171
+ return;
172
+ } catch (e) {}
173
+ // PhantomJS, via a method injected by phantomjs-testrunner.js
174
+ try {
175
+ // turn filename into a qualified path
176
+ filename = getQualifiedFilename(window.fs_path_separator);
177
+ __phantom_writeFile(filename, text);
178
+ return;
179
+ } catch (f) {}
180
+ // Node.js
181
+ try {
182
+ var fs = require("fs");
183
+ var nodejs_path = require("path");
184
+ var fd = fs.openSync(nodejs_path.join(path, filename), "w");
185
+ fs.writeSync(fd, text, 0);
186
+ fs.closeSync(fd);
187
+ return;
188
+ } catch (g) {}
189
+ },
190
+
191
+ getFullName: function(suite, isFilename) {
192
+ var fullName;
193
+ if (this.useDotNotation) {
194
+ fullName = suite.description;
195
+ for (var parentSuite = suite.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
196
+ fullName = parentSuite.description + '.' + fullName;
197
+ }
198
+ }
199
+ else {
200
+ fullName = suite.getFullName();
201
+ }
202
+
203
+ // Either remove or escape invalid XML characters
204
+ if (isFilename) {
205
+ return fullName.replace(/[^\w]/g, "");
206
+ }
207
+ return escapeInvalidXmlChars(fullName);
208
+ },
209
+
210
+ log: function(str) {
211
+ var console = jasmine.getGlobal().console;
212
+
213
+ if (console && console.log) {
214
+ console.log(str);
215
+ }
216
+ }
217
+ };
218
+
219
+ if (typeof module !== 'undefined' && module.exports) {
220
+ module.exports = JUnitXmlReporter;
221
+ } else {
222
+ window.JUnitXmlReporter = JUnitXmlReporter;
223
+ }
224
+ }).call(this);
@@ -2,7 +2,6 @@
2
2
  var ConsoleReporter;
3
3
 
4
4
  ConsoleReporter = (function() {
5
-
6
5
  function ConsoleReporter() {}
7
6
 
8
7
  ConsoleReporter.prototype.runnerResult = {
@@ -27,10 +26,11 @@
27
26
 
28
27
  ConsoleReporter.prototype.reportSpecResults = function(spec) {
29
28
  var messages, result, specResult, _base, _i, _len, _name, _ref;
29
+
30
30
  if (!spec.results().skipped) {
31
31
  specResult = {
32
32
  id: spec.id,
33
- description: spec.description,
33
+ description: '' + spec.description,
34
34
  passed: spec.results().failedCount === 0
35
35
  };
36
36
  if (spec.results().failedCount !== 0) {
@@ -52,11 +52,12 @@
52
52
 
53
53
  ConsoleReporter.prototype.reportSuiteResults = function(suite) {
54
54
  var parent, suiteResult, _base, _ref;
55
+
55
56
  if (!suite.results().skipped) {
56
57
  suiteResult = {
57
58
  id: suite.id,
58
59
  parent: (_ref = suite.parentSuite) != null ? _ref.id : void 0,
59
- description: suite.description,
60
+ description: '' + suite.description,
60
61
  passed: suite.results().failedCount === 0,
61
62
  specs: this.currentSpecs[suite.id] || [],
62
63
  suites: []
@@ -77,6 +78,7 @@
77
78
 
78
79
  ConsoleReporter.prototype.reportRunnerResults = function(runner) {
79
80
  var end, runtime;
81
+
80
82
  runtime = (new Date().getTime() - this.startTime) / 1000;
81
83
  this.runnerResult['passed'] = runner.results().failedCount === 0;
82
84
  this.runnerResult['stats'] = {
@@ -84,6 +86,9 @@
84
86
  failures: runner.results().failedCount,
85
87
  time: runtime
86
88
  };
89
+ if (window.__coverage__) {
90
+ this.runnerResult['coverage'] = window.__coverage__;
91
+ }
87
92
  end = function() {
88
93
  return console.log("RUNNER_END");
89
94
  };
@@ -96,6 +101,7 @@
96
101
 
97
102
  ConsoleReporter.prototype.addNestedSuites = function(suiteResult) {
98
103
  var suite, _i, _len, _ref, _results;
104
+
99
105
  if (this.nestedSuiteResults[suiteResult.id]) {
100
106
  _ref = this.nestedSuiteResults[suiteResult.id];
101
107
  _results = [];
@@ -110,6 +116,7 @@
110
116
 
111
117
  ConsoleReporter.prototype.removeEmptySuites = function(suiteResult) {
112
118
  var suite, suites, _i, _len, _ref;
119
+
113
120
  suites = [];
114
121
  _ref = suiteResult.suites;
115
122
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -2,7 +2,6 @@
2
2
  var Result;
3
3
 
4
4
  Result = (function() {
5
-
6
5
  function Result(result, logs, errors, options) {
7
6
  this.result = result;
8
7
  this.logs = logs != null ? logs : {};
@@ -12,8 +11,10 @@
12
11
 
13
12
  Result.prototype.addLogs = function(suite) {
14
13
  var id, s, spec;
14
+
15
15
  suite.suites = (function() {
16
16
  var _i, _len, _ref, _results;
17
+
17
18
  _ref = suite.suites;
18
19
  _results = [];
19
20
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -25,6 +26,7 @@
25
26
  if (suite.specs) {
26
27
  suite.specs = (function() {
27
28
  var _i, _len, _ref, _results;
29
+
28
30
  _ref = suite.specs;
29
31
  _results = [];
30
32
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -45,8 +47,10 @@
45
47
 
46
48
  Result.prototype.addErrors = function(suite) {
47
49
  var id, s, spec;
50
+
48
51
  suite.suites = (function() {
49
52
  var _i, _len, _ref, _results;
53
+
50
54
  _ref = suite.suites;
51
55
  _results = [];
52
56
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -58,6 +62,7 @@
58
62
  if (suite.specs) {
59
63
  suite.specs = (function() {
60
64
  var _i, _len, _ref, _results;
65
+
61
66
  _ref = suite.specs;
62
67
  _results = [];
63
68
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -76,10 +81,31 @@
76
81
  return suite;
77
82
  };
78
83
 
84
+ Result.prototype.addGlobalError = function(suite) {
85
+ var b, err, errMsg, globalErrors, noSpecs, noSuites, _i, _len, _ref;
86
+
87
+ noSuites = !suite.suites || suite.suites.length === 0;
88
+ noSpecs = !suite.specs || suite.specs.length === 0;
89
+ globalErrors = this.errors[-1] && this.errors[-1].length !== 0;
90
+ if (noSuites && noSpecs && globalErrors) {
91
+ err = this.errors[-1][0];
92
+ errMsg = [err.msg];
93
+ _ref = err.trace;
94
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
95
+ b = _ref[_i];
96
+ errMsg.push("\n " + b.file + ":" + b.line + " " + b["function"]);
97
+ }
98
+ suite.error = errMsg.join("");
99
+ return suite.passed = false;
100
+ }
101
+ };
102
+
79
103
  Result.prototype.cleanResult = function(suite) {
80
104
  var s, spec, _i, _len, _ref;
105
+
81
106
  suite.suites = (function() {
82
107
  var _i, _len, _ref, _results;
108
+
83
109
  _ref = suite.suites;
84
110
  _results = [];
85
111
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@@ -106,6 +132,7 @@
106
132
  }
107
133
  if (this.options.errors !== 'never') {
108
134
  this.addErrors(this.result);
135
+ this.addGlobalError(this.result);
109
136
  }
110
137
  this.cleanResult(this.result);
111
138
  return this.result;