Skip to content

Commit 6d24063

Browse files
danielstjulesdasilvacontin
authored andcommittedMay 25, 2016
Fix HTML reporter regression causing duplicate error output (#2112)
Fixes #2083.
1 parent 08cb423 commit 6d24063

File tree

1 file changed

+79
-67
lines changed

1 file changed

+79
-67
lines changed
 

‎lib/reporters/html.js

+79-67
Original file line numberDiff line numberDiff line change
@@ -128,88 +128,82 @@ function HTML(runner) {
128128
stack.shift();
129129
});
130130

131-
runner.on('fail', function(test) {
132-
// For type = 'test' its possible that the test failed due to multiple
133-
// done() calls. So report the issue here.
134-
if (test.type === 'hook'
135-
|| test.type === 'test') {
136-
runner.emit('test end', test);
137-
}
131+
runner.on('pass', function(test) {
132+
var url = self.testURL(test);
133+
var markup = '<li class="test pass %e"><h2>%e<span class="duration">%ems</span> '
134+
+ '<a href="%s" class="replay">‣</a></h2></li>';
135+
var el = fragment(markup, test.speed, test.title, test.duration, url);
136+
self.addCodeToggle(el, test.body);
137+
appendToStack(el);
138+
updateStats();
138139
});
139140

140-
runner.on('test end', function(test) {
141-
// TODO: add to stats
142-
var percent = stats.tests / this.total * 100 | 0;
143-
if (progress) {
144-
progress.update(percent).draw(ctx);
141+
runner.on('fail', function(test) {
142+
var el = fragment('<li class="test fail"><h2>%e <a href="%e" class="replay">‣</a></h2></li>',
143+
test.title, self.testURL(test));
144+
var stackString; // Note: Includes leading newline
145+
var message = test.err.toString();
146+
147+
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
148+
// check for the result of the stringifying.
149+
if (message === '[object Error]') {
150+
message = test.err.message;
145151
}
146152

147-
// update stats
148-
var ms = new Date() - stats.start;
149-
text(passes, stats.passes);
150-
text(failures, stats.failures);
151-
text(duration, (ms / 1000).toFixed(2));
152-
153-
// test
154-
var el;
155-
if (test.state === 'passed') {
156-
var url = self.testURL(test);
157-
el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span> <a href="%s" class="replay">‣</a></h2></li>', test.speed, test.title, test.duration, url);
158-
} else if (test.isPending()) {
159-
el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
160-
} else {
161-
el = fragment('<li class="test fail"><h2>%e <a href="%e" class="replay">‣</a></h2></li>', test.title, self.testURL(test));
162-
var stackString; // Note: Includes leading newline
163-
var message = test.err.toString();
164-
165-
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
166-
// check for the result of the stringifying.
167-
if (message === '[object Error]') {
168-
message = test.err.message;
169-
}
170-
171-
if (test.err.stack) {
172-
var indexOfMessage = test.err.stack.indexOf(test.err.message);
173-
if (indexOfMessage === -1) {
174-
stackString = test.err.stack;
175-
} else {
176-
stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);
177-
}
178-
} else if (test.err.sourceURL && test.err.line !== undefined) {
179-
// Safari doesn't give you a stack. Let's at least provide a source line.
180-
stackString = '\n(' + test.err.sourceURL + ':' + test.err.line + ')';
181-
}
182-
183-
stackString = stackString || '';
184-
185-
if (test.err.htmlMessage && stackString) {
186-
el.appendChild(fragment('<div class="html-error">%s\n<pre class="error">%e</pre></div>', test.err.htmlMessage, stackString));
187-
} else if (test.err.htmlMessage) {
188-
el.appendChild(fragment('<div class="html-error">%s</div>', test.err.htmlMessage));
153+
if (test.err.stack) {
154+
var indexOfMessage = test.err.stack.indexOf(test.err.message);
155+
if (indexOfMessage === -1) {
156+
stackString = test.err.stack;
189157
} else {
190-
el.appendChild(fragment('<pre class="error">%e%e</pre>', message, stackString));
158+
stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);
191159
}
160+
} else if (test.err.sourceURL && test.err.line !== undefined) {
161+
// Safari doesn't give you a stack. Let's at least provide a source line.
162+
stackString = '\n(' + test.err.sourceURL + ':' + test.err.line + ')';
192163
}
193164

194-
// toggle code
195-
// TODO: defer
196-
if (!test.isPending()) {
197-
var h2 = el.getElementsByTagName('h2')[0];
165+
stackString = stackString || '';
198166

199-
on(h2, 'click', function() {
200-
pre.style.display = pre.style.display === 'none' ? 'block' : 'none';
201-
});
202-
203-
var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.body));
204-
el.appendChild(pre);
205-
pre.style.display = 'none';
167+
if (test.err.htmlMessage && stackString) {
168+
el.appendChild(fragment('<div class="html-error">%s\n<pre class="error">%e</pre></div>',
169+
test.err.htmlMessage, stackString));
170+
} else if (test.err.htmlMessage) {
171+
el.appendChild(fragment('<div class="html-error">%s</div>', test.err.htmlMessage));
172+
} else {
173+
el.appendChild(fragment('<pre class="error">%e%e</pre>', message, stackString));
206174
}
207175

176+
self.addCodeToggle(el, test.body);
177+
appendToStack(el);
178+
updateStats();
179+
});
180+
181+
runner.on('pending', function(test) {
182+
var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
183+
appendToStack(el);
184+
updateStats();
185+
});
186+
187+
function appendToStack(el) {
208188
// Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
209189
if (stack[0]) {
210190
stack[0].appendChild(el);
211191
}
212-
});
192+
}
193+
194+
function updateStats() {
195+
// TODO: add to stats
196+
var percent = stats.tests / this.total * 100 | 0;
197+
if (progress) {
198+
progress.update(percent).draw(ctx);
199+
}
200+
201+
// update stats
202+
var ms = new Date() - stats.start;
203+
text(passes, stats.passes);
204+
text(failures, stats.failures);
205+
text(duration, (ms / 1000).toFixed(2));
206+
}
213207
}
214208

215209
/**
@@ -247,6 +241,24 @@ HTML.prototype.testURL = function(test) {
247241
return makeUrl(test.fullTitle());
248242
};
249243

244+
/**
245+
* Adds code toggle functionality for the provided test's list element.
246+
*
247+
* @param {HTMLLIElement} el
248+
* @param {string} contents
249+
*/
250+
HTML.prototype.addCodeToggle = function(el, contents) {
251+
var h2 = el.getElementsByTagName('h2')[0];
252+
253+
on(h2, 'click', function() {
254+
pre.style.display = pre.style.display === 'none' ? 'block' : 'none';
255+
});
256+
257+
var pre = fragment('<pre><code>%e</code></pre>', utils.clean(contents));
258+
el.appendChild(pre);
259+
pre.style.display = 'none';
260+
};
261+
250262
/**
251263
* Display error `msg`.
252264
*

0 commit comments

Comments
 (0)
Please sign in to comment.