mocha_rails 0.0.3 → 0.0.4
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.
@@ -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
|
/**
|
@@ -513,6 +517,11 @@ module.exports = function(suite){
|
|
513
517
|
|
514
518
|
suite.on('pre-require', function(context){
|
515
519
|
|
520
|
+
// noop variants
|
521
|
+
|
522
|
+
context.xdescribe = function(){};
|
523
|
+
context.xit = function(){};
|
524
|
+
|
516
525
|
/**
|
517
526
|
* Execute before running tests.
|
518
527
|
*/
|
@@ -845,11 +854,27 @@ require.register("mocha.js", function(module, exports, require){
|
|
845
854
|
* MIT Licensed
|
846
855
|
*/
|
847
856
|
|
857
|
+
/**
|
858
|
+
* Module dependencies.
|
859
|
+
*/
|
860
|
+
|
861
|
+
var path = require('browser/path');
|
862
|
+
|
863
|
+
/**
|
864
|
+
* Expose `Mocha`.
|
865
|
+
*/
|
866
|
+
|
867
|
+
exports = module.exports = Mocha;
|
868
|
+
|
848
869
|
/**
|
849
870
|
* Library version.
|
850
871
|
*/
|
851
872
|
|
852
|
-
exports.version = '0.
|
873
|
+
exports.version = '1.0.0';
|
874
|
+
|
875
|
+
/**
|
876
|
+
* Expose internals.
|
877
|
+
*/
|
853
878
|
|
854
879
|
exports.utils = require('./utils');
|
855
880
|
exports.interfaces = require('./interfaces');
|
@@ -861,6 +886,144 @@ exports.Suite = require('./suite');
|
|
861
886
|
exports.Hook = require('./hook');
|
862
887
|
exports.Test = require('./test');
|
863
888
|
|
889
|
+
/**
|
890
|
+
* Return image `name` path.
|
891
|
+
*
|
892
|
+
* @param {String} name
|
893
|
+
* @return {String}
|
894
|
+
* @api private
|
895
|
+
*/
|
896
|
+
|
897
|
+
function image(name) {
|
898
|
+
return __dirname + '/../images/' + name + '.png';
|
899
|
+
}
|
900
|
+
|
901
|
+
/**
|
902
|
+
* Setup mocha with `options`.
|
903
|
+
*
|
904
|
+
* Options:
|
905
|
+
*
|
906
|
+
* - `ui` name "bdd", "tdd", "exports" etc
|
907
|
+
* - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
|
908
|
+
* - `globals` array of accepted globals
|
909
|
+
* - `timeout` timeout in milliseconds
|
910
|
+
* - `ignoreLeaks` ignore global leaks
|
911
|
+
*
|
912
|
+
* @param {Object} options
|
913
|
+
* @api public
|
914
|
+
*/
|
915
|
+
|
916
|
+
function Mocha(options) {
|
917
|
+
options = options || {};
|
918
|
+
this.files = [];
|
919
|
+
this.options = options;
|
920
|
+
this.suite = new exports.Suite('', new exports.Context);
|
921
|
+
this.ui(options.ui);
|
922
|
+
this.reporter(options.reporter);
|
923
|
+
if (options.timeout) this.suite.timeout(options.timeout);
|
924
|
+
}
|
925
|
+
|
926
|
+
/**
|
927
|
+
* Add test `file`.
|
928
|
+
*
|
929
|
+
* @param {String} file
|
930
|
+
* @api public
|
931
|
+
*/
|
932
|
+
|
933
|
+
Mocha.prototype.addFile = function(file){
|
934
|
+
this.files.push(file);
|
935
|
+
return this;
|
936
|
+
};
|
937
|
+
|
938
|
+
/**
|
939
|
+
* Set reporter to `name`, defaults to "dot".
|
940
|
+
*
|
941
|
+
* @param {String} name
|
942
|
+
* @api public
|
943
|
+
*/
|
944
|
+
|
945
|
+
Mocha.prototype.reporter = function(name){
|
946
|
+
name = name || 'dot';
|
947
|
+
this._reporter = require('./reporters/' + name);
|
948
|
+
if (!this._reporter) throw new Error('invalid reporter "' + name + '"');
|
949
|
+
return this;
|
950
|
+
};
|
951
|
+
|
952
|
+
/**
|
953
|
+
* Set test UI `name`, defaults to "bdd".
|
954
|
+
*
|
955
|
+
* @param {String} bdd
|
956
|
+
* @api public
|
957
|
+
*/
|
958
|
+
|
959
|
+
Mocha.prototype.ui = function(name){
|
960
|
+
name = name || 'bdd';
|
961
|
+
this._ui = exports.interfaces[name];
|
962
|
+
if (!this._ui) throw new Error('invalid interface "' + name + '"');
|
963
|
+
this._ui = this._ui(this.suite);
|
964
|
+
return this;
|
965
|
+
};
|
966
|
+
|
967
|
+
/**
|
968
|
+
* Load registered files.
|
969
|
+
*
|
970
|
+
* @api private
|
971
|
+
*/
|
972
|
+
|
973
|
+
Mocha.prototype.loadFiles = function(){
|
974
|
+
var suite = this.suite;
|
975
|
+
this.files.forEach(function(file){
|
976
|
+
file = path.resolve(file);
|
977
|
+
suite.emit('pre-require', global, file);
|
978
|
+
suite.emit('require', require(file), file);
|
979
|
+
suite.emit('post-require', global, file);
|
980
|
+
});
|
981
|
+
};
|
982
|
+
|
983
|
+
/**
|
984
|
+
* Enable growl support.
|
985
|
+
*
|
986
|
+
* @api private
|
987
|
+
*/
|
988
|
+
|
989
|
+
Mocha.prototype.growl = function(runner, reporter) {
|
990
|
+
var notify = require('growl');
|
991
|
+
|
992
|
+
runner.on('end', function(){
|
993
|
+
var stats = reporter.stats;
|
994
|
+
if (stats.failures) {
|
995
|
+
var msg = stats.failures + ' of ' + runner.total + ' tests failed';
|
996
|
+
notify(msg, { title: 'Failed', image: image('fail') });
|
997
|
+
} else {
|
998
|
+
notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
|
999
|
+
title: 'Passed'
|
1000
|
+
, image: image('pass')
|
1001
|
+
});
|
1002
|
+
}
|
1003
|
+
});
|
1004
|
+
};
|
1005
|
+
|
1006
|
+
/**
|
1007
|
+
* Run tests and invoke `fn()` when complete.
|
1008
|
+
*
|
1009
|
+
* @param {Function} fn
|
1010
|
+
* @return {Runner}
|
1011
|
+
* @api public
|
1012
|
+
*/
|
1013
|
+
|
1014
|
+
Mocha.prototype.run = function(fn){
|
1015
|
+
this.loadFiles();
|
1016
|
+
var suite = this.suite;
|
1017
|
+
var options = this.options;
|
1018
|
+
var runner = new exports.Runner(suite);
|
1019
|
+
var reporter = new this._reporter(runner);
|
1020
|
+
runner.ignoreLeaks = options.ignoreLeaks;
|
1021
|
+
if (options.grep) runner.grep(options.grep);
|
1022
|
+
if (options.globals) runner.globals(options.globals);
|
1023
|
+
if (options.growl) this.growl(runner, reporter);
|
1024
|
+
return runner.run(fn);
|
1025
|
+
};
|
1026
|
+
|
864
1027
|
}); // module: mocha.js
|
865
1028
|
|
866
1029
|
require.register("reporters/base.js", function(module, exports, require){
|
@@ -869,7 +1032,8 @@ require.register("reporters/base.js", function(module, exports, require){
|
|
869
1032
|
* Module dependencies.
|
870
1033
|
*/
|
871
1034
|
|
872
|
-
var tty = require('browser/tty')
|
1035
|
+
var tty = require('browser/tty')
|
1036
|
+
, diff = require('browser/diff');
|
873
1037
|
|
874
1038
|
/**
|
875
1039
|
* Check if both stdio streams are associated with a tty.
|
@@ -910,6 +1074,9 @@ exports.colors = {
|
|
910
1074
|
, 'slow': 31
|
911
1075
|
, 'green': 32
|
912
1076
|
, 'light': 90
|
1077
|
+
, 'diff gutter': 90
|
1078
|
+
, 'diff added': 42
|
1079
|
+
, 'diff removed': 41
|
913
1080
|
};
|
914
1081
|
|
915
1082
|
/**
|
@@ -997,10 +1164,44 @@ exports.list = function(failures){
|
|
997
1164
|
, message = err.message || ''
|
998
1165
|
, stack = err.stack || message
|
999
1166
|
, index = stack.indexOf(message) + message.length
|
1000
|
-
, msg = stack.slice(0, index)
|
1167
|
+
, msg = stack.slice(0, index)
|
1168
|
+
, actual = err.actual
|
1169
|
+
, expected = err.expected;
|
1170
|
+
|
1171
|
+
// actual / expected diff
|
1172
|
+
if ('string' == typeof actual && 'string' == typeof expected) {
|
1173
|
+
var len = Math.max(actual.length, expected.length);
|
1174
|
+
|
1175
|
+
if (len < 20) msg = errorDiff(err, 'Chars');
|
1176
|
+
else msg = errorDiff(err, 'Words');
|
1177
|
+
|
1178
|
+
// linenos
|
1179
|
+
var lines = msg.split('\n');
|
1180
|
+
if (lines.length > 4) {
|
1181
|
+
var width = String(lines.length).length;
|
1182
|
+
msg = lines.map(function(str, i){
|
1183
|
+
return pad(++i, width) + ' |' + ' ' + str;
|
1184
|
+
}).join('\n');
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
// legend
|
1188
|
+
msg = '\n'
|
1189
|
+
+ color('diff removed', 'actual')
|
1190
|
+
+ ' '
|
1191
|
+
+ color('diff added', 'expected')
|
1192
|
+
+ '\n\n'
|
1193
|
+
+ msg
|
1194
|
+
+ '\n';
|
1195
|
+
|
1196
|
+
// indent
|
1197
|
+
msg = msg.replace(/^/gm, ' ');
|
1198
|
+
|
1199
|
+
fmt = color('error title', ' %s) %s:\n%s')
|
1200
|
+
+ color('error stack', '\n%s\n');
|
1201
|
+
}
|
1001
1202
|
|
1002
1203
|
// indent stack trace without msg
|
1003
|
-
stack = stack.slice(index + 1)
|
1204
|
+
stack = stack.slice(index ? index + 1 : index)
|
1004
1205
|
.replace(/^/gm, ' ');
|
1005
1206
|
|
1006
1207
|
console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
|
@@ -1101,6 +1302,51 @@ Base.prototype.epilogue = function(){
|
|
1101
1302
|
console.log();
|
1102
1303
|
};
|
1103
1304
|
|
1305
|
+
/**
|
1306
|
+
* Pad the given `str` to `len`.
|
1307
|
+
*
|
1308
|
+
* @param {String} str
|
1309
|
+
* @param {String} len
|
1310
|
+
* @return {String}
|
1311
|
+
* @api private
|
1312
|
+
*/
|
1313
|
+
|
1314
|
+
function pad(str, len) {
|
1315
|
+
str = String(str);
|
1316
|
+
return Array(len - str.length + 1).join(' ') + str;
|
1317
|
+
}
|
1318
|
+
|
1319
|
+
/**
|
1320
|
+
* Return a character diff for `err`.
|
1321
|
+
*
|
1322
|
+
* @param {Error} err
|
1323
|
+
* @return {String}
|
1324
|
+
* @api private
|
1325
|
+
*/
|
1326
|
+
|
1327
|
+
function errorDiff(err, type) {
|
1328
|
+
return diff['diff' + type](err.actual, err.expected).map(function(str){
|
1329
|
+
if (str.added) return colorLines('diff added', str.value);
|
1330
|
+
if (str.removed) return colorLines('diff removed', str.value);
|
1331
|
+
return str.value;
|
1332
|
+
}).join('');
|
1333
|
+
}
|
1334
|
+
|
1335
|
+
/**
|
1336
|
+
* Color lines for `str`, using the color `name`.
|
1337
|
+
*
|
1338
|
+
* @param {String} name
|
1339
|
+
* @param {String} str
|
1340
|
+
* @return {String}
|
1341
|
+
* @api private
|
1342
|
+
*/
|
1343
|
+
|
1344
|
+
function colorLines(name, str) {
|
1345
|
+
return str.split('\n').map(function(str){
|
1346
|
+
return color(name, str);
|
1347
|
+
}).join('\n');
|
1348
|
+
}
|
1349
|
+
|
1104
1350
|
}); // module: reporters/base.js
|
1105
1351
|
|
1106
1352
|
require.register("reporters/doc.js", function(module, exports, require){
|
@@ -1247,6 +1493,53 @@ Dot.prototype.constructor = Dot;
|
|
1247
1493
|
|
1248
1494
|
}); // module: reporters/dot.js
|
1249
1495
|
|
1496
|
+
require.register("reporters/html-cov.js", function(module, exports, require){
|
1497
|
+
|
1498
|
+
/**
|
1499
|
+
* Module dependencies.
|
1500
|
+
*/
|
1501
|
+
|
1502
|
+
var JSONCov = require('./json-cov')
|
1503
|
+
, fs = require('browser/fs');
|
1504
|
+
|
1505
|
+
/**
|
1506
|
+
* Expose `HTMLCov`.
|
1507
|
+
*/
|
1508
|
+
|
1509
|
+
exports = module.exports = HTMLCov;
|
1510
|
+
|
1511
|
+
/**
|
1512
|
+
* Initialize a new `JsCoverage` reporter.
|
1513
|
+
*
|
1514
|
+
* @param {Runner} runner
|
1515
|
+
* @api public
|
1516
|
+
*/
|
1517
|
+
|
1518
|
+
function HTMLCov(runner) {
|
1519
|
+
var jade = require('jade')
|
1520
|
+
, file = __dirname + '/templates/coverage.jade'
|
1521
|
+
, str = fs.readFileSync(file, 'utf8')
|
1522
|
+
, fn = jade.compile(str, { filename: file })
|
1523
|
+
, self = this;
|
1524
|
+
|
1525
|
+
JSONCov.call(this, runner, false);
|
1526
|
+
|
1527
|
+
runner.on('end', function(){
|
1528
|
+
process.stdout.write(fn({
|
1529
|
+
cov: self.cov
|
1530
|
+
, coverageClass: coverageClass
|
1531
|
+
}));
|
1532
|
+
});
|
1533
|
+
}
|
1534
|
+
|
1535
|
+
function coverageClass(n) {
|
1536
|
+
if (n >= 75) return 'high';
|
1537
|
+
if (n >= 50) return 'medium';
|
1538
|
+
if (n >= 25) return 'low';
|
1539
|
+
return 'terrible';
|
1540
|
+
}
|
1541
|
+
}); // module: reporters/html-cov.js
|
1542
|
+
|
1250
1543
|
require.register("reporters/html.js", function(module, exports, require){
|
1251
1544
|
|
1252
1545
|
/**
|
@@ -1285,15 +1578,17 @@ var statsTemplate = '<ul id="stats">'
|
|
1285
1578
|
function HTML(runner) {
|
1286
1579
|
Base.call(this, runner);
|
1287
1580
|
|
1288
|
-
// TODO: clean up
|
1289
|
-
|
1290
1581
|
var self = this
|
1291
1582
|
, stats = this.stats
|
1292
1583
|
, total = runner.total
|
1293
|
-
, root =
|
1584
|
+
, root = document.getElementById('mocha')
|
1585
|
+
, stat = fragment(statsTemplate)
|
1586
|
+
, items = stat.getElementsByTagName('li')
|
1587
|
+
, passes = items[1].getElementsByTagName('em')[0]
|
1588
|
+
, failures = items[2].getElementsByTagName('em')[0]
|
1589
|
+
, duration = items[3].getElementsByTagName('em')[0]
|
1590
|
+
, canvas = stat.getElementsByTagName('canvas')[0]
|
1294
1591
|
, stack = [root]
|
1295
|
-
, stat = $(statsTemplate).appendTo(root)
|
1296
|
-
, canvas = stat.find('canvas').get(0)
|
1297
1592
|
, progress
|
1298
1593
|
, ctx
|
1299
1594
|
|
@@ -1302,7 +1597,9 @@ function HTML(runner) {
|
|
1302
1597
|
progress = new Progress;
|
1303
1598
|
}
|
1304
1599
|
|
1305
|
-
if (!root
|
1600
|
+
if (!root) return error('#mocha div missing, add it to your document');
|
1601
|
+
|
1602
|
+
root.appendChild(stat);
|
1306
1603
|
|
1307
1604
|
if (progress) progress.size(40);
|
1308
1605
|
|
@@ -1310,12 +1607,12 @@ function HTML(runner) {
|
|
1310
1607
|
if (suite.root) return;
|
1311
1608
|
|
1312
1609
|
// suite
|
1313
|
-
var el =
|
1610
|
+
var el = fragment('<div class="suite"><h1>%s</h1></div>', suite.title);
|
1314
1611
|
|
1315
1612
|
// container
|
1316
|
-
stack[0].
|
1317
|
-
stack.unshift(
|
1318
|
-
el.
|
1613
|
+
stack[0].appendChild(el);
|
1614
|
+
stack.unshift(document.createElement('div'));
|
1615
|
+
el.appendChild(stack[0]);
|
1319
1616
|
});
|
1320
1617
|
|
1321
1618
|
runner.on('suite end', function(suite){
|
@@ -1330,48 +1627,58 @@ function HTML(runner) {
|
|
1330
1627
|
runner.on('test end', function(test){
|
1331
1628
|
// TODO: add to stats
|
1332
1629
|
var percent = stats.tests / total * 100 | 0;
|
1333
|
-
|
1334
|
-
if (progress) {
|
1335
|
-
progress.update(percent).draw(ctx);
|
1336
|
-
}
|
1630
|
+
if (progress) progress.update(percent).draw(ctx);
|
1337
1631
|
|
1338
1632
|
// update stats
|
1339
1633
|
var ms = new Date - stats.start;
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1634
|
+
text(passes, stats.passes);
|
1635
|
+
text(failures, stats.failures);
|
1636
|
+
text(duration, (ms / 1000).toFixed(2));
|
1343
1637
|
|
1344
1638
|
// test
|
1345
|
-
if (test.
|
1346
|
-
var el =
|
1639
|
+
if ('passed' == test.state) {
|
1640
|
+
var el = fragment('<div class="test pass"><h2>%e</h2></div>', test.title);
|
1347
1641
|
} else if (test.pending) {
|
1348
|
-
var el =
|
1642
|
+
var el = fragment('<div class="test pass pending"><h2>%e</h2></div>', test.title);
|
1349
1643
|
} else {
|
1350
|
-
var el =
|
1351
|
-
var str = test.err.stack || test.err;
|
1644
|
+
var el = fragment('<div class="test fail"><h2>%e</h2></div>', test.title);
|
1645
|
+
var str = test.err.stack || test.err.toString();
|
1646
|
+
|
1647
|
+
// FF / Opera do not add the message
|
1648
|
+
if (!~str.indexOf(test.err.message)) {
|
1649
|
+
str = test.err.message + '\n' + str;
|
1650
|
+
}
|
1352
1651
|
|
1353
1652
|
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
|
1354
1653
|
// check for the result of the stringifying.
|
1355
1654
|
if ('[object Error]' == str) str = test.err.message;
|
1356
1655
|
|
1357
|
-
|
1656
|
+
// Safari doesn't give you a stack. Let's at least provide a source line.
|
1657
|
+
if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
|
1658
|
+
str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
|
1659
|
+
}
|
1660
|
+
|
1661
|
+
el.appendChild(fragment('<pre class="error">%e</pre>', str));
|
1358
1662
|
}
|
1359
1663
|
|
1360
1664
|
// toggle code
|
1361
|
-
el.
|
1362
|
-
|
1363
|
-
|
1364
|
-
pre
|
1665
|
+
var h2 = el.getElementsByTagName('h2')[0];
|
1666
|
+
|
1667
|
+
on(h2, 'click', function(){
|
1668
|
+
pre.style.display = 'none' == pre.style.display
|
1669
|
+
? 'block'
|
1670
|
+
: 'none';
|
1365
1671
|
});
|
1366
1672
|
|
1367
1673
|
// code
|
1368
1674
|
// TODO: defer
|
1369
1675
|
if (!test.pending) {
|
1370
|
-
var
|
1371
|
-
|
1372
|
-
pre.
|
1676
|
+
var pre = fragment('<pre><code>%e</code></pre>', clean(test.fn.toString()));
|
1677
|
+
el.appendChild(pre);
|
1678
|
+
pre.style.display = 'none';
|
1373
1679
|
}
|
1374
|
-
|
1680
|
+
|
1681
|
+
stack[0].appendChild(el);
|
1375
1682
|
});
|
1376
1683
|
}
|
1377
1684
|
|
@@ -1380,7 +1687,50 @@ function HTML(runner) {
|
|
1380
1687
|
*/
|
1381
1688
|
|
1382
1689
|
function error(msg) {
|
1383
|
-
|
1690
|
+
document.body.appendChild(fragment('<div id="error">%s</div>', msg));
|
1691
|
+
}
|
1692
|
+
|
1693
|
+
/**
|
1694
|
+
* Return a DOM fragment from `html`.
|
1695
|
+
*/
|
1696
|
+
|
1697
|
+
function fragment(html) {
|
1698
|
+
var args = arguments
|
1699
|
+
, div = document.createElement('div')
|
1700
|
+
, i = 1;
|
1701
|
+
|
1702
|
+
div.innerHTML = html.replace(/%([se])/g, function(_, type){
|
1703
|
+
switch (type) {
|
1704
|
+
case 's': return String(args[i++]);
|
1705
|
+
case 'e': return escape(args[i++]);
|
1706
|
+
}
|
1707
|
+
});
|
1708
|
+
|
1709
|
+
return div.firstChild;
|
1710
|
+
}
|
1711
|
+
|
1712
|
+
/**
|
1713
|
+
* Set `el` text to `str`.
|
1714
|
+
*/
|
1715
|
+
|
1716
|
+
function text(el, str) {
|
1717
|
+
if (el.textContent) {
|
1718
|
+
el.textContent = str;
|
1719
|
+
} else {
|
1720
|
+
el.innerText = str;
|
1721
|
+
}
|
1722
|
+
}
|
1723
|
+
|
1724
|
+
/**
|
1725
|
+
* Listen on `event` with callback `fn`.
|
1726
|
+
*/
|
1727
|
+
|
1728
|
+
function on(el, event, fn) {
|
1729
|
+
if (el.addEventListener) {
|
1730
|
+
el.addEventListener(event, fn, false);
|
1731
|
+
} else {
|
1732
|
+
el.attachEvent('on' + event, fn);
|
1733
|
+
}
|
1384
1734
|
}
|
1385
1735
|
|
1386
1736
|
/**
|
@@ -1414,14 +1764,171 @@ exports.TAP = require('./tap');
|
|
1414
1764
|
exports.JSON = require('./json');
|
1415
1765
|
exports.HTML = require('./html');
|
1416
1766
|
exports.List = require('./list');
|
1767
|
+
exports.Min = require('./min');
|
1417
1768
|
exports.Spec = require('./spec');
|
1418
1769
|
exports.Progress = require('./progress');
|
1419
1770
|
exports.Landing = require('./landing');
|
1771
|
+
exports.JSONCov = require('./json-cov');
|
1772
|
+
exports.HTMLCov = require('./html-cov');
|
1420
1773
|
exports.JSONStream = require('./json-stream');
|
1421
1774
|
exports.XUnit = require('./xunit')
|
1775
|
+
exports.Teamcity = require('./teamcity')
|
1422
1776
|
|
1423
1777
|
}); // module: reporters/index.js
|
1424
1778
|
|
1779
|
+
require.register("reporters/json-cov.js", function(module, exports, require){
|
1780
|
+
|
1781
|
+
/**
|
1782
|
+
* Module dependencies.
|
1783
|
+
*/
|
1784
|
+
|
1785
|
+
var Base = require('./base');
|
1786
|
+
|
1787
|
+
/**
|
1788
|
+
* Expose `JSONCov`.
|
1789
|
+
*/
|
1790
|
+
|
1791
|
+
exports = module.exports = JSONCov;
|
1792
|
+
|
1793
|
+
/**
|
1794
|
+
* Initialize a new `JsCoverage` reporter.
|
1795
|
+
*
|
1796
|
+
* @param {Runner} runner
|
1797
|
+
* @param {Boolean} output
|
1798
|
+
* @api public
|
1799
|
+
*/
|
1800
|
+
|
1801
|
+
function JSONCov(runner, output) {
|
1802
|
+
var self = this
|
1803
|
+
, output = 1 == arguments.length ? true : output;
|
1804
|
+
|
1805
|
+
Base.call(this, runner);
|
1806
|
+
|
1807
|
+
var tests = []
|
1808
|
+
, failures = []
|
1809
|
+
, passes = [];
|
1810
|
+
|
1811
|
+
runner.on('test end', function(test){
|
1812
|
+
tests.push(test);
|
1813
|
+
});
|
1814
|
+
|
1815
|
+
runner.on('pass', function(test){
|
1816
|
+
passes.push(test);
|
1817
|
+
});
|
1818
|
+
|
1819
|
+
runner.on('fail', function(test){
|
1820
|
+
failures.push(test);
|
1821
|
+
});
|
1822
|
+
|
1823
|
+
runner.on('end', function(){
|
1824
|
+
var cov = global._$jscoverage || {};
|
1825
|
+
var result = self.cov = map(cov);
|
1826
|
+
result.stats = self.stats;
|
1827
|
+
result.tests = tests.map(clean);
|
1828
|
+
result.failures = failures.map(clean);
|
1829
|
+
result.passes = passes.map(clean);
|
1830
|
+
if (!output) return;
|
1831
|
+
process.stdout.write(JSON.stringify(result, null, 2 ));
|
1832
|
+
});
|
1833
|
+
}
|
1834
|
+
|
1835
|
+
/**
|
1836
|
+
* Map jscoverage data to a JSON structure
|
1837
|
+
* suitable for reporting.
|
1838
|
+
*
|
1839
|
+
* @param {Object} cov
|
1840
|
+
* @return {Object}
|
1841
|
+
* @api private
|
1842
|
+
*/
|
1843
|
+
|
1844
|
+
function map(cov) {
|
1845
|
+
var ret = {
|
1846
|
+
instrumentation: 'node-jscoverage'
|
1847
|
+
, sloc: 0
|
1848
|
+
, hits: 0
|
1849
|
+
, misses: 0
|
1850
|
+
, coverage: 0
|
1851
|
+
, files: []
|
1852
|
+
};
|
1853
|
+
|
1854
|
+
for (var filename in cov) {
|
1855
|
+
var data = coverage(filename, cov[filename]);
|
1856
|
+
ret.files.push(data);
|
1857
|
+
ret.hits += data.hits;
|
1858
|
+
ret.misses += data.misses;
|
1859
|
+
ret.sloc += data.sloc;
|
1860
|
+
}
|
1861
|
+
|
1862
|
+
if (ret.sloc > 0) {
|
1863
|
+
ret.coverage = (ret.hits / ret.sloc) * 100;
|
1864
|
+
}
|
1865
|
+
|
1866
|
+
return ret;
|
1867
|
+
};
|
1868
|
+
|
1869
|
+
/**
|
1870
|
+
* Map jscoverage data for a single source file
|
1871
|
+
* to a JSON structure suitable for reporting.
|
1872
|
+
*
|
1873
|
+
* @param {String} filename name of the source file
|
1874
|
+
* @param {Object} data jscoverage coverage data
|
1875
|
+
* @return {Object}
|
1876
|
+
* @api private
|
1877
|
+
*/
|
1878
|
+
|
1879
|
+
function coverage(filename, data) {
|
1880
|
+
var ret = {
|
1881
|
+
filename: filename,
|
1882
|
+
coverage: 0,
|
1883
|
+
hits: 0,
|
1884
|
+
misses: 0,
|
1885
|
+
sloc: 0,
|
1886
|
+
source: {}
|
1887
|
+
};
|
1888
|
+
|
1889
|
+
data.source.forEach(function(line, num){
|
1890
|
+
num++;
|
1891
|
+
|
1892
|
+
if (data[num] === 0) {
|
1893
|
+
ret.misses++;
|
1894
|
+
ret.sloc++;
|
1895
|
+
} else if (data[num] !== undefined) {
|
1896
|
+
ret.hits++;
|
1897
|
+
ret.sloc++;
|
1898
|
+
}
|
1899
|
+
|
1900
|
+
ret.source[num] = {
|
1901
|
+
source: line
|
1902
|
+
, coverage: data[num] === undefined
|
1903
|
+
? ''
|
1904
|
+
: data[num]
|
1905
|
+
};
|
1906
|
+
});
|
1907
|
+
|
1908
|
+
ret.coverage = ret.hits / ret.sloc * 100;
|
1909
|
+
|
1910
|
+
return ret;
|
1911
|
+
}
|
1912
|
+
|
1913
|
+
/**
|
1914
|
+
* Return a plain-object representation of `test`
|
1915
|
+
* free of cyclic properties etc.
|
1916
|
+
*
|
1917
|
+
* @param {Object} test
|
1918
|
+
* @return {Object}
|
1919
|
+
* @api private
|
1920
|
+
*/
|
1921
|
+
|
1922
|
+
function clean(test) {
|
1923
|
+
return {
|
1924
|
+
title: test.title
|
1925
|
+
, fullTitle: test.fullTitle()
|
1926
|
+
, duration: test.duration
|
1927
|
+
}
|
1928
|
+
}
|
1929
|
+
|
1930
|
+
}); // module: reporters/json-cov.js
|
1931
|
+
|
1425
1932
|
require.register("reporters/json-stream.js", function(module, exports, require){
|
1426
1933
|
|
1427
1934
|
/**
|
@@ -1537,7 +2044,7 @@ function JSONReporter(runner) {
|
|
1537
2044
|
, passes: passes.map(clean)
|
1538
2045
|
};
|
1539
2046
|
|
1540
|
-
process.stdout.write(JSON.stringify(obj));
|
2047
|
+
process.stdout.write(JSON.stringify(obj, null, 2));
|
1541
2048
|
});
|
1542
2049
|
}
|
1543
2050
|
|
@@ -1629,7 +2136,7 @@ function Landing(runner) {
|
|
1629
2136
|
: crashed;
|
1630
2137
|
|
1631
2138
|
// show the crash
|
1632
|
-
if (test.
|
2139
|
+
if ('failed' == test.state) {
|
1633
2140
|
plane = color('plane crash', '✈');
|
1634
2141
|
crashed = col;
|
1635
2142
|
}
|
@@ -1731,6 +2238,162 @@ List.prototype.constructor = List;
|
|
1731
2238
|
|
1732
2239
|
}); // module: reporters/list.js
|
1733
2240
|
|
2241
|
+
require.register("reporters/markdown.js", function(module, exports, require){
|
2242
|
+
|
2243
|
+
/**
|
2244
|
+
* Module dependencies.
|
2245
|
+
*/
|
2246
|
+
|
2247
|
+
var Base = require('./base')
|
2248
|
+
, utils = require('../utils');
|
2249
|
+
|
2250
|
+
/**
|
2251
|
+
* Expose `Markdown`.
|
2252
|
+
*/
|
2253
|
+
|
2254
|
+
exports = module.exports = Markdown;
|
2255
|
+
|
2256
|
+
/**
|
2257
|
+
* Initialize a new `Markdown` reporter.
|
2258
|
+
*
|
2259
|
+
* @param {Runner} runner
|
2260
|
+
* @api public
|
2261
|
+
*/
|
2262
|
+
|
2263
|
+
function Markdown(runner) {
|
2264
|
+
Base.call(this, runner);
|
2265
|
+
|
2266
|
+
var self = this
|
2267
|
+
, stats = this.stats
|
2268
|
+
, total = runner.total
|
2269
|
+
, level = 0
|
2270
|
+
, buf = '';
|
2271
|
+
|
2272
|
+
function title(str) {
|
2273
|
+
return Array(level).join('#') + ' ' + str;
|
2274
|
+
}
|
2275
|
+
|
2276
|
+
function indent() {
|
2277
|
+
return Array(level).join(' ');
|
2278
|
+
}
|
2279
|
+
|
2280
|
+
function mapTOC(suite, obj) {
|
2281
|
+
var ret = obj;
|
2282
|
+
obj = obj[suite.title] = obj[suite.title] || { suite: suite };
|
2283
|
+
suite.suites.forEach(function(suite){
|
2284
|
+
mapTOC(suite, obj);
|
2285
|
+
});
|
2286
|
+
return ret;
|
2287
|
+
}
|
2288
|
+
|
2289
|
+
function stringifyTOC(obj, level) {
|
2290
|
+
++level;
|
2291
|
+
var buf = '';
|
2292
|
+
var link;
|
2293
|
+
for (var key in obj) {
|
2294
|
+
if ('suite' == key) continue;
|
2295
|
+
if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
|
2296
|
+
if (key) buf += Array(level).join(' ') + link;
|
2297
|
+
buf += stringifyTOC(obj[key], level);
|
2298
|
+
}
|
2299
|
+
--level;
|
2300
|
+
return buf;
|
2301
|
+
}
|
2302
|
+
|
2303
|
+
function generateTOC(suite) {
|
2304
|
+
var obj = mapTOC(suite, {});
|
2305
|
+
return stringifyTOC(obj, 0);
|
2306
|
+
}
|
2307
|
+
|
2308
|
+
generateTOC(runner.suite);
|
2309
|
+
|
2310
|
+
runner.on('suite', function(suite){
|
2311
|
+
++level;
|
2312
|
+
var slug = utils.slug(suite.fullTitle());
|
2313
|
+
buf += '<a name="' + slug + '" />' + '\n';
|
2314
|
+
buf += title(suite.title) + '\n';
|
2315
|
+
});
|
2316
|
+
|
2317
|
+
runner.on('suite end', function(suite){
|
2318
|
+
--level;
|
2319
|
+
});
|
2320
|
+
|
2321
|
+
runner.on('pass', function(test){
|
2322
|
+
var code = clean(test.fn.toString());
|
2323
|
+
buf += test.title + '.\n';
|
2324
|
+
buf += '\n```js';
|
2325
|
+
buf += code + '\n';
|
2326
|
+
buf += '```\n\n';
|
2327
|
+
});
|
2328
|
+
|
2329
|
+
runner.on('end', function(){
|
2330
|
+
process.stdout.write('# TOC\n');
|
2331
|
+
process.stdout.write(generateTOC(runner.suite));
|
2332
|
+
process.stdout.write(buf);
|
2333
|
+
});
|
2334
|
+
}
|
2335
|
+
|
2336
|
+
/**
|
2337
|
+
* Strip the function definition from `str`,
|
2338
|
+
* and re-indent for pre whitespace.
|
2339
|
+
*/
|
2340
|
+
|
2341
|
+
function clean(str) {
|
2342
|
+
str = str
|
2343
|
+
.replace(/^function *\(.*\) *{/, '')
|
2344
|
+
.replace(/\s+\}$/, '');
|
2345
|
+
|
2346
|
+
var spaces = str.match(/^\n?( *)/)[1].length
|
2347
|
+
, re = new RegExp('^ {' + spaces + '}', 'gm');
|
2348
|
+
|
2349
|
+
str = str.replace(re, '');
|
2350
|
+
|
2351
|
+
return str;
|
2352
|
+
}
|
2353
|
+
}); // module: reporters/markdown.js
|
2354
|
+
|
2355
|
+
require.register("reporters/min.js", function(module, exports, require){
|
2356
|
+
/**
|
2357
|
+
* Module dependencies.
|
2358
|
+
*/
|
2359
|
+
|
2360
|
+
var Base = require('./base');
|
2361
|
+
|
2362
|
+
/**
|
2363
|
+
* Expose `Min`.
|
2364
|
+
*/
|
2365
|
+
|
2366
|
+
exports = module.exports = Min;
|
2367
|
+
|
2368
|
+
/**
|
2369
|
+
* Initialize a new `Min` minimal test reporter (best used with --watch).
|
2370
|
+
*
|
2371
|
+
* @param {Runner} runner
|
2372
|
+
* @api public
|
2373
|
+
*/
|
2374
|
+
|
2375
|
+
function Min(runner) {
|
2376
|
+
Base.call(this, runner);
|
2377
|
+
|
2378
|
+
runner.on('start', function(){
|
2379
|
+
// clear screen
|
2380
|
+
process.stdout.write('\033[2J');
|
2381
|
+
// set cursor position
|
2382
|
+
process.stdout.write('\033[1;3H');
|
2383
|
+
});
|
2384
|
+
|
2385
|
+
runner.on('end', this.epilogue.bind(this));
|
2386
|
+
}
|
2387
|
+
|
2388
|
+
/**
|
2389
|
+
* Inherit from `Base.prototype`.
|
2390
|
+
*/
|
2391
|
+
|
2392
|
+
Min.prototype = new Base;
|
2393
|
+
Min.prototype.constructor = Min;
|
2394
|
+
|
2395
|
+
}); // module: reporters/min.js
|
2396
|
+
|
1734
2397
|
require.register("reporters/progress.js", function(module, exports, require){
|
1735
2398
|
|
1736
2399
|
/**
|
@@ -2109,7 +2772,7 @@ function test(test) {
|
|
2109
2772
|
, time: test.duration / 1000
|
2110
2773
|
};
|
2111
2774
|
|
2112
|
-
if (test.
|
2775
|
+
if ('failed' == test.state) {
|
2113
2776
|
var err = test.err;
|
2114
2777
|
attrs.message = escape(err.message);
|
2115
2778
|
console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata(err.stack))));
|
@@ -2436,7 +3099,7 @@ Runner.prototype.checkGlobals = function(test){
|
|
2436
3099
|
|
2437
3100
|
Runner.prototype.fail = function(test, err){
|
2438
3101
|
++this.failures;
|
2439
|
-
test.
|
3102
|
+
test.state = 'failed';
|
2440
3103
|
this.emit('fail', test, err);
|
2441
3104
|
};
|
2442
3105
|
|
@@ -2643,7 +3306,7 @@ Runner.prototype.runTests = function(suite, fn){
|
|
2643
3306
|
return self.hookUp('afterEach', next);
|
2644
3307
|
}
|
2645
3308
|
|
2646
|
-
test.
|
3309
|
+
test.state = 'passed';
|
2647
3310
|
self.emit('pass', test);
|
2648
3311
|
self.emit('test end', test);
|
2649
3312
|
self.hookUp('afterEach', next);
|
@@ -2700,7 +3363,7 @@ Runner.prototype.runSuite = function(suite, fn){
|
|
2700
3363
|
Runner.prototype.uncaught = function(err){
|
2701
3364
|
debug('uncaught exception');
|
2702
3365
|
var runnable = this.currentRunnable;
|
2703
|
-
if (runnable.
|
3366
|
+
if ('failed' == runnable.state) return;
|
2704
3367
|
runnable.clearTimeout();
|
2705
3368
|
err.uncaught = true;
|
2706
3369
|
this.fail(runnable, err);
|
@@ -2834,6 +3497,7 @@ Suite.prototype.constructor = Suite;
|
|
2834
3497
|
Suite.prototype.clone = function(){
|
2835
3498
|
var suite = new Suite(this.title);
|
2836
3499
|
debug('clone');
|
3500
|
+
suite.ctx = this.ctx;
|
2837
3501
|
suite.timeout(this.timeout());
|
2838
3502
|
suite.bail(this.bail());
|
2839
3503
|
return suite;
|
@@ -3178,9 +3842,9 @@ exports.keys = Object.keys || function(obj) {
|
|
3178
3842
|
var keys = []
|
3179
3843
|
, has = Object.prototype.hasOwnProperty // for `window` on <=IE8
|
3180
3844
|
|
3181
|
-
for (var
|
3182
|
-
if (has.call(obj,
|
3183
|
-
keys.push(
|
3845
|
+
for (var key in obj) {
|
3846
|
+
if (has.call(obj, key)) {
|
3847
|
+
keys.push(key);
|
3184
3848
|
}
|
3185
3849
|
}
|
3186
3850
|
|
@@ -3218,7 +3882,7 @@ function ignored(path){
|
|
3218
3882
|
* Lookup files in the given `dir`.
|
3219
3883
|
*
|
3220
3884
|
* @return {Array}
|
3221
|
-
* @api
|
3885
|
+
* @api private
|
3222
3886
|
*/
|
3223
3887
|
|
3224
3888
|
exports.files = function(dir, ret){
|
@@ -3237,6 +3901,20 @@ exports.files = function(dir, ret){
|
|
3237
3901
|
|
3238
3902
|
return ret;
|
3239
3903
|
};
|
3904
|
+
|
3905
|
+
/**
|
3906
|
+
* Compute a slug from the given `str`.
|
3907
|
+
*
|
3908
|
+
* @param {String} str
|
3909
|
+
* @return {String}
|
3910
|
+
*/
|
3911
|
+
|
3912
|
+
exports.slug = function(str){
|
3913
|
+
return str
|
3914
|
+
.toLowerCase()
|
3915
|
+
.replace(/ +/g, '-')
|
3916
|
+
.replace(/[^-\w]/g, '');
|
3917
|
+
};
|
3240
3918
|
}); // module: utils.js
|
3241
3919
|
|
3242
3920
|
/**
|
@@ -3310,13 +3988,7 @@ window.mocha = require('mocha');
|
|
3310
3988
|
;(function(){
|
3311
3989
|
var suite = new mocha.Suite('', new mocha.Context)
|
3312
3990
|
, utils = mocha.utils
|
3313
|
-
,
|
3314
|
-
|
3315
|
-
$(function(){
|
3316
|
-
$('code').each(function(){
|
3317
|
-
$(this).html(highlight($(this).text()));
|
3318
|
-
});
|
3319
|
-
});
|
3991
|
+
, options = {}
|
3320
3992
|
|
3321
3993
|
/**
|
3322
3994
|
* Highlight the given string of `js`.
|
@@ -3327,13 +3999,24 @@ window.mocha = require('mocha');
|
|
3327
3999
|
.replace(/</g, '<')
|
3328
4000
|
.replace(/>/g, '>')
|
3329
4001
|
.replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
|
3330
|
-
.replace(/('
|
4002
|
+
.replace(/('.*?')/gm, '<span class="string">$1</span>')
|
3331
4003
|
.replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
|
3332
4004
|
.replace(/(\d+)/gm, '<span class="number">$1</span>')
|
3333
4005
|
.replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
|
3334
4006
|
.replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
|
3335
4007
|
}
|
3336
4008
|
|
4009
|
+
/**
|
4010
|
+
* Highlight code contents.
|
4011
|
+
*/
|
4012
|
+
|
4013
|
+
function highlightCode() {
|
4014
|
+
var code = document.getElementsByTagName('code');
|
4015
|
+
for (var i = 0, len = code.length; i < len; ++i) {
|
4016
|
+
code[i].innerHTML = highlight(code[i].innerHTML);
|
4017
|
+
}
|
4018
|
+
}
|
4019
|
+
|
3337
4020
|
/**
|
3338
4021
|
* Parse the given `qs`.
|
3339
4022
|
*/
|
@@ -3350,12 +4033,16 @@ window.mocha = require('mocha');
|
|
3350
4033
|
}
|
3351
4034
|
|
3352
4035
|
/**
|
3353
|
-
* Setup mocha with the
|
4036
|
+
* Setup mocha with the given setting options.
|
3354
4037
|
*/
|
3355
4038
|
|
3356
|
-
mocha.setup = function(
|
3357
|
-
ui =
|
4039
|
+
mocha.setup = function(opts){
|
4040
|
+
if ('string' === typeof opts) options.ui = opts;
|
4041
|
+
else options = opts;
|
4042
|
+
|
4043
|
+
ui = mocha.interfaces[options.ui];
|
3358
4044
|
if (!ui) throw new Error('invalid mocha interface "' + ui + '"');
|
4045
|
+
if (options.timeout) suite.timeout(options.timeout);
|
3359
4046
|
ui(suite);
|
3360
4047
|
suite.emit('pre-require', window);
|
3361
4048
|
};
|
@@ -3367,14 +4054,14 @@ window.mocha = require('mocha');
|
|
3367
4054
|
mocha.run = function(){
|
3368
4055
|
suite.emit('run');
|
3369
4056
|
var runner = new mocha.Runner(suite);
|
4057
|
+
var Reporter = options.reporter || mocha.reporters.HTML;
|
3370
4058
|
var reporter = new Reporter(runner);
|
3371
4059
|
var query = parse(window.location.search || "");
|
3372
4060
|
if (query.grep) runner.grep(new RegExp(query.grep));
|
3373
|
-
runner.
|
3374
|
-
|
3375
|
-
|
3376
|
-
|
3377
|
-
});
|
4061
|
+
if (options.ignoreLeaks) runner.ignoreLeaks = true;
|
4062
|
+
if (options.globals) runner.globals(options.globals);
|
4063
|
+
runner.globals(['location']);
|
4064
|
+
runner.on('end', highlightCode);
|
3378
4065
|
return runner.run();
|
3379
4066
|
};
|
3380
4067
|
})();
|