You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4698 lines
91 KiB

  1. ;(function(){
  2. // CommonJS require()
  3. function require(p){
  4. var path = require.resolve(p)
  5. , mod = require.modules[path];
  6. if (!mod) throw new Error('failed to require "' + p + '"');
  7. if (!mod.exports) {
  8. mod.exports = {};
  9. mod.call(mod.exports, mod, mod.exports, require.relative(path));
  10. }
  11. return mod.exports;
  12. }
  13. require.modules = {};
  14. require.resolve = function (path){
  15. var orig = path
  16. , reg = path + '.js'
  17. , index = path + '/index.js';
  18. return require.modules[reg] && reg
  19. || require.modules[index] && index
  20. || orig;
  21. };
  22. require.register = function (path, fn){
  23. require.modules[path] = fn;
  24. };
  25. require.relative = function (parent) {
  26. return function(p){
  27. if ('.' != p.charAt(0)) return require(p);
  28. var path = parent.split('/')
  29. , segs = p.split('/');
  30. path.pop();
  31. for (var i = 0; i < segs.length; i++) {
  32. var seg = segs[i];
  33. if ('..' == seg) path.pop();
  34. else if ('.' != seg) path.push(seg);
  35. }
  36. return require(path.join('/'));
  37. };
  38. };
  39. require.register("browser/debug.js", function(module, exports, require){
  40. module.exports = function(type){
  41. return function(){
  42. }
  43. };
  44. }); // module: browser/debug.js
  45. require.register("browser/diff.js", function(module, exports, require){
  46. }); // module: browser/diff.js
  47. require.register("browser/events.js", function(module, exports, require){
  48. /**
  49. * Module exports.
  50. */
  51. exports.EventEmitter = EventEmitter;
  52. /**
  53. * Check if `obj` is an array.
  54. */
  55. function isArray(obj) {
  56. return '[object Array]' == {}.toString.call(obj);
  57. }
  58. /**
  59. * Event emitter constructor.
  60. *
  61. * @api public
  62. */
  63. function EventEmitter(){};
  64. /**
  65. * Adds a listener.
  66. *
  67. * @api public
  68. */
  69. EventEmitter.prototype.on = function (name, fn) {
  70. if (!this.$events) {
  71. this.$events = {};
  72. }
  73. if (!this.$events[name]) {
  74. this.$events[name] = fn;
  75. } else if (isArray(this.$events[name])) {
  76. this.$events[name].push(fn);
  77. } else {
  78. this.$events[name] = [this.$events[name], fn];
  79. }
  80. return this;
  81. };
  82. EventEmitter.prototype.addListener = EventEmitter.prototype.on;
  83. /**
  84. * Adds a volatile listener.
  85. *
  86. * @api public
  87. */
  88. EventEmitter.prototype.once = function (name, fn) {
  89. var self = this;
  90. function on () {
  91. self.removeListener(name, on);
  92. fn.apply(this, arguments);
  93. };
  94. on.listener = fn;
  95. this.on(name, on);
  96. return this;
  97. };
  98. /**
  99. * Removes a listener.
  100. *
  101. * @api public
  102. */
  103. EventEmitter.prototype.removeListener = function (name, fn) {
  104. if (this.$events && this.$events[name]) {
  105. var list = this.$events[name];
  106. if (isArray(list)) {
  107. var pos = -1;
  108. for (var i = 0, l = list.length; i < l; i++) {
  109. if (list[i] === fn || (list[i].listener && list[i].listener === fn)) {
  110. pos = i;
  111. break;
  112. }
  113. }
  114. if (pos < 0) {
  115. return this;
  116. }
  117. list.splice(pos, 1);
  118. if (!list.length) {
  119. delete this.$events[name];
  120. }
  121. } else if (list === fn || (list.listener && list.listener === fn)) {
  122. delete this.$events[name];
  123. }
  124. }
  125. return this;
  126. };
  127. /**
  128. * Removes all listeners for an event.
  129. *
  130. * @api public
  131. */
  132. EventEmitter.prototype.removeAllListeners = function (name) {
  133. if (name === undefined) {
  134. this.$events = {};
  135. return this;
  136. }
  137. if (this.$events && this.$events[name]) {
  138. this.$events[name] = null;
  139. }
  140. return this;
  141. };
  142. /**
  143. * Gets all listeners for a certain event.
  144. *
  145. * @api public
  146. */
  147. EventEmitter.prototype.listeners = function (name) {
  148. if (!this.$events) {
  149. this.$events = {};
  150. }
  151. if (!this.$events[name]) {
  152. this.$events[name] = [];
  153. }
  154. if (!isArray(this.$events[name])) {
  155. this.$events[name] = [this.$events[name]];
  156. }
  157. return this.$events[name];
  158. };
  159. /**
  160. * Emits an event.
  161. *
  162. * @api public
  163. */
  164. EventEmitter.prototype.emit = function (name) {
  165. if (!this.$events) {
  166. return false;
  167. }
  168. var handler = this.$events[name];
  169. if (!handler) {
  170. return false;
  171. }
  172. var args = [].slice.call(arguments, 1);
  173. if ('function' == typeof handler) {
  174. handler.apply(this, args);
  175. } else if (isArray(handler)) {
  176. var listeners = handler.slice();
  177. for (var i = 0, l = listeners.length; i < l; i++) {
  178. listeners[i].apply(this, args);
  179. }
  180. } else {
  181. return false;
  182. }
  183. return true;
  184. };
  185. }); // module: browser/events.js
  186. require.register("browser/fs.js", function(module, exports, require){
  187. }); // module: browser/fs.js
  188. require.register("browser/path.js", function(module, exports, require){
  189. }); // module: browser/path.js
  190. require.register("browser/progress.js", function(module, exports, require){
  191. /**
  192. * Expose `Progress`.
  193. */
  194. module.exports = Progress;
  195. /**
  196. * Initialize a new `Progress` indicator.
  197. */
  198. function Progress() {
  199. this.percent = 0;
  200. this.size(0);
  201. this.fontSize(11);
  202. this.font('helvetica, arial, sans-serif');
  203. }
  204. /**
  205. * Set progress size to `n`.
  206. *
  207. * @param {Number} n
  208. * @return {Progress} for chaining
  209. * @api public
  210. */
  211. Progress.prototype.size = function(n){
  212. this._size = n;
  213. return this;
  214. };
  215. /**
  216. * Set text to `str`.
  217. *
  218. * @param {String} str
  219. * @return {Progress} for chaining
  220. * @api public
  221. */
  222. Progress.prototype.text = function(str){
  223. this._text = str;
  224. return this;
  225. };
  226. /**
  227. * Set font size to `n`.
  228. *
  229. * @param {Number} n
  230. * @return {Progress} for chaining
  231. * @api public
  232. */
  233. Progress.prototype.fontSize = function(n){
  234. this._fontSize = n;
  235. return this;
  236. };
  237. /**
  238. * Set font `family`.
  239. *
  240. * @param {String} family
  241. * @return {Progress} for chaining
  242. */
  243. Progress.prototype.font = function(family){
  244. this._font = family;
  245. return this;
  246. };
  247. /**
  248. * Update percentage to `n`.
  249. *
  250. * @param {Number} n
  251. * @return {Progress} for chaining
  252. */
  253. Progress.prototype.update = function(n){
  254. this.percent = n;
  255. return this;
  256. };
  257. /**
  258. * Draw on `ctx`.
  259. *
  260. * @param {CanvasRenderingContext2d} ctx
  261. * @return {Progress} for chaining
  262. */
  263. Progress.prototype.draw = function(ctx){
  264. var percent = Math.min(this.percent, 100)
  265. , size = this._size
  266. , half = size / 2
  267. , x = half
  268. , y = half
  269. , rad = half - 1
  270. , fontSize = this._fontSize;
  271. ctx.font = fontSize + 'px ' + this._font;
  272. var angle = Math.PI * 2 * (percent / 100);
  273. ctx.clearRect(0, 0, size, size);
  274. // outer circle
  275. ctx.strokeStyle = '#9f9f9f';
  276. ctx.beginPath();
  277. ctx.arc(x, y, rad, 0, angle, false);
  278. ctx.stroke();
  279. // inner circle
  280. ctx.strokeStyle = '#eee';
  281. ctx.beginPath();
  282. ctx.arc(x, y, rad - 1, 0, angle, true);
  283. ctx.stroke();
  284. // text
  285. var text = this._text || (percent | 0) + '%'
  286. , w = ctx.measureText(text).width;
  287. ctx.fillText(
  288. text
  289. , x - w / 2 + 1
  290. , y + fontSize / 2 - 1);
  291. return this;
  292. };
  293. }); // module: browser/progress.js
  294. require.register("browser/tty.js", function(module, exports, require){
  295. exports.isatty = function(){
  296. return true;
  297. };
  298. exports.getWindowSize = function(){
  299. return [window.innerHeight, window.innerWidth];
  300. };
  301. }); // module: browser/tty.js
  302. require.register("context.js", function(module, exports, require){
  303. /**
  304. * Expose `Context`.
  305. */
  306. module.exports = Context;
  307. /**
  308. * Initialize a new `Context`.
  309. *
  310. * @api private
  311. */
  312. function Context(){}
  313. /**
  314. * Set or get the context `Runnable` to `runnable`.
  315. *
  316. * @param {Runnable} runnable
  317. * @return {Context}
  318. * @api private
  319. */
  320. Context.prototype.runnable = function(runnable){
  321. if (0 == arguments.length) return this._runnable;
  322. this.test = this._runnable = runnable;
  323. return this;
  324. };
  325. /**
  326. * Set test timeout `ms`.
  327. *
  328. * @param {Number} ms
  329. * @return {Context} self
  330. * @api private
  331. */
  332. Context.prototype.timeout = function(ms){
  333. this.runnable().timeout(ms);
  334. return this;
  335. };
  336. /**
  337. * Inspect the context void of `._runnable`.
  338. *
  339. * @return {String}
  340. * @api private
  341. */
  342. Context.prototype.inspect = function(){
  343. return JSON.stringify(this, function(key, val){
  344. if ('_runnable' == key) return;
  345. if ('test' == key) return;
  346. return val;
  347. }, 2);
  348. };
  349. }); // module: context.js
  350. require.register("hook.js", function(module, exports, require){
  351. /**
  352. * Module dependencies.
  353. */
  354. var Runnable = require('./runnable');
  355. /**
  356. * Expose `Hook`.
  357. */
  358. module.exports = Hook;
  359. /**
  360. * Initialize a new `Hook` with the given `title` and callback `fn`.
  361. *
  362. * @param {String} title
  363. * @param {Function} fn
  364. * @api private
  365. */
  366. function Hook(title, fn) {
  367. Runnable.call(this, title, fn);
  368. this.type = 'hook';
  369. }
  370. /**
  371. * Inherit from `Runnable.prototype`.
  372. */
  373. Hook.prototype = new Runnable;
  374. Hook.prototype.constructor = Hook;
  375. /**
  376. * Get or set the test `err`.
  377. *
  378. * @param {Error} err
  379. * @return {Error}
  380. * @api public
  381. */
  382. Hook.prototype.error = function(err){
  383. if (0 == arguments.length) {
  384. var err = this._error;
  385. this._error = null;
  386. return err;
  387. }
  388. this._error = err;
  389. };
  390. }); // module: hook.js
  391. require.register("interfaces/bdd.js", function(module, exports, require){
  392. /**
  393. * Module dependencies.
  394. */
  395. var Suite = require('../suite')
  396. , Test = require('../test');
  397. /**
  398. * BDD-style interface:
  399. *
  400. * describe('Array', function(){
  401. * describe('#indexOf()', function(){
  402. * it('should return -1 when not present', function(){
  403. *
  404. * });
  405. *
  406. * it('should return the index when present', function(){
  407. *
  408. * });
  409. * });
  410. * });
  411. *
  412. */
  413. module.exports = function(suite){
  414. var suites = [suite];
  415. suite.on('pre-require', function(context, file, mocha){
  416. /**
  417. * Execute before running tests.
  418. */
  419. context.before = function(fn){
  420. suites[0].beforeAll(fn);
  421. };
  422. /**
  423. * Execute after running tests.
  424. */
  425. context.after = function(fn){
  426. suites[0].afterAll(fn);
  427. };
  428. /**
  429. * Execute before each test case.
  430. */
  431. context.beforeEach = function(fn){
  432. suites[0].beforeEach(fn);
  433. };
  434. /**
  435. * Execute after each test case.
  436. */
  437. context.afterEach = function(fn){
  438. suites[0].afterEach(fn);
  439. };
  440. /**
  441. * Describe a "suite" with the given `title`
  442. * and callback `fn` containing nested suites
  443. * and/or tests.
  444. */
  445. context.describe = context.context = function(title, fn){
  446. var suite = Suite.create(suites[0], title);
  447. suites.unshift(suite);
  448. fn();
  449. suites.shift();
  450. return suite;
  451. };
  452. /**
  453. * Pending describe.
  454. */
  455. context.xdescribe =
  456. context.xcontext =
  457. context.describe.skip = function(title, fn){
  458. var suite = Suite.create(suites[0], title);
  459. suite.pending = true;
  460. suites.unshift(suite);
  461. fn();
  462. suites.shift();
  463. };
  464. /**
  465. * Exclusive suite.
  466. */
  467. context.describe.only = function(title, fn){
  468. var suite = context.describe(title, fn);
  469. mocha.grep(suite.fullTitle());
  470. };
  471. /**
  472. * Describe a specification or test-case
  473. * with the given `title` and callback `fn`
  474. * acting as a thunk.
  475. */
  476. context.it = context.specify = function(title, fn){
  477. var suite = suites[0];
  478. if (suite.pending) var fn = null;
  479. var test = new Test(title, fn);
  480. suite.addTest(test);
  481. return test;
  482. };
  483. /**
  484. * Exclusive test-case.
  485. */
  486. context.it.only = function(title, fn){
  487. var test = context.it(title, fn);
  488. mocha.grep(test.fullTitle());
  489. };
  490. /**
  491. * Pending test case.
  492. */
  493. context.xit =
  494. context.xspecify =
  495. context.it.skip = function(title){
  496. context.it(title);
  497. };
  498. });
  499. };
  500. }); // module: interfaces/bdd.js
  501. require.register("interfaces/exports.js", function(module, exports, require){
  502. /**
  503. * Module dependencies.
  504. */
  505. var Suite = require('../suite')
  506. , Test = require('../test');
  507. /**
  508. * TDD-style interface:
  509. *
  510. * exports.Array = {
  511. * '#indexOf()': {
  512. * 'should return -1 when the value is not present': function(){
  513. *
  514. * },
  515. *
  516. * 'should return the correct index when the value is present': function(){
  517. *
  518. * }
  519. * }
  520. * };
  521. *
  522. */
  523. module.exports = function(suite){
  524. var suites = [suite];
  525. suite.on('require', visit);
  526. function visit(obj) {
  527. var suite;
  528. for (var key in obj) {
  529. if ('function' == typeof obj[key]) {
  530. var fn = obj[key];
  531. switch (key) {
  532. case 'before':
  533. suites[0].beforeAll(fn);
  534. break;
  535. case 'after':
  536. suites[0].afterAll(fn);
  537. break;
  538. case 'beforeEach':
  539. suites[0].beforeEach(fn);
  540. break;
  541. case 'afterEach':
  542. suites[0].afterEach(fn);
  543. break;
  544. default:
  545. suites[0].addTest(new Test(key, fn));
  546. }
  547. } else {
  548. var suite = Suite.create(suites[0], key);
  549. suites.unshift(suite);
  550. visit(obj[key]);
  551. suites.shift();
  552. }
  553. }
  554. }
  555. };
  556. }); // module: interfaces/exports.js
  557. require.register("interfaces/index.js", function(module, exports, require){
  558. exports.bdd = require('./bdd');
  559. exports.tdd = require('./tdd');
  560. exports.qunit = require('./qunit');
  561. exports.exports = require('./exports');
  562. }); // module: interfaces/index.js
  563. require.register("interfaces/qunit.js", function(module, exports, require){
  564. /**
  565. * Module dependencies.
  566. */
  567. var Suite = require('../suite')
  568. , Test = require('../test');
  569. /**
  570. * QUnit-style interface:
  571. *
  572. * suite('Array');
  573. *
  574. * test('#length', function(){
  575. * var arr = [1,2,3];
  576. * ok(arr.length == 3);
  577. * });
  578. *
  579. * test('#indexOf()', function(){
  580. * var arr = [1,2,3];
  581. * ok(arr.indexOf(1) == 0);
  582. * ok(arr.indexOf(2) == 1);
  583. * ok(arr.indexOf(3) == 2);
  584. * });
  585. *
  586. * suite('String');
  587. *
  588. * test('#length', function(){
  589. * ok('foo'.length == 3);
  590. * });
  591. *
  592. */
  593. module.exports = function(suite){
  594. var suites = [suite];
  595. suite.on('pre-require', function(context){
  596. /**
  597. * Execute before running tests.
  598. */
  599. context.before = function(fn){
  600. suites[0].beforeAll(fn);
  601. };
  602. /**
  603. * Execute after running tests.
  604. */
  605. context.after = function(fn){
  606. suites[0].afterAll(fn);
  607. };
  608. /**
  609. * Execute before each test case.
  610. */
  611. context.beforeEach = function(fn){
  612. suites[0].beforeEach(fn);
  613. };
  614. /**
  615. * Execute after each test case.
  616. */
  617. context.afterEach = function(fn){
  618. suites[0].afterEach(fn);
  619. };
  620. /**
  621. * Describe a "suite" with the given `title`.
  622. */
  623. context.suite = function(title){
  624. if (suites.length > 1) suites.shift();
  625. var suite = Suite.create(suites[0], title);
  626. suites.unshift(suite);
  627. };
  628. /**
  629. * Describe a specification or test-case
  630. * with the given `title` and callback `fn`
  631. * acting as a thunk.
  632. */
  633. context.test = function(title, fn){
  634. suites[0].addTest(new Test(title, fn));
  635. };
  636. });
  637. };
  638. }); // module: interfaces/qunit.js
  639. require.register("interfaces/tdd.js", function(module, exports, require){
  640. /**
  641. * Module dependencies.
  642. */
  643. var Suite = require('../suite')
  644. , Test = require('../test');
  645. /**
  646. * TDD-style interface:
  647. *
  648. * suite('Array', function(){
  649. * suite('#indexOf()', function(){
  650. * suiteSetup(function(){
  651. *
  652. * });
  653. *
  654. * test('should return -1 when not present', function(){
  655. *
  656. * });
  657. *
  658. * test('should return the index when present', function(){
  659. *
  660. * });
  661. *
  662. * suiteTeardown(function(){
  663. *
  664. * });
  665. * });
  666. * });
  667. *
  668. */
  669. module.exports = function(suite){
  670. var suites = [suite];
  671. suite.on('pre-require', function(context, file, mocha){
  672. /**
  673. * Execute before each test case.
  674. */
  675. context.setup = function(fn){
  676. suites[0].beforeEach(fn);
  677. };
  678. /**
  679. * Execute after each test case.
  680. */
  681. context.teardown = function(fn){
  682. suites[0].afterEach(fn);
  683. };
  684. /**
  685. * Execute before the suite.
  686. */
  687. context.suiteSetup = function(fn){
  688. suites[0].beforeAll(fn);
  689. };
  690. /**
  691. * Execute after the suite.
  692. */
  693. context.suiteTeardown = function(fn){
  694. suites[0].afterAll(fn);
  695. };
  696. /**
  697. * Describe a "suite" with the given `title`
  698. * and callback `fn` containing nested suites
  699. * and/or tests.
  700. */
  701. context.suite = function(title, fn){
  702. var suite = Suite.create(suites[0], title);
  703. suites.unshift(suite);
  704. fn();
  705. suites.shift();
  706. return suite;
  707. };
  708. /**
  709. * Exclusive test-case.
  710. */
  711. context.suite.only = function(title, fn){
  712. var suite = context.suite(title, fn);
  713. mocha.grep(suite.fullTitle());
  714. };
  715. /**
  716. * Describe a specification or test-case
  717. * with the given `title` and callback `fn`
  718. * acting as a thunk.
  719. */
  720. context.test = function(title, fn){
  721. var test = new Test(title, fn);
  722. suites[0].addTest(test);
  723. return test;
  724. };
  725. /**
  726. * Exclusive test-case.
  727. */
  728. context.test.only = function(title, fn){
  729. var test = context.test(title, fn);
  730. mocha.grep(test.fullTitle());
  731. };
  732. });
  733. };
  734. }); // module: interfaces/tdd.js
  735. require.register("mocha.js", function(module, exports, require){
  736. /*!
  737. * mocha
  738. * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>
  739. * MIT Licensed
  740. */
  741. /**
  742. * Module dependencies.
  743. */
  744. var path = require('browser/path')
  745. , utils = require('./utils');
  746. /**
  747. * Expose `Mocha`.
  748. */
  749. exports = module.exports = Mocha;
  750. /**
  751. * Expose internals.
  752. */
  753. exports.utils = utils;
  754. exports.interfaces = require('./interfaces');
  755. exports.reporters = require('./reporters');
  756. exports.Runnable = require('./runnable');
  757. exports.Context = require('./context');
  758. exports.Runner = require('./runner');
  759. exports.Suite = require('./suite');
  760. exports.Hook = require('./hook');
  761. exports.Test = require('./test');
  762. /**
  763. * Return image `name` path.
  764. *
  765. * @param {String} name
  766. * @return {String}
  767. * @api private
  768. */
  769. function image(name) {
  770. return __dirname + '/../images/' + name + '.png';
  771. }
  772. /**
  773. * Setup mocha with `options`.
  774. *
  775. * Options:
  776. *
  777. * - `ui` name "bdd", "tdd", "exports" etc
  778. * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
  779. * - `globals` array of accepted globals
  780. * - `timeout` timeout in milliseconds
  781. * - `ignoreLeaks` ignore global leaks
  782. * - `grep` string or regexp to filter tests with
  783. *
  784. * @param {Object} options
  785. * @api public
  786. */
  787. function Mocha(options) {
  788. options = options || {};
  789. this.files = [];
  790. this.options = options;
  791. this.grep(options.grep);
  792. this.suite = new exports.Suite('', new exports.Context);
  793. this.ui(options.ui);
  794. this.reporter(options.reporter);
  795. if (options.timeout) this.timeout(options.timeout);
  796. }
  797. /**
  798. * Add test `file`.
  799. *
  800. * @param {String} file
  801. * @api public
  802. */
  803. Mocha.prototype.addFile = function(file){
  804. this.files.push(file);
  805. return this;
  806. };
  807. /**
  808. * Set reporter to `reporter`, defaults to "dot".
  809. *
  810. * @param {String|Function} reporter name of a reporter or a reporter constructor
  811. * @api public
  812. */
  813. Mocha.prototype.reporter = function(reporter){
  814. if ('function' == typeof reporter) {
  815. this._reporter = reporter;
  816. } else {
  817. reporter = reporter || 'dot';
  818. try {
  819. this._reporter = require('./reporters/' + reporter);
  820. } catch (err) {
  821. this._reporter = require(reporter);
  822. }
  823. if (!this._reporter) throw new Error('invalid reporter "' + reporter + '"');
  824. }
  825. return this;
  826. };
  827. /**
  828. * Set test UI `name`, defaults to "bdd".
  829. *
  830. * @param {String} bdd
  831. * @api public
  832. */
  833. Mocha.prototype.ui = function(name){
  834. name = name || 'bdd';
  835. this._ui = exports.interfaces[name];
  836. if (!this._ui) throw new Error('invalid interface "' + name + '"');
  837. this._ui = this._ui(this.suite);
  838. return this;
  839. };
  840. /**
  841. * Load registered files.
  842. *
  843. * @api private
  844. */
  845. Mocha.prototype.loadFiles = function(fn){
  846. var self = this;
  847. var suite = this.suite;
  848. var pending = this.files.length;
  849. this.files.forEach(function(file){
  850. file = path.resolve(file);
  851. suite.emit('pre-require', global, file, self);
  852. suite.emit('require', require(file), file, self);
  853. suite.emit('post-require', global, file, self);
  854. --pending || (fn && fn());
  855. });
  856. };
  857. /**
  858. * Enable growl support.
  859. *
  860. * @api private
  861. */
  862. Mocha.prototype._growl = function(runner, reporter) {
  863. var notify = require('growl');
  864. runner.on('end', function(){
  865. var stats = reporter.stats;
  866. if (stats.failures) {
  867. var msg = stats.failures + ' of ' + runner.total + ' tests failed';
  868. notify(msg, { name: 'mocha', title: 'Failed', image: image('error') });
  869. } else {
  870. notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
  871. name: 'mocha'
  872. , title: 'Passed'
  873. , image: image('ok')
  874. });
  875. }
  876. });
  877. };
  878. /**
  879. * Add regexp to grep, if `re` is a string it is escaped.
  880. *
  881. * @param {RegExp|String} re
  882. * @return {Mocha}
  883. * @api public
  884. */
  885. Mocha.prototype.grep = function(re){
  886. this.options.grep = 'string' == typeof re
  887. ? new RegExp(utils.escapeRegexp(re))
  888. : re;
  889. return this;
  890. };
  891. /**
  892. * Invert `.grep()` matches.
  893. *
  894. * @return {Mocha}
  895. * @api public
  896. */
  897. Mocha.prototype.invert = function(){
  898. this.options.invert = true;
  899. return this;
  900. };
  901. /**
  902. * Ignore global leaks.
  903. *
  904. * @return {Mocha}
  905. * @api public
  906. */
  907. Mocha.prototype.ignoreLeaks = function(){
  908. this.options.ignoreLeaks = true;
  909. return this;
  910. };
  911. /**
  912. * Enable growl support.
  913. *
  914. * @return {Mocha}
  915. * @api public
  916. */
  917. Mocha.prototype.growl = function(){
  918. this.options.growl = true;
  919. return this;
  920. };
  921. /**
  922. * Ignore `globals` array or string.
  923. *
  924. * @param {Array|String} globals
  925. * @return {Mocha}
  926. * @api public
  927. */
  928. Mocha.prototype.globals = function(globals){
  929. this.options.globals = (this.options.globals || []).concat(globals);
  930. return this;
  931. };
  932. /**
  933. * Set the timeout in milliseconds.
  934. *
  935. * @param {Number} timeout
  936. * @return {Mocha}
  937. * @api public
  938. */
  939. Mocha.prototype.timeout = function(timeout){
  940. this.suite.timeout(timeout);
  941. return this;
  942. };
  943. /**
  944. * Run tests and invoke `fn()` when complete.
  945. *
  946. * @param {Function} fn
  947. * @return {Runner}
  948. * @api public
  949. */
  950. Mocha.prototype.run = function(fn){
  951. this.loadFiles();
  952. var suite = this.suite;
  953. var options = this.options;
  954. var runner = new exports.Runner(suite);
  955. var reporter = new this._reporter(runner);
  956. runner.ignoreLeaks = options.ignoreLeaks;
  957. if (options.grep) runner.grep(options.grep, options.invert);
  958. if (options.globals) runner.globals(options.globals);
  959. if (options.growl) this._growl(runner, reporter);
  960. return runner.run(fn);
  961. };
  962. }); // module: mocha.js
  963. require.register("reporters/base.js", function(module, exports, require){
  964. /**
  965. * Module dependencies.
  966. */
  967. var tty = require('browser/tty')
  968. , diff = require('browser/diff');
  969. /**
  970. * Save timer references to avoid Sinon interfering (see GH-237).
  971. */
  972. var Date = global.Date
  973. , setTimeout = global.setTimeout
  974. , setInterval = global.setInterval
  975. , clearTimeout = global.clearTimeout
  976. , clearInterval = global.clearInterval;
  977. /**
  978. * Check if both stdio streams are associated with a tty.
  979. */
  980. var isatty = tty.isatty(1) && tty.isatty(2);
  981. /**
  982. * Expose `Base`.
  983. */
  984. exports = module.exports = Base;
  985. /**
  986. * Enable coloring by default.
  987. */
  988. exports.useColors = isatty;
  989. /**
  990. * Default color map.
  991. */
  992. exports.colors = {
  993. 'pass': 90
  994. , 'fail': 31
  995. , 'bright pass': 92
  996. , 'bright fail': 91
  997. , 'bright yellow': 93
  998. , 'pending': 36
  999. , 'suite': 0
  1000. , 'error title': 0
  1001. , 'error message': 31
  1002. , 'error stack': 90
  1003. , 'checkmark': 32
  1004. , 'fast': 90
  1005. , 'medium': 33
  1006. , 'slow': 31
  1007. , 'green': 32
  1008. , 'light': 90
  1009. , 'diff gutter': 90
  1010. , 'diff added': 42
  1011. , 'diff removed': 41
  1012. };
  1013. /**
  1014. * Color `str` with the given `type`,
  1015. * allowing colors to be disabled,
  1016. * as well as user-defined color
  1017. * schemes.
  1018. *
  1019. * @param {String} type
  1020. * @param {String} str
  1021. * @return {String}
  1022. * @api private
  1023. */
  1024. var color = exports.color = function(type, str) {
  1025. if (!exports.useColors) return str;
  1026. return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m';
  1027. };
  1028. /**
  1029. * Expose term window size, with some
  1030. * defaults for when stderr is not a tty.
  1031. */
  1032. exports.window = {
  1033. width: isatty
  1034. ? process.stdout.getWindowSize
  1035. ? process.stdout.getWindowSize(1)[0]
  1036. : tty.getWindowSize()[1]
  1037. : 75
  1038. };
  1039. /**
  1040. * Expose some basic cursor interactions
  1041. * that are common among reporters.
  1042. */
  1043. exports.cursor = {
  1044. hide: function(){
  1045. process.stdout.write('\u001b[?25l');
  1046. },
  1047. show: function(){
  1048. process.stdout.write('\u001b[?25h');
  1049. },
  1050. deleteLine: function(){
  1051. process.stdout.write('\u001b[2K');
  1052. },
  1053. beginningOfLine: function(){
  1054. process.stdout.write('\u001b[0G');
  1055. },
  1056. CR: function(){
  1057. exports.cursor.deleteLine();
  1058. exports.cursor.beginningOfLine();
  1059. }
  1060. };
  1061. /**
  1062. * A test is considered slow if it
  1063. * exceeds the following value in milliseconds.
  1064. */
  1065. exports.slow = 75;
  1066. /**
  1067. * Outut the given `failures` as a list.
  1068. *
  1069. * @param {Array} failures
  1070. * @api public
  1071. */
  1072. exports.list = function(failures){
  1073. console.error();
  1074. failures.forEach(function(test, i){
  1075. // format
  1076. var fmt = color('error title', ' %s) %s:\n')
  1077. + color('error message', ' %s')
  1078. + color('error stack', '\n%s\n');
  1079. // msg
  1080. var err = test.err
  1081. , message = err.message || ''
  1082. , stack = err.stack || message
  1083. , index = stack.indexOf(message) + message.length
  1084. , msg = stack.slice(0, index)
  1085. , actual = err.actual
  1086. , expected = err.expected;
  1087. // actual / expected diff
  1088. if ('string' == typeof actual && 'string' == typeof expected) {
  1089. var len = Math.max(actual.length, expected.length);
  1090. if (len < 20) msg = errorDiff(err, 'Chars');
  1091. else msg = errorDiff(err, 'Words');
  1092. // linenos
  1093. var lines = msg.split('\n');
  1094. if (lines.length > 4) {
  1095. var width = String(lines.length).length;
  1096. msg = lines.map(function(str, i){
  1097. return pad(++i, width) + ' |' + ' ' + str;
  1098. }).join('\n');
  1099. }
  1100. // legend
  1101. msg = '\n'
  1102. + color('diff removed', 'actual')
  1103. + ' '
  1104. + color('diff added', 'expected')
  1105. + '\n\n'
  1106. + msg
  1107. + '\n';
  1108. // indent
  1109. msg = msg.replace(/^/gm, ' ');
  1110. fmt = color('error title', ' %s) %s:\n%s')
  1111. + color('error stack', '\n%s\n');
  1112. }
  1113. // indent stack trace without msg
  1114. stack = stack.slice(index ? index + 1 : index)
  1115. .replace(/^/gm, ' ');
  1116. console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
  1117. });
  1118. };
  1119. /**
  1120. * Initialize a new `Base` reporter.
  1121. *
  1122. * All other reporters generally
  1123. * inherit from this reporter, providing
  1124. * stats such as test duration, number
  1125. * of tests passed / failed etc.
  1126. *
  1127. * @param {Runner} runner
  1128. * @api public
  1129. */
  1130. function Base(runner) {
  1131. var self = this
  1132. , stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }
  1133. , failures = this.failures = [];
  1134. if (!runner) return;
  1135. this.runner = runner;
  1136. runner.on('start', function(){
  1137. stats.start = new Date;
  1138. });
  1139. runner.on('suite', function(suite){
  1140. stats.suites = stats.suites || 0;
  1141. suite.root || stats.suites++;
  1142. });
  1143. runner.on('test end', function(test){
  1144. stats.tests = stats.tests || 0;
  1145. stats.tests++;
  1146. });
  1147. runner.on('pass', function(test){
  1148. stats.passes = stats.passes || 0;
  1149. var medium = exports.slow / 2;
  1150. test.speed = test.duration > exports.slow
  1151. ? 'slow'
  1152. : test.duration > medium
  1153. ? 'medium'
  1154. : 'fast';
  1155. stats.passes++;
  1156. });
  1157. runner.on('fail', function(test, err){
  1158. stats.failures = stats.failures || 0;
  1159. stats.failures++;
  1160. test.err = err;
  1161. failures.push(test);
  1162. });
  1163. runner.on('end', function(){
  1164. stats.end = new Date;
  1165. stats.duration = new Date - stats.start;
  1166. });
  1167. runner.on('pending', function(){
  1168. stats.pending++;
  1169. });
  1170. }
  1171. /**
  1172. * Output common epilogue used by many of
  1173. * the bundled reporters.
  1174. *
  1175. * @api public
  1176. */
  1177. Base.prototype.epilogue = function(){
  1178. var stats = this.stats
  1179. , fmt
  1180. , tests;
  1181. console.log();
  1182. function pluralize(n) {
  1183. return 1 == n ? 'test' : 'tests';
  1184. }
  1185. // failure
  1186. if (stats.failures) {
  1187. fmt = color('bright fail', ' ✖')
  1188. + color('fail', ' %d of %d %s failed')
  1189. + color('light', ':')
  1190. console.error(fmt,
  1191. stats.failures,
  1192. this.runner.total,
  1193. pluralize(this.runner.total));
  1194. Base.list(this.failures);
  1195. console.error();
  1196. return;
  1197. }
  1198. // pass
  1199. fmt = color('bright pass', ' ✔')
  1200. + color('green', ' %d %s complete')
  1201. + color('light', ' (%dms)');
  1202. console.log(fmt,
  1203. stats.tests || 0,
  1204. pluralize(stats.tests),
  1205. stats.duration);
  1206. // pending
  1207. if (stats.pending) {
  1208. fmt = color('pending', ' •')
  1209. + color('pending', ' %d %s pending');
  1210. console.log(fmt, stats.pending, pluralize(stats.pending));
  1211. }
  1212. console.log();
  1213. };
  1214. /**
  1215. * Pad the given `str` to `len`.
  1216. *
  1217. * @param {String} str
  1218. * @param {String} len
  1219. * @return {String}
  1220. * @api private
  1221. */
  1222. function pad(str, len) {
  1223. str = String(str);
  1224. return Array(len - str.length + 1).join(' ') + str;
  1225. }
  1226. /**
  1227. * Return a character diff for `err`.
  1228. *
  1229. * @param {Error} err
  1230. * @return {String}
  1231. * @api private
  1232. */
  1233. function errorDiff(err, type) {
  1234. return diff['diff' + type](err.actual, err.expected).map(function(str){
  1235. if (/^(\n+)$/.test(str.value)) str.value = Array(++RegExp.$1.length).join('<newline>');
  1236. if (str.added) return colorLines('diff added', str.value);
  1237. if (str.removed) return colorLines('diff removed', str.value);
  1238. return str.value;
  1239. }).join('');
  1240. }
  1241. /**
  1242. * Color lines for `str`, using the color `name`.
  1243. *
  1244. * @param {String} name
  1245. * @param {String} str
  1246. * @return {String}
  1247. * @api private
  1248. */
  1249. function colorLines(name, str) {
  1250. return str.split('\n').map(function(str){
  1251. return color(name, str);
  1252. }).join('\n');
  1253. }
  1254. }); // module: reporters/base.js
  1255. require.register("reporters/doc.js", function(module, exports, require){
  1256. /**
  1257. * Module dependencies.
  1258. */
  1259. var Base = require('./base')
  1260. , utils = require('../utils');
  1261. /**
  1262. * Expose `Doc`.
  1263. */
  1264. exports = module.exports = Doc;
  1265. /**
  1266. * Initialize a new `Doc` reporter.
  1267. *
  1268. * @param {Runner} runner
  1269. * @api public
  1270. */
  1271. function Doc(runner) {
  1272. Base.call(this, runner);
  1273. var self = this
  1274. , stats = this.stats
  1275. , total = runner.total
  1276. , indents = 2;
  1277. function indent() {
  1278. return Array(indents).join(' ');
  1279. }
  1280. runner.on('suite', function(suite){
  1281. if (suite.root) return;
  1282. ++indents;
  1283. console.log('%s<section class="suite">', indent());
  1284. ++indents;
  1285. console.log('%s<h1>%s</h1>', indent(), suite.title);
  1286. console.log('%s<dl>', indent());
  1287. });
  1288. runner.on('suite end', function(suite){
  1289. if (suite.root) return;
  1290. console.log('%s</dl>', indent());
  1291. --indents;
  1292. console.log('%s</section>', indent());
  1293. --indents;
  1294. });
  1295. runner.on('pass', function(test){
  1296. console.log('%s <dt>%s</dt>', indent(), test.title);
  1297. var code = utils.escape(utils.clean(test.fn.toString()));
  1298. console.log('%s <dd><pre><code>%s</code></pre></dd>', indent(), code);
  1299. });
  1300. }
  1301. }); // module: reporters/doc.js
  1302. require.register("reporters/dot.js", function(module, exports, require){
  1303. /**
  1304. * Module dependencies.
  1305. */
  1306. var Base = require('./base')
  1307. , color = Base.color;
  1308. /**
  1309. * Expose `Dot`.
  1310. */
  1311. exports = module.exports = Dot;
  1312. /**
  1313. * Initialize a new `Dot` matrix test reporter.
  1314. *
  1315. * @param {Runner} runner
  1316. * @api public
  1317. */
  1318. function Dot(runner) {
  1319. Base.call(this, runner);
  1320. var self = this
  1321. , stats = this.stats
  1322. , width = Base.window.width * .75 | 0
  1323. , c = '․'
  1324. , n = 0;
  1325. runner.on('start', function(){
  1326. process.stdout.write('\n ');
  1327. });
  1328. runner.on('pending', function(test){
  1329. process.stdout.write(color('pending', c));
  1330. });
  1331. runner.on('pass', function(test){
  1332. if (++n % width == 0) process.stdout.write('\n ');
  1333. if ('slow' == test.speed) {
  1334. process.stdout.write(color('bright yellow', c));
  1335. } else {
  1336. process.stdout.write(color(test.speed, c));
  1337. }
  1338. });
  1339. runner.on('fail', function(test, err){
  1340. if (++n % width == 0) process.stdout.write('\n ');
  1341. process.stdout.write(color('fail', c));
  1342. });
  1343. runner.on('end', function(){
  1344. console.log();
  1345. self.epilogue();
  1346. });
  1347. }
  1348. /**
  1349. * Inherit from `Base.prototype`.
  1350. */
  1351. Dot.prototype = new Base;
  1352. Dot.prototype.constructor = Dot;
  1353. }); // module: reporters/dot.js
  1354. require.register("reporters/html-cov.js", function(module, exports, require){
  1355. /**
  1356. * Module dependencies.
  1357. */
  1358. var JSONCov = require('./json-cov')
  1359. , fs = require('browser/fs');
  1360. /**
  1361. * Expose `HTMLCov`.
  1362. */
  1363. exports = module.exports = HTMLCov;
  1364. /**
  1365. * Initialize a new `JsCoverage` reporter.
  1366. *
  1367. * @param {Runner} runner
  1368. * @api public
  1369. */
  1370. function HTMLCov(runner) {
  1371. var jade = require('jade')
  1372. , file = __dirname + '/templates/coverage.jade'
  1373. , str = fs.readFileSync(file, 'utf8')
  1374. , fn = jade.compile(str, { filename: file })
  1375. , self = this;
  1376. JSONCov.call(this, runner, false);
  1377. runner.on('end', function(){
  1378. process.stdout.write(fn({
  1379. cov: self.cov
  1380. , coverageClass: coverageClass
  1381. }));
  1382. });
  1383. }
  1384. /**
  1385. * Return coverage class for `n`.
  1386. *
  1387. * @return {String}
  1388. * @api private
  1389. */
  1390. function coverageClass(n) {
  1391. if (n >= 75) return 'high';
  1392. if (n >= 50) return 'medium';
  1393. if (n >= 25) return 'low';
  1394. return 'terrible';
  1395. }
  1396. }); // module: reporters/html-cov.js
  1397. require.register("reporters/html.js", function(module, exports, require){
  1398. /**
  1399. * Module dependencies.
  1400. */
  1401. var Base = require('./base')
  1402. , utils = require('../utils')
  1403. , Progress = require('../browser/progress')
  1404. , escape = utils.escape;
  1405. /**
  1406. * Save timer references to avoid Sinon interfering (see GH-237).
  1407. */
  1408. var Date = global.Date
  1409. , setTimeout = global.setTimeout
  1410. , setInterval = global.setInterval
  1411. , clearTimeout = global.clearTimeout
  1412. , clearInterval = global.clearInterval;
  1413. /**
  1414. * Expose `Doc`.
  1415. */
  1416. exports = module.exports = HTML;
  1417. /**
  1418. * Stats template.
  1419. */
  1420. var statsTemplate = '<ul id="stats">'
  1421. + '<li class="progress"><canvas width="40" height="40"></canvas></li>'
  1422. + '<li class="passes"><a href="#">passes:</a> <em>0</em></li>'
  1423. + '<li class="failures"><a href="#">failures:</a> <em>0</em></li>'
  1424. + '<li class="duration">duration: <em>0</em>s</li>'
  1425. + '</ul>';
  1426. /**
  1427. * Initialize a new `Doc` reporter.
  1428. *
  1429. * @param {Runner} runner
  1430. * @api public
  1431. */
  1432. function HTML(runner, root) {
  1433. Base.call(this, runner);
  1434. var self = this
  1435. , stats = this.stats
  1436. , total = runner.total
  1437. , stat = fragment(statsTemplate)
  1438. , items = stat.getElementsByTagName('li')
  1439. , passes = items[1].getElementsByTagName('em')[0]
  1440. , passesLink = items[1].getElementsByTagName('a')[0]
  1441. , failures = items[2].getElementsByTagName('em')[0]
  1442. , failuresLink = items[2].getElementsByTagName('a')[0]
  1443. , duration = items[3].getElementsByTagName('em')[0]
  1444. , canvas = stat.getElementsByTagName('canvas')[0]
  1445. , report = fragment('<ul id="report"></ul>')
  1446. , stack = [report]
  1447. , progress
  1448. , ctx
  1449. root = root || document.getElementById('mocha');
  1450. if (canvas.getContext) {
  1451. var ratio = window.devicePixelRatio || 1;
  1452. canvas.style.width = canvas.width;
  1453. canvas.style.height = canvas.height;
  1454. canvas.width *= ratio;
  1455. canvas.height *= ratio;
  1456. ctx = canvas.getContext('2d');
  1457. ctx.scale(ratio, ratio);
  1458. progress = new Progress;
  1459. }
  1460. if (!root) return error('#mocha div missing, add it to your document');
  1461. // pass toggle
  1462. on(passesLink, 'click', function () {
  1463. var className = /pass/.test(report.className) ? '' : ' pass';
  1464. report.className = report.className.replace(/fail|pass/g, '') + className;
  1465. });
  1466. // failure toggle
  1467. on(failuresLink, 'click', function () {
  1468. var className = /fail/.test(report.className) ? '' : ' fail';
  1469. report.className = report.className.replace(/fail|pass/g, '') + className;
  1470. });
  1471. root.appendChild(stat);
  1472. root.appendChild(report);
  1473. if (progress) progress.size(40);
  1474. runner.on('suite', function(suite){
  1475. if (suite.root) return;
  1476. // suite
  1477. var url = '?grep=' + encodeURIComponent(suite.fullTitle());
  1478. var el = fragment('<li class="suite"><h1><a href="%s">%s</a></h1></li>', url, escape(suite.title));
  1479. // container
  1480. stack[0].appendChild(el);
  1481. stack.unshift(document.createElement('ul'));
  1482. el.appendChild(stack[0]);
  1483. });
  1484. runner.on('suite end', function(suite){
  1485. if (suite.root) return;
  1486. stack.shift();
  1487. });
  1488. runner.on('fail', function(test, err){
  1489. if ('hook' == test.type || err.uncaught) runner.emit('test end', test);
  1490. });
  1491. runner.on('test end', function(test){
  1492. window.scrollTo(0, document.body.scrollHeight);
  1493. // TODO: add to stats
  1494. var percent = stats.tests / total * 100 | 0;
  1495. if (progress) progress.update(percent).draw(ctx);
  1496. // update stats
  1497. var ms = new Date - stats.start;
  1498. text(passes, stats.passes);
  1499. text(failures, stats.failures);
  1500. text(duration, (ms / 1000).toFixed(2));
  1501. // test
  1502. if ('passed' == test.state) {
  1503. var el = fragment('<li class="test pass %e"><h2>%e<span class="duration">%ems</span></h2></li>', test.speed, test.title, test.duration);
  1504. } else if (test.pending) {
  1505. var el = fragment('<li class="test pass pending"><h2>%e</h2></li>', test.title);
  1506. } else {
  1507. var el = fragment('<li class="test fail"><h2>%e</h2></li>', test.title);
  1508. var str = test.err.stack || test.err.toString();
  1509. // FF / Opera do not add the message
  1510. if (!~str.indexOf(test.err.message)) {
  1511. str = test.err.message + '\n' + str;
  1512. }
  1513. // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
  1514. // check for the result of the stringifying.
  1515. if ('[object Error]' == str) str = test.err.message;
  1516. // Safari doesn't give you a stack. Let's at least provide a source line.
  1517. if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
  1518. str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
  1519. }
  1520. el.appendChild(fragment('<pre class="error">%e</pre>', str));
  1521. }
  1522. // toggle code
  1523. // TODO: defer
  1524. if (!test.pending) {
  1525. var h2 = el.getElementsByTagName('h2')[0];
  1526. on(h2, 'click', function(){
  1527. pre.style.display = 'none' == pre.style.display
  1528. ? 'inline-block'
  1529. : 'none';
  1530. });
  1531. var pre = fragment('<pre><code>%e</code></pre>', utils.clean(test.fn.toString()));
  1532. el.appendChild(pre);
  1533. pre.style.display = 'none';
  1534. }
  1535. stack[0].appendChild(el);
  1536. });
  1537. }
  1538. /**
  1539. * Display error `msg`.
  1540. */
  1541. function error(msg) {
  1542. document.body.appendChild(fragment('<div id="error">%s</div>', msg));
  1543. }
  1544. /**
  1545. * Return a DOM fragment from `html`.
  1546. */
  1547. function fragment(html) {
  1548. var args = arguments
  1549. , div = document.createElement('div')
  1550. , i = 1;
  1551. div.innerHTML = html.replace(/%([se])/g, function(_, type){
  1552. switch (type) {
  1553. case 's': return String(args[i++]);
  1554. case 'e': return escape(args[i++]);
  1555. }
  1556. });
  1557. return div.firstChild;
  1558. }
  1559. /**
  1560. * Set `el` text to `str`.
  1561. */
  1562. function text(el, str) {
  1563. if (el.textContent) {
  1564. el.textContent = str;
  1565. } else {
  1566. el.innerText = str;
  1567. }
  1568. }
  1569. /**
  1570. * Listen on `event` with callback `fn`.
  1571. */
  1572. function on(el, event, fn) {
  1573. if (el.addEventListener) {
  1574. el.addEventListener(event, fn, false);
  1575. } else {
  1576. el.attachEvent('on' + event, fn);
  1577. }
  1578. }
  1579. }); // module: reporters/html.js
  1580. require.register("reporters/index.js", function(module, exports, require){
  1581. exports.Base = require('./base');
  1582. exports.Dot = require('./dot');
  1583. exports.Doc = require('./doc');
  1584. exports.TAP = require('./tap');
  1585. exports.JSON = require('./json');
  1586. exports.HTML = require('./html');
  1587. exports.List = require('./list');
  1588. exports.Min = require('./min');
  1589. exports.Spec = require('./spec');
  1590. exports.Nyan = require('./nyan');
  1591. exports.XUnit = require('./xunit');
  1592. exports.Markdown = require('./markdown');
  1593. exports.Progress = require('./progress');
  1594. exports.Landing = require('./landing');
  1595. exports.JSONCov = require('./json-cov');
  1596. exports.HTMLCov = require('./html-cov');
  1597. exports.JSONStream = require('./json-stream');
  1598. exports.Teamcity = require('./teamcity');
  1599. }); // module: reporters/index.js
  1600. require.register("reporters/json-cov.js", function(module, exports, require){
  1601. /**
  1602. * Module dependencies.
  1603. */
  1604. var Base = require('./base');
  1605. /**
  1606. * Expose `JSONCov`.
  1607. */
  1608. exports = module.exports = JSONCov;
  1609. /**
  1610. * Initialize a new `JsCoverage` reporter.
  1611. *
  1612. * @param {Runner} runner
  1613. * @param {Boolean} output
  1614. * @api public
  1615. */
  1616. function JSONCov(runner, output) {
  1617. var self = this
  1618. , output = 1 == arguments.length ? true : output;
  1619. Base.call(this, runner);
  1620. var tests = []
  1621. , failures = []
  1622. , passes = [];
  1623. runner.on('test end', function(test){
  1624. tests.push(test);
  1625. });
  1626. runner.on('pass', function(test){
  1627. passes.push(test);
  1628. });
  1629. runner.on('fail', function(test){
  1630. failures.push(test);
  1631. });
  1632. runner.on('end', function(){
  1633. var cov = global._$jscoverage || {};
  1634. var result = self.cov = map(cov);
  1635. result.stats = self.stats;
  1636. result.tests = tests.map(clean);
  1637. result.failures = failures.map(clean);
  1638. result.passes = passes.map(clean);
  1639. if (!output) return;
  1640. process.stdout.write(JSON.stringify(result, null, 2 ));
  1641. });
  1642. }
  1643. /**
  1644. * Map jscoverage data to a JSON structure
  1645. * suitable for reporting.
  1646. *
  1647. * @param {Object} cov
  1648. * @return {Object}
  1649. * @api private
  1650. */
  1651. function map(cov) {
  1652. var ret = {
  1653. instrumentation: 'node-jscoverage'
  1654. , sloc: 0
  1655. , hits: 0
  1656. , misses: 0
  1657. , coverage: 0
  1658. , files: []
  1659. };
  1660. for (var filename in cov) {
  1661. var data = coverage(filename, cov[filename]);
  1662. ret.files.push(data);
  1663. ret.hits += data.hits;
  1664. ret.misses += data.misses;
  1665. ret.sloc += data.sloc;
  1666. }
  1667. if (ret.sloc > 0) {
  1668. ret.coverage = (ret.hits / ret.sloc) * 100;
  1669. }
  1670. return ret;
  1671. };
  1672. /**
  1673. * Map jscoverage data for a single source file
  1674. * to a JSON structure suitable for reporting.
  1675. *
  1676. * @param {String} filename name of the source file
  1677. * @param {Object} data jscoverage coverage data
  1678. * @return {Object}
  1679. * @api private
  1680. */
  1681. function coverage(filename, data) {
  1682. var ret = {
  1683. filename: filename,
  1684. coverage: 0,
  1685. hits: 0,
  1686. misses: 0,
  1687. sloc: 0,
  1688. source: {}
  1689. };
  1690. data.source.forEach(function(line, num){
  1691. num++;
  1692. if (data[num] === 0) {
  1693. ret.misses++;
  1694. ret.sloc++;
  1695. } else if (data[num] !== undefined) {
  1696. ret.hits++;
  1697. ret.sloc++;
  1698. }
  1699. ret.source[num] = {
  1700. source: line
  1701. , coverage: data[num] === undefined
  1702. ? ''
  1703. : data[num]
  1704. };
  1705. });
  1706. ret.coverage = ret.hits / ret.sloc * 100;
  1707. return ret;
  1708. }
  1709. /**
  1710. * Return a plain-object representation of `test`
  1711. * free of cyclic properties etc.
  1712. *
  1713. * @param {Object} test
  1714. * @return {Object}
  1715. * @api private
  1716. */
  1717. function clean(test) {
  1718. return {
  1719. title: test.title
  1720. , fullTitle: test.fullTitle()
  1721. , duration: test.duration
  1722. }
  1723. }
  1724. }); // module: reporters/json-cov.js
  1725. require.register("reporters/json-stream.js", function(module, exports, require){
  1726. /**
  1727. * Module dependencies.
  1728. */
  1729. var Base = require('./base')
  1730. , color = Base.color;
  1731. /**
  1732. * Expose `List`.
  1733. */
  1734. exports = module.exports = List;
  1735. /**
  1736. * Initialize a new `List` test reporter.
  1737. *
  1738. * @param {Runner} runner
  1739. * @api public
  1740. */
  1741. function List(runner) {
  1742. Base.call(this, runner);
  1743. var self = this
  1744. , stats = this.stats
  1745. , total = runner.total;
  1746. runner.on('start', function(){
  1747. console.log(JSON.stringify(['start', { total: total }]));
  1748. });
  1749. runner.on('pass', function(test){
  1750. console.log(JSON.stringify(['pass', clean(test)]));
  1751. });
  1752. runner.on('fail', function(test, err){
  1753. console.log(JSON.stringify(['fail', clean(test)]));
  1754. });
  1755. runner.on('end', function(){
  1756. process.stdout.write(JSON.stringify(['end', self.stats]));
  1757. });
  1758. }
  1759. /**
  1760. * Return a plain-object representation of `test`
  1761. * free of cyclic properties etc.
  1762. *
  1763. * @param {Object} test
  1764. * @return {Object}
  1765. * @api private
  1766. */
  1767. function clean(test) {
  1768. return {
  1769. title: test.title
  1770. , fullTitle: test.fullTitle()
  1771. , duration: test.duration
  1772. }
  1773. }
  1774. }); // module: reporters/json-stream.js
  1775. require.register("reporters/json.js", function(module, exports, require){
  1776. /**
  1777. * Module dependencies.
  1778. */
  1779. var Base = require('./base')
  1780. , cursor = Base.cursor
  1781. , color = Base.color;
  1782. /**
  1783. * Expose `JSON`.
  1784. */
  1785. exports = module.exports = JSONReporter;
  1786. /**
  1787. * Initialize a new `JSON` reporter.
  1788. *
  1789. * @param {Runner} runner
  1790. * @api public
  1791. */
  1792. function JSONReporter(runner) {
  1793. var self = this;
  1794. Base.call(this, runner);
  1795. var tests = []
  1796. , failures = []
  1797. , passes = [];
  1798. runner.on('test end', function(test){
  1799. tests.push(test);
  1800. });
  1801. runner.on('pass', function(test){
  1802. passes.push(test);
  1803. });
  1804. runner.on('fail', function(test){
  1805. failures.push(test);
  1806. });
  1807. runner.on('end', function(){
  1808. var obj = {
  1809. stats: self.stats
  1810. , tests: tests.map(clean)
  1811. , failures: failures.map(clean)
  1812. , passes: passes.map(clean)
  1813. };
  1814. process.stdout.write(JSON.stringify(obj, null, 2));
  1815. });
  1816. }
  1817. /**
  1818. * Return a plain-object representation of `test`
  1819. * free of cyclic properties etc.
  1820. *
  1821. * @param {Object} test
  1822. * @return {Object}
  1823. * @api private
  1824. */
  1825. function clean(test) {
  1826. return {
  1827. title: test.title
  1828. , fullTitle: test.fullTitle()
  1829. , duration: test.duration
  1830. }
  1831. }
  1832. }); // module: reporters/json.js
  1833. require.register("reporters/landing.js", function(module, exports, require){
  1834. /**
  1835. * Module dependencies.
  1836. */
  1837. var Base = require('./base')
  1838. , cursor = Base.cursor
  1839. , color = Base.color;
  1840. /**
  1841. * Expose `Landing`.
  1842. */
  1843. exports = module.exports = Landing;
  1844. /**
  1845. * Airplane color.
  1846. */
  1847. Base.colors.plane = 0;
  1848. /**
  1849. * Airplane crash color.
  1850. */
  1851. Base.colors['plane crash'] = 31;
  1852. /**
  1853. * Runway color.
  1854. */
  1855. Base.colors.runway = 90;
  1856. /**
  1857. * Initialize a new `Landing` reporter.
  1858. *
  1859. * @param {Runner} runner
  1860. * @api public
  1861. */
  1862. function Landing(runner) {
  1863. Base.call(this, runner);
  1864. var self = this
  1865. , stats = this.stats
  1866. , width = Base.window.width * .75 | 0
  1867. , total = runner.total
  1868. , stream = process.stdout
  1869. , plane = color('plane', '✈')
  1870. , crashed = -1
  1871. , n = 0;
  1872. function runway() {
  1873. var buf = Array(width).join('-');
  1874. return ' ' + color('runway', buf);
  1875. }
  1876. runner.on('start', function(){
  1877. stream.write('\n ');
  1878. cursor.hide();
  1879. });
  1880. runner.on('test end', function(test){
  1881. // check if the plane crashed
  1882. var col = -1 == crashed
  1883. ? width * ++n / total | 0
  1884. : crashed;
  1885. // show the crash
  1886. if ('failed' == test.state) {
  1887. plane = color('plane crash', '✈');
  1888. crashed = col;
  1889. }
  1890. // render landing strip
  1891. stream.write('\u001b[4F\n\n');
  1892. stream.write(runway());
  1893. stream.write('\n ');
  1894. stream.write(color('runway', Array(col).join('⋅')));
  1895. stream.write(plane)
  1896. stream.write(color('runway', Array(width - col).join('⋅') + '\n'));
  1897. stream.write(runway());
  1898. stream.write('\u001b[0m');
  1899. });
  1900. runner.on('end', function(){
  1901. cursor.show();
  1902. console.log();
  1903. self.epilogue();
  1904. });
  1905. }
  1906. /**
  1907. * Inherit from `Base.prototype`.
  1908. */
  1909. Landing.prototype = new Base;
  1910. Landing.prototype.constructor = Landing;
  1911. }); // module: reporters/landing.js
  1912. require.register("reporters/list.js", function(module, exports, require){
  1913. /**
  1914. * Module dependencies.
  1915. */
  1916. var Base = require('./base')
  1917. , cursor = Base.cursor
  1918. , color = Base.color;
  1919. /**
  1920. * Expose `List`.
  1921. */
  1922. exports = module.exports = List;
  1923. /**
  1924. * Initialize a new `List` test reporter.
  1925. *
  1926. * @param {Runner} runner
  1927. * @api public
  1928. */
  1929. function List(runner) {
  1930. Base.call(this, runner);
  1931. var self = this
  1932. , stats = this.stats
  1933. , n = 0;
  1934. runner.on('start', function(){
  1935. console.log();
  1936. });
  1937. runner.on('test', function(test){
  1938. process.stdout.write(color('pass', ' ' + test.fullTitle() + ': '));
  1939. });
  1940. runner.on('pending', function(test){
  1941. var fmt = color('checkmark', ' -')
  1942. + color('pending', ' %s');
  1943. console.log(fmt, test.fullTitle());
  1944. });
  1945. runner.on('pass', function(test){
  1946. var fmt = color('checkmark', ' ✓')
  1947. + color('pass', ' %s: ')
  1948. + color(test.speed, '%dms');
  1949. cursor.CR();
  1950. console.log(fmt, test.fullTitle(), test.duration);
  1951. });
  1952. runner.on('fail', function(test, err){
  1953. cursor.CR();
  1954. console.log(color('fail', ' %d) %s'), ++n, test.fullTitle());
  1955. });
  1956. runner.on('end', self.epilogue.bind(self));
  1957. }
  1958. /**
  1959. * Inherit from `Base.prototype`.
  1960. */
  1961. List.prototype = new Base;
  1962. List.prototype.constructor = List;
  1963. }); // module: reporters/list.js
  1964. require.register("reporters/markdown.js", function(module, exports, require){
  1965. /**
  1966. * Module dependencies.
  1967. */
  1968. var Base = require('./base')
  1969. , utils = require('../utils');
  1970. /**
  1971. * Expose `Markdown`.
  1972. */
  1973. exports = module.exports = Markdown;
  1974. /**
  1975. * Initialize a new `Markdown` reporter.
  1976. *
  1977. * @param {Runner} runner
  1978. * @api public
  1979. */
  1980. function Markdown(runner) {
  1981. Base.call(this, runner);
  1982. var self = this
  1983. , stats = this.stats
  1984. , total = runner.total
  1985. , level = 0
  1986. , buf = '';
  1987. function title(str) {
  1988. return Array(level).join('#') + ' ' + str;
  1989. }
  1990. function indent() {
  1991. return Array(level).join(' ');
  1992. }
  1993. function mapTOC(suite, obj) {
  1994. var ret = obj;
  1995. obj = obj[suite.title] = obj[suite.title] || { suite: suite };
  1996. suite.suites.forEach(function(suite){
  1997. mapTOC(suite, obj);
  1998. });
  1999. return ret;
  2000. }
  2001. function stringifyTOC(obj, level) {
  2002. ++level;
  2003. var buf = '';
  2004. var link;
  2005. for (var key in obj) {
  2006. if ('suite' == key) continue;
  2007. if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
  2008. if (key) buf += Array(level).join(' ') + link;
  2009. buf += stringifyTOC(obj[key], level);
  2010. }
  2011. --level;
  2012. return buf;
  2013. }
  2014. function generateTOC(suite) {
  2015. var obj = mapTOC(suite, {});
  2016. return stringifyTOC(obj, 0);
  2017. }
  2018. generateTOC(runner.suite);
  2019. runner.on('suite', function(suite){
  2020. ++level;
  2021. var slug = utils.slug(suite.fullTitle());
  2022. buf += '<a name="' + slug + '" />' + '\n';
  2023. buf += title(suite.title) + '\n';
  2024. });
  2025. runner.on('suite end', function(suite){
  2026. --level;
  2027. });
  2028. runner.on('pass', function(test){
  2029. var code = utils.clean(test.fn.toString());
  2030. buf += test.title + '.\n';
  2031. buf += '\n```js\n';
  2032. buf += code + '\n';
  2033. buf += '```\n\n';
  2034. });
  2035. runner.on('end', function(){
  2036. process.stdout.write('# TOC\n');
  2037. process.stdout.write(generateTOC(runner.suite));
  2038. process.stdout.write(buf);
  2039. });
  2040. }
  2041. }); // module: reporters/markdown.js
  2042. require.register("reporters/min.js", function(module, exports, require){
  2043. /**
  2044. * Module dependencies.
  2045. */
  2046. var Base = require('./base');
  2047. /**
  2048. * Expose `Min`.
  2049. */
  2050. exports = module.exports = Min;
  2051. /**
  2052. * Initialize a new `Min` minimal test reporter (best used with --watch).
  2053. *
  2054. * @param {Runner} runner
  2055. * @api public
  2056. */
  2057. function Min(runner) {
  2058. Base.call(this, runner);
  2059. runner.on('start', function(){
  2060. // clear screen
  2061. process.stdout.write('\u001b[2J');
  2062. // set cursor position
  2063. process.stdout.write('\u001b[1;3H');
  2064. });
  2065. runner.on('end', this.epilogue.bind(this));
  2066. }
  2067. /**
  2068. * Inherit from `Base.prototype`.
  2069. */
  2070. Min.prototype = new Base;
  2071. Min.prototype.constructor = Min;
  2072. }); // module: reporters/min.js
  2073. require.register("reporters/nyan.js", function(module, exports, require){
  2074. /**
  2075. * Module dependencies.
  2076. */
  2077. var Base = require('./base')
  2078. , color = Base.color;
  2079. /**
  2080. * Expose `Dot`.
  2081. */
  2082. exports = module.exports = NyanCat;
  2083. /**
  2084. * Initialize a new `Dot` matrix test reporter.
  2085. *
  2086. * @param {Runner} runner
  2087. * @api public
  2088. */
  2089. function NyanCat(runner) {
  2090. Base.call(this, runner);
  2091. var self = this
  2092. , stats = this.stats
  2093. , width = Base.window.width * .75 | 0
  2094. , rainbowColors = this.rainbowColors = self.generateColors()
  2095. , colorIndex = this.colorIndex = 0
  2096. , numerOfLines = this.numberOfLines = 4
  2097. , trajectories = this.trajectories = [[], [], [], []]
  2098. , nyanCatWidth = this.nyanCatWidth = 11
  2099. , trajectoryWidthMax = this.trajectoryWidthMax = (width - nyanCatWidth)
  2100. , scoreboardWidth = this.scoreboardWidth = 5
  2101. , tick = this.tick = 0
  2102. , n = 0;
  2103. runner.on('start', function(){
  2104. Base.cursor.hide();
  2105. self.draw('start');
  2106. });
  2107. runner.on('pending', function(test){
  2108. self.draw('pending');
  2109. });
  2110. runner.on('pass', function(test){
  2111. self.draw('pass');
  2112. });
  2113. runner.on('fail', function(test, err){
  2114. self.draw('fail');
  2115. });
  2116. runner.on('end', function(){
  2117. Base.cursor.show();
  2118. for (var i = 0; i < self.numberOfLines; i++) write('\n');
  2119. self.epilogue();
  2120. });
  2121. }
  2122. /**
  2123. * Draw the nyan cat with runner `status`.
  2124. *
  2125. * @param {String} status
  2126. * @api private
  2127. */
  2128. NyanCat.prototype.draw = function(status){
  2129. this.appendRainbow();
  2130. this.drawScoreboard();
  2131. this.drawRainbow();
  2132. this.drawNyanCat(status);
  2133. this.tick = !this.tick;
  2134. };
  2135. /**
  2136. * Draw the "scoreboard" showing the number
  2137. * of passes, failures and pending tests.
  2138. *
  2139. * @api private
  2140. */
  2141. NyanCat.prototype.drawScoreboard = function(){
  2142. var stats = this.stats;
  2143. var colors = Base.colors;
  2144. function draw(color, n) {
  2145. write(' ');
  2146. write('\u001b[' + color + 'm' + n + '\u001b[0m');
  2147. write('\n');
  2148. }
  2149. draw(colors.green, stats.passes);
  2150. draw(colors.fail, stats.failures);
  2151. draw(colors.pending, stats.pending);
  2152. write('\n');
  2153. this.cursorUp(this.numberOfLines);
  2154. };
  2155. /**
  2156. * Append the rainbow.
  2157. *
  2158. * @api private
  2159. */
  2160. NyanCat.prototype.appendRainbow = function(){
  2161. var segment = this.tick ? '_' : '-';
  2162. var rainbowified = this.rainbowify(segment);
  2163. for (var index = 0; index < this.numberOfLines; index++) {
  2164. var trajectory = this.trajectories[index];
  2165. if (trajectory.length >= this.trajectoryWidthMax) trajectory.shift();
  2166. trajectory.push(rainbowified);
  2167. }
  2168. };
  2169. /**
  2170. * Draw the rainbow.
  2171. *
  2172. * @api private
  2173. */
  2174. NyanCat.prototype.drawRainbow = function(){
  2175. var self = this;
  2176. this.trajectories.forEach(function(line, index) {
  2177. write('\u001b[' + self.scoreboardWidth + 'C');
  2178. write(line.join(''));
  2179. write('\n');
  2180. });
  2181. this.cursorUp(this.numberOfLines);
  2182. };
  2183. /**
  2184. * Draw the nyan cat with `status`.
  2185. *
  2186. * @param {String} status
  2187. * @api private
  2188. */
  2189. NyanCat.prototype.drawNyanCat = function(status) {
  2190. var self = this;
  2191. var startWidth = this.scoreboardWidth + this.trajectories[0].length;
  2192. [0, 1, 2, 3].forEach(function(index) {
  2193. write('\u001b[' + startWidth + 'C');
  2194. switch (index) {
  2195. case 0:
  2196. write('_,------,');
  2197. write('\n');
  2198. break;
  2199. case 1:
  2200. var padding = self.tick ? ' ' : ' ';
  2201. write('_|' + padding + '/\\_/\\ ');
  2202. write('\n');
  2203. break;
  2204. case 2:
  2205. var padding = self.tick ? '_' : '__';
  2206. var tail = self.tick ? '~' : '^';
  2207. var face;
  2208. switch (status) {
  2209. case 'pass':
  2210. face = '( ^ .^)';
  2211. break;
  2212. case 'fail':
  2213. face = '( o .o)';
  2214. break;
  2215. default:
  2216. face = '( - .-)';
  2217. }
  2218. write(tail + '|' + padding + face + ' ');
  2219. write('\n');
  2220. break;
  2221. case 3:
  2222. var padding = self.tick ? ' ' : ' ';
  2223. write(padding + '"" "" ');
  2224. write('\n');
  2225. break;
  2226. }
  2227. });
  2228. this.cursorUp(this.numberOfLines);
  2229. };
  2230. /**
  2231. * Move cursor up `n`.
  2232. *
  2233. * @param {Number} n
  2234. * @api private
  2235. */
  2236. NyanCat.prototype.cursorUp = function(n) {
  2237. write('\u001b[' + n + 'A');
  2238. };
  2239. /**
  2240. * Move cursor down `n`.
  2241. *
  2242. * @param {Number} n
  2243. * @api private
  2244. */
  2245. NyanCat.prototype.cursorDown = function(n) {
  2246. write('\u001b[' + n + 'B');
  2247. };
  2248. /**
  2249. * Generate rainbow colors.
  2250. *
  2251. * @return {Array}
  2252. * @api private
  2253. */
  2254. NyanCat.prototype.generateColors = function(){
  2255. var colors = [];
  2256. for (var i = 0; i < (6 * 7); i++) {
  2257. var pi3 = Math.floor(Math.PI / 3);
  2258. var n = (i * (1.0 / 6));
  2259. var r = Math.floor(3 * Math.sin(n) + 3);
  2260. var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);
  2261. var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);
  2262. colors.push(36 * r + 6 * g + b + 16);
  2263. }
  2264. return colors;
  2265. };
  2266. /**
  2267. * Apply rainbow to the given `str`.
  2268. *
  2269. * @param {String} str
  2270. * @return {String}
  2271. * @api private
  2272. */
  2273. NyanCat.prototype.rainbowify = function(str){
  2274. var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];
  2275. this.colorIndex += 1;
  2276. return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m';
  2277. };
  2278. /**
  2279. * Stdout helper.
  2280. */
  2281. function write(string) {
  2282. process.stdout.write(string);
  2283. }
  2284. /**
  2285. * Inherit from `Base.prototype`.
  2286. */
  2287. NyanCat.prototype = new Base;
  2288. NyanCat.prototype.constructor = NyanCat;
  2289. }); // module: reporters/nyan.js
  2290. require.register("reporters/progress.js", function(module, exports, require){
  2291. /**
  2292. * Module dependencies.
  2293. */
  2294. var Base = require('./base')
  2295. , cursor = Base.cursor
  2296. , color = Base.color;
  2297. /**
  2298. * Expose `Progress`.
  2299. */
  2300. exports = module.exports = Progress;
  2301. /**
  2302. * General progress bar color.
  2303. */
  2304. Base.colors.progress = 90;
  2305. /**
  2306. * Initialize a new `Progress` bar test reporter.
  2307. *
  2308. * @param {Runner} runner
  2309. * @param {Object} options
  2310. * @api public
  2311. */
  2312. function Progress(runner, options) {
  2313. Base.call(this, runner);
  2314. var self = this
  2315. , options = options || {}
  2316. , stats = this.stats
  2317. , width = Base.window.width * .50 | 0
  2318. , total = runner.total
  2319. , complete = 0
  2320. , max = Math.max;
  2321. // default chars
  2322. options.open = options.open || '[';
  2323. options.complete = options.complete || '▬';
  2324. options.incomplete = options.incomplete || '⋅';
  2325. options.close = options.close || ']';
  2326. options.verbose = false;
  2327. // tests started
  2328. runner.on('start', function(){
  2329. console.log();
  2330. cursor.hide();
  2331. });
  2332. // tests complete
  2333. runner.on('test end', function(){
  2334. complete++;
  2335. var incomplete = total - complete
  2336. , percent = complete / total
  2337. , n = width * percent | 0
  2338. , i = width - n;
  2339. cursor.CR();
  2340. process.stdout.write('\u001b[J');
  2341. process.stdout.write(color('progress', ' ' + options.open));
  2342. process.stdout.write(Array(n).join(options.complete));
  2343. process.stdout.write(Array(i).join(options.incomplete));
  2344. process.stdout.write(color('progress', options.close));
  2345. if (options.verbose) {
  2346. process.stdout.write(color('progress', ' ' + complete + ' of ' + total));
  2347. }
  2348. });
  2349. // tests are complete, output some stats
  2350. // and the failures if any
  2351. runner.on('end', function(){
  2352. cursor.show();
  2353. console.log();
  2354. self.epilogue();
  2355. });
  2356. }
  2357. /**
  2358. * Inherit from `Base.prototype`.
  2359. */
  2360. Progress.prototype = new Base;
  2361. Progress.prototype.constructor = Progress;
  2362. }); // module: reporters/progress.js
  2363. require.register("reporters/spec.js", function(module, exports, require){
  2364. /**
  2365. * Module dependencies.
  2366. */
  2367. var Base = require('./base')
  2368. , cursor = Base.cursor
  2369. , color = Base.color;
  2370. /**
  2371. * Expose `Spec`.
  2372. */
  2373. exports = module.exports = Spec;
  2374. /**
  2375. * Initialize a new `Spec` test reporter.
  2376. *
  2377. * @param {Runner} runner
  2378. * @api public
  2379. */
  2380. function Spec(runner) {
  2381. Base.call(this, runner);
  2382. var self = this
  2383. , stats = this.stats
  2384. , indents = 0
  2385. , n = 0;
  2386. function indent() {
  2387. return Array(indents).join(' ')
  2388. }
  2389. runner.on('start', function(){
  2390. console.log();
  2391. });
  2392. runner.on('suite', function(suite){
  2393. ++indents;
  2394. console.log(color('suite', '%s%s'), indent(), suite.title);
  2395. });
  2396. runner.on('suite end', function(suite){
  2397. --indents;
  2398. if (1 == indents) console.log();
  2399. });
  2400. runner.on('test', function(test){
  2401. process.stdout.write(indent() + color('pass', ' ◦ ' + test.title + ': '));
  2402. });
  2403. runner.on('pending', function(test){
  2404. var fmt = indent() + color('pending', ' - %s');
  2405. console.log(fmt, test.title);
  2406. });
  2407. runner.on('pass', function(test){
  2408. if ('fast' == test.speed) {
  2409. var fmt = indent()
  2410. + color('checkmark', ' ✓')
  2411. + color('pass', ' %s ');
  2412. cursor.CR();
  2413. console.log(fmt, test.title);
  2414. } else {
  2415. var fmt = indent()
  2416. + color('checkmark', ' ✓')
  2417. + color('pass', ' %s ')
  2418. + color(test.speed, '(%dms)');
  2419. cursor.CR();
  2420. console.log(fmt, test.title, test.duration);
  2421. }
  2422. });
  2423. runner.on('fail', function(test, err){
  2424. cursor.CR();
  2425. console.log(indent() + color('fail', ' %d) %s'), ++n, test.title);
  2426. });
  2427. runner.on('end', self.epilogue.bind(self));
  2428. }
  2429. /**
  2430. * Inherit from `Base.prototype`.
  2431. */
  2432. Spec.prototype = new Base;
  2433. Spec.prototype.constructor = Spec;
  2434. }); // module: reporters/spec.js
  2435. require.register("reporters/tap.js", function(module, exports, require){
  2436. /**
  2437. * Module dependencies.
  2438. */
  2439. var Base = require('./base')
  2440. , cursor = Base.cursor
  2441. , color = Base.color;
  2442. /**
  2443. * Expose `TAP`.
  2444. */
  2445. exports = module.exports = TAP;
  2446. /**
  2447. * Initialize a new `TAP` reporter.
  2448. *
  2449. * @param {Runner} runner
  2450. * @api public
  2451. */
  2452. function TAP(runner) {
  2453. Base.call(this, runner);
  2454. var self = this
  2455. , stats = this.stats
  2456. , total = runner.total
  2457. , n = 1;
  2458. runner.on('start', function(){
  2459. console.log('%d..%d', 1, total);
  2460. });
  2461. runner.on('test end', function(){
  2462. ++n;
  2463. });
  2464. runner.on('pending', function(test){
  2465. console.log('ok %d %s # SKIP -', n, title(test));
  2466. });
  2467. runner.on('pass', function(test){
  2468. console.log('ok %d %s', n, title(test));
  2469. });
  2470. runner.on('fail', function(test, err){
  2471. console.log('not ok %d %s', n, title(test));
  2472. console.log(err.stack.replace(/^/gm, ' '));
  2473. });
  2474. }
  2475. /**
  2476. * Return a TAP-safe title of `test`
  2477. *
  2478. * @param {Object} test
  2479. * @return {String}
  2480. * @api private
  2481. */
  2482. function title(test) {
  2483. return test.fullTitle().replace(/#/g, '');
  2484. }
  2485. }); // module: reporters/tap.js
  2486. require.register("reporters/teamcity.js", function(module, exports, require){
  2487. /**
  2488. * Module dependencies.
  2489. */
  2490. var Base = require('./base');
  2491. /**
  2492. * Expose `Teamcity`.
  2493. */
  2494. exports = module.exports = Teamcity;
  2495. /**
  2496. * Initialize a new `Teamcity` reporter.
  2497. *
  2498. * @param {Runner} runner
  2499. * @api public
  2500. */
  2501. function Teamcity(runner) {
  2502. Base.call(this, runner);
  2503. var stats = this.stats;
  2504. runner.on('start', function() {
  2505. console.log("##teamcity[testSuiteStarted name='mocha.suite']");
  2506. });
  2507. runner.on('test', function(test) {
  2508. console.log("##teamcity[testStarted name='" + escape(test.fullTitle()) + "']");
  2509. });
  2510. runner.on('fail', function(test, err) {
  2511. console.log("##teamcity[testFailed name='" + escape(test.fullTitle()) + "' message='" + escape(err.message) + "']");
  2512. });
  2513. runner.on('pending', function(test) {
  2514. console.log("##teamcity[testIgnored name='" + escape(test.fullTitle()) + "' message='pending']");
  2515. });
  2516. runner.on('test end', function(test) {
  2517. console.log("##teamcity[testFinished name='" + escape(test.fullTitle()) + "' duration='" + test.duration + "']");
  2518. });
  2519. runner.on('end', function() {
  2520. console.log("##teamcity[testSuiteFinished name='mocha.suite' duration='" + stats.duration + "']");
  2521. });
  2522. }
  2523. /**
  2524. * Escape the given `str`.
  2525. */
  2526. function escape(str) {
  2527. return str
  2528. .replace(/\|/g, "||")
  2529. .replace(/\n/g, "|n")
  2530. .replace(/\r/g, "|r")
  2531. .replace(/\[/g, "|[")
  2532. .replace(/\]/g, "|]")
  2533. .replace(/\u0085/g, "|x")
  2534. .replace(/\u2028/g, "|l")
  2535. .replace(/\u2029/g, "|p")
  2536. .replace(/'/g, "|'");
  2537. }
  2538. }); // module: reporters/teamcity.js
  2539. require.register("reporters/xunit.js", function(module, exports, require){
  2540. /**
  2541. * Module dependencies.
  2542. */
  2543. var Base = require('./base')
  2544. , utils = require('../utils')
  2545. , escape = utils.escape;
  2546. /**
  2547. * Save timer references to avoid Sinon interfering (see GH-237).
  2548. */
  2549. var Date = global.Date
  2550. , setTimeout = global.setTimeout
  2551. , setInterval = global.setInterval
  2552. , clearTimeout = global.clearTimeout
  2553. , clearInterval = global.clearInterval;
  2554. /**
  2555. * Expose `XUnit`.
  2556. */
  2557. exports = module.exports = XUnit;
  2558. /**
  2559. * Initialize a new `XUnit` reporter.
  2560. *
  2561. * @param {Runner} runner
  2562. * @api public
  2563. */
  2564. function XUnit(runner) {
  2565. Base.call(this, runner);
  2566. var stats = this.stats
  2567. , tests = []
  2568. , self = this;
  2569. runner.on('pass', function(test){
  2570. tests.push(test);
  2571. });
  2572. runner.on('fail', function(test){
  2573. tests.push(test);
  2574. });
  2575. runner.on('end', function(){
  2576. console.log(tag('testsuite', {
  2577. name: 'Mocha Tests'
  2578. , tests: stats.tests
  2579. , failures: stats.failures
  2580. , errors: stats.failures
  2581. , skip: stats.tests - stats.failures - stats.passes
  2582. , timestamp: (new Date).toUTCString()
  2583. , time: stats.duration / 1000
  2584. }, false));
  2585. tests.forEach(test);
  2586. console.log('</testsuite>');
  2587. });
  2588. }
  2589. /**
  2590. * Inherit from `Base.prototype`.
  2591. */
  2592. XUnit.prototype = new Base;
  2593. XUnit.prototype.constructor = XUnit;
  2594. /**
  2595. * Output tag for the given `test.`
  2596. */
  2597. function test(test) {
  2598. var attrs = {
  2599. classname: test.parent.fullTitle()
  2600. , name: test.title
  2601. , time: test.duration / 1000
  2602. };
  2603. if ('failed' == test.state) {
  2604. var err = test.err;
  2605. attrs.message = escape(err.message);
  2606. console.log(tag('testcase', attrs, false, tag('failure', attrs, false, cdata(err.stack))));
  2607. } else if (test.pending) {
  2608. console.log(tag('testcase', attrs, false, tag('skipped', {}, true)));
  2609. } else {
  2610. console.log(tag('testcase', attrs, true) );
  2611. }
  2612. }
  2613. /**
  2614. * HTML tag helper.
  2615. */
  2616. function tag(name, attrs, close, content) {
  2617. var end = close ? '/>' : '>'
  2618. , pairs = []
  2619. , tag;
  2620. for (var key in attrs) {
  2621. pairs.push(key + '="' + escape(attrs[key]) + '"');
  2622. }
  2623. tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end;
  2624. if (content) tag += content + '</' + name + end;
  2625. return tag;
  2626. }
  2627. /**
  2628. * Return cdata escaped CDATA `str`.
  2629. */
  2630. function cdata(str) {
  2631. return '<![CDATA[' + escape(str) + ']]>';
  2632. }
  2633. }); // module: reporters/xunit.js
  2634. require.register("runnable.js", function(module, exports, require){
  2635. /**
  2636. * Module dependencies.
  2637. */
  2638. var EventEmitter = require('browser/events').EventEmitter
  2639. , debug = require('browser/debug')('mocha:runnable');
  2640. /**
  2641. * Save timer references to avoid Sinon interfering (see GH-237).
  2642. */
  2643. var Date = global.Date
  2644. , setTimeout = global.setTimeout
  2645. , setInterval = global.setInterval
  2646. , clearTimeout = global.clearTimeout
  2647. , clearInterval = global.clearInterval;
  2648. /**
  2649. * Expose `Runnable`.
  2650. */
  2651. module.exports = Runnable;
  2652. /**
  2653. * Initialize a new `Runnable` with the given `title` and callback `fn`.
  2654. *
  2655. * @param {String} title
  2656. * @param {Function} fn
  2657. * @api private
  2658. */
  2659. function Runnable(title, fn) {
  2660. this.title = title;
  2661. this.fn = fn;
  2662. this.async = fn && fn.length;
  2663. this.sync = ! this.async;
  2664. this._timeout = 2000;
  2665. this.timedOut = false;
  2666. }
  2667. /**
  2668. * Inherit from `EventEmitter.prototype`.
  2669. */
  2670. Runnable.prototype = new EventEmitter;
  2671. Runnable.prototype.constructor = Runnable;
  2672. /**
  2673. * Set & get timeout `ms`.
  2674. *
  2675. * @param {Number} ms
  2676. * @return {Runnable|Number} ms or self
  2677. * @api private
  2678. */
  2679. Runnable.prototype.timeout = function(ms){
  2680. if (0 == arguments.length) return this._timeout;
  2681. debug('timeout %d', ms);
  2682. this._timeout = ms;
  2683. if (this.timer) this.resetTimeout();
  2684. return this;
  2685. };
  2686. /**
  2687. * Return the full title generated by recursively
  2688. * concatenating the parent's full title.
  2689. *
  2690. * @return {String}
  2691. * @api public
  2692. */
  2693. Runnable.prototype.fullTitle = function(){
  2694. return this.parent.fullTitle() + ' ' + this.title;
  2695. };
  2696. /**
  2697. * Clear the timeout.
  2698. *
  2699. * @api private
  2700. */
  2701. Runnable.prototype.clearTimeout = function(){
  2702. clearTimeout(this.timer);
  2703. };
  2704. /**
  2705. * Inspect the runnable void of private properties.
  2706. *
  2707. * @return {String}
  2708. * @api private
  2709. */
  2710. Runnable.prototype.inspect = function(){
  2711. return JSON.stringify(this, function(key, val){
  2712. if ('_' == key[0]) return;
  2713. if ('parent' == key) return '#<Suite>';
  2714. if ('ctx' == key) return '#<Context>';
  2715. return val;
  2716. }, 2);
  2717. };
  2718. /**
  2719. * Reset the timeout.
  2720. *
  2721. * @api private
  2722. */
  2723. Runnable.prototype.resetTimeout = function(){
  2724. var self = this
  2725. , ms = this.timeout();
  2726. this.clearTimeout();
  2727. if (ms) {
  2728. this.timer = setTimeout(function(){
  2729. self.callback(new Error('timeout of ' + ms + 'ms exceeded'));
  2730. self.timedOut = true;
  2731. }, ms);
  2732. }
  2733. };
  2734. /**
  2735. * Run the test and invoke `fn(err)`.
  2736. *
  2737. * @param {Function} fn
  2738. * @api private
  2739. */
  2740. Runnable.prototype.run = function(fn){
  2741. var self = this
  2742. , ms = this.timeout()
  2743. , start = new Date
  2744. , ctx = this.ctx
  2745. , finished
  2746. , emitted;
  2747. if (ctx) ctx.runnable(this);
  2748. // timeout
  2749. if (this.async) {
  2750. if (ms) {
  2751. this.timer = setTimeout(function(){
  2752. done(new Error('timeout of ' + ms + 'ms exceeded'));
  2753. self.timedOut = true;
  2754. }, ms);
  2755. }
  2756. }
  2757. // called multiple times
  2758. function multiple(err) {
  2759. if (emitted) return;
  2760. emitted = true;
  2761. self.emit('error', err || new Error('done() called multiple times'));
  2762. }
  2763. // finished
  2764. function done(err) {
  2765. if (self.timedOut) return;
  2766. if (finished) return multiple(err);
  2767. self.clearTimeout();
  2768. self.duration = new Date - start;
  2769. finished = true;
  2770. fn(err);
  2771. }
  2772. // for .resetTimeout()
  2773. this.callback = done;
  2774. // async
  2775. if (this.async) {
  2776. try {
  2777. this.fn.call(ctx, function(err){
  2778. if (err instanceof Error) return done(err);
  2779. if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
  2780. done();
  2781. });
  2782. } catch (err) {
  2783. done(err);
  2784. }
  2785. return;
  2786. }
  2787. // sync
  2788. try {
  2789. if (!this.pending) this.fn.call(ctx);
  2790. this.duration = new Date - start;
  2791. fn();
  2792. } catch (err) {
  2793. fn(err);
  2794. }
  2795. };
  2796. }); // module: runnable.js
  2797. require.register("runner.js", function(module, exports, require){
  2798. /**
  2799. * Module dependencies.
  2800. */
  2801. var EventEmitter = require('browser/events').EventEmitter
  2802. , debug = require('browser/debug')('mocha:runner')
  2803. , Test = require('./test')
  2804. , utils = require('./utils')
  2805. , filter = utils.filter
  2806. , keys = utils.keys
  2807. , noop = function(){};
  2808. /**
  2809. * Expose `Runner`.
  2810. */
  2811. module.exports = Runner;
  2812. /**
  2813. * Initialize a `Runner` for the given `suite`.
  2814. *
  2815. * Events:
  2816. *
  2817. * - `start` execution started
  2818. * - `end` execution complete
  2819. * - `suite` (suite) test suite execution started
  2820. * - `suite end` (suite) all tests (and sub-suites) have finished
  2821. * - `test` (test) test execution started
  2822. * - `test end` (test) test completed
  2823. * - `hook` (hook) hook execution started
  2824. * - `hook end` (hook) hook complete
  2825. * - `pass` (test) test passed
  2826. * - `fail` (test, err) test failed
  2827. *
  2828. * @api public
  2829. */
  2830. function Runner(suite) {
  2831. var self = this;
  2832. this._globals = [];
  2833. this.suite = suite;
  2834. this.total = suite.total();
  2835. this.failures = 0;
  2836. this.on('test end', function(test){ self.checkGlobals(test); });
  2837. this.on('hook end', function(hook){ self.checkGlobals(hook); });
  2838. this.grep(/.*/);
  2839. this.globals(utils.keys(global).concat(['errno']));
  2840. }
  2841. /**
  2842. * Inherit from `EventEmitter.prototype`.
  2843. */
  2844. Runner.prototype = new EventEmitter;
  2845. Runner.prototype.constructor = Runner;
  2846. /**
  2847. * Run tests with full titles matching `re`. Updates runner.total
  2848. * with number of tests matched.
  2849. *
  2850. * @param {RegExp} re
  2851. * @param {Boolean} invert
  2852. * @return {Runner} for chaining
  2853. * @api public
  2854. */
  2855. Runner.prototype.grep = function(re, invert){
  2856. debug('grep %s', re);
  2857. this._grep = re;
  2858. this._invert = invert;
  2859. this.total = this.grepTotal(this.suite);
  2860. return this;
  2861. };
  2862. /**
  2863. * Returns the number of tests matching the grep search for the
  2864. * given suite.
  2865. *
  2866. * @param {Suite} suite
  2867. * @return {Number}
  2868. * @api public
  2869. */
  2870. Runner.prototype.grepTotal = function(suite) {
  2871. var self = this;
  2872. var total = 0;
  2873. suite.eachTest(function(test){
  2874. var match = self._grep.test(test.fullTitle());
  2875. if (self._invert) match = !match;
  2876. if (match) total++;
  2877. });
  2878. return total;
  2879. };
  2880. /**
  2881. * Allow the given `arr` of globals.
  2882. *
  2883. * @param {Array} arr
  2884. * @return {Runner} for chaining
  2885. * @api public
  2886. */
  2887. Runner.prototype.globals = function(arr){
  2888. if (0 == arguments.length) return this._globals;
  2889. debug('globals %j', arr);
  2890. utils.forEach(arr, function(arr){
  2891. this._globals.push(arr);
  2892. }, this);
  2893. return this;
  2894. };
  2895. /**
  2896. * Check for global variable leaks.
  2897. *
  2898. * @api private
  2899. */
  2900. Runner.prototype.checkGlobals = function(test){
  2901. if (this.ignoreLeaks) return;
  2902. var leaks = filterLeaks(this._globals);
  2903. this._globals = this._globals.concat(leaks);
  2904. if (leaks.length > 1) {
  2905. this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + ''));
  2906. } else if (leaks.length) {
  2907. this.fail(test, new Error('global leak detected: ' + leaks[0]));
  2908. }
  2909. };
  2910. /**
  2911. * Fail the given `test`.
  2912. *
  2913. * @param {Test} test
  2914. * @param {Error} err
  2915. * @api private
  2916. */
  2917. Runner.prototype.fail = function(test, err){
  2918. ++this.failures;
  2919. test.state = 'failed';
  2920. if ('string' == typeof err) {
  2921. err = new Error('the string "' + err + '" was thrown, throw an Error :)');
  2922. }
  2923. this.emit('fail', test, err);
  2924. };
  2925. /**
  2926. * Fail the given `hook` with `err`.
  2927. *
  2928. * Hook failures (currently) hard-end due
  2929. * to that fact that a failing hook will
  2930. * surely cause subsequent tests to fail,
  2931. * causing jumbled reporting.
  2932. *
  2933. * @param {Hook} hook
  2934. * @param {Error} err
  2935. * @api private
  2936. */
  2937. Runner.prototype.failHook = function(hook, err){
  2938. this.fail(hook, err);
  2939. this.emit('end');
  2940. };
  2941. /**
  2942. * Run hook `name` callbacks and then invoke `fn()`.
  2943. *
  2944. * @param {String} name
  2945. * @param {Function} function
  2946. * @api private
  2947. */
  2948. Runner.prototype.hook = function(name, fn){
  2949. var suite = this.suite
  2950. , hooks = suite['_' + name]
  2951. , ms = suite._timeout
  2952. , self = this
  2953. , timer;
  2954. function next(i) {
  2955. var hook = hooks[i];
  2956. if (!hook) return fn();
  2957. self.currentRunnable = hook;
  2958. self.emit('hook', hook);
  2959. hook.on('error', function(err){
  2960. self.failHook(hook, err);
  2961. });
  2962. hook.run(function(err){
  2963. hook.removeAllListeners('error');
  2964. var testError = hook.error();
  2965. if (testError) self.fail(self.test, testError);
  2966. if (err) return self.failHook(hook, err);
  2967. self.emit('hook end', hook);
  2968. next(++i);
  2969. });
  2970. }
  2971. process.nextTick(function(){
  2972. next(0);
  2973. });
  2974. };
  2975. /**
  2976. * Run hook `name` for the given array of `suites`
  2977. * in order, and callback `fn(err)`.
  2978. *
  2979. * @param {String} name
  2980. * @param {Array} suites
  2981. * @param {Function} fn
  2982. * @api private
  2983. */
  2984. Runner.prototype.hooks = function(name, suites, fn){
  2985. var self = this
  2986. , orig = this.suite;
  2987. function next(suite) {
  2988. self.suite = suite;
  2989. if (!suite) {
  2990. self.suite = orig;
  2991. return fn();
  2992. }
  2993. self.hook(name, function(err){
  2994. if (err) {
  2995. self.suite = orig;
  2996. return fn(err);
  2997. }
  2998. next(suites.pop());
  2999. });
  3000. }
  3001. next(suites.pop());
  3002. };
  3003. /**
  3004. * Run hooks from the top level down.
  3005. *
  3006. * @param {String} name
  3007. * @param {Function} fn
  3008. * @api private
  3009. */
  3010. Runner.prototype.hookUp = function(name, fn){
  3011. var suites = [this.suite].concat(this.parents()).reverse();
  3012. this.hooks(name, suites, fn);
  3013. };
  3014. /**
  3015. * Run hooks from the bottom up.
  3016. *
  3017. * @param {String} name
  3018. * @param {Function} fn
  3019. * @api private
  3020. */
  3021. Runner.prototype.hookDown = function(name, fn){
  3022. var suites = [this.suite].concat(this.parents());
  3023. this.hooks(name, suites, fn);
  3024. };
  3025. /**
  3026. * Return an array of parent Suites from
  3027. * closest to furthest.
  3028. *
  3029. * @return {Array}
  3030. * @api private
  3031. */
  3032. Runner.prototype.parents = function(){
  3033. var suite = this.suite
  3034. , suites = [];
  3035. while (suite = suite.parent) suites.push(suite);
  3036. return suites;
  3037. };
  3038. /**
  3039. * Run the current test and callback `fn(err)`.
  3040. *
  3041. * @param {Function} fn
  3042. * @api private
  3043. */
  3044. Runner.prototype.runTest = function(fn){
  3045. var test = this.test
  3046. , self = this;
  3047. try {
  3048. test.on('error', function(err){
  3049. self.fail(test, err);
  3050. });
  3051. test.run(fn);
  3052. } catch (err) {
  3053. fn(err);
  3054. }
  3055. };
  3056. /**
  3057. * Run tests in the given `suite` and invoke
  3058. * the callback `fn()` when complete.
  3059. *
  3060. * @param {Suite} suite
  3061. * @param {Function} fn
  3062. * @api private
  3063. */
  3064. Runner.prototype.runTests = function(suite, fn){
  3065. var self = this
  3066. , tests = suite.tests
  3067. , test;
  3068. function next(err) {
  3069. // if we bail after first err
  3070. if (self.failures && suite._bail) return fn();
  3071. // next test
  3072. test = tests.shift();
  3073. // all done
  3074. if (!test) return fn();
  3075. // grep
  3076. var match = self._grep.test(test.fullTitle());
  3077. if (self._invert) match = !match;
  3078. if (!match) return next();
  3079. // pending
  3080. if (test.pending) {
  3081. self.emit('pending', test);
  3082. self.emit('test end', test);
  3083. return next();
  3084. }
  3085. // execute test and hook(s)
  3086. self.emit('test', self.test = test);
  3087. self.hookDown('beforeEach', function(){
  3088. self.currentRunnable = self.test;
  3089. self.runTest(function(err){
  3090. test = self.test;
  3091. if (err) {
  3092. self.fail(test, err);
  3093. self.emit('test end', test);
  3094. return self.hookUp('afterEach', next);
  3095. }
  3096. test.state = 'passed';
  3097. self.emit('pass', test);
  3098. self.emit('test end', test);
  3099. self.hookUp('afterEach', next);
  3100. });
  3101. });
  3102. }
  3103. this.next = next;
  3104. next();
  3105. };
  3106. /**
  3107. * Run the given `suite` and invoke the
  3108. * callback `fn()` when complete.
  3109. *
  3110. * @param {Suite} suite
  3111. * @param {Function} fn
  3112. * @api private
  3113. */
  3114. Runner.prototype.runSuite = function(suite, fn){
  3115. var total = this.grepTotal(suite)
  3116. , self = this
  3117. , i = 0;
  3118. debug('run suite %s', suite.fullTitle());
  3119. if (!total) return fn();
  3120. this.emit('suite', this.suite = suite);
  3121. function next() {
  3122. var curr = suite.suites[i++];
  3123. if (!curr) return done();
  3124. self.runSuite(curr, next);
  3125. }
  3126. function done() {
  3127. self.suite = suite;
  3128. self.hook('afterAll', function(){
  3129. self.emit('suite end', suite);
  3130. fn();
  3131. });
  3132. }
  3133. this.hook('beforeAll', function(){
  3134. self.runTests(suite, next);
  3135. });
  3136. };
  3137. /**
  3138. * Handle uncaught exceptions.
  3139. *
  3140. * @param {Error} err
  3141. * @api private
  3142. */
  3143. Runner.prototype.uncaught = function(err){
  3144. debug('uncaught exception %s', err.message);
  3145. var runnable = this.currentRunnable;
  3146. if (!runnable || 'failed' == runnable.state) return;
  3147. runnable.clearTimeout();
  3148. err.uncaught = true;
  3149. this.fail(runnable, err);
  3150. // recover from test
  3151. if ('test' == runnable.type) {
  3152. this.emit('test end', runnable);
  3153. this.hookUp('afterEach', this.next);
  3154. return;
  3155. }
  3156. // bail on hooks
  3157. this.emit('end');
  3158. };
  3159. /**
  3160. * Run the root suite and invoke `fn(failures)`
  3161. * on completion.
  3162. *
  3163. * @param {Function} fn
  3164. * @return {Runner} for chaining
  3165. * @api public
  3166. */
  3167. Runner.prototype.run = function(fn){
  3168. var self = this
  3169. , fn = fn || function(){};
  3170. debug('start');
  3171. // uncaught callback
  3172. function uncaught(err) {
  3173. self.uncaught(err);
  3174. }
  3175. // callback
  3176. this.on('end', function(){
  3177. debug('end');
  3178. process.removeListener('uncaughtException', uncaught);
  3179. fn(self.failures);
  3180. });
  3181. // run suites
  3182. this.emit('start');
  3183. this.runSuite(this.suite, function(){
  3184. debug('finished running');
  3185. self.emit('end');
  3186. });
  3187. // uncaught exception
  3188. process.on('uncaughtException', uncaught);
  3189. return this;
  3190. };
  3191. /**
  3192. * Filter leaks with the given globals flagged as `ok`.
  3193. *
  3194. * @param {Array} ok
  3195. * @return {Array}
  3196. * @api private
  3197. */
  3198. function filterLeaks(ok) {
  3199. return filter(keys(global), function(key){
  3200. var matched = filter(ok, function(ok){
  3201. if (~ok.indexOf('*')) return 0 == key.indexOf(ok.split('*')[0]);
  3202. return key == ok;
  3203. });
  3204. return matched.length == 0 && (!global.navigator || 'onerror' !== key);
  3205. });
  3206. }
  3207. }); // module: runner.js
  3208. require.register("suite.js", function(module, exports, require){
  3209. /**
  3210. * Module dependencies.
  3211. */
  3212. var EventEmitter = require('browser/events').EventEmitter
  3213. , debug = require('browser/debug')('mocha:suite')
  3214. , utils = require('./utils')
  3215. , Hook = require('./hook');
  3216. /**
  3217. * Expose `Suite`.
  3218. */
  3219. exports = module.exports = Suite;
  3220. /**
  3221. * Create a new `Suite` with the given `title`
  3222. * and parent `Suite`. When a suite with the
  3223. * same title is already present, that suite
  3224. * is returned to provide nicer reporter
  3225. * and more flexible meta-testing.
  3226. *
  3227. * @param {Suite} parent
  3228. * @param {String} title
  3229. * @return {Suite}
  3230. * @api public
  3231. */
  3232. exports.create = function(parent, title){
  3233. var suite = new Suite(title, parent.ctx);
  3234. suite.parent = parent;
  3235. if (parent.pending) suite.pending = true;
  3236. title = suite.fullTitle();
  3237. parent.addSuite(suite);
  3238. return suite;
  3239. };
  3240. /**
  3241. * Initialize a new `Suite` with the given
  3242. * `title` and `ctx`.
  3243. *
  3244. * @param {String} title
  3245. * @param {Context} ctx
  3246. * @api private
  3247. */
  3248. function Suite(title, ctx) {
  3249. this.title = title;
  3250. this.ctx = ctx;
  3251. this.suites = [];
  3252. this.tests = [];
  3253. this.pending = false;
  3254. this._beforeEach = [];
  3255. this._beforeAll = [];
  3256. this._afterEach = [];
  3257. this._afterAll = [];
  3258. this.root = !title;
  3259. this._timeout = 2000;
  3260. this._bail = false;
  3261. }
  3262. /**
  3263. * Inherit from `EventEmitter.prototype`.
  3264. */
  3265. Suite.prototype = new EventEmitter;
  3266. Suite.prototype.constructor = Suite;
  3267. /**
  3268. * Return a clone of this `Suite`.
  3269. *
  3270. * @return {Suite}
  3271. * @api private
  3272. */
  3273. Suite.prototype.clone = function(){
  3274. var suite = new Suite(this.title);
  3275. debug('clone');
  3276. suite.ctx = this.ctx;
  3277. suite.timeout(this.timeout());
  3278. suite.bail(this.bail());
  3279. return suite;
  3280. };
  3281. /**
  3282. * Set timeout `ms` or short-hand such as "2s".
  3283. *
  3284. * @param {Number|String} ms
  3285. * @return {Suite|Number} for chaining
  3286. * @api private
  3287. */
  3288. Suite.prototype.timeout = function(ms){
  3289. if (0 == arguments.length) return this._timeout;
  3290. if (String(ms).match(/s$/)) ms = parseFloat(ms) * 1000;
  3291. debug('timeout %d', ms);
  3292. this._timeout = parseInt(ms, 10);
  3293. return this;
  3294. };
  3295. /**
  3296. * Sets whether to bail after first error.
  3297. *
  3298. * @parma {Boolean} bail
  3299. * @return {Suite|Number} for chaining
  3300. * @api private
  3301. */
  3302. Suite.prototype.bail = function(bail){
  3303. if (0 == arguments.length) return this._bail;
  3304. debug('bail %s', bail);
  3305. this._bail = bail;
  3306. return this;
  3307. };
  3308. /**
  3309. * Run `fn(test[, done])` before running tests.
  3310. *
  3311. * @param {Function} fn
  3312. * @return {Suite} for chaining
  3313. * @api private
  3314. */
  3315. Suite.prototype.beforeAll = function(fn){
  3316. if (this.pending) return this;
  3317. var hook = new Hook('"before all" hook', fn);
  3318. hook.parent = this;
  3319. hook.timeout(this.timeout());
  3320. hook.ctx = this.ctx;
  3321. this._beforeAll.push(hook);
  3322. this.emit('beforeAll', hook);
  3323. return this;
  3324. };
  3325. /**
  3326. * Run `fn(test[, done])` after running tests.
  3327. *
  3328. * @param {Function} fn
  3329. * @return {Suite} for chaining
  3330. * @api private
  3331. */
  3332. Suite.prototype.afterAll = function(fn){
  3333. if (this.pending) return this;
  3334. var hook = new Hook('"after all" hook', fn);
  3335. hook.parent = this;
  3336. hook.timeout(this.timeout());
  3337. hook.ctx = this.ctx;
  3338. this._afterAll.push(hook);
  3339. this.emit('afterAll', hook);
  3340. return this;
  3341. };
  3342. /**
  3343. * Run `fn(test[, done])` before each test case.
  3344. *
  3345. * @param {Function} fn
  3346. * @return {Suite} for chaining
  3347. * @api private
  3348. */
  3349. Suite.prototype.beforeEach = function(fn){
  3350. if (this.pending) return this;
  3351. var hook = new Hook('"before each" hook', fn);
  3352. hook.parent = this;
  3353. hook.timeout(this.timeout());
  3354. hook.ctx = this.ctx;
  3355. this._beforeEach.push(hook);
  3356. this.emit('beforeEach', hook);
  3357. return this;
  3358. };
  3359. /**
  3360. * Run `fn(test[, done])` after each test case.
  3361. *
  3362. * @param {Function} fn
  3363. * @return {Suite} for chaining
  3364. * @api private
  3365. */
  3366. Suite.prototype.afterEach = function(fn){
  3367. if (this.pending) return this;
  3368. var hook = new Hook('"after each" hook', fn);
  3369. hook.parent = this;
  3370. hook.timeout(this.timeout());
  3371. hook.ctx = this.ctx;
  3372. this._afterEach.push(hook);
  3373. this.emit('afterEach', hook);
  3374. return this;
  3375. };
  3376. /**
  3377. * Add a test `suite`.
  3378. *
  3379. * @param {Suite} suite
  3380. * @return {Suite} for chaining
  3381. * @api private
  3382. */
  3383. Suite.prototype.addSuite = function(suite){
  3384. suite.parent = this;
  3385. suite.timeout(this.timeout());
  3386. suite.bail(this.bail());
  3387. this.suites.push(suite);
  3388. this.emit('suite', suite);
  3389. return this;
  3390. };
  3391. /**
  3392. * Add a `test` to this suite.
  3393. *
  3394. * @param {Test} test
  3395. * @return {Suite} for chaining
  3396. * @api private
  3397. */
  3398. Suite.prototype.addTest = function(test){
  3399. test.parent = this;
  3400. test.timeout(this.timeout());
  3401. test.ctx = this.ctx;
  3402. this.tests.push(test);
  3403. this.emit('test', test);
  3404. return this;
  3405. };
  3406. /**
  3407. * Return the full title generated by recursively
  3408. * concatenating the parent's full title.
  3409. *
  3410. * @return {String}
  3411. * @api public
  3412. */
  3413. Suite.prototype.fullTitle = function(){
  3414. if (this.parent) {
  3415. var full = this.parent.fullTitle();
  3416. if (full) return full + ' ' + this.title;
  3417. }
  3418. return this.title;
  3419. };
  3420. /**
  3421. * Return the total number of tests.
  3422. *
  3423. * @return {Number}
  3424. * @api public
  3425. */
  3426. Suite.prototype.total = function(){
  3427. return utils.reduce(this.suites, function(sum, suite){
  3428. return sum + suite.total();
  3429. }, 0) + this.tests.length;
  3430. };
  3431. /**
  3432. * Iterates through each suite recursively to find
  3433. * all tests. Applies a function in the format
  3434. * `fn(test)`.
  3435. *
  3436. * @param {Function} fn
  3437. * @return {Suite}
  3438. * @api private
  3439. */
  3440. Suite.prototype.eachTest = function(fn){
  3441. utils.forEach(this.tests, fn);
  3442. utils.forEach(this.suites, function(suite){
  3443. suite.eachTest(fn);
  3444. });
  3445. return this;
  3446. };
  3447. }); // module: suite.js
  3448. require.register("test.js", function(module, exports, require){
  3449. /**
  3450. * Module dependencies.
  3451. */
  3452. var Runnable = require('./runnable');
  3453. /**
  3454. * Expose `Test`.
  3455. */
  3456. module.exports = Test;
  3457. /**
  3458. * Initialize a new `Test` with the given `title` and callback `fn`.
  3459. *
  3460. * @param {String} title
  3461. * @param {Function} fn
  3462. * @api private
  3463. */
  3464. function Test(title, fn) {
  3465. Runnable.call(this, title, fn);
  3466. this.pending = !fn;
  3467. this.type = 'test';
  3468. }
  3469. /**
  3470. * Inherit from `Runnable.prototype`.
  3471. */
  3472. Test.prototype = new Runnable;
  3473. Test.prototype.constructor = Test;
  3474. }); // module: test.js
  3475. require.register("utils.js", function(module, exports, require){
  3476. /**
  3477. * Module dependencies.
  3478. */
  3479. var fs = require('browser/fs')
  3480. , path = require('browser/path')
  3481. , join = path.join
  3482. , debug = require('browser/debug')('mocha:watch');
  3483. /**
  3484. * Ignored directories.
  3485. */
  3486. var ignore = ['node_modules', '.git'];
  3487. /**
  3488. * Escape special characters in the given string of html.
  3489. *
  3490. * @param {String} html
  3491. * @return {String}
  3492. * @api private
  3493. */
  3494. exports.escape = function(html) {
  3495. return String(html)
  3496. .replace(/&/g, '&amp;')
  3497. .replace(/"/g, '&quot;')
  3498. .replace(/</g, '&lt;')
  3499. .replace(/>/g, '&gt;');
  3500. };
  3501. /**
  3502. * Array#forEach (<=IE8)
  3503. *
  3504. * @param {Array} array
  3505. * @param {Function} fn
  3506. * @param {Object} scope
  3507. * @api private
  3508. */
  3509. exports.forEach = function(arr, fn, scope) {
  3510. for (var i = 0, l = arr.length; i < l; i++)
  3511. fn.call(scope, arr[i], i);
  3512. };
  3513. /**
  3514. * Array#indexOf (<=IE8)
  3515. *
  3516. * @parma {Array} arr
  3517. * @param {Object} obj to find index of
  3518. * @param {Number} start
  3519. * @api private
  3520. */
  3521. exports.indexOf = function (arr, obj, start) {
  3522. for (var i = start || 0, l = arr.length; i < l; i++) {
  3523. if (arr[i] === obj)
  3524. return i;
  3525. }
  3526. return -1;
  3527. };
  3528. /**
  3529. * Array#reduce (<=IE8)
  3530. *
  3531. * @param {Array} array
  3532. * @param {Function} fn
  3533. * @param {Object} initial value
  3534. * @param {Object} scope
  3535. * @api private
  3536. */
  3537. exports.reduce = function(arr, fn, val, scope) {
  3538. var rval = val;
  3539. for (var i = 0, l = arr.length; i < l; i++) {
  3540. rval = fn.call(scope, rval, arr[i], i, arr);
  3541. }
  3542. return rval;
  3543. };
  3544. /**
  3545. * Array#filter (<=IE8)
  3546. *
  3547. * @param {Array} array
  3548. * @param {Function} fn
  3549. * @param {Object} scope
  3550. * @api private
  3551. */
  3552. exports.filter = function(arr, fn, scope) {
  3553. var ret = [];
  3554. for (var i = 0, l = arr.length; i < l; i++) {
  3555. var val = arr[i];
  3556. if (fn.call(scope, val, i, arr))
  3557. ret.push(val);
  3558. }
  3559. return ret;
  3560. };
  3561. /**
  3562. * Object.keys (<=IE8)
  3563. *
  3564. * @param {Object} obj
  3565. * @return {Array} keys
  3566. * @api private
  3567. */
  3568. exports.keys = Object.keys || function(obj) {
  3569. var keys = []
  3570. , has = Object.prototype.hasOwnProperty // for `window` on <=IE8
  3571. for (var key in obj) {
  3572. if (has.call(obj, key)) {
  3573. keys.push(key);
  3574. }
  3575. }
  3576. return keys;
  3577. };
  3578. /**
  3579. * Watch the given `files` for changes
  3580. * and invoke `fn(file)` on modification.
  3581. *
  3582. * @param {Array} files
  3583. * @param {Function} fn
  3584. * @api private
  3585. */
  3586. exports.watch = function(files, fn){
  3587. var options = { interval: 100 };
  3588. files.forEach(function(file){
  3589. debug('file %s', file);
  3590. fs.watchFile(file, options, function(curr, prev){
  3591. if (prev.mtime < curr.mtime) fn(file);
  3592. });
  3593. });
  3594. };
  3595. /**
  3596. * Ignored files.
  3597. */
  3598. function ignored(path){
  3599. return !~ignore.indexOf(path);
  3600. }
  3601. /**
  3602. * Lookup files in the given `dir`.
  3603. *
  3604. * @return {Array}
  3605. * @api private
  3606. */
  3607. exports.files = function(dir, ret){
  3608. ret = ret || [];
  3609. fs.readdirSync(dir)
  3610. .filter(ignored)
  3611. .forEach(function(path){
  3612. path = join(dir, path);
  3613. if (fs.statSync(path).isDirectory()) {
  3614. exports.files(path, ret);
  3615. } else if (path.match(/\.(js|coffee)$/)) {
  3616. ret.push(path);
  3617. }
  3618. });
  3619. return ret;
  3620. };
  3621. /**
  3622. * Compute a slug from the given `str`.
  3623. *
  3624. * @param {String} str
  3625. * @return {String}
  3626. * @api private
  3627. */
  3628. exports.slug = function(str){
  3629. return str
  3630. .toLowerCase()
  3631. .replace(/ +/g, '-')
  3632. .replace(/[^-\w]/g, '');
  3633. };
  3634. /**
  3635. * Strip the function definition from `str`,
  3636. * and re-indent for pre whitespace.
  3637. */
  3638. exports.clean = function(str) {
  3639. str = str
  3640. .replace(/^function *\(.*\) *{/, '')
  3641. .replace(/\s+\}$/, '');
  3642. var spaces = str.match(/^\n?( *)/)[1].length
  3643. , re = new RegExp('^ {' + spaces + '}', 'gm');
  3644. str = str.replace(re, '');
  3645. return exports.trim(str);
  3646. };
  3647. /**
  3648. * Escape regular expression characters in `str`.
  3649. *
  3650. * @param {String} str
  3651. * @return {String}
  3652. * @api private
  3653. */
  3654. exports.escapeRegexp = function(str){
  3655. return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
  3656. };
  3657. /**
  3658. * Trim the given `str`.
  3659. *
  3660. * @param {String} str
  3661. * @return {String}
  3662. * @api private
  3663. */
  3664. exports.trim = function(str){
  3665. return str.replace(/^\s+|\s+$/g, '');
  3666. };
  3667. /**
  3668. * Parse the given `qs`.
  3669. *
  3670. * @param {String} qs
  3671. * @return {Object}
  3672. * @api private
  3673. */
  3674. exports.parseQuery = function(qs){
  3675. return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair){
  3676. var i = pair.indexOf('=')
  3677. , key = pair.slice(0, i)
  3678. , val = pair.slice(++i);
  3679. obj[key] = decodeURIComponent(val);
  3680. return obj;
  3681. }, {});
  3682. };
  3683. /**
  3684. * Highlight the given string of `js`.
  3685. *
  3686. * @param {String} js
  3687. * @return {String}
  3688. * @api private
  3689. */
  3690. function highlight(js) {
  3691. return js
  3692. .replace(/</g, '&lt;')
  3693. .replace(/>/g, '&gt;')
  3694. .replace(/\/\/(.*)/gm, '<span class="comment">//$1</span>')
  3695. .replace(/('.*?')/gm, '<span class="string">$1</span>')
  3696. .replace(/(\d+\.\d+)/gm, '<span class="number">$1</span>')
  3697. .replace(/(\d+)/gm, '<span class="number">$1</span>')
  3698. .replace(/\bnew *(\w+)/gm, '<span class="keyword">new</span> <span class="init">$1</span>')
  3699. .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '<span class="keyword">$1</span>')
  3700. }
  3701. /**
  3702. * Highlight the contents of tag `name`.
  3703. *
  3704. * @param {String} name
  3705. * @api private
  3706. */
  3707. exports.highlightTags = function(name) {
  3708. var code = document.getElementsByTagName(name);
  3709. for (var i = 0, len = code.length; i < len; ++i) {
  3710. code[i].innerHTML = highlight(code[i].innerHTML);
  3711. }
  3712. };
  3713. }); // module: utils.js
  3714. /**
  3715. * Node shims.
  3716. *
  3717. * These are meant only to allow
  3718. * mocha.js to run untouched, not
  3719. * to allow running node code in
  3720. * the browser.
  3721. */
  3722. process = {};
  3723. process.exit = function(status){};
  3724. process.stdout = {};
  3725. global = window;
  3726. /**
  3727. * next tick implementation.
  3728. */
  3729. process.nextTick = (function(){
  3730. // postMessage behaves badly on IE8
  3731. if (window.ActiveXObject || !window.postMessage) {
  3732. return function(fn){ fn() };
  3733. }
  3734. // based on setZeroTimeout by David Baron
  3735. // - http://dbaron.org/log/20100309-faster-timeouts
  3736. var timeouts = []
  3737. , name = 'mocha-zero-timeout'
  3738. window.addEventListener('message', function(e){
  3739. if (e.source == window && e.data == name) {
  3740. if (e.stopPropagation) e.stopPropagation();
  3741. if (timeouts.length) timeouts.shift()();
  3742. }
  3743. }, true);
  3744. return function(fn){
  3745. timeouts.push(fn);
  3746. window.postMessage(name, '*');
  3747. }
  3748. })();
  3749. /**
  3750. * Remove uncaughtException listener.
  3751. */
  3752. process.removeListener = function(e){
  3753. if ('uncaughtException' == e) {
  3754. window.onerror = null;
  3755. }
  3756. };
  3757. /**
  3758. * Implements uncaughtException listener.
  3759. */
  3760. process.on = function(e, fn){
  3761. if ('uncaughtException' == e) {
  3762. window.onerror = fn;
  3763. }
  3764. };
  3765. // boot
  3766. ;(function(){
  3767. /**
  3768. * Expose mocha.
  3769. */
  3770. var Mocha = window.Mocha = require('mocha'),
  3771. mocha = window.mocha = new Mocha({ reporter: 'html' });
  3772. /**
  3773. * Override ui to ensure that the ui functions are initialized.
  3774. * Normally this would happen in Mocha.prototype.loadFiles.
  3775. */
  3776. mocha.ui = function(ui){
  3777. Mocha.prototype.ui.call(this, ui);
  3778. this.suite.emit('pre-require', window, null, this);
  3779. return this;
  3780. };
  3781. /**
  3782. * Setup mocha with the given setting options.
  3783. */
  3784. mocha.setup = function(opts){
  3785. if ('string' == typeof opts) opts = { ui: opts };
  3786. for (var opt in opts) this[opt](opts[opt]);
  3787. return this;
  3788. };
  3789. /**
  3790. * Run mocha, returning the Runner.
  3791. */
  3792. mocha.run = function(fn){
  3793. var options = mocha.options;
  3794. mocha.globals('location');
  3795. var query = Mocha.utils.parseQuery(window.location.search || '');
  3796. if (query.grep) mocha.grep(query.grep);
  3797. return Mocha.prototype.run.call(mocha, function(){
  3798. Mocha.utils.highlightTags('code');
  3799. if (fn) fn();
  3800. });
  3801. };
  3802. })();
  3803. })();