konacha 0.9.0 → 0.9.1
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.
- data/.gitignore +1 -0
- data/History.md +14 -0
- data/README.md +6 -21
- data/Vendorfile +5 -0
- data/app/controllers/konacha/specs_controller.rb +4 -15
- data/app/helpers/konacha/specs_helper.rb +11 -0
- data/app/models/konacha/spec.rb +8 -5
- data/app/views/{layouts/konacha → konacha/specs}/specs.html.erb +10 -6
- data/config/routes.rb +2 -2
- data/konacha.gemspec +4 -3
- data/lib/konacha/engine.rb +4 -2
- data/spec/controllers/specs_controller_spec.rb +8 -32
- data/spec/dummy/spec/javascripts/test_element_spec.js.coffee +10 -0
- data/spec/models/spec_spec.rb +25 -13
- data/spec/runner_spec.rb +9 -4
- data/spec/server_spec.rb +6 -0
- data/spec/spec_helper.rb +22 -3
- data/spec/views/specs/specs.html.erb_spec.rb +33 -3
- data/vendor/assets/javascripts/chai.js +221 -86
- data/vendor/assets/javascripts/konacha/runner.js +29 -62
- data/vendor/assets/javascripts/konacha/server.js +3 -0
- data/vendor/assets/javascripts/mocha.js +493 -59
- data/vendor/assets/stylesheets/konacha.css +6 -0
- data/vendor/assets/stylesheets/mocha.css +5 -1
- metadata +49 -32
- data/app/views/konacha/specs/index.html.erb +0 -1
- data/app/views/konacha/specs/show.html.erb +0 -1
- data/spec/dummy/spec/javascripts/transactions_spec.js.coffee +0 -7
- data/spec/views/specs/index.html.erb_spec.rb +0 -12
- data/spec/views/specs/show.html.erb_spec.rb +0 -10
@@ -1,70 +1,37 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
dots:"",
|
1
|
+
window.Konacha = {
|
2
|
+
dots:"",
|
4
3
|
|
5
|
-
|
6
|
-
|
4
|
+
Reporter:function (runner) {
|
5
|
+
window.mocha.reporters.Base.call(this, runner);
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
runner.on('pass', function (test) {
|
13
|
-
Konacha.dots += ".";
|
14
|
-
Konacha.results.push({
|
15
|
-
name: test.title,
|
16
|
-
passed: true
|
17
|
-
});
|
18
|
-
});
|
7
|
+
runner.on('start', function () {
|
8
|
+
Konacha.results = [];
|
9
|
+
});
|
19
10
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
message: test.err.message,
|
26
|
-
trace: test.err.stack
|
27
|
-
});
|
11
|
+
runner.on('pass', function (test) {
|
12
|
+
Konacha.dots += ".";
|
13
|
+
Konacha.results.push({
|
14
|
+
name:test.title,
|
15
|
+
passed:true
|
28
16
|
});
|
29
|
-
|
30
|
-
|
31
|
-
|
17
|
+
});
|
18
|
+
|
19
|
+
runner.on('fail', function (test) {
|
20
|
+
Konacha.dots += "F";
|
21
|
+
Konacha.results.push({
|
22
|
+
name:test.title,
|
23
|
+
passed:false,
|
24
|
+
message:test.err.message,
|
25
|
+
trace:test.err.stack
|
32
26
|
});
|
33
|
-
}
|
27
|
+
});
|
34
28
|
|
35
|
-
|
36
|
-
|
37
|
-
}
|
38
|
-
}
|
29
|
+
runner.on('end', function () {
|
30
|
+
Konacha.done = true;
|
31
|
+
});
|
32
|
+
},
|
39
33
|
|
40
|
-
|
41
|
-
|
42
|
-
, Reporter = Konacha.Reporter;
|
43
|
-
|
44
|
-
function parse(qs) {
|
45
|
-
return utils.reduce(qs.replace('?', '').split('&'), function(obj, pair){
|
46
|
-
var i = pair.indexOf('=')
|
47
|
-
, key = pair.slice(0, i)
|
48
|
-
, val = pair.slice(++i);
|
49
|
-
|
50
|
-
obj[key] = decodeURIComponent(val);
|
51
|
-
return obj;
|
52
|
-
}, {});
|
34
|
+
getResults:function () {
|
35
|
+
return JSON.stringify(Konacha.results);
|
53
36
|
}
|
54
|
-
|
55
|
-
mocha.setup = function (ui) {
|
56
|
-
ui = mocha.interfaces[ui];
|
57
|
-
if (!ui) throw new Error('invalid mocha interface "' + ui + '"');
|
58
|
-
ui(suite);
|
59
|
-
suite.emit('pre-require', window);
|
60
|
-
};
|
61
|
-
|
62
|
-
mocha.run = function () {
|
63
|
-
suite.emit('run');
|
64
|
-
var runner = new mocha.Runner(suite);
|
65
|
-
var reporter = new Reporter(runner);
|
66
|
-
var query = parse(window.location.search || "");
|
67
|
-
if (query.grep) runner.grep(new RegExp(query.grep));
|
68
|
-
return runner.run();
|
69
|
-
};
|
70
|
-
})();
|
37
|
+
};
|
@@ -57,6 +57,10 @@ module.exports = function(type){
|
|
57
57
|
};
|
58
58
|
}); // module: browser/debug.js
|
59
59
|
|
60
|
+
require.register("browser/diff.js", function(module, exports, require){
|
61
|
+
|
62
|
+
}); // module: browser/diff.js
|
63
|
+
|
60
64
|
require.register("browser/events.js", function(module, exports, require){
|
61
65
|
|
62
66
|
/**
|
@@ -386,6 +390,65 @@ exports.getWindowSize = function(){
|
|
386
390
|
};
|
387
391
|
}); // module: browser/tty.js
|
388
392
|
|
393
|
+
require.register("context.js", function(module, exports, require){
|
394
|
+
|
395
|
+
/**
|
396
|
+
* Expose `Context`.
|
397
|
+
*/
|
398
|
+
|
399
|
+
module.exports = Context;
|
400
|
+
|
401
|
+
/**
|
402
|
+
* Initialize a new `Context`.
|
403
|
+
*
|
404
|
+
* @api private
|
405
|
+
*/
|
406
|
+
|
407
|
+
function Context(){}
|
408
|
+
|
409
|
+
/**
|
410
|
+
* Set the context `Test` to `test`.
|
411
|
+
*
|
412
|
+
* @param {Test} test
|
413
|
+
* @return {Context}
|
414
|
+
* @api private
|
415
|
+
*/
|
416
|
+
|
417
|
+
Context.prototype.test = function(test){
|
418
|
+
this._test = test;
|
419
|
+
return this;
|
420
|
+
};
|
421
|
+
|
422
|
+
/**
|
423
|
+
* Set test timeout `ms`.
|
424
|
+
*
|
425
|
+
* @param {Number} ms
|
426
|
+
* @return {Context} self
|
427
|
+
* @api private
|
428
|
+
*/
|
429
|
+
|
430
|
+
Context.prototype.timeout = function(ms){
|
431
|
+
this._test.timeout(ms);
|
432
|
+
return this;
|
433
|
+
};
|
434
|
+
|
435
|
+
/**
|
436
|
+
* Inspect the context void of `._test`.
|
437
|
+
*
|
438
|
+
* @return {String}
|
439
|
+
* @api private
|
440
|
+
*/
|
441
|
+
|
442
|
+
Context.prototype.inspect = function(){
|
443
|
+
return JSON.stringify(this, function(key, val){
|
444
|
+
return '_test' == key
|
445
|
+
? undefined
|
446
|
+
: val;
|
447
|
+
}, 2);
|
448
|
+
};
|
449
|
+
|
450
|
+
}); // module: context.js
|
451
|
+
|
389
452
|
require.register("hook.js", function(module, exports, require){
|
390
453
|
|
391
454
|
/**
|
@@ -410,6 +473,7 @@ module.exports = Hook;
|
|
410
473
|
|
411
474
|
function Hook(title, fn) {
|
412
475
|
Runnable.call(this, title, fn);
|
476
|
+
this.type = 'hook';
|
413
477
|
}
|
414
478
|
|
415
479
|
/**
|
@@ -453,6 +517,11 @@ module.exports = function(suite){
|
|
453
517
|
|
454
518
|
suite.on('pre-require', function(context){
|
455
519
|
|
520
|
+
// noop variants
|
521
|
+
|
522
|
+
context.xdescribe = function(){};
|
523
|
+
context.xit = function(){};
|
524
|
+
|
456
525
|
/**
|
457
526
|
* Execute before running tests.
|
458
527
|
*/
|
@@ -789,12 +858,13 @@ require.register("mocha.js", function(module, exports, require){
|
|
789
858
|
* Library version.
|
790
859
|
*/
|
791
860
|
|
792
|
-
exports.version = '0.
|
861
|
+
exports.version = '0.14.0';
|
793
862
|
|
794
863
|
exports.utils = require('./utils');
|
795
864
|
exports.interfaces = require('./interfaces');
|
796
865
|
exports.reporters = require('./reporters');
|
797
866
|
exports.Runnable = require('./runnable');
|
867
|
+
exports.Context = require('./context');
|
798
868
|
exports.Runner = require('./runner');
|
799
869
|
exports.Suite = require('./suite');
|
800
870
|
exports.Hook = require('./hook');
|
@@ -808,7 +878,8 @@ require.register("reporters/base.js", function(module, exports, require){
|
|
808
878
|
* Module dependencies.
|
809
879
|
*/
|
810
880
|
|
811
|
-
var tty = require('browser/tty')
|
881
|
+
var tty = require('browser/tty')
|
882
|
+
, diff = require('browser/diff');
|
812
883
|
|
813
884
|
/**
|
814
885
|
* Check if both stdio streams are associated with a tty.
|
@@ -849,6 +920,9 @@ exports.colors = {
|
|
849
920
|
, 'slow': 31
|
850
921
|
, 'green': 32
|
851
922
|
, 'light': 90
|
923
|
+
, 'diff gutter': 90
|
924
|
+
, 'diff added': 42
|
925
|
+
, 'diff removed': 41
|
852
926
|
};
|
853
927
|
|
854
928
|
/**
|
@@ -936,7 +1010,41 @@ exports.list = function(failures){
|
|
936
1010
|
, message = err.message || ''
|
937
1011
|
, stack = err.stack || message
|
938
1012
|
, index = stack.indexOf(message) + message.length
|
939
|
-
, msg = stack.slice(0, index)
|
1013
|
+
, msg = stack.slice(0, index)
|
1014
|
+
, actual = err.actual
|
1015
|
+
, expected = err.expected;
|
1016
|
+
|
1017
|
+
// actual / expected diff
|
1018
|
+
if ('string' == typeof actual && 'string' == typeof expected) {
|
1019
|
+
var len = Math.max(actual.length, expected.length);
|
1020
|
+
|
1021
|
+
if (len < 20) msg = errorDiff(err, 'Chars');
|
1022
|
+
else msg = errorDiff(err, 'Words');
|
1023
|
+
|
1024
|
+
// linenos
|
1025
|
+
var lines = msg.split('\n');
|
1026
|
+
if (lines.length > 4) {
|
1027
|
+
var width = String(lines.length).length;
|
1028
|
+
msg = lines.map(function(str, i){
|
1029
|
+
return pad(++i, width) + ' |' + ' ' + str;
|
1030
|
+
}).join('\n');
|
1031
|
+
}
|
1032
|
+
|
1033
|
+
// legend
|
1034
|
+
msg = '\n'
|
1035
|
+
+ color('diff removed', 'actual')
|
1036
|
+
+ ' '
|
1037
|
+
+ color('diff added', 'expected')
|
1038
|
+
+ '\n\n'
|
1039
|
+
+ msg
|
1040
|
+
+ '\n';
|
1041
|
+
|
1042
|
+
// indent
|
1043
|
+
msg = msg.replace(/^/gm, ' ');
|
1044
|
+
|
1045
|
+
fmt = color('error title', ' %s) %s:\n%s')
|
1046
|
+
+ color('error stack', '\n%s\n');
|
1047
|
+
}
|
940
1048
|
|
941
1049
|
// indent stack trace without msg
|
942
1050
|
stack = stack.slice(index + 1)
|
@@ -1040,6 +1148,51 @@ Base.prototype.epilogue = function(){
|
|
1040
1148
|
console.log();
|
1041
1149
|
};
|
1042
1150
|
|
1151
|
+
/**
|
1152
|
+
* Pad the given `str` to `len`.
|
1153
|
+
*
|
1154
|
+
* @param {String} str
|
1155
|
+
* @param {String} len
|
1156
|
+
* @return {String}
|
1157
|
+
* @api private
|
1158
|
+
*/
|
1159
|
+
|
1160
|
+
function pad(str, len) {
|
1161
|
+
str = String(str);
|
1162
|
+
return Array(len - str.length + 1).join(' ') + str;
|
1163
|
+
}
|
1164
|
+
|
1165
|
+
/**
|
1166
|
+
* Return a character diff for `err`.
|
1167
|
+
*
|
1168
|
+
* @param {Error} err
|
1169
|
+
* @return {String}
|
1170
|
+
* @api private
|
1171
|
+
*/
|
1172
|
+
|
1173
|
+
function errorDiff(err, type) {
|
1174
|
+
return diff['diff' + type](err.actual, err.expected).map(function(str){
|
1175
|
+
if (str.added) return colorLines('diff added', str.value);
|
1176
|
+
if (str.removed) return colorLines('diff removed', str.value);
|
1177
|
+
return str.value;
|
1178
|
+
}).join('');
|
1179
|
+
}
|
1180
|
+
|
1181
|
+
/**
|
1182
|
+
* Color lines for `str`, using the color `name`.
|
1183
|
+
*
|
1184
|
+
* @param {String} name
|
1185
|
+
* @param {String} str
|
1186
|
+
* @return {String}
|
1187
|
+
* @api private
|
1188
|
+
*/
|
1189
|
+
|
1190
|
+
function colorLines(name, str) {
|
1191
|
+
return str.split('\n').map(function(str){
|
1192
|
+
return color(name, str);
|
1193
|
+
}).join('\n');
|
1194
|
+
}
|
1195
|
+
|
1043
1196
|
}); // module: reporters/base.js
|
1044
1197
|
|
1045
1198
|
require.register("reporters/doc.js", function(module, exports, require){
|
@@ -1186,6 +1339,53 @@ Dot.prototype.constructor = Dot;
|
|
1186
1339
|
|
1187
1340
|
}); // module: reporters/dot.js
|
1188
1341
|
|
1342
|
+
require.register("reporters/html-cov.js", function(module, exports, require){
|
1343
|
+
|
1344
|
+
/**
|
1345
|
+
* Module dependencies.
|
1346
|
+
*/
|
1347
|
+
|
1348
|
+
var JSONCov = require('./json-cov')
|
1349
|
+
, fs = require('browser/fs');
|
1350
|
+
|
1351
|
+
/**
|
1352
|
+
* Expose `HTMLCov`.
|
1353
|
+
*/
|
1354
|
+
|
1355
|
+
exports = module.exports = HTMLCov;
|
1356
|
+
|
1357
|
+
/**
|
1358
|
+
* Initialize a new `JsCoverage` reporter.
|
1359
|
+
*
|
1360
|
+
* @param {Runner} runner
|
1361
|
+
* @api public
|
1362
|
+
*/
|
1363
|
+
|
1364
|
+
function HTMLCov(runner) {
|
1365
|
+
var jade = require('jade')
|
1366
|
+
, file = __dirname + '/templates/coverage.jade'
|
1367
|
+
, str = fs.readFileSync(file, 'utf8')
|
1368
|
+
, fn = jade.compile(str, { filename: file })
|
1369
|
+
, self = this;
|
1370
|
+
|
1371
|
+
JSONCov.call(this, runner, false);
|
1372
|
+
|
1373
|
+
runner.on('end', function(){
|
1374
|
+
process.stdout.write(fn({
|
1375
|
+
cov: self.cov
|
1376
|
+
, coverageClass: coverageClass
|
1377
|
+
}));
|
1378
|
+
});
|
1379
|
+
}
|
1380
|
+
|
1381
|
+
function coverageClass(n) {
|
1382
|
+
if (n >= 75) return 'high';
|
1383
|
+
if (n >= 50) return 'medium';
|
1384
|
+
if (n >= 25) return 'low';
|
1385
|
+
return 'terrible';
|
1386
|
+
}
|
1387
|
+
}); // module: reporters/html-cov.js
|
1388
|
+
|
1189
1389
|
require.register("reporters/html.js", function(module, exports, require){
|
1190
1390
|
|
1191
1391
|
/**
|
@@ -1224,15 +1424,17 @@ var statsTemplate = '<ul id="stats">'
|
|
1224
1424
|
function HTML(runner) {
|
1225
1425
|
Base.call(this, runner);
|
1226
1426
|
|
1227
|
-
// TODO: clean up
|
1228
|
-
|
1229
1427
|
var self = this
|
1230
1428
|
, stats = this.stats
|
1231
1429
|
, total = runner.total
|
1232
|
-
, root =
|
1430
|
+
, root = document.getElementById('mocha')
|
1431
|
+
, stat = fragment(statsTemplate)
|
1432
|
+
, items = stat.getElementsByTagName('li')
|
1433
|
+
, passes = items[1].getElementsByTagName('em')[0]
|
1434
|
+
, failures = items[2].getElementsByTagName('em')[0]
|
1435
|
+
, duration = items[3].getElementsByTagName('em')[0]
|
1436
|
+
, canvas = stat.getElementsByTagName('canvas')[0]
|
1233
1437
|
, stack = [root]
|
1234
|
-
, stat = $(statsTemplate).appendTo(root)
|
1235
|
-
, canvas = stat.find('canvas').get(0)
|
1236
1438
|
, progress
|
1237
1439
|
, ctx
|
1238
1440
|
|
@@ -1241,7 +1443,9 @@ function HTML(runner) {
|
|
1241
1443
|
progress = new Progress;
|
1242
1444
|
}
|
1243
1445
|
|
1244
|
-
if (!root
|
1446
|
+
if (!root) return error('#mocha div missing, add it to your document');
|
1447
|
+
|
1448
|
+
root.appendChild(stat);
|
1245
1449
|
|
1246
1450
|
if (progress) progress.size(40);
|
1247
1451
|
|
@@ -1249,12 +1453,12 @@ function HTML(runner) {
|
|
1249
1453
|
if (suite.root) return;
|
1250
1454
|
|
1251
1455
|
// suite
|
1252
|
-
var el =
|
1456
|
+
var el = fragment('<div class="suite"><h1>%s</h1></div>', suite.title);
|
1253
1457
|
|
1254
1458
|
// container
|
1255
|
-
stack[0].
|
1256
|
-
stack.unshift(
|
1257
|
-
el.
|
1459
|
+
stack[0].appendChild(el);
|
1460
|
+
stack.unshift(document.createElement('div'));
|
1461
|
+
el.appendChild(stack[0]);
|
1258
1462
|
});
|
1259
1463
|
|
1260
1464
|
runner.on('suite end', function(suite){
|
@@ -1269,48 +1473,48 @@ function HTML(runner) {
|
|
1269
1473
|
runner.on('test end', function(test){
|
1270
1474
|
// TODO: add to stats
|
1271
1475
|
var percent = stats.tests / total * 100 | 0;
|
1272
|
-
|
1273
|
-
if (progress) {
|
1274
|
-
progress.update(percent).draw(ctx);
|
1275
|
-
}
|
1476
|
+
if (progress) progress.update(percent).draw(ctx);
|
1276
1477
|
|
1277
1478
|
// update stats
|
1278
1479
|
var ms = new Date - stats.start;
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1480
|
+
text(passes, stats.passes);
|
1481
|
+
text(failures, stats.failures);
|
1482
|
+
text(duration, (ms / 1000).toFixed(2));
|
1282
1483
|
|
1283
1484
|
// test
|
1284
|
-
if (test.
|
1285
|
-
var el =
|
1485
|
+
if ('passed' == test.state) {
|
1486
|
+
var el = fragment('<div class="test pass"><h2>%e</h2></div>', test.title);
|
1286
1487
|
} else if (test.pending) {
|
1287
|
-
var el =
|
1488
|
+
var el = fragment('<div class="test pass pending"><h2>%e</h2></div>', test.title);
|
1288
1489
|
} else {
|
1289
|
-
var el =
|
1490
|
+
var el = fragment('<div class="test fail"><h2>%e</h2></div>', test.title);
|
1290
1491
|
var str = test.err.stack || test.err;
|
1291
1492
|
|
1292
1493
|
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
|
1293
1494
|
// check for the result of the stringifying.
|
1294
1495
|
if ('[object Error]' == str) str = test.err.message;
|
1295
1496
|
|
1296
|
-
|
1497
|
+
el.appendChild(fragment('<pre class="error">%e</pre>', str));
|
1297
1498
|
}
|
1298
1499
|
|
1299
1500
|
// toggle code
|
1300
|
-
el.
|
1301
|
-
|
1302
|
-
|
1303
|
-
pre
|
1501
|
+
var h2 = el.getElementsByTagName('h2')[0];
|
1502
|
+
|
1503
|
+
on(h2, 'click', function(){
|
1504
|
+
pre.style.display = 'none' == pre.style.display
|
1505
|
+
? 'block'
|
1506
|
+
: 'none';
|
1304
1507
|
});
|
1305
1508
|
|
1306
1509
|
// code
|
1307
1510
|
// TODO: defer
|
1308
1511
|
if (!test.pending) {
|
1309
|
-
var
|
1310
|
-
|
1311
|
-
pre.
|
1512
|
+
var pre = fragment('<pre><code>%e</code></pre>', clean(test.fn.toString()));
|
1513
|
+
el.appendChild(pre);
|
1514
|
+
pre.style.display = 'none';
|
1312
1515
|
}
|
1313
|
-
|
1516
|
+
|
1517
|
+
stack[0].appendChild(el);
|
1314
1518
|
});
|
1315
1519
|
}
|
1316
1520
|
|
@@ -1319,7 +1523,50 @@ function HTML(runner) {
|
|
1319
1523
|
*/
|
1320
1524
|
|
1321
1525
|
function error(msg) {
|
1322
|
-
|
1526
|
+
document.body.appendChild(fragment('<div id="error">%s</div>', msg));
|
1527
|
+
}
|
1528
|
+
|
1529
|
+
/**
|
1530
|
+
* Return a DOM fragment from `html`.
|
1531
|
+
*/
|
1532
|
+
|
1533
|
+
function fragment(html) {
|
1534
|
+
var args = arguments
|
1535
|
+
, div = document.createElement('div')
|
1536
|
+
, i = 1;
|
1537
|
+
|
1538
|
+
div.innerHTML = html.replace(/%([se])/g, function(_, type){
|
1539
|
+
switch (type) {
|
1540
|
+
case 's': return String(args[i++]);
|
1541
|
+
case 'e': return escape(args[i++]);
|
1542
|
+
}
|
1543
|
+
});
|
1544
|
+
|
1545
|
+
return div.firstChild;
|
1546
|
+
}
|
1547
|
+
|
1548
|
+
/**
|
1549
|
+
* Set `el` text to `str`.
|
1550
|
+
*/
|
1551
|
+
|
1552
|
+
function text(el, str) {
|
1553
|
+
if (el.textContent) {
|
1554
|
+
el.textContent = str;
|
1555
|
+
} else {
|
1556
|
+
el.innerText = str;
|
1557
|
+
}
|
1558
|
+
}
|
1559
|
+
|
1560
|
+
/**
|
1561
|
+
* Listen on `event` with callback `fn`.
|
1562
|
+
*/
|
1563
|
+
|
1564
|
+
function on(el, event, fn) {
|
1565
|
+
if (el.addEventListener) {
|
1566
|
+
el.addEventListener(event, fn, false);
|
1567
|
+
} else {
|
1568
|
+
el.attachEvent('on' + event, fn);
|
1569
|
+
}
|
1323
1570
|
}
|
1324
1571
|
|
1325
1572
|
/**
|
@@ -1356,11 +1603,166 @@ exports.List = require('./list');
|
|
1356
1603
|
exports.Spec = require('./spec');
|
1357
1604
|
exports.Progress = require('./progress');
|
1358
1605
|
exports.Landing = require('./landing');
|
1606
|
+
exports.JSONCov = require('./json-cov');
|
1607
|
+
exports.HTMLCov = require('./html-cov');
|
1359
1608
|
exports.JSONStream = require('./json-stream');
|
1360
1609
|
exports.XUnit = require('./xunit')
|
1361
1610
|
|
1362
1611
|
}); // module: reporters/index.js
|
1363
1612
|
|
1613
|
+
require.register("reporters/json-cov.js", function(module, exports, require){
|
1614
|
+
|
1615
|
+
/**
|
1616
|
+
* Module dependencies.
|
1617
|
+
*/
|
1618
|
+
|
1619
|
+
var Base = require('./base');
|
1620
|
+
|
1621
|
+
/**
|
1622
|
+
* Expose `JSONCov`.
|
1623
|
+
*/
|
1624
|
+
|
1625
|
+
exports = module.exports = JSONCov;
|
1626
|
+
|
1627
|
+
/**
|
1628
|
+
* Initialize a new `JsCoverage` reporter.
|
1629
|
+
*
|
1630
|
+
* @param {Runner} runner
|
1631
|
+
* @param {Boolean} output
|
1632
|
+
* @api public
|
1633
|
+
*/
|
1634
|
+
|
1635
|
+
function JSONCov(runner, output) {
|
1636
|
+
var self = this
|
1637
|
+
, output = 1 == arguments.length ? true : output;
|
1638
|
+
|
1639
|
+
Base.call(this, runner);
|
1640
|
+
|
1641
|
+
var tests = []
|
1642
|
+
, failures = []
|
1643
|
+
, passes = [];
|
1644
|
+
|
1645
|
+
runner.on('test end', function(test){
|
1646
|
+
tests.push(test);
|
1647
|
+
});
|
1648
|
+
|
1649
|
+
runner.on('pass', function(test){
|
1650
|
+
passes.push(test);
|
1651
|
+
});
|
1652
|
+
|
1653
|
+
runner.on('fail', function(test){
|
1654
|
+
failures.push(test);
|
1655
|
+
});
|
1656
|
+
|
1657
|
+
runner.on('end', function(){
|
1658
|
+
var cov = global._$jscoverage || {};
|
1659
|
+
var result = self.cov = map(cov);
|
1660
|
+
result.stats = self.stats;
|
1661
|
+
result.tests = tests.map(clean);
|
1662
|
+
result.failures = failures.map(clean);
|
1663
|
+
result.passes = passes.map(clean);
|
1664
|
+
if (!output) return;
|
1665
|
+
process.stdout.write(JSON.stringify(result, null, 2 ));
|
1666
|
+
});
|
1667
|
+
}
|
1668
|
+
|
1669
|
+
/**
|
1670
|
+
* Map jscoverage data to a JSON structure
|
1671
|
+
* suitable for reporting.
|
1672
|
+
*
|
1673
|
+
* @param {Object} cov
|
1674
|
+
* @return {Object}
|
1675
|
+
* @api private
|
1676
|
+
*/
|
1677
|
+
|
1678
|
+
function map(cov) {
|
1679
|
+
var ret = {
|
1680
|
+
instrumentation: 'node-jscoverage'
|
1681
|
+
, sloc: 0
|
1682
|
+
, hits: 0
|
1683
|
+
, misses: 0
|
1684
|
+
, coverage: 0
|
1685
|
+
, files: []
|
1686
|
+
};
|
1687
|
+
|
1688
|
+
for (var filename in cov) {
|
1689
|
+
var data = coverage(filename, cov[filename]);
|
1690
|
+
ret.files.push(data);
|
1691
|
+
ret.hits += data.hits;
|
1692
|
+
ret.misses += data.misses;
|
1693
|
+
ret.sloc += data.sloc;
|
1694
|
+
}
|
1695
|
+
|
1696
|
+
if (ret.sloc > 0) {
|
1697
|
+
ret.coverage = (ret.hits / ret.sloc) * 100;
|
1698
|
+
}
|
1699
|
+
|
1700
|
+
return ret;
|
1701
|
+
};
|
1702
|
+
|
1703
|
+
/**
|
1704
|
+
* Map jscoverage data for a single source file
|
1705
|
+
* to a JSON structure suitable for reporting.
|
1706
|
+
*
|
1707
|
+
* @param {String} filename name of the source file
|
1708
|
+
* @param {Object} data jscoverage coverage data
|
1709
|
+
* @return {Object}
|
1710
|
+
* @api private
|
1711
|
+
*/
|
1712
|
+
|
1713
|
+
function coverage(filename, data) {
|
1714
|
+
var ret = {
|
1715
|
+
filename: filename,
|
1716
|
+
coverage: 0,
|
1717
|
+
hits: 0,
|
1718
|
+
misses: 0,
|
1719
|
+
sloc: 0,
|
1720
|
+
source: {}
|
1721
|
+
};
|
1722
|
+
|
1723
|
+
data.source.forEach(function(line, num){
|
1724
|
+
num++;
|
1725
|
+
|
1726
|
+
if (data[num] === 0) {
|
1727
|
+
ret.misses++;
|
1728
|
+
ret.sloc++;
|
1729
|
+
} else if (data[num] !== undefined) {
|
1730
|
+
ret.hits++;
|
1731
|
+
ret.sloc++;
|
1732
|
+
}
|
1733
|
+
|
1734
|
+
ret.source[num] = {
|
1735
|
+
source: line
|
1736
|
+
, coverage: data[num] === undefined
|
1737
|
+
? ''
|
1738
|
+
: data[num]
|
1739
|
+
};
|
1740
|
+
});
|
1741
|
+
|
1742
|
+
ret.coverage = ret.hits / ret.sloc * 100;
|
1743
|
+
|
1744
|
+
return ret;
|
1745
|
+
}
|
1746
|
+
|
1747
|
+
/**
|
1748
|
+
* Return a plain-object representation of `test`
|
1749
|
+
* free of cyclic properties etc.
|
1750
|
+
*
|
1751
|
+
* @param {Object} test
|
1752
|
+
* @return {Object}
|
1753
|
+
* @api private
|
1754
|
+
*/
|
1755
|
+
|
1756
|
+
function clean(test) {
|
1757
|
+
return {
|
1758
|
+
title: test.title
|
1759
|
+
, fullTitle: test.fullTitle()
|
1760
|
+
, duration: test.duration
|
1761
|
+
}
|
1762
|
+
}
|
1763
|
+
|
1764
|
+
}); // module: reporters/json-cov.js
|
1765
|
+
|
1364
1766
|
require.register("reporters/json-stream.js", function(module, exports, require){
|
1365
1767
|
|
1366
1768
|
/**
|
@@ -1476,7 +1878,7 @@ function JSONReporter(runner) {
|
|
1476
1878
|
, passes: passes.map(clean)
|
1477
1879
|
};
|
1478
1880
|
|
1479
|
-
process.stdout.write(JSON.stringify(obj));
|
1881
|
+
process.stdout.write(JSON.stringify(obj, null, 2));
|
1480
1882
|
});
|
1481
1883
|
}
|
1482
1884
|
|
@@ -1568,7 +1970,7 @@ function Landing(runner) {
|
|
1568
1970
|
: crashed;
|
1569
1971
|
|
1570
1972
|
// show the crash
|
1571
|
-
if (test.
|
1973
|
+
if ('failed' == test.state) {
|
1572
1974
|
plane = color('plane crash', '✈');
|
1573
1975
|
crashed = col;
|
1574
1976
|
}
|
@@ -2048,7 +2450,7 @@ function test(test) {
|
|
2048
2450
|
, time: test.duration / 1000
|
2049
2451
|
};
|
2050
2452
|
|
2051
|
-
if (test.
|
2453
|
+
if ('failed' == test.state) {
|
2052
2454
|
var err = test.err;
|
2053
2455
|
attrs.message = escape(err.message);
|
2054
2456
|
console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata(err.stack))));
|
@@ -2117,7 +2519,6 @@ function Runnable(title, fn) {
|
|
2117
2519
|
this.sync = ! this.async;
|
2118
2520
|
this._timeout = 2000;
|
2119
2521
|
this.timedOut = false;
|
2120
|
-
this.context = this;
|
2121
2522
|
}
|
2122
2523
|
|
2123
2524
|
/**
|
@@ -2196,7 +2597,7 @@ Runnable.prototype.run = function(fn){
|
|
2196
2597
|
var self = this
|
2197
2598
|
, ms = this.timeout()
|
2198
2599
|
, start = new Date
|
2199
|
-
, ctx = this.
|
2600
|
+
, ctx = this.ctx
|
2200
2601
|
, finished
|
2201
2602
|
, emitted;
|
2202
2603
|
|
@@ -2376,7 +2777,7 @@ Runner.prototype.checkGlobals = function(test){
|
|
2376
2777
|
|
2377
2778
|
Runner.prototype.fail = function(test, err){
|
2378
2779
|
++this.failures;
|
2379
|
-
test.
|
2780
|
+
test.state = 'failed';
|
2380
2781
|
this.emit('fail', test, err);
|
2381
2782
|
};
|
2382
2783
|
|
@@ -2417,7 +2818,7 @@ Runner.prototype.hook = function(name, fn){
|
|
2417
2818
|
var hook = hooks[i];
|
2418
2819
|
if (!hook) return fn();
|
2419
2820
|
self.currentRunnable = hook;
|
2420
|
-
hook.
|
2821
|
+
hook.ctx.test(self.test);
|
2421
2822
|
|
2422
2823
|
self.emit('hook', hook);
|
2423
2824
|
|
@@ -2526,6 +2927,7 @@ Runner.prototype.runTest = function(fn){
|
|
2526
2927
|
, self = this;
|
2527
2928
|
|
2528
2929
|
try {
|
2930
|
+
test.ctx.test(test);
|
2529
2931
|
test.on('error', function(err){
|
2530
2932
|
self.fail(test, err);
|
2531
2933
|
});
|
@@ -2582,7 +2984,7 @@ Runner.prototype.runTests = function(suite, fn){
|
|
2582
2984
|
return self.hookUp('afterEach', next);
|
2583
2985
|
}
|
2584
2986
|
|
2585
|
-
test.
|
2987
|
+
test.state = 'passed';
|
2586
2988
|
self.emit('pass', test);
|
2587
2989
|
self.emit('test end', test);
|
2588
2990
|
self.hookUp('afterEach', next);
|
@@ -2639,7 +3041,7 @@ Runner.prototype.runSuite = function(suite, fn){
|
|
2639
3041
|
Runner.prototype.uncaught = function(err){
|
2640
3042
|
debug('uncaught exception');
|
2641
3043
|
var runnable = this.currentRunnable;
|
2642
|
-
if (runnable.
|
3044
|
+
if ('failed' == runnable.state) return;
|
2643
3045
|
runnable.clearTimeout();
|
2644
3046
|
err.uncaught = true;
|
2645
3047
|
this.fail(runnable, err);
|
@@ -2725,7 +3127,7 @@ exports = module.exports = Suite;
|
|
2725
3127
|
*/
|
2726
3128
|
|
2727
3129
|
exports.create = function(parent, title){
|
2728
|
-
var suite = new Suite(title);
|
3130
|
+
var suite = new Suite(title, parent.ctx);
|
2729
3131
|
suite.parent = parent;
|
2730
3132
|
title = suite.fullTitle();
|
2731
3133
|
parent.addSuite(suite);
|
@@ -2733,14 +3135,17 @@ exports.create = function(parent, title){
|
|
2733
3135
|
};
|
2734
3136
|
|
2735
3137
|
/**
|
2736
|
-
* Initialize a new `Suite` with the given
|
3138
|
+
* Initialize a new `Suite` with the given
|
3139
|
+
* `title` and `ctx`.
|
2737
3140
|
*
|
2738
3141
|
* @param {String} title
|
3142
|
+
* @param {Context} ctx
|
2739
3143
|
* @api private
|
2740
3144
|
*/
|
2741
3145
|
|
2742
|
-
function Suite(title) {
|
3146
|
+
function Suite(title, ctx) {
|
2743
3147
|
this.title = title;
|
3148
|
+
this.ctx = ctx;
|
2744
3149
|
this.suites = [];
|
2745
3150
|
this.tests = [];
|
2746
3151
|
this._beforeEach = [];
|
@@ -2770,6 +3175,7 @@ Suite.prototype.constructor = Suite;
|
|
2770
3175
|
Suite.prototype.clone = function(){
|
2771
3176
|
var suite = new Suite(this.title);
|
2772
3177
|
debug('clone');
|
3178
|
+
suite.ctx = this.ctx;
|
2773
3179
|
suite.timeout(this.timeout());
|
2774
3180
|
suite.bail(this.bail());
|
2775
3181
|
return suite;
|
@@ -2818,6 +3224,7 @@ Suite.prototype.beforeAll = function(fn){
|
|
2818
3224
|
var hook = new Hook('"before all" hook', fn);
|
2819
3225
|
hook.parent = this;
|
2820
3226
|
hook.timeout(this.timeout());
|
3227
|
+
hook.ctx = this.ctx;
|
2821
3228
|
this._beforeAll.push(hook);
|
2822
3229
|
this.emit('beforeAll', hook);
|
2823
3230
|
return this;
|
@@ -2835,6 +3242,7 @@ Suite.prototype.afterAll = function(fn){
|
|
2835
3242
|
var hook = new Hook('"after all" hook', fn);
|
2836
3243
|
hook.parent = this;
|
2837
3244
|
hook.timeout(this.timeout());
|
3245
|
+
hook.ctx = this.ctx;
|
2838
3246
|
this._afterAll.push(hook);
|
2839
3247
|
this.emit('afterAll', hook);
|
2840
3248
|
return this;
|
@@ -2852,6 +3260,7 @@ Suite.prototype.beforeEach = function(fn){
|
|
2852
3260
|
var hook = new Hook('"before each" hook', fn);
|
2853
3261
|
hook.parent = this;
|
2854
3262
|
hook.timeout(this.timeout());
|
3263
|
+
hook.ctx = this.ctx;
|
2855
3264
|
this._beforeEach.push(hook);
|
2856
3265
|
this.emit('beforeEach', hook);
|
2857
3266
|
return this;
|
@@ -2869,6 +3278,7 @@ Suite.prototype.afterEach = function(fn){
|
|
2869
3278
|
var hook = new Hook('"after each" hook', fn);
|
2870
3279
|
hook.parent = this;
|
2871
3280
|
hook.timeout(this.timeout());
|
3281
|
+
hook.ctx = this.ctx;
|
2872
3282
|
this._afterEach.push(hook);
|
2873
3283
|
this.emit('afterEach', hook);
|
2874
3284
|
return this;
|
@@ -2902,6 +3312,7 @@ Suite.prototype.addSuite = function(suite){
|
|
2902
3312
|
Suite.prototype.addTest = function(test){
|
2903
3313
|
test.parent = this;
|
2904
3314
|
test.timeout(this.timeout());
|
3315
|
+
test.ctx = this.ctx;
|
2905
3316
|
this.tests.push(test);
|
2906
3317
|
this.emit('test', test);
|
2907
3318
|
return this;
|
@@ -2974,6 +3385,22 @@ Test.prototype = new Runnable;
|
|
2974
3385
|
Test.prototype.constructor = Test;
|
2975
3386
|
|
2976
3387
|
|
3388
|
+
/**
|
3389
|
+
* Inspect the context void of private properties.
|
3390
|
+
*
|
3391
|
+
* @return {String}
|
3392
|
+
* @api private
|
3393
|
+
*/
|
3394
|
+
|
3395
|
+
Test.prototype.inspect = function(){
|
3396
|
+
return JSON.stringify(this, function(key, val){
|
3397
|
+
return '_' == key[0]
|
3398
|
+
? undefined
|
3399
|
+
: 'parent' == key
|
3400
|
+
? '#<Suite>'
|
3401
|
+
: val;
|
3402
|
+
}, 2);
|
3403
|
+
};
|
2977
3404
|
}); // module: test.js
|
2978
3405
|
|
2979
3406
|
require.register("utils.js", function(module, exports, require){
|
@@ -3093,9 +3520,9 @@ exports.keys = Object.keys || function(obj) {
|
|
3093
3520
|
var keys = []
|
3094
3521
|
, has = Object.prototype.hasOwnProperty // for `window` on <=IE8
|
3095
3522
|
|
3096
|
-
for (var
|
3097
|
-
if (has.call(obj,
|
3098
|
-
keys.push(
|
3523
|
+
for (var key in obj) {
|
3524
|
+
if (has.call(obj, key)) {
|
3525
|
+
keys.push(key);
|
3099
3526
|
}
|
3100
3527
|
}
|
3101
3528
|
|
@@ -3133,7 +3560,7 @@ function ignored(path){
|
|
3133
3560
|
* Lookup files in the given `dir`.
|
3134
3561
|
*
|
3135
3562
|
* @return {Array}
|
3136
|
-
* @api
|
3563
|
+
* @api private
|
3137
3564
|
*/
|
3138
3565
|
|
3139
3566
|
exports.files = function(dir, ret){
|
@@ -3223,9 +3650,8 @@ window.mocha = require('mocha');
|
|
3223
3650
|
|
3224
3651
|
// boot
|
3225
3652
|
;(function(){
|
3226
|
-
var suite = new mocha.Suite
|
3653
|
+
var suite = new mocha.Suite('', new mocha.Context)
|
3227
3654
|
, utils = mocha.utils
|
3228
|
-
, Reporter = mocha.reporters.HTML
|
3229
3655
|
|
3230
3656
|
/**
|
3231
3657
|
* Highlight the given string of `js`.
|
@@ -3236,13 +3662,24 @@ window.mocha = require('mocha');
|
|
3236
3662
|
.replace(/</g, '<')
|
3237
3663
|
.replace(/>/g, '>')
|
3238
3664
|
.replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
|
3239
|
-
.replace(/('
|
3665
|
+
.replace(/('.*?')/gm, '<span class="string">$1</span>')
|
3240
3666
|
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
|
3241
3667
|
.replace(/(\d+)/gm, '<span class="number">$1</span>')
|
3242
3668
|
.replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
|
3243
3669
|
.replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
|
3244
3670
|
}
|
3245
3671
|
|
3672
|
+
/**
|
3673
|
+
* Highlight code contents.
|
3674
|
+
*/
|
3675
|
+
|
3676
|
+
function highlightCode() {
|
3677
|
+
var code = document.getElementsByTagName('code');
|
3678
|
+
for (var i = 0, len = code.length; i < len; ++i) {
|
3679
|
+
code[i].innerHTML = highlight(code[i].innerHTML);
|
3680
|
+
}
|
3681
|
+
}
|
3682
|
+
|
3246
3683
|
/**
|
3247
3684
|
* Parse the given `qs`.
|
3248
3685
|
*/
|
@@ -3273,17 +3710,14 @@ window.mocha = require('mocha');
|
|
3273
3710
|
* Run mocha, returning the Runner.
|
3274
3711
|
*/
|
3275
3712
|
|
3276
|
-
mocha.run = function(){
|
3713
|
+
mocha.run = function(Reporter){
|
3277
3714
|
suite.emit('run');
|
3278
3715
|
var runner = new mocha.Runner(suite);
|
3716
|
+
Reporter = Reporter || mocha.reporters.HTML;
|
3279
3717
|
var reporter = new Reporter(runner);
|
3280
3718
|
var query = parse(window.location.search || "");
|
3281
3719
|
if (query.grep) runner.grep(new RegExp(query.grep));
|
3282
|
-
runner.on('end',
|
3283
|
-
$('code').each(function(){
|
3284
|
-
$(this).html(highlight($(this).text()));
|
3285
|
-
});
|
3286
|
-
});
|
3720
|
+
runner.on('end', highlightCode);
|
3287
3721
|
return runner.run();
|
3288
3722
|
};
|
3289
3723
|
})();
|