konacha 0.10.0 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Konacha::Server, :type => :request do
4
- def app
5
- Konacha.application
6
- end
7
-
8
4
  before do
9
5
  Konacha.mode = :server
10
6
  end
@@ -19,3 +19,16 @@ Capybara.configure do |config|
19
19
  config.default_driver = :selenium_with_firebug
20
20
  config.app = Konacha.application
21
21
  end
22
+
23
+ module Konacha
24
+ module RequestSpec
25
+ def app
26
+ # Override the RSpec default of `Rails.application`.
27
+ Konacha.application
28
+ end
29
+ end
30
+ end
31
+
32
+ RSpec.configure do |config|
33
+ config.include Konacha::RequestSpec, :type => :request
34
+ end
@@ -1,12 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "konacha/specs/specs" do
4
- it "sets up the specified interface" do
5
- Konacha.should_receive(:interface).any_number_of_times { :tdd }
6
- render
7
- rendered.should include('mocha.setup("tdd")')
8
- end
9
-
10
4
  it "includes konacha JS for given mode" do
11
5
  Konacha.should_receive(:mode).any_number_of_times { :runner }
12
6
  render
@@ -140,7 +140,7 @@ function Assertion (obj, msg, stack) {
140
140
  Assertion.includeStack = false;
141
141
 
142
142
  /*!
143
- * # .assert(expression, message, negateMessage)
143
+ * # .assert(expression, message, negateMessage, expected, actual)
144
144
  *
145
145
  * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
146
146
  *
@@ -148,21 +148,21 @@ Assertion.includeStack = false;
148
148
  * @param {Philosophical} expression to be tested
149
149
  * @param {String} message to display if fails
150
150
  * @param {String} negatedMessage to display if negated expression fails
151
+ * @param {*} expected value (remember to check for negation)
152
+ * @param {*} actual (optional) will default to `this.obj`
151
153
  * @api private
152
154
  */
153
155
 
154
156
  Assertion.prototype.assert = function (expr, msg, negateMsg, expected, actual) {
155
157
  actual = actual || this.obj;
156
158
  var msg = (this.negate ? negateMsg : msg)
157
- , ok = this.negate ? !expr : expr
158
- , act = this.negate ? expected : actual
159
- , exp = this.negate ? actual : expected;
159
+ , ok = this.negate ? !expr : expr;
160
160
 
161
161
  if (!ok) {
162
162
  throw new AssertionError({
163
163
  message: this.msg ? this.msg + ': ' + msg : msg // include custom message if available
164
- , actual: act
165
- , expected: exp
164
+ , actual: actual
165
+ , expected: expected
166
166
  , stackStartFunction: (Assertion.includeStack) ? this.assert : this.ssfi
167
167
  });
168
168
  }
@@ -442,10 +442,16 @@ Object.defineProperty(Assertion.prototype, 'exist',
442
442
 
443
443
  Object.defineProperty(Assertion.prototype, 'empty',
444
444
  { get: function () {
445
- new Assertion(this.obj).to.have.property('length');
445
+ var expected = this.obj;
446
+
447
+ if (Array.isArray(this.obj)) {
448
+ expected = this.obj.length;
449
+ } else if (typeof this.obj === 'object') {
450
+ expected = Object.keys(this.obj).length;
451
+ }
446
452
 
447
453
  this.assert(
448
- 0 === this.obj.length
454
+ !expected
449
455
  , 'expected ' + this.inspect + ' to be empty'
450
456
  , 'expected ' + this.inspect + ' not to be empty');
451
457
 
@@ -891,10 +897,21 @@ Assertion.prototype.keys = function(keys) {
891
897
  /**
892
898
  * # .throw(constructor)
893
899
  *
894
- * Assert that a function will throw a specific type of error.
900
+ * Assert that a function will throw a specific type of error or that error
901
+ * thrown will match a RegExp or include a string.
895
902
  *
896
- * var fn = function () { throw new ReferenceError(''); }
903
+ * var fn = function () { throw new ReferenceError('This is a bad function.'); }
897
904
  * expect(fn).to.throw(ReferenceError);
905
+ * expect(fn).to.throw(/bad function/);
906
+ * expect(fn).to.not.throw('good function');
907
+ * expect(fn).to.throw(ReferenceError, /bad function/);
908
+ *
909
+ * Please note that when a throw expectation is negated, it will check each
910
+ * parameter independently, starting with Error constructor type. The appropriate way
911
+ * to check for the existence of a type of error but for a message that does not match
912
+ * is to use `and`.
913
+ *
914
+ * expect(fn).to.throw(ReferenceError).and.not.throw(/good function/);
898
915
  *
899
916
  * @name throw
900
917
  * @alias throws
@@ -904,25 +921,44 @@ Assertion.prototype.keys = function(keys) {
904
921
  * @api public
905
922
  */
906
923
 
907
- Assertion.prototype.throw = function (constructor) {
924
+ Assertion.prototype.throw = function (constructor, msg) {
908
925
  new Assertion(this.obj).is.a('function');
909
926
 
910
927
  var thrown = false;
911
928
 
929
+ if (arguments.length === 0) {
930
+ msg = null;
931
+ constructor = null;
932
+ } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
933
+ msg = constructor;
934
+ constructor = null;
935
+ }
936
+
912
937
  try {
913
938
  this.obj();
914
939
  } catch (err) {
915
- if (constructor && 'function' === typeof constructor && constructor.constructor != RegExp) {
940
+ // first, check constructor
941
+ if (constructor && 'function' === typeof constructor) {
916
942
  this.assert(
917
943
  err instanceof constructor && err.name == constructor.name
918
944
  , 'expected ' + this.inspect + ' to throw ' + constructor.name + ' but a ' + err.name + ' was thrown'
919
945
  , 'expected ' + this.inspect + ' to not throw ' + constructor.name );
946
+ if (!msg) return this;
947
+ }
948
+ // next, check message
949
+ if (err.message && msg && msg instanceof RegExp) {
950
+ this.assert(
951
+ msg.exec(err.message)
952
+ , 'expected ' + this.inspect + ' to throw error matching ' + msg + ' but got ' + inspect(err.message)
953
+ , 'expected ' + this.inspect + ' to throw error not matching ' + msg
954
+ );
920
955
  return this;
921
- } else if (constructor && constructor instanceof RegExp) {
956
+ } else if (err.message && msg && 'string' === typeof msg) {
922
957
  this.assert(
923
- constructor.exec(err.message)
924
- , 'expected ' + this.inspect + ' to throw error matching ' + constructor + ' but got ' + inspect(err.message)
925
- , 'expected ' + this.inspect + ' to throw error not matching ' + constructor);
958
+ ~err.message.indexOf(msg)
959
+ , 'expected ' + this.inspect + ' to throw error including ' + inspect(msg) + ' but got ' + inspect(err.message)
960
+ , 'expected ' + this.inspect + ' to throw error not including ' + inspect(msg)
961
+ );
926
962
  return this;
927
963
  } else {
928
964
  thrown = true;
@@ -1043,7 +1079,7 @@ require.register("chai.js", function(module, exports, require){
1043
1079
  var used = [];
1044
1080
  var exports = module.exports = {};
1045
1081
 
1046
- exports.version = '0.4.2';
1082
+ exports.version = '0.5.2';
1047
1083
 
1048
1084
  exports.Assertion = require('./assertion');
1049
1085
  exports.AssertionError = require('./error');
@@ -1151,6 +1187,29 @@ module.exports = function (chai) {
1151
1187
 
1152
1188
  var assert = chai.assert = {};
1153
1189
 
1190
+ /**
1191
+ * # .fail(actual, expect, msg, operator)
1192
+ *
1193
+ * Throw a failure. Node.js compatible.
1194
+ *
1195
+ * @name fail
1196
+ * @param {*} actual value
1197
+ * @param {*} expected value
1198
+ * @param {String} message
1199
+ * @param {String} operator
1200
+ * @api public
1201
+ */
1202
+
1203
+ assert.fail = function (actual, expected, message, operator) {
1204
+ throw new chai.AssertionError({
1205
+ actual: actual
1206
+ , expected: expected
1207
+ , message: message
1208
+ , operator: operator
1209
+ , stackStartFunction: assert.fail
1210
+ });
1211
+ }
1212
+
1154
1213
  /**
1155
1214
  * # .ok(object, [message])
1156
1215
  *
@@ -1375,6 +1434,24 @@ module.exports = function (chai) {
1375
1434
  new Assertion(val, msg).to.equal(undefined);
1376
1435
  };
1377
1436
 
1437
+ /**
1438
+ * # .isDefined(value, [message])
1439
+ *
1440
+ * Assert `value` is not undefined.
1441
+ *
1442
+ * var tea = 'cup of chai';
1443
+ * assert.isDefined(tea, 'no tea defined');
1444
+ *
1445
+ * @name isUndefined
1446
+ * @param {*} value
1447
+ * @param {String} message
1448
+ * @api public
1449
+ */
1450
+
1451
+ assert.isDefined = function (val, msg) {
1452
+ new Assertion(val, msg).to.not.equal(undefined);
1453
+ };
1454
+
1378
1455
  /**
1379
1456
  * # .isFunction(value, [message])
1380
1457
  *
@@ -1660,7 +1737,11 @@ module.exports = function (chai) {
1660
1737
  if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
1661
1738
  throw new Error('Invalid operator "' + operator + '"');
1662
1739
  }
1663
- new Assertion(eval(val + operator + val2), msg).to.be.true;
1740
+ var test = new Assertion(eval(val + operator + val2), msg);
1741
+ test.assert(
1742
+ true === test.obj
1743
+ , 'expected ' + inspect(val) + ' to be ' + operator + ' ' + inspect(val2)
1744
+ , 'expected ' + inspect(val) + ' to not be ' + operator + ' ' + inspect(val2) );
1664
1745
  };
1665
1746
 
1666
1747
  /*!
@@ -1732,8 +1813,8 @@ module.exports = function (chai) {
1732
1813
  new Assertion(val1).to.equal(val2);
1733
1814
  };
1734
1815
 
1735
- should.throw = function (fn, err) {
1736
- new Assertion(fn).to.throw(err);
1816
+ should.throw = function (fn, errt, errs) {
1817
+ new Assertion(fn).to.throw(errt, errs);
1737
1818
  };
1738
1819
 
1739
1820
  should.exist = function (val) {
@@ -1747,8 +1828,8 @@ module.exports = function (chai) {
1747
1828
  new Assertion(val1).to.not.equal(val2);
1748
1829
  };
1749
1830
 
1750
- should.not.throw = function (fn, err) {
1751
- new Assertion(fn).to.not.throw(err);
1831
+ should.not.throw = function (fn, errt, errs) {
1832
+ new Assertion(fn).to.not.throw(errt, errs);
1752
1833
  };
1753
1834
 
1754
1835
  should.not.exist = function (val) {
@@ -854,11 +854,27 @@ require.register("mocha.js", function(module, exports, require){
854
854
  * MIT Licensed
855
855
  */
856
856
 
857
+ /**
858
+ * Module dependencies.
859
+ */
860
+
861
+ var path = require('browser/path');
862
+
863
+ /**
864
+ * Expose `Mocha`.
865
+ */
866
+
867
+ exports = module.exports = Mocha;
868
+
857
869
  /**
858
870
  * Library version.
859
871
  */
860
872
 
861
- exports.version = '0.14.0';
873
+ exports.version = '1.0.0';
874
+
875
+ /**
876
+ * Expose internals.
877
+ */
862
878
 
863
879
  exports.utils = require('./utils');
864
880
  exports.interfaces = require('./interfaces');
@@ -870,6 +886,144 @@ exports.Suite = require('./suite');
870
886
  exports.Hook = require('./hook');
871
887
  exports.Test = require('./test');
872
888
 
889
+ /**
890
+ * Return image `name` path.
891
+ *
892
+ * @param {String} name
893
+ * @return {String}
894
+ * @api private
895
+ */
896
+
897
+ function image(name) {
898
+ return __dirname + '/../images/' + name + '.png';
899
+ }
900
+
901
+ /**
902
+ * Setup mocha with `options`.
903
+ *
904
+ * Options:
905
+ *
906
+ * - `ui` name "bdd", "tdd", "exports" etc
907
+ * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
908
+ * - `globals` array of accepted globals
909
+ * - `timeout` timeout in milliseconds
910
+ * - `ignoreLeaks` ignore global leaks
911
+ *
912
+ * @param {Object} options
913
+ * @api public
914
+ */
915
+
916
+ function Mocha(options) {
917
+ options = options || {};
918
+ this.files = [];
919
+ this.options = options;
920
+ this.suite = new exports.Suite('', new exports.Context);
921
+ this.ui(options.ui);
922
+ this.reporter(options.reporter);
923
+ if (options.timeout) this.suite.timeout(options.timeout);
924
+ }
925
+
926
+ /**
927
+ * Add test `file`.
928
+ *
929
+ * @param {String} file
930
+ * @api public
931
+ */
932
+
933
+ Mocha.prototype.addFile = function(file){
934
+ this.files.push(file);
935
+ return this;
936
+ };
937
+
938
+ /**
939
+ * Set reporter to `name`, defaults to "dot".
940
+ *
941
+ * @param {String} name
942
+ * @api public
943
+ */
944
+
945
+ Mocha.prototype.reporter = function(name){
946
+ name = name || 'dot';
947
+ this._reporter = require('./reporters/' + name);
948
+ if (!this._reporter) throw new Error('invalid reporter "' + name + '"');
949
+ return this;
950
+ };
951
+
952
+ /**
953
+ * Set test UI `name`, defaults to "bdd".
954
+ *
955
+ * @param {String} bdd
956
+ * @api public
957
+ */
958
+
959
+ Mocha.prototype.ui = function(name){
960
+ name = name || 'bdd';
961
+ this._ui = exports.interfaces[name];
962
+ if (!this._ui) throw new Error('invalid interface "' + name + '"');
963
+ this._ui = this._ui(this.suite);
964
+ return this;
965
+ };
966
+
967
+ /**
968
+ * Load registered files.
969
+ *
970
+ * @api private
971
+ */
972
+
973
+ Mocha.prototype.loadFiles = function(){
974
+ var suite = this.suite;
975
+ this.files.forEach(function(file){
976
+ file = path.resolve(file);
977
+ suite.emit('pre-require', global, file);
978
+ suite.emit('require', require(file), file);
979
+ suite.emit('post-require', global, file);
980
+ });
981
+ };
982
+
983
+ /**
984
+ * Enable growl support.
985
+ *
986
+ * @api private
987
+ */
988
+
989
+ Mocha.prototype.growl = function(runner, reporter) {
990
+ var notify = require('growl');
991
+
992
+ runner.on('end', function(){
993
+ var stats = reporter.stats;
994
+ if (stats.failures) {
995
+ var msg = stats.failures + ' of ' + runner.total + ' tests failed';
996
+ notify(msg, { title: 'Failed', image: image('fail') });
997
+ } else {
998
+ notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', {
999
+ title: 'Passed'
1000
+ , image: image('pass')
1001
+ });
1002
+ }
1003
+ });
1004
+ };
1005
+
1006
+ /**
1007
+ * Run tests and invoke `fn()` when complete.
1008
+ *
1009
+ * @param {Function} fn
1010
+ * @return {Runner}
1011
+ * @api public
1012
+ */
1013
+
1014
+ Mocha.prototype.run = function(fn){
1015
+ this.loadFiles();
1016
+ var suite = this.suite;
1017
+ var options = this.options;
1018
+ var runner = new exports.Runner(suite);
1019
+ var reporter = new this._reporter(runner);
1020
+ runner.ignoreLeaks = options.ignoreLeaks;
1021
+ if (options.grep) runner.grep(options.grep);
1022
+ if (options.globals) runner.globals(options.globals);
1023
+ if (options.growl) this.growl(runner, reporter);
1024
+ return runner.run(fn);
1025
+ };
1026
+
873
1027
  }); // module: mocha.js
874
1028
 
875
1029
  require.register("reporters/base.js", function(module, exports, require){
@@ -1047,7 +1201,7 @@ exports.list = function(failures){
1047
1201
  }
1048
1202
 
1049
1203
  // indent stack trace without msg
1050
- stack = stack.slice(index + 1)
1204
+ stack = stack.slice(index ? index + 1 : index)
1051
1205
  .replace(/^/gm, ' ');
1052
1206
 
1053
1207
  console.error(fmt, (i + 1), test.fullTitle(), msg, stack);
@@ -1488,12 +1642,22 @@ function HTML(runner) {
1488
1642
  var el = fragment('<div class="test pass pending"><h2>%e</h2></div>', test.title);
1489
1643
  } else {
1490
1644
  var el = fragment('<div class="test fail"><h2>%e</h2></div>', test.title);
1491
- var str = test.err.stack || test.err;
1645
+ var str = test.err.stack || test.err.toString();
1646
+
1647
+ // FF / Opera do not add the message
1648
+ if (!~str.indexOf(test.err.message)) {
1649
+ str = test.err.message + '\n' + str;
1650
+ }
1492
1651
 
1493
1652
  // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
1494
1653
  // check for the result of the stringifying.
1495
1654
  if ('[object Error]' == str) str = test.err.message;
1496
1655
 
1656
+ // Safari doesn't give you a stack. Let's at least provide a source line.
1657
+ if (!test.err.stack && test.err.sourceURL && test.err.line !== undefined) {
1658
+ str += "\n(" + test.err.sourceURL + ":" + test.err.line + ")";
1659
+ }
1660
+
1497
1661
  el.appendChild(fragment('<pre class="error">%e</pre>', str));
1498
1662
  }
1499
1663
 
@@ -1600,6 +1764,7 @@ exports.TAP = require('./tap');
1600
1764
  exports.JSON = require('./json');
1601
1765
  exports.HTML = require('./html');
1602
1766
  exports.List = require('./list');
1767
+ exports.Min = require('./min');
1603
1768
  exports.Spec = require('./spec');
1604
1769
  exports.Progress = require('./progress');
1605
1770
  exports.Landing = require('./landing');
@@ -1607,6 +1772,7 @@ exports.JSONCov = require('./json-cov');
1607
1772
  exports.HTMLCov = require('./html-cov');
1608
1773
  exports.JSONStream = require('./json-stream');
1609
1774
  exports.XUnit = require('./xunit')
1775
+ exports.Teamcity = require('./teamcity')
1610
1776
 
1611
1777
  }); // module: reporters/index.js
1612
1778
 
@@ -2072,6 +2238,162 @@ List.prototype.constructor = List;
2072
2238
 
2073
2239
  }); // module: reporters/list.js
2074
2240
 
2241
+ require.register("reporters/markdown.js", function(module, exports, require){
2242
+
2243
+ /**
2244
+ * Module dependencies.
2245
+ */
2246
+
2247
+ var Base = require('./base')
2248
+ , utils = require('../utils');
2249
+
2250
+ /**
2251
+ * Expose `Markdown`.
2252
+ */
2253
+
2254
+ exports = module.exports = Markdown;
2255
+
2256
+ /**
2257
+ * Initialize a new `Markdown` reporter.
2258
+ *
2259
+ * @param {Runner} runner
2260
+ * @api public
2261
+ */
2262
+
2263
+ function Markdown(runner) {
2264
+ Base.call(this, runner);
2265
+
2266
+ var self = this
2267
+ , stats = this.stats
2268
+ , total = runner.total
2269
+ , level = 0
2270
+ , buf = '';
2271
+
2272
+ function title(str) {
2273
+ return Array(level).join('#') + ' ' + str;
2274
+ }
2275
+
2276
+ function indent() {
2277
+ return Array(level).join(' ');
2278
+ }
2279
+
2280
+ function mapTOC(suite, obj) {
2281
+ var ret = obj;
2282
+ obj = obj[suite.title] = obj[suite.title] || { suite: suite };
2283
+ suite.suites.forEach(function(suite){
2284
+ mapTOC(suite, obj);
2285
+ });
2286
+ return ret;
2287
+ }
2288
+
2289
+ function stringifyTOC(obj, level) {
2290
+ ++level;
2291
+ var buf = '';
2292
+ var link;
2293
+ for (var key in obj) {
2294
+ if ('suite' == key) continue;
2295
+ if (key) link = ' - [' + key + '](#' + utils.slug(obj[key].suite.fullTitle()) + ')\n';
2296
+ if (key) buf += Array(level).join(' ') + link;
2297
+ buf += stringifyTOC(obj[key], level);
2298
+ }
2299
+ --level;
2300
+ return buf;
2301
+ }
2302
+
2303
+ function generateTOC(suite) {
2304
+ var obj = mapTOC(suite, {});
2305
+ return stringifyTOC(obj, 0);
2306
+ }
2307
+
2308
+ generateTOC(runner.suite);
2309
+
2310
+ runner.on('suite', function(suite){
2311
+ ++level;
2312
+ var slug = utils.slug(suite.fullTitle());
2313
+ buf += '<a name="' + slug + '" />' + '\n';
2314
+ buf += title(suite.title) + '\n';
2315
+ });
2316
+
2317
+ runner.on('suite end', function(suite){
2318
+ --level;
2319
+ });
2320
+
2321
+ runner.on('pass', function(test){
2322
+ var code = clean(test.fn.toString());
2323
+ buf += test.title + '.\n';
2324
+ buf += '\n```js';
2325
+ buf += code + '\n';
2326
+ buf += '```\n\n';
2327
+ });
2328
+
2329
+ runner.on('end', function(){
2330
+ process.stdout.write('# TOC\n');
2331
+ process.stdout.write(generateTOC(runner.suite));
2332
+ process.stdout.write(buf);
2333
+ });
2334
+ }
2335
+
2336
+ /**
2337
+ * Strip the function definition from `str`,
2338
+ * and re-indent for pre whitespace.
2339
+ */
2340
+
2341
+ function clean(str) {
2342
+ str = str
2343
+ .replace(/^function *\(.*\) *{/, '')
2344
+ .replace(/\s+\}$/, '');
2345
+
2346
+ var spaces = str.match(/^\n?( *)/)[1].length
2347
+ , re = new RegExp('^ {' + spaces + '}', 'gm');
2348
+
2349
+ str = str.replace(re, '');
2350
+
2351
+ return str;
2352
+ }
2353
+ }); // module: reporters/markdown.js
2354
+
2355
+ require.register("reporters/min.js", function(module, exports, require){
2356
+ /**
2357
+ * Module dependencies.
2358
+ */
2359
+
2360
+ var Base = require('./base');
2361
+
2362
+ /**
2363
+ * Expose `Min`.
2364
+ */
2365
+
2366
+ exports = module.exports = Min;
2367
+
2368
+ /**
2369
+ * Initialize a new `Min` minimal test reporter (best used with --watch).
2370
+ *
2371
+ * @param {Runner} runner
2372
+ * @api public
2373
+ */
2374
+
2375
+ function Min(runner) {
2376
+ Base.call(this, runner);
2377
+
2378
+ runner.on('start', function(){
2379
+ // clear screen
2380
+ process.stdout.write('\033[2J');
2381
+ // set cursor position
2382
+ process.stdout.write('\033[1;3H');
2383
+ });
2384
+
2385
+ runner.on('end', this.epilogue.bind(this));
2386
+ }
2387
+
2388
+ /**
2389
+ * Inherit from `Base.prototype`.
2390
+ */
2391
+
2392
+ Min.prototype = new Base;
2393
+ Min.prototype.constructor = Min;
2394
+
2395
+ }); // module: reporters/min.js
2396
+
2075
2397
  require.register("reporters/progress.js", function(module, exports, require){
2076
2398
 
2077
2399
  /**
@@ -3579,6 +3901,20 @@ exports.files = function(dir, ret){
3579
3901
 
3580
3902
  return ret;
3581
3903
  };
3904
+
3905
+ /**
3906
+ * Compute a slug from the given `str`.
3907
+ *
3908
+ * @param {String} str
3909
+ * @return {String}
3910
+ */
3911
+
3912
+ exports.slug = function(str){
3913
+ return str
3914
+ .toLowerCase()
3915
+ .replace(/ +/g, '-')
3916
+ .replace(/[^-\w]/g, '');
3917
+ };
3582
3918
  }); // module: utils.js
3583
3919
 
3584
3920
  /**
@@ -3652,6 +3988,7 @@ window.mocha = require('mocha');
3652
3988
  ;(function(){
3653
3989
  var suite = new mocha.Suite('', new mocha.Context)
3654
3990
  , utils = mocha.utils
3991
+ , options = {}
3655
3992
 
3656
3993
  /**
3657
3994
  * Highlight the given string of `js`.
@@ -3696,12 +4033,16 @@ window.mocha = require('mocha');
3696
4033
  }
3697
4034
 
3698
4035
  /**
3699
- * Setup mocha with the give `ui` name.
4036
+ * Setup mocha with the given setting options.
3700
4037
  */
3701
4038
 
3702
- mocha.setup = function(ui){
3703
- ui = mocha.interfaces[ui];
4039
+ mocha.setup = function(opts){
4040
+ if ('string' === typeof opts) options.ui = opts;
4041
+ else options = opts;
4042
+
4043
+ ui = mocha.interfaces[options.ui];
3704
4044
  if (!ui) throw new Error('invalid mocha interface "' + ui + '"');
4045
+ if (options.timeout) suite.timeout(options.timeout);
3705
4046
  ui(suite);
3706
4047
  suite.emit('pre-require', window);
3707
4048
  };
@@ -3710,13 +4051,16 @@ window.mocha = require('mocha');
3710
4051
  * Run mocha, returning the Runner.
3711
4052
  */
3712
4053
 
3713
- mocha.run = function(Reporter){
4054
+ mocha.run = function(){
3714
4055
  suite.emit('run');
3715
4056
  var runner = new mocha.Runner(suite);
3716
- Reporter = Reporter || mocha.reporters.HTML;
4057
+ var Reporter = options.reporter || mocha.reporters.HTML;
3717
4058
  var reporter = new Reporter(runner);
3718
4059
  var query = parse(window.location.search || "");
3719
4060
  if (query.grep) runner.grep(new RegExp(query.grep));
4061
+ if (options.ignoreLeaks) runner.ignoreLeaks = true;
4062
+ if (options.globals) runner.globals(options.globals);
4063
+ runner.globals(['location']);
3720
4064
  runner.on('end', highlightCode);
3721
4065
  return runner.run();
3722
4066
  };