konacha 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
})();
|