mocha 1.7.3 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/_mocha.js CHANGED
@@ -56,6 +56,293 @@ module.exports = function(type){
56
56
  }); // module: browser/debug.js
57
57
 
58
58
  require.register("browser/diff.js", function(module, exports, require){
59
+ /* See license.txt for terms of usage */
60
+
61
+ /*
62
+ * Text diff implementation.
63
+ *
64
+ * This library supports the following APIS:
65
+ * JsDiff.diffChars: Character by character diff
66
+ * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
67
+ * JsDiff.diffLines: Line based diff
68
+ *
69
+ * JsDiff.diffCss: Diff targeted at CSS content
70
+ *
71
+ * These methods are based on the implementation proposed in
72
+ * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
73
+ * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
74
+ */
75
+ var JsDiff = (function() {
76
+ function clonePath(path) {
77
+ return { newPos: path.newPos, components: path.components.slice(0) };
78
+ }
79
+ function removeEmpty(array) {
80
+ var ret = [];
81
+ for (var i = 0; i < array.length; i++) {
82
+ if (array[i]) {
83
+ ret.push(array[i]);
84
+ }
85
+ }
86
+ return ret;
87
+ }
88
+ function escapeHTML(s) {
89
+ var n = s;
90
+ n = n.replace(/&/g, "&amp;");
91
+ n = n.replace(/</g, "&lt;");
92
+ n = n.replace(/>/g, "&gt;");
93
+ n = n.replace(/"/g, "&quot;");
94
+
95
+ return n;
96
+ }
97
+
98
+
99
+ var fbDiff = function(ignoreWhitespace) {
100
+ this.ignoreWhitespace = ignoreWhitespace;
101
+ };
102
+ fbDiff.prototype = {
103
+ diff: function(oldString, newString) {
104
+ // Handle the identity case (this is due to unrolling editLength == 0
105
+ if (newString == oldString) {
106
+ return [{ value: newString }];
107
+ }
108
+ if (!newString) {
109
+ return [{ value: oldString, removed: true }];
110
+ }
111
+ if (!oldString) {
112
+ return [{ value: newString, added: true }];
113
+ }
114
+
115
+ newString = this.tokenize(newString);
116
+ oldString = this.tokenize(oldString);
117
+
118
+ var newLen = newString.length, oldLen = oldString.length;
119
+ var maxEditLength = newLen + oldLen;
120
+ var bestPath = [{ newPos: -1, components: [] }];
121
+
122
+ // Seed editLength = 0
123
+ var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
124
+ if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
125
+ return bestPath[0].components;
126
+ }
127
+
128
+ for (var editLength = 1; editLength <= maxEditLength; editLength++) {
129
+ for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
130
+ var basePath;
131
+ var addPath = bestPath[diagonalPath-1],
132
+ removePath = bestPath[diagonalPath+1];
133
+ oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
134
+ if (addPath) {
135
+ // No one else is going to attempt to use this value, clear it
136
+ bestPath[diagonalPath-1] = undefined;
137
+ }
138
+
139
+ var canAdd = addPath && addPath.newPos+1 < newLen;
140
+ var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
141
+ if (!canAdd && !canRemove) {
142
+ bestPath[diagonalPath] = undefined;
143
+ continue;
144
+ }
145
+
146
+ // Select the diagonal that we want to branch from. We select the prior
147
+ // path whose position in the new string is the farthest from the origin
148
+ // and does not pass the bounds of the diff graph
149
+ if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
150
+ basePath = clonePath(removePath);
151
+ this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
152
+ } else {
153
+ basePath = clonePath(addPath);
154
+ basePath.newPos++;
155
+ this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
156
+ }
157
+
158
+ var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
159
+
160
+ if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
161
+ return basePath.components;
162
+ } else {
163
+ bestPath[diagonalPath] = basePath;
164
+ }
165
+ }
166
+ }
167
+ },
168
+
169
+ pushComponent: function(components, value, added, removed) {
170
+ var last = components[components.length-1];
171
+ if (last && last.added === added && last.removed === removed) {
172
+ // We need to clone here as the component clone operation is just
173
+ // as shallow array clone
174
+ components[components.length-1] =
175
+ {value: this.join(last.value, value), added: added, removed: removed };
176
+ } else {
177
+ components.push({value: value, added: added, removed: removed });
178
+ }
179
+ },
180
+ extractCommon: function(basePath, newString, oldString, diagonalPath) {
181
+ var newLen = newString.length,
182
+ oldLen = oldString.length,
183
+ newPos = basePath.newPos,
184
+ oldPos = newPos - diagonalPath;
185
+ while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
186
+ newPos++;
187
+ oldPos++;
188
+
189
+ this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
190
+ }
191
+ basePath.newPos = newPos;
192
+ return oldPos;
193
+ },
194
+
195
+ equals: function(left, right) {
196
+ var reWhitespace = /\S/;
197
+ if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
198
+ return true;
199
+ } else {
200
+ return left == right;
201
+ }
202
+ },
203
+ join: function(left, right) {
204
+ return left + right;
205
+ },
206
+ tokenize: function(value) {
207
+ return value;
208
+ }
209
+ };
210
+
211
+ var CharDiff = new fbDiff();
212
+
213
+ var WordDiff = new fbDiff(true);
214
+ WordDiff.tokenize = function(value) {
215
+ return removeEmpty(value.split(/(\s+|\b)/));
216
+ };
217
+
218
+ var CssDiff = new fbDiff(true);
219
+ CssDiff.tokenize = function(value) {
220
+ return removeEmpty(value.split(/([{}:;,]|\s+)/));
221
+ };
222
+
223
+ var LineDiff = new fbDiff();
224
+ LineDiff.tokenize = function(value) {
225
+ return value.split(/^/m);
226
+ };
227
+
228
+ return {
229
+ diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
230
+ diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
231
+ diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
232
+
233
+ diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
234
+
235
+ createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
236
+ var ret = [];
237
+
238
+ ret.push("Index: " + fileName);
239
+ ret.push("===================================================================");
240
+ ret.push("--- " + fileName + (typeof oldHeader === "undefined" ? "" : "\t" + oldHeader));
241
+ ret.push("+++ " + fileName + (typeof newHeader === "undefined" ? "" : "\t" + newHeader));
242
+
243
+ var diff = LineDiff.diff(oldStr, newStr);
244
+ if (!diff[diff.length-1].value) {
245
+ diff.pop(); // Remove trailing newline add
246
+ }
247
+ diff.push({value: "", lines: []}); // Append an empty value to make cleanup easier
248
+
249
+ function contextLines(lines) {
250
+ return lines.map(function(entry) { return ' ' + entry; });
251
+ }
252
+ function eofNL(curRange, i, current) {
253
+ var last = diff[diff.length-2],
254
+ isLast = i === diff.length-2,
255
+ isLastOfType = i === diff.length-3 && (current.added === !last.added || current.removed === !last.removed);
256
+
257
+ // Figure out if this is the last line for the given file and missing NL
258
+ if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
259
+ curRange.push('\');
260
+ }
261
+ }
262
+
263
+ var oldRangeStart = 0, newRangeStart = 0, curRange = [],
264
+ oldLine = 1, newLine = 1;
265
+ for (var i = 0; i < diff.length; i++) {
266
+ var current = diff[i],
267
+ lines = current.lines || current.value.replace(/\n$/, "").split("\n");
268
+ current.lines = lines;
269
+
270
+ if (current.added || current.removed) {
271
+ if (!oldRangeStart) {
272
+ var prev = diff[i-1];
273
+ oldRangeStart = oldLine;
274
+ newRangeStart = newLine;
275
+
276
+ if (prev) {
277
+ curRange = contextLines(prev.lines.slice(-4));
278
+ oldRangeStart -= curRange.length;
279
+ newRangeStart -= curRange.length;
280
+ }
281
+ }
282
+ curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?"+":"-") + entry; }));
283
+ eofNL(curRange, i, current);
284
+
285
+ if (current.added) {
286
+ newLine += lines.length;
287
+ } else {
288
+ oldLine += lines.length;
289
+ }
290
+ } else {
291
+ if (oldRangeStart) {
292
+ // Close out any changes that have been output (or join overlapping)
293
+ if (lines.length <= 8 && i < diff.length-2) {
294
+ // Overlapping
295
+ curRange.push.apply(curRange, contextLines(lines));
296
+ } else {
297
+ // end the range and output
298
+ var contextSize = Math.min(lines.length, 4);
299
+ ret.push(
300
+ "@@ -" + oldRangeStart + "," + (oldLine-oldRangeStart+contextSize)
301
+ + " +" + newRangeStart + "," + (newLine-newRangeStart+contextSize)
302
+ + " @@");
303
+ ret.push.apply(ret, curRange);
304
+ ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
305
+ if (lines.length <= 4) {
306
+ eofNL(ret, i, current);
307
+ }
308
+
309
+ oldRangeStart = 0; newRangeStart = 0; curRange = [];
310
+ }
311
+ }
312
+ oldLine += lines.length;
313
+ newLine += lines.length;
314
+ }
315
+ }
316
+
317
+ return ret.join('\n') + '\n';
318
+ },
319
+
320
+ convertChangesToXML: function(changes){
321
+ var ret = [];
322
+ for ( var i = 0; i < changes.length; i++) {
323
+ var change = changes[i];
324
+ if (change.added) {
325
+ ret.push("<ins>");
326
+ } else if (change.removed) {
327
+ ret.push("<del>");
328
+ }
329
+
330
+ ret.push(escapeHTML(change.value));
331
+
332
+ if (change.added) {
333
+ ret.push("</ins>");
334
+ } else if (change.removed) {
335
+ ret.push("</del>");
336
+ }
337
+ }
338
+ return ret.join("");
339
+ }
340
+ };
341
+ })();
342
+
343
+ if (typeof module !== "undefined") {
344
+ module.exports = JsDiff;
345
+ }
59
346
 
60
347
  }); // module: browser/diff.js
61
348
 
@@ -492,7 +779,9 @@ function Hook(title, fn) {
492
779
  * Inherit from `Runnable.prototype`.
493
780
  */
494
781
 
495
- Hook.prototype = new Runnable;
782
+ function F(){};
783
+ F.prototype = Runnable.prototype;
784
+ Hook.prototype = new F;
496
785
  Hook.prototype.constructor = Hook;
497
786
 
498
787
 
@@ -1003,6 +1292,7 @@ function image(name) {
1003
1292
  * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
1004
1293
  * - `globals` array of accepted globals
1005
1294
  * - `timeout` timeout in milliseconds
1295
+ * - `bail` bail on the first test failure
1006
1296
  * - `slow` milliseconds to wait before considering a test slow
1007
1297
  * - `ignoreLeaks` ignore global leaks
1008
1298
  * - `grep` string or regexp to filter tests with
@@ -1018,11 +1308,25 @@ function Mocha(options) {
1018
1308
  this.grep(options.grep);
1019
1309
  this.suite = new exports.Suite('', new exports.Context);
1020
1310
  this.ui(options.ui);
1311
+ this.bail(options.bail);
1021
1312
  this.reporter(options.reporter);
1022
1313
  if (options.timeout) this.timeout(options.timeout);
1023
1314
  if (options.slow) this.slow(options.slow);
1024
1315
  }
1025
1316
 
1317
+ /**
1318
+ * Enable or disable bailing on the first failure.
1319
+ *
1320
+ * @param {Boolean} [bail]
1321
+ * @api public
1322
+ */
1323
+
1324
+ Mocha.prototype.bail = function(bail){
1325
+ if (0 == arguments.length) bail = true;
1326
+ this.suite.bail(bail);
1327
+ return this;
1328
+ };
1329
+
1026
1330
  /**
1027
1331
  * Add test `file`.
1028
1332
  *
@@ -1038,7 +1342,7 @@ Mocha.prototype.addFile = function(file){
1038
1342
  /**
1039
1343
  * Set reporter to `reporter`, defaults to "dot".
1040
1344
  *
1041
- * @param {String|Function} reporter name of a reporter or a reporter constructor
1345
+ * @param {String|Function} reporter name or constructor
1042
1346
  * @api public
1043
1347
  */
1044
1348
 
@@ -1844,7 +2148,9 @@ function Dot(runner) {
1844
2148
  * Inherit from `Base.prototype`.
1845
2149
  */
1846
2150
 
1847
- Dot.prototype = new Base;
2151
+ function F(){};
2152
+ F.prototype = Base.prototype;
2153
+ Dot.prototype = new F;
1848
2154
  Dot.prototype.constructor = Dot;
1849
2155
 
1850
2156
  }); // module: reporters/dot.js
@@ -2071,7 +2377,7 @@ function HTML(runner, root) {
2071
2377
 
2072
2378
  on(h2, 'click', function(){
2073
2379
  pre.style.display = 'none' == pre.style.display
2074
- ? 'inline-block'
2380
+ ? 'block'
2075
2381
  : 'none';
2076
2382
  });
2077
2383
 
@@ -2576,7 +2882,9 @@ function Landing(runner) {
2576
2882
  * Inherit from `Base.prototype`.
2577
2883
  */
2578
2884
 
2579
- Landing.prototype = new Base;
2885
+ function F(){};
2886
+ F.prototype = Base.prototype;
2887
+ Landing.prototype = new F;
2580
2888
  Landing.prototype.constructor = Landing;
2581
2889
 
2582
2890
  }); // module: reporters/landing.js
@@ -2645,7 +2953,9 @@ function List(runner) {
2645
2953
  * Inherit from `Base.prototype`.
2646
2954
  */
2647
2955
 
2648
- List.prototype = new Base;
2956
+ function F(){};
2957
+ F.prototype = Base.prototype;
2958
+ List.prototype = new F;
2649
2959
  List.prototype.constructor = List;
2650
2960
 
2651
2961
 
@@ -2677,7 +2987,6 @@ function Markdown(runner) {
2677
2987
 
2678
2988
  var self = this
2679
2989
  , stats = this.stats
2680
- , total = runner.total
2681
2990
  , level = 0
2682
2991
  , buf = '';
2683
2992
 
@@ -2784,7 +3093,9 @@ function Min(runner) {
2784
3093
  * Inherit from `Base.prototype`.
2785
3094
  */
2786
3095
 
2787
- Min.prototype = new Base;
3096
+ function F(){};
3097
+ F.prototype = Base.prototype;
3098
+ Min.prototype = new F;
2788
3099
  Min.prototype.constructor = Min;
2789
3100
 
2790
3101
  }); // module: reporters/min.js
@@ -3048,7 +3359,9 @@ function write(string) {
3048
3359
  * Inherit from `Base.prototype`.
3049
3360
  */
3050
3361
 
3051
- NyanCat.prototype = new Base;
3362
+ function F(){};
3363
+ F.prototype = Base.prototype;
3364
+ NyanCat.prototype = new F;
3052
3365
  NyanCat.prototype.constructor = NyanCat;
3053
3366
 
3054
3367
 
@@ -3140,7 +3453,9 @@ function Progress(runner, options) {
3140
3453
  * Inherit from `Base.prototype`.
3141
3454
  */
3142
3455
 
3143
- Progress.prototype = new Base;
3456
+ function F(){};
3457
+ F.prototype = Base.prototype;
3458
+ Progress.prototype = new F;
3144
3459
  Progress.prototype.constructor = Progress;
3145
3460
 
3146
3461
 
@@ -3233,7 +3548,9 @@ function Spec(runner) {
3233
3548
  * Inherit from `Base.prototype`.
3234
3549
  */
3235
3550
 
3236
- Spec.prototype = new Base;
3551
+ function F(){};
3552
+ F.prototype = Base.prototype;
3553
+ Spec.prototype = new F;
3237
3554
  Spec.prototype.constructor = Spec;
3238
3555
 
3239
3556
 
@@ -3267,7 +3584,9 @@ function TAP(runner) {
3267
3584
 
3268
3585
  var self = this
3269
3586
  , stats = this.stats
3270
- , n = 1;
3587
+ , n = 1
3588
+ , passes = 0
3589
+ , failures = 0;
3271
3590
 
3272
3591
  runner.on('start', function(){
3273
3592
  var total = runner.grepTotal(runner.suite);
@@ -3283,12 +3602,20 @@ function TAP(runner) {
3283
3602
  });
3284
3603
 
3285
3604
  runner.on('pass', function(test){
3605
+ passes++;
3286
3606
  console.log('ok %d %s', n, title(test));
3287
3607
  });
3288
3608
 
3289
3609
  runner.on('fail', function(test, err){
3610
+ failures++;
3290
3611
  console.log('not ok %d %s', n, title(test));
3291
- console.log(err.stack.replace(/^/gm, ' '));
3612
+ if (err.stack) console.log(err.stack.replace(/^/gm, ' '));
3613
+ });
3614
+
3615
+ runner.on('end', function(){
3616
+ console.log('# tests ' + (passes + failures));
3617
+ console.log('# pass ' + passes);
3618
+ console.log('# fail ' + failures);
3292
3619
  });
3293
3620
  }
3294
3621
 
@@ -3442,7 +3769,9 @@ function XUnit(runner) {
3442
3769
  * Inherit from `Base.prototype`.
3443
3770
  */
3444
3771
 
3445
- XUnit.prototype = new Base;
3772
+ function F(){};
3773
+ F.prototype = Base.prototype;
3774
+ XUnit.prototype = new F;
3446
3775
  XUnit.prototype.constructor = XUnit;
3447
3776
 
3448
3777
 
@@ -3550,7 +3879,9 @@ function Runnable(title, fn) {
3550
3879
  * Inherit from `EventEmitter.prototype`.
3551
3880
  */
3552
3881
 
3553
- Runnable.prototype = new EventEmitter;
3882
+ function F(){};
3883
+ F.prototype = EventEmitter.prototype;
3884
+ Runnable.prototype = new F;
3554
3885
  Runnable.prototype.constructor = Runnable;
3555
3886
 
3556
3887
 
@@ -3695,7 +4026,7 @@ Runnable.prototype.run = function(fn){
3695
4026
  if (this.async) {
3696
4027
  try {
3697
4028
  this.fn.call(ctx, function(err){
3698
- if (toString.call(err) === "[object Error]") return done(err);
4029
+ if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
3699
4030
  if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
3700
4031
  done();
3701
4032
  });
@@ -3789,7 +4120,9 @@ function Runner(suite) {
3789
4120
  * Inherit from `EventEmitter.prototype`.
3790
4121
  */
3791
4122
 
3792
- Runner.prototype = new EventEmitter;
4123
+ function F(){};
4124
+ F.prototype = EventEmitter.prototype;
4125
+ Runner.prototype = new F;
3793
4126
  Runner.prototype.constructor = Runner;
3794
4127
 
3795
4128
 
@@ -3845,7 +4178,7 @@ Runner.prototype.globalProps = function() {
3845
4178
 
3846
4179
  // non-enumerables
3847
4180
  for (var i = 0; i < globals.length; ++i) {
3848
- if (~props.indexOf(globals[i])) continue;
4181
+ if (~utils.indexOf(props, globals[i])) continue;
3849
4182
  props.push(globals[i]);
3850
4183
  }
3851
4184
 
@@ -4216,7 +4549,9 @@ Runner.prototype.run = function(fn){
4216
4549
  // callback
4217
4550
  this.on('end', function(){
4218
4551
  debug('end');
4219
- process.removeListener('uncaughtException', self.uncaught.bind(self));
4552
+ process.removeListener('uncaughtException', function(err){
4553
+ self.uncaught(err);
4554
+ });
4220
4555
  fn(self.failures);
4221
4556
  });
4222
4557
 
@@ -4228,7 +4563,9 @@ Runner.prototype.run = function(fn){
4228
4563
  });
4229
4564
 
4230
4565
  // uncaught exception
4231
- process.on('uncaughtException', this.uncaught.bind(this));
4566
+ process.on('uncaughtException', function(err){
4567
+ self.uncaught(err);
4568
+ });
4232
4569
 
4233
4570
  return this;
4234
4571
  };
@@ -4325,7 +4662,9 @@ function Suite(title, ctx) {
4325
4662
  * Inherit from `EventEmitter.prototype`.
4326
4663
  */
4327
4664
 
4328
- Suite.prototype = new EventEmitter;
4665
+ function F(){};
4666
+ F.prototype = EventEmitter.prototype;
4667
+ Suite.prototype = new F;
4329
4668
  Suite.prototype.constructor = Suite;
4330
4669
 
4331
4670
 
@@ -4590,7 +4929,9 @@ function Test(title, fn) {
4590
4929
  * Inherit from `Runnable.prototype`.
4591
4930
  */
4592
4931
 
4593
- Test.prototype = new Runnable;
4932
+ function F(){};
4933
+ F.prototype = Runnable.prototype;
4934
+ Test.prototype = new F;
4594
4935
  Test.prototype.constructor = Test;
4595
4936
 
4596
4937
 
package/bin/_mocha CHANGED
@@ -5,10 +5,9 @@
5
5
  */
6
6
 
7
7
  var program = require('commander')
8
- , exec = require('child_process').exec
8
+ , sprintf = require('util').format
9
9
  , path = require('path')
10
10
  , fs = require('fs')
11
- , vm = require('vm')
12
11
  , resolve = path.resolve
13
12
  , exists = fs.existsSync || path.existsSync
14
13
  , Mocha = require('../')
@@ -286,14 +285,13 @@ if (program.watch) {
286
285
  process.exit();
287
286
  });
288
287
 
289
- var frames = [
290
- ' \u001b[96m◜ \u001b[90mwatching\u001b[0m'
291
- , ' \u001b[96m \u001b[90mwatching\u001b[0m'
292
- , ' \u001b[96m◝ \u001b[90mwatching\u001b[0m'
293
- , ' \u001b[96m◞ \u001b[90mwatching\u001b[0m'
294
- , ' \u001b[96m \u001b[90mwatching\u001b[0m'
295
- , ' \u001b[96m◟ \u001b[90mwatching\u001b[0m'
296
- ];
288
+ var spinner = 'win32' == process.platform
289
+ ? ['|','/','-','\\']
290
+ : ['◜','◠','◝','◞','◡','◟'];
291
+
292
+ var frames = spinner.map(function(c) {
293
+ return sprintf(' \u001b[96m%s \u001b[90mwatching\u001b[0m', c);
294
+ });
297
295
 
298
296
  var watchFiles = utils.files(cwd);
299
297
 
@@ -417,6 +415,6 @@ function play(arr, interval) {
417
415
 
418
416
  play.timer = setInterval(function(){
419
417
  var str = arr[i++ % len];
420
- process.stdout.write('\r' + str);
418
+ process.stdout.write('\u001b[0G' + str);
421
419
  }, interval);
422
420
  }
package/component.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "mocha",
3
+ "version": "1.8.2",
4
+ "repo": "visionmedia/mocha",
5
+ "description": "simple, flexible, fun test framework",
6
+ "keywords": [
7
+ "mocha",
8
+ "test",
9
+ "bdd",
10
+ "tdd",
11
+ "tap"
12
+ ],
13
+ "main": "mocha.js",
14
+ "scripts": ["mocha.js"],
15
+ "styles": ["mocha.css"]
16
+ }