mocha 2.2.5 → 2.3.3
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.
- package/HISTORY.md +1034 -0
- package/bin/.eslintrc +3 -0
- package/bin/_mocha +12 -15
- package/bin/mocha +3 -10
- package/bin/options.js +6 -5
- package/lib/browser/debug.js +3 -3
- package/lib/browser/events.js +42 -26
- package/lib/browser/progress.js +37 -45
- package/lib/browser/tty.js +4 -5
- package/lib/context.js +26 -32
- package/lib/hook.js +5 -7
- package/lib/interfaces/bdd.js +21 -26
- package/lib/interfaces/common.js +33 -15
- package/lib/interfaces/exports.js +7 -7
- package/lib/interfaces/qunit.js +16 -17
- package/lib/interfaces/tdd.js +24 -28
- package/lib/mocha.js +140 -99
- package/lib/ms.js +43 -24
- package/lib/pending.js +2 -3
- package/lib/reporters/base.js +159 -138
- package/lib/reporters/doc.js +13 -13
- package/lib/reporters/dot.js +23 -19
- package/lib/reporters/html-cov.js +25 -19
- package/lib/reporters/html.js +130 -91
- package/lib/reporters/index.js +19 -17
- package/lib/reporters/json-cov.js +39 -41
- package/lib/reporters/json-stream.js +14 -17
- package/lib/reporters/json.js +16 -19
- package/lib/reporters/landing.js +20 -24
- package/lib/reporters/list.js +14 -16
- package/lib/reporters/markdown.js +17 -20
- package/lib/reporters/min.js +4 -5
- package/lib/reporters/nyan.js +49 -48
- package/lib/reporters/progress.js +20 -23
- package/lib/reporters/spec.js +23 -22
- package/lib/reporters/tap.js +15 -19
- package/lib/reporters/xunit.js +83 -63
- package/lib/runnable.js +134 -94
- package/lib/runner.js +291 -167
- package/lib/suite.js +105 -95
- package/lib/template.html +1 -1
- package/lib/test.js +3 -4
- package/lib/utils.js +227 -199
- package/mocha.css +35 -0
- package/mocha.js +8324 -2471
- package/package.json +250 -10
- package/lib/browser/escape-string-regexp.js +0 -11
- package/lib/browser/fs.js +0 -0
- package/lib/browser/glob.js +0 -0
- package/lib/browser/path.js +0 -0
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Module dependencies.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
var JSONCov = require('./json-cov')
|
|
6
|
-
|
|
5
|
+
var JSONCov = require('./json-cov');
|
|
6
|
+
var readFileSync = require('fs').readFileSync;
|
|
7
|
+
var join = require('path').join;
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Expose `HTMLCov`.
|
|
@@ -14,37 +15,42 @@ exports = module.exports = HTMLCov;
|
|
|
14
15
|
/**
|
|
15
16
|
* Initialize a new `JsCoverage` reporter.
|
|
16
17
|
*
|
|
17
|
-
* @param {Runner} runner
|
|
18
18
|
* @api public
|
|
19
|
+
* @param {Runner} runner
|
|
19
20
|
*/
|
|
20
|
-
|
|
21
21
|
function HTMLCov(runner) {
|
|
22
|
-
var jade = require('jade')
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
var jade = require('jade');
|
|
23
|
+
var file = join(__dirname, '/templates/coverage.jade');
|
|
24
|
+
var str = readFileSync(file, 'utf8');
|
|
25
|
+
var fn = jade.compile(str, { filename: file });
|
|
26
|
+
var self = this;
|
|
27
27
|
|
|
28
28
|
JSONCov.call(this, runner, false);
|
|
29
29
|
|
|
30
|
-
runner.on('end', function(){
|
|
30
|
+
runner.on('end', function() {
|
|
31
31
|
process.stdout.write(fn({
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
cov: self.cov,
|
|
33
|
+
coverageClass: coverageClass
|
|
34
34
|
}));
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* Return coverage class for
|
|
39
|
+
* Return coverage class for a given coverage percentage.
|
|
40
40
|
*
|
|
41
|
-
* @return {String}
|
|
42
41
|
* @api private
|
|
42
|
+
* @param {number} coveragePctg
|
|
43
|
+
* @return {string}
|
|
43
44
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (
|
|
45
|
+
function coverageClass(coveragePctg) {
|
|
46
|
+
if (coveragePctg >= 75) {
|
|
47
|
+
return 'high';
|
|
48
|
+
}
|
|
49
|
+
if (coveragePctg >= 50) {
|
|
50
|
+
return 'medium';
|
|
51
|
+
}
|
|
52
|
+
if (coveragePctg >= 25) {
|
|
53
|
+
return 'low';
|
|
54
|
+
}
|
|
49
55
|
return 'terrible';
|
|
50
56
|
}
|
package/lib/reporters/html.js
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
|
+
/* eslint-env browser */
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Module dependencies.
|
|
3
5
|
*/
|
|
4
6
|
|
|
5
|
-
var Base = require('./base')
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
var Base = require('./base');
|
|
8
|
+
var utils = require('../utils');
|
|
9
|
+
var Progress = require('../browser/progress');
|
|
10
|
+
var escapeRe = require('escape-string-regexp');
|
|
11
|
+
var escape = utils.escape;
|
|
9
12
|
|
|
10
13
|
/**
|
|
11
14
|
* Save timer references to avoid Sinon interfering (see GH-237).
|
|
12
15
|
*/
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
/* eslint-disable no-unused-vars, no-native-reassign */
|
|
18
|
+
var Date = global.Date;
|
|
19
|
+
var setTimeout = global.setTimeout;
|
|
20
|
+
var setInterval = global.setInterval;
|
|
21
|
+
var clearTimeout = global.clearTimeout;
|
|
22
|
+
var clearInterval = global.clearInterval;
|
|
23
|
+
/* eslint-enable no-unused-vars, no-native-reassign */
|
|
19
24
|
|
|
20
25
|
/**
|
|
21
26
|
* Expose `HTML`.
|
|
@@ -29,37 +34,35 @@ exports = module.exports = HTML;
|
|
|
29
34
|
|
|
30
35
|
var statsTemplate = '<ul id="mocha-stats">'
|
|
31
36
|
+ '<li class="progress"><canvas width="40" height="40"></canvas></li>'
|
|
32
|
-
+ '<li class="passes"><a href="
|
|
33
|
-
+ '<li class="failures"><a href="
|
|
37
|
+
+ '<li class="passes"><a href="javascript:void(0);">passes:</a> <em>0</em></li>'
|
|
38
|
+
+ '<li class="failures"><a href="javascript:void(0);">failures:</a> <em>0</em></li>'
|
|
34
39
|
+ '<li class="duration">duration: <em>0</em>s</li>'
|
|
35
40
|
+ '</ul>';
|
|
36
41
|
|
|
37
42
|
/**
|
|
38
43
|
* Initialize a new `HTML` reporter.
|
|
39
44
|
*
|
|
40
|
-
* @param {Runner} runner
|
|
41
45
|
* @api public
|
|
46
|
+
* @param {Runner} runner
|
|
42
47
|
*/
|
|
43
|
-
|
|
44
48
|
function HTML(runner) {
|
|
45
49
|
Base.call(this, runner);
|
|
46
50
|
|
|
47
|
-
var self = this
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
, root = document.getElementById('mocha');
|
|
51
|
+
var self = this;
|
|
52
|
+
var stats = this.stats;
|
|
53
|
+
var stat = fragment(statsTemplate);
|
|
54
|
+
var items = stat.getElementsByTagName('li');
|
|
55
|
+
var passes = items[1].getElementsByTagName('em')[0];
|
|
56
|
+
var passesLink = items[1].getElementsByTagName('a')[0];
|
|
57
|
+
var failures = items[2].getElementsByTagName('em')[0];
|
|
58
|
+
var failuresLink = items[2].getElementsByTagName('a')[0];
|
|
59
|
+
var duration = items[3].getElementsByTagName('em')[0];
|
|
60
|
+
var canvas = stat.getElementsByTagName('canvas')[0];
|
|
61
|
+
var report = fragment('<ul id="mocha-report"></ul>');
|
|
62
|
+
var stack = [report];
|
|
63
|
+
var progress;
|
|
64
|
+
var ctx;
|
|
65
|
+
var root = document.getElementById('mocha');
|
|
63
66
|
|
|
64
67
|
if (canvas.getContext) {
|
|
65
68
|
var ratio = window.devicePixelRatio || 1;
|
|
@@ -69,34 +72,44 @@ function HTML(runner) {
|
|
|
69
72
|
canvas.height *= ratio;
|
|
70
73
|
ctx = canvas.getContext('2d');
|
|
71
74
|
ctx.scale(ratio, ratio);
|
|
72
|
-
progress = new Progress;
|
|
75
|
+
progress = new Progress();
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
if (!root)
|
|
78
|
+
if (!root) {
|
|
79
|
+
return error('#mocha div missing, add it to your document');
|
|
80
|
+
}
|
|
76
81
|
|
|
77
82
|
// pass toggle
|
|
78
|
-
on(passesLink, 'click', function(){
|
|
83
|
+
on(passesLink, 'click', function() {
|
|
79
84
|
unhide();
|
|
80
|
-
var name = /pass
|
|
85
|
+
var name = (/pass/).test(report.className) ? '' : ' pass';
|
|
81
86
|
report.className = report.className.replace(/fail|pass/g, '') + name;
|
|
82
|
-
if (report.className.trim())
|
|
87
|
+
if (report.className.trim()) {
|
|
88
|
+
hideSuitesWithout('test pass');
|
|
89
|
+
}
|
|
83
90
|
});
|
|
84
91
|
|
|
85
92
|
// failure toggle
|
|
86
|
-
on(failuresLink, 'click', function(){
|
|
93
|
+
on(failuresLink, 'click', function() {
|
|
87
94
|
unhide();
|
|
88
|
-
var name = /fail
|
|
95
|
+
var name = (/fail/).test(report.className) ? '' : ' fail';
|
|
89
96
|
report.className = report.className.replace(/fail|pass/g, '') + name;
|
|
90
|
-
if (report.className.trim())
|
|
97
|
+
if (report.className.trim()) {
|
|
98
|
+
hideSuitesWithout('test fail');
|
|
99
|
+
}
|
|
91
100
|
});
|
|
92
101
|
|
|
93
102
|
root.appendChild(stat);
|
|
94
103
|
root.appendChild(report);
|
|
95
104
|
|
|
96
|
-
if (progress)
|
|
105
|
+
if (progress) {
|
|
106
|
+
progress.size(40);
|
|
107
|
+
}
|
|
97
108
|
|
|
98
|
-
runner.on('suite', function(suite){
|
|
99
|
-
if (suite.root)
|
|
109
|
+
runner.on('suite', function(suite) {
|
|
110
|
+
if (suite.root) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
100
113
|
|
|
101
114
|
// suite
|
|
102
115
|
var url = self.suiteURL(suite);
|
|
@@ -108,51 +121,71 @@ function HTML(runner) {
|
|
|
108
121
|
el.appendChild(stack[0]);
|
|
109
122
|
});
|
|
110
123
|
|
|
111
|
-
runner.on('suite end', function(suite){
|
|
112
|
-
if (suite.root)
|
|
124
|
+
runner.on('suite end', function(suite) {
|
|
125
|
+
if (suite.root) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
113
128
|
stack.shift();
|
|
114
129
|
});
|
|
115
130
|
|
|
116
|
-
runner.on('fail', function(test
|
|
117
|
-
if (
|
|
131
|
+
runner.on('fail', function(test) {
|
|
132
|
+
if (test.type === 'hook') {
|
|
133
|
+
runner.emit('test end', test);
|
|
134
|
+
}
|
|
118
135
|
});
|
|
119
136
|
|
|
120
|
-
runner.on('test end', function(test){
|
|
137
|
+
runner.on('test end', function(test) {
|
|
121
138
|
// TODO: add to stats
|
|
122
139
|
var percent = stats.tests / this.total * 100 | 0;
|
|
123
|
-
if (progress)
|
|
140
|
+
if (progress) {
|
|
141
|
+
progress.update(percent).draw(ctx);
|
|
142
|
+
}
|
|
124
143
|
|
|
125
144
|
// update stats
|
|
126
|
-
var ms = new Date - stats.start;
|
|
145
|
+
var ms = new Date() - stats.start;
|
|
127
146
|
text(passes, stats.passes);
|
|
128
147
|
text(failures, stats.failures);
|
|
129
148
|
text(duration, (ms / 1000).toFixed(2));
|
|
130
149
|
|
|
131
150
|
// test
|
|
132
|
-
|
|
151
|
+
var el;
|
|
152
|
+
if (test.state === 'passed') {
|
|
133
153
|
var url = self.testURL(test);
|
|
134
|
-
|
|
154
|
+
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);
|
|
135
155
|
} else if (test.pending) {
|
|
136
|
-
|
|
156
|
+
el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
|
|
137
157
|
} else {
|
|
138
|
-
|
|
139
|
-
var
|
|
140
|
-
|
|
141
|
-
// FF / Opera do not add the message
|
|
142
|
-
if (!~str.indexOf(test.err.message)) {
|
|
143
|
-
str = test.err.message + '\n' + str;
|
|
144
|
-
}
|
|
158
|
+
el = fragment('<li class="test fail"><h2>%e <a href="%e" class="replay">‣</a></h2></li>', test.title, self.testURL(test));
|
|
159
|
+
var stackString; // Note: Includes leading newline
|
|
160
|
+
var message = test.err.toString();
|
|
145
161
|
|
|
146
162
|
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
|
|
147
163
|
// check for the result of the stringifying.
|
|
148
|
-
if ('[object Error]'
|
|
164
|
+
if (message === '[object Error]') {
|
|
165
|
+
message = test.err.message;
|
|
166
|
+
}
|
|
149
167
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
168
|
+
if (test.err.stack) {
|
|
169
|
+
var indexOfMessage = test.err.stack.indexOf(test.err.message);
|
|
170
|
+
if (indexOfMessage === -1) {
|
|
171
|
+
stackString = test.err.stack;
|
|
172
|
+
} else {
|
|
173
|
+
stackString = test.err.stack.substr(test.err.message.length + indexOfMessage);
|
|
174
|
+
}
|
|
175
|
+
} else if (test.err.sourceURL && test.err.line !== undefined) {
|
|
176
|
+
// Safari doesn't give you a stack. Let's at least provide a source line.
|
|
177
|
+
stackString = '\n(' + test.err.sourceURL + ':' + test.err.line + ')';
|
|
153
178
|
}
|
|
154
179
|
|
|
155
|
-
|
|
180
|
+
stackString = stackString || '';
|
|
181
|
+
|
|
182
|
+
if (test.err.htmlMessage && stackString) {
|
|
183
|
+
el.appendChild(fragment('<div class="html-error">%s\n<pre class="error">%e</pre></div>', test.err.htmlMessage, stackString));
|
|
184
|
+
} else if (test.err.htmlMessage) {
|
|
185
|
+
el.appendChild(fragment('<div class="html-error">%s</div>', test.err.htmlMessage));
|
|
186
|
+
} else {
|
|
187
|
+
el.appendChild(fragment('<pre class="error">%e%e</pre>', message, stackString));
|
|
188
|
+
}
|
|
156
189
|
}
|
|
157
190
|
|
|
158
191
|
// toggle code
|
|
@@ -160,10 +193,8 @@ function HTML(runner) {
|
|
|
160
193
|
if (!test.pending) {
|
|
161
194
|
var h2 = el.getElementsByTagName('h2')[0];
|
|
162
195
|
|
|
163
|
-
on(h2, 'click', function(){
|
|
164
|
-
pre.style.display = 'none'
|
|
165
|
-
? 'block'
|
|
166
|
-
: 'none';
|
|
196
|
+
on(h2, 'click', function() {
|
|
197
|
+
pre.style.display = pre.style.display === 'none' ? 'block' : 'none';
|
|
167
198
|
});
|
|
168
199
|
|
|
169
200
|
var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
|
|
@@ -172,16 +203,19 @@ function HTML(runner) {
|
|
|
172
203
|
}
|
|
173
204
|
|
|
174
205
|
// Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.
|
|
175
|
-
if (stack[0])
|
|
206
|
+
if (stack[0]) {
|
|
207
|
+
stack[0].appendChild(el);
|
|
208
|
+
}
|
|
176
209
|
});
|
|
177
210
|
}
|
|
178
211
|
|
|
179
212
|
/**
|
|
180
213
|
* Makes a URL, preserving querystring ("search") parameters.
|
|
214
|
+
*
|
|
181
215
|
* @param {string} s
|
|
182
|
-
* @
|
|
216
|
+
* @return {string} A new URL.
|
|
183
217
|
*/
|
|
184
|
-
|
|
218
|
+
function makeUrl(s) {
|
|
185
219
|
var search = window.location.search;
|
|
186
220
|
|
|
187
221
|
// Remove previous grep query parameter if present
|
|
@@ -189,49 +223,51 @@ var makeUrl = function makeUrl(s) {
|
|
|
189
223
|
search = search.replace(/[?&]grep=[^&\s]*/g, '').replace(/^&/, '?');
|
|
190
224
|
}
|
|
191
225
|
|
|
192
|
-
return window.location.pathname + (search ? search + '&' : '?'
|
|
193
|
-
}
|
|
226
|
+
return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s));
|
|
227
|
+
}
|
|
194
228
|
|
|
195
229
|
/**
|
|
196
|
-
* Provide suite URL
|
|
230
|
+
* Provide suite URL.
|
|
197
231
|
*
|
|
198
232
|
* @param {Object} [suite]
|
|
199
233
|
*/
|
|
200
|
-
HTML.prototype.suiteURL = function(suite){
|
|
234
|
+
HTML.prototype.suiteURL = function(suite) {
|
|
201
235
|
return makeUrl(suite.fullTitle());
|
|
202
236
|
};
|
|
203
237
|
|
|
204
238
|
/**
|
|
205
|
-
* Provide test URL
|
|
239
|
+
* Provide test URL.
|
|
206
240
|
*
|
|
207
241
|
* @param {Object} [test]
|
|
208
242
|
*/
|
|
209
|
-
|
|
210
|
-
HTML.prototype.testURL = function(test){
|
|
243
|
+
HTML.prototype.testURL = function(test) {
|
|
211
244
|
return makeUrl(test.fullTitle());
|
|
212
245
|
};
|
|
213
246
|
|
|
214
247
|
/**
|
|
215
248
|
* Display error `msg`.
|
|
249
|
+
*
|
|
250
|
+
* @param {string} msg
|
|
216
251
|
*/
|
|
217
|
-
|
|
218
252
|
function error(msg) {
|
|
219
253
|
document.body.appendChild(fragment('<div id="mocha-error">%s</div>', msg));
|
|
220
254
|
}
|
|
221
255
|
|
|
222
256
|
/**
|
|
223
257
|
* Return a DOM fragment from `html`.
|
|
258
|
+
*
|
|
259
|
+
* @param {string} html
|
|
224
260
|
*/
|
|
225
|
-
|
|
226
261
|
function fragment(html) {
|
|
227
|
-
var args = arguments
|
|
228
|
-
|
|
229
|
-
|
|
262
|
+
var args = arguments;
|
|
263
|
+
var div = document.createElement('div');
|
|
264
|
+
var i = 1;
|
|
230
265
|
|
|
231
|
-
div.innerHTML = html.replace(/%([se])/g, function(_, type){
|
|
266
|
+
div.innerHTML = html.replace(/%([se])/g, function(_, type) {
|
|
232
267
|
switch (type) {
|
|
233
268
|
case 's': return String(args[i++]);
|
|
234
269
|
case 'e': return escape(args[i++]);
|
|
270
|
+
// no default
|
|
235
271
|
}
|
|
236
272
|
});
|
|
237
273
|
|
|
@@ -241,20 +277,22 @@ function fragment(html) {
|
|
|
241
277
|
/**
|
|
242
278
|
* Check for suites that do not have elements
|
|
243
279
|
* with `classname`, and hide them.
|
|
280
|
+
*
|
|
281
|
+
* @param {text} classname
|
|
244
282
|
*/
|
|
245
|
-
|
|
246
283
|
function hideSuitesWithout(classname) {
|
|
247
284
|
var suites = document.getElementsByClassName('suite');
|
|
248
285
|
for (var i = 0; i < suites.length; i++) {
|
|
249
286
|
var els = suites[i].getElementsByClassName(classname);
|
|
250
|
-
if (
|
|
287
|
+
if (!els.length) {
|
|
288
|
+
suites[i].className += ' hidden';
|
|
289
|
+
}
|
|
251
290
|
}
|
|
252
291
|
}
|
|
253
292
|
|
|
254
293
|
/**
|
|
255
294
|
* Unhide .hidden suites.
|
|
256
295
|
*/
|
|
257
|
-
|
|
258
296
|
function unhide() {
|
|
259
297
|
var els = document.getElementsByClassName('suite hidden');
|
|
260
298
|
for (var i = 0; i < els.length; ++i) {
|
|
@@ -263,21 +301,22 @@ function unhide() {
|
|
|
263
301
|
}
|
|
264
302
|
|
|
265
303
|
/**
|
|
266
|
-
* Set
|
|
304
|
+
* Set an element's text contents.
|
|
305
|
+
*
|
|
306
|
+
* @param {HTMLElement} el
|
|
307
|
+
* @param {string} contents
|
|
267
308
|
*/
|
|
268
|
-
|
|
269
|
-
function text(el, str) {
|
|
309
|
+
function text(el, contents) {
|
|
270
310
|
if (el.textContent) {
|
|
271
|
-
el.textContent =
|
|
311
|
+
el.textContent = contents;
|
|
272
312
|
} else {
|
|
273
|
-
el.innerText =
|
|
313
|
+
el.innerText = contents;
|
|
274
314
|
}
|
|
275
315
|
}
|
|
276
316
|
|
|
277
317
|
/**
|
|
278
318
|
* Listen on `event` with callback `fn`.
|
|
279
319
|
*/
|
|
280
|
-
|
|
281
320
|
function on(el, event, fn) {
|
|
282
321
|
if (el.addEventListener) {
|
|
283
322
|
el.addEventListener(event, fn, false);
|
package/lib/reporters/index.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
exports
|
|
2
|
-
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
10
|
-
exports.
|
|
11
|
-
exports.
|
|
12
|
-
exports.
|
|
13
|
-
exports.
|
|
14
|
-
exports.
|
|
15
|
-
exports.
|
|
16
|
-
exports.
|
|
17
|
-
exports.
|
|
1
|
+
// Alias exports to a their normalized format Mocha#reporter to prevent a need
|
|
2
|
+
// for dynamic (try/catch) requires, which Browserify doesn't handle.
|
|
3
|
+
exports.Base = exports.base = require('./base');
|
|
4
|
+
exports.Dot = exports.dot = require('./dot');
|
|
5
|
+
exports.Doc = exports.doc = require('./doc');
|
|
6
|
+
exports.TAP = exports.tap = require('./tap');
|
|
7
|
+
exports.JSON = exports.json = require('./json');
|
|
8
|
+
exports.HTML = exports.html = require('./html');
|
|
9
|
+
exports.List = exports.list = require('./list');
|
|
10
|
+
exports.Min = exports.min = require('./min');
|
|
11
|
+
exports.Spec = exports.spec = require('./spec');
|
|
12
|
+
exports.Nyan = exports.nyan = require('./nyan');
|
|
13
|
+
exports.XUnit = exports.xunit = require('./xunit');
|
|
14
|
+
exports.Markdown = exports.markdown = require('./markdown');
|
|
15
|
+
exports.Progress = exports.progress = require('./progress');
|
|
16
|
+
exports.Landing = exports.landing = require('./landing');
|
|
17
|
+
exports.JSONCov = exports['json-cov'] = require('./json-cov');
|
|
18
|
+
exports.HTMLCov = exports['html-cov'] = require('./html-cov');
|
|
19
|
+
exports.JSONStream = exports['json-stream'] = require('./json-stream');
|
|
@@ -13,42 +13,42 @@ exports = module.exports = JSONCov;
|
|
|
13
13
|
/**
|
|
14
14
|
* Initialize a new `JsCoverage` reporter.
|
|
15
15
|
*
|
|
16
|
-
* @param {Runner} runner
|
|
17
|
-
* @param {Boolean} output
|
|
18
16
|
* @api public
|
|
17
|
+
* @param {Runner} runner
|
|
18
|
+
* @param {boolean} output
|
|
19
19
|
*/
|
|
20
|
-
|
|
21
20
|
function JSONCov(runner, output) {
|
|
22
|
-
var self = this
|
|
23
|
-
, output = 1 == arguments.length ? true : output;
|
|
24
|
-
|
|
25
21
|
Base.call(this, runner);
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
output = arguments.length === 1 || output;
|
|
24
|
+
var self = this;
|
|
25
|
+
var tests = [];
|
|
26
|
+
var failures = [];
|
|
27
|
+
var passes = [];
|
|
30
28
|
|
|
31
|
-
runner.on('test end', function(test){
|
|
29
|
+
runner.on('test end', function(test) {
|
|
32
30
|
tests.push(test);
|
|
33
31
|
});
|
|
34
32
|
|
|
35
|
-
runner.on('pass', function(test){
|
|
33
|
+
runner.on('pass', function(test) {
|
|
36
34
|
passes.push(test);
|
|
37
35
|
});
|
|
38
36
|
|
|
39
|
-
runner.on('fail', function(test){
|
|
37
|
+
runner.on('fail', function(test) {
|
|
40
38
|
failures.push(test);
|
|
41
39
|
});
|
|
42
40
|
|
|
43
|
-
runner.on('end', function(){
|
|
41
|
+
runner.on('end', function() {
|
|
44
42
|
var cov = global._$jscoverage || {};
|
|
45
43
|
var result = self.cov = map(cov);
|
|
46
44
|
result.stats = self.stats;
|
|
47
45
|
result.tests = tests.map(clean);
|
|
48
46
|
result.failures = failures.map(clean);
|
|
49
47
|
result.passes = passes.map(clean);
|
|
50
|
-
if (!output)
|
|
51
|
-
|
|
48
|
+
if (!output) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
process.stdout.write(JSON.stringify(result, null, 2));
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -56,27 +56,29 @@ function JSONCov(runner, output) {
|
|
|
56
56
|
* Map jscoverage data to a JSON structure
|
|
57
57
|
* suitable for reporting.
|
|
58
58
|
*
|
|
59
|
+
* @api private
|
|
59
60
|
* @param {Object} cov
|
|
60
61
|
* @return {Object}
|
|
61
|
-
* @api private
|
|
62
62
|
*/
|
|
63
63
|
|
|
64
64
|
function map(cov) {
|
|
65
65
|
var ret = {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
instrumentation: 'node-jscoverage',
|
|
67
|
+
sloc: 0,
|
|
68
|
+
hits: 0,
|
|
69
|
+
misses: 0,
|
|
70
|
+
coverage: 0,
|
|
71
|
+
files: []
|
|
72
72
|
};
|
|
73
73
|
|
|
74
74
|
for (var filename in cov) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
if (Object.prototype.hasOwnProperty.call(cov, filename)) {
|
|
76
|
+
var data = coverage(filename, cov[filename]);
|
|
77
|
+
ret.files.push(data);
|
|
78
|
+
ret.hits += data.hits;
|
|
79
|
+
ret.misses += data.misses;
|
|
80
|
+
ret.sloc += data.sloc;
|
|
81
|
+
}
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
ret.files.sort(function(a, b) {
|
|
@@ -94,12 +96,11 @@ function map(cov) {
|
|
|
94
96
|
* Map jscoverage data for a single source file
|
|
95
97
|
* to a JSON structure suitable for reporting.
|
|
96
98
|
*
|
|
97
|
-
* @
|
|
99
|
+
* @api private
|
|
100
|
+
* @param {string} filename name of the source file
|
|
98
101
|
* @param {Object} data jscoverage coverage data
|
|
99
102
|
* @return {Object}
|
|
100
|
-
* @api private
|
|
101
103
|
*/
|
|
102
|
-
|
|
103
104
|
function coverage(filename, data) {
|
|
104
105
|
var ret = {
|
|
105
106
|
filename: filename,
|
|
@@ -110,7 +111,7 @@ function coverage(filename, data) {
|
|
|
110
111
|
source: {}
|
|
111
112
|
};
|
|
112
113
|
|
|
113
|
-
data.source.forEach(function(line, num){
|
|
114
|
+
data.source.forEach(function(line, num) {
|
|
114
115
|
num++;
|
|
115
116
|
|
|
116
117
|
if (data[num] === 0) {
|
|
@@ -122,10 +123,8 @@ function coverage(filename, data) {
|
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
ret.source[num] = {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
? ''
|
|
128
|
-
: data[num]
|
|
126
|
+
source: line,
|
|
127
|
+
coverage: data[num] === undefined ? '' : data[num]
|
|
129
128
|
};
|
|
130
129
|
});
|
|
131
130
|
|
|
@@ -138,15 +137,14 @@ function coverage(filename, data) {
|
|
|
138
137
|
* Return a plain-object representation of `test`
|
|
139
138
|
* free of cyclic properties etc.
|
|
140
139
|
*
|
|
140
|
+
* @api private
|
|
141
141
|
* @param {Object} test
|
|
142
142
|
* @return {Object}
|
|
143
|
-
* @api private
|
|
144
143
|
*/
|
|
145
|
-
|
|
146
144
|
function clean(test) {
|
|
147
145
|
return {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
146
|
+
duration: test.duration,
|
|
147
|
+
fullTitle: test.fullTitle(),
|
|
148
|
+
title: test.title
|
|
149
|
+
};
|
|
152
150
|
}
|