teaspoon 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/MIT.LICENSE +1 -1
  3. data/README.md +46 -377
  4. data/app/assets/javascripts/teaspoon-jasmine.js +200 -194
  5. data/app/assets/javascripts/teaspoon-mocha.js +183 -185
  6. data/app/assets/javascripts/teaspoon-qunit.js +201 -193
  7. data/app/assets/javascripts/teaspoon-teaspoon.js +10 -10
  8. data/app/assets/javascripts/teaspoon/base/fixture.coffee +0 -1
  9. data/app/assets/javascripts/teaspoon/base/hook.coffee +7 -6
  10. data/app/assets/javascripts/teaspoon/qunit.coffee +10 -0
  11. data/app/controllers/teaspoon/suite_controller.rb +3 -4
  12. data/app/views/teaspoon/suite/_boot.html.erb +1 -1
  13. data/app/views/teaspoon/suite/_boot_require_js.html.erb +1 -0
  14. data/bin/teaspoon +1 -1
  15. data/config/routes.rb +4 -14
  16. data/lib/generators/teaspoon/install/install_generator.rb +22 -11
  17. data/lib/generators/teaspoon/install/templates/jasmine/{env_comments.rb → env_comments.rb.tt} +10 -5
  18. data/lib/generators/teaspoon/install/templates/jasmine/spec_helper.coffee +5 -5
  19. data/lib/generators/teaspoon/install/templates/jasmine/spec_helper.js +5 -5
  20. data/lib/generators/teaspoon/install/templates/mocha/{env_comments.rb → env_comments.rb.tt} +10 -5
  21. data/lib/generators/teaspoon/install/templates/mocha/spec_helper.coffee +6 -5
  22. data/lib/generators/teaspoon/install/templates/mocha/spec_helper.js +6 -5
  23. data/lib/generators/teaspoon/install/templates/qunit/{env_comments.rb → env_comments.rb.tt} +10 -5
  24. data/lib/generators/teaspoon/install/templates/qunit/test_helper.coffee +5 -5
  25. data/lib/generators/teaspoon/install/templates/qunit/test_helper.js +5 -5
  26. data/lib/tasks/teaspoon.rake +1 -1
  27. data/lib/teaspoon/command_line.rb +37 -40
  28. data/lib/teaspoon/configuration.rb +27 -30
  29. data/lib/teaspoon/configuration.rb.orig +187 -0
  30. data/lib/teaspoon/console.rb +31 -17
  31. data/lib/teaspoon/coverage.rb +2 -3
  32. data/lib/teaspoon/deprecated.rb +13 -8
  33. data/lib/teaspoon/drivers/base.rb +2 -2
  34. data/lib/teaspoon/drivers/capybara_webkit_driver.rb +33 -0
  35. data/lib/teaspoon/drivers/phantomjs/runner.js +2 -2
  36. data/lib/teaspoon/drivers/phantomjs_driver.rb +13 -4
  37. data/lib/teaspoon/drivers/selenium_driver.rb +3 -5
  38. data/lib/teaspoon/engine.rb +33 -5
  39. data/lib/teaspoon/environment.rb +2 -4
  40. data/lib/teaspoon/exceptions.rb +8 -5
  41. data/lib/teaspoon/formatters/base.rb +39 -27
  42. data/lib/teaspoon/formatters/clean_formatter.rb +0 -1
  43. data/lib/teaspoon/formatters/description.rb +36 -0
  44. data/lib/teaspoon/formatters/documentation_formatter.rb +2 -2
  45. data/lib/teaspoon/formatters/json_formatter.rb +1 -2
  46. data/lib/teaspoon/formatters/junit_formatter.rb +20 -20
  47. data/lib/teaspoon/formatters/modules/report_module.rb +4 -4
  48. data/lib/teaspoon/formatters/pride_formatter.rb +0 -1
  49. data/lib/teaspoon/formatters/rspec_html_formatter.rb +463 -0
  50. data/lib/teaspoon/formatters/snowday_formatter.rb +0 -1
  51. data/lib/teaspoon/formatters/swayze_or_oprah_formatter.rb +5 -4
  52. data/lib/teaspoon/formatters/tap_formatter.rb +2 -3
  53. data/lib/teaspoon/formatters/tap_y_formatter.rb +20 -21
  54. data/lib/teaspoon/formatters/teamcity_formatter.rb +4 -5
  55. data/lib/teaspoon/instrumentation.rb +7 -7
  56. data/lib/teaspoon/result.rb +1 -3
  57. data/lib/teaspoon/runner.rb +1 -2
  58. data/lib/teaspoon/server.rb +2 -1
  59. data/lib/teaspoon/suite.rb +20 -17
  60. data/lib/teaspoon/utility.rb +1 -3
  61. data/lib/teaspoon/version.rb +1 -1
  62. data/spec/dummy/config/application.rb +14 -18
  63. data/spec/dummy/config/boot.rb +2 -6
  64. data/spec/dummy/config/environment.rb +3 -3
  65. data/spec/dummy/config/environments/development.rb +27 -13
  66. data/spec/dummy/config/environments/production.rb +79 -0
  67. data/spec/dummy/config/environments/test.rb +26 -13
  68. data/spec/dummy/config/routes.rb +1 -1
  69. data/spec/dummy/config/secrets.yml +22 -0
  70. data/spec/features/console_reporter_spec.rb +3 -8
  71. data/spec/features/hooks_spec.rb +17 -4
  72. data/spec/features/html_reporter_spec.rb +12 -1
  73. data/spec/features/install_generator_spec.rb +2 -3
  74. data/spec/features/instrumentation_spec.rb +11 -11
  75. data/spec/javascripts/teaspoon/base/teaspoon_spec.coffee +14 -1
  76. data/spec/spec_helper.rb +7 -4
  77. data/spec/teaspoon/command_line_spec.rb +19 -28
  78. data/spec/teaspoon/configuration_spec.rb +22 -14
  79. data/spec/teaspoon/console_spec.rb +79 -63
  80. data/spec/teaspoon/coverage_spec.rb +23 -23
  81. data/spec/teaspoon/drivers/capybara_webkit_driver_spec.rb +39 -0
  82. data/spec/teaspoon/drivers/phantomjs_driver_spec.rb +10 -5
  83. data/spec/teaspoon/drivers/selenium_driver_spec.rb +10 -10
  84. data/spec/teaspoon/environment_spec.rb +28 -20
  85. data/spec/teaspoon/exceptions_spec.rb +4 -4
  86. data/spec/teaspoon/exporter_spec.rb +28 -28
  87. data/spec/teaspoon/formatters/base_spec.rb +29 -29
  88. data/spec/teaspoon/formatters/clean_formatter_spec.rb +1 -1
  89. data/spec/teaspoon/formatters/documentation_formatter_spec.rb +1 -1
  90. data/spec/teaspoon/formatters/dot_formatter_spec.rb +1 -1
  91. data/spec/teaspoon/formatters/json_formatter_spec.rb +7 -7
  92. data/spec/teaspoon/formatters/junit_formatter_spec.rb +10 -10
  93. data/spec/teaspoon/formatters/pride_formatter_spec.rb +1 -1
  94. data/spec/teaspoon/formatters/rspec_html_formatter_spec.rb +107 -0
  95. data/spec/teaspoon/formatters/snowday_formatter_spec.rb +1 -1
  96. data/spec/teaspoon/formatters/tap_formatter_spec.rb +1 -1
  97. data/spec/teaspoon/formatters/tap_y_formatter_spec.rb +1 -1
  98. data/spec/teaspoon/formatters/teamcity_formatter_spec.rb +27 -27
  99. data/spec/teaspoon/instrumentation_spec.rb +35 -29
  100. data/spec/teaspoon/result_spec.rb +40 -36
  101. data/spec/teaspoon/runner_spec.rb +23 -20
  102. data/spec/teaspoon/server_spec.rb +19 -16
  103. data/spec/teaspoon/suite_spec.rb +23 -9
  104. data/spec/teaspoon_env.rb +7 -12
  105. data/test/javascripts/teaspoon/qunit/models_test.coffee +6 -2
  106. data/vendor/assets/javascripts/support/chai-1.10.0.js +4800 -0
  107. data/vendor/assets/javascripts/support/chai-jq-0.0.7.js +524 -0
  108. data/vendor/assets/javascripts/support/chai.js +4435 -4349
  109. metadata +57 -54
  110. data/app/assets/javascripts/teaspoon-angular.js +0 -1299
  111. data/app/assets/javascripts/teaspoon/angular.coffee +0 -55
  112. data/app/assets/javascripts/teaspoon/angular/reporters/console.coffee +0 -11
  113. data/app/assets/javascripts/teaspoon/angular/reporters/html.coffee +0 -21
  114. data/spec/javascripts/angular_helper.coffee +0 -5
  115. data/spec/javascripts/teaspoon/angular/models_aspec.coffee +0 -95
  116. data/spec/javascripts/teaspoon/angular/reporters/html_aspec.coffee +0 -9
  117. data/vendor/assets/javascripts/angular/1.0.5.js +0 -26195
  118. data/vendor/assets/javascripts/angular/MIT-LICENSE +0 -22
@@ -0,0 +1,4800 @@
1
+
2
+ ;(function(){
3
+
4
+ /**
5
+ * Require the module at `name`.
6
+ *
7
+ * @param {String} name
8
+ * @return {Object} exports
9
+ * @api public
10
+ */
11
+
12
+ function require(name) {
13
+ var module = require.modules[name];
14
+ if (!module) throw new Error('failed to require "' + name + '"');
15
+
16
+ if (!('exports' in module) && typeof module.definition === 'function') {
17
+ module.client = module.component = true;
18
+ module.definition.call(this, module.exports = {}, module);
19
+ delete module.definition;
20
+ }
21
+
22
+ return module.exports;
23
+ }
24
+
25
+ /**
26
+ * Meta info, accessible in the global scope unless you use AMD option.
27
+ */
28
+
29
+ require.loader = 'component';
30
+
31
+ /**
32
+ * Internal helper object, contains a sorting function for semantiv versioning
33
+ */
34
+ require.helper = {};
35
+ require.helper.semVerSort = function(a, b) {
36
+ var aArray = a.version.split('.');
37
+ var bArray = b.version.split('.');
38
+ for (var i=0; i<aArray.length; ++i) {
39
+ var aInt = parseInt(aArray[i], 10);
40
+ var bInt = parseInt(bArray[i], 10);
41
+ if (aInt === bInt) {
42
+ var aLex = aArray[i].substr((""+aInt).length);
43
+ var bLex = bArray[i].substr((""+bInt).length);
44
+ if (aLex === '' && bLex !== '') return 1;
45
+ if (aLex !== '' && bLex === '') return -1;
46
+ if (aLex !== '' && bLex !== '') return aLex > bLex ? 1 : -1;
47
+ continue;
48
+ } else if (aInt > bInt) {
49
+ return 1;
50
+ } else {
51
+ return -1;
52
+ }
53
+ }
54
+ return 0;
55
+ }
56
+
57
+ /**
58
+ * Find and require a module which name starts with the provided name.
59
+ * If multiple modules exists, the highest semver is used.
60
+ * This function can only be used for remote dependencies.
61
+
62
+ * @param {String} name - module name: `user~repo`
63
+ * @param {Boolean} returnPath - returns the canonical require path if true,
64
+ * otherwise it returns the epxorted module
65
+ */
66
+ require.latest = function (name, returnPath) {
67
+ function showError(name) {
68
+ throw new Error('failed to find latest module of "' + name + '"');
69
+ }
70
+ // only remotes with semvers, ignore local files conataining a '/'
71
+ var versionRegexp = /(.*)~(.*)@v?(\d+\.\d+\.\d+[^\/]*)$/;
72
+ var remoteRegexp = /(.*)~(.*)/;
73
+ if (!remoteRegexp.test(name)) showError(name);
74
+ var moduleNames = Object.keys(require.modules);
75
+ var semVerCandidates = [];
76
+ var otherCandidates = []; // for instance: name of the git branch
77
+ for (var i=0; i<moduleNames.length; i++) {
78
+ var moduleName = moduleNames[i];
79
+ if (new RegExp(name + '@').test(moduleName)) {
80
+ var version = moduleName.substr(name.length+1);
81
+ var semVerMatch = versionRegexp.exec(moduleName);
82
+ if (semVerMatch != null) {
83
+ semVerCandidates.push({version: version, name: moduleName});
84
+ } else {
85
+ otherCandidates.push({version: version, name: moduleName});
86
+ }
87
+ }
88
+ }
89
+ if (semVerCandidates.concat(otherCandidates).length === 0) {
90
+ showError(name);
91
+ }
92
+ if (semVerCandidates.length > 0) {
93
+ var module = semVerCandidates.sort(require.helper.semVerSort).pop().name;
94
+ if (returnPath === true) {
95
+ return module;
96
+ }
97
+ return require(module);
98
+ }
99
+ // if the build contains more than one branch of the same module
100
+ // you should not use this funciton
101
+ var module = otherCandidates.pop().name;
102
+ if (returnPath === true) {
103
+ return module;
104
+ }
105
+ return require(module);
106
+ }
107
+
108
+ /**
109
+ * Registered modules.
110
+ */
111
+
112
+ require.modules = {};
113
+
114
+ /**
115
+ * Register module at `name` with callback `definition`.
116
+ *
117
+ * @param {String} name
118
+ * @param {Function} definition
119
+ * @api private
120
+ */
121
+
122
+ require.register = function (name, definition) {
123
+ require.modules[name] = {
124
+ definition: definition
125
+ };
126
+ };
127
+
128
+ /**
129
+ * Define a module's exports immediately with `exports`.
130
+ *
131
+ * @param {String} name
132
+ * @param {Generic} exports
133
+ * @api private
134
+ */
135
+
136
+ require.define = function (name, exports) {
137
+ require.modules[name] = {
138
+ exports: exports
139
+ };
140
+ };
141
+ require.register("chaijs~assertion-error@1.0.0", function (exports, module) {
142
+ /*!
143
+ * assertion-error
144
+ * Copyright(c) 2013 Jake Luer <jake@qualiancy.com>
145
+ * MIT Licensed
146
+ */
147
+
148
+ /*!
149
+ * Return a function that will copy properties from
150
+ * one object to another excluding any originally
151
+ * listed. Returned function will create a new `{}`.
152
+ *
153
+ * @param {String} excluded properties ...
154
+ * @return {Function}
155
+ */
156
+
157
+ function exclude () {
158
+ var excludes = [].slice.call(arguments);
159
+
160
+ function excludeProps (res, obj) {
161
+ Object.keys(obj).forEach(function (key) {
162
+ if (!~excludes.indexOf(key)) res[key] = obj[key];
163
+ });
164
+ }
165
+
166
+ return function extendExclude () {
167
+ var args = [].slice.call(arguments)
168
+ , i = 0
169
+ , res = {};
170
+
171
+ for (; i < args.length; i++) {
172
+ excludeProps(res, args[i]);
173
+ }
174
+
175
+ return res;
176
+ };
177
+ };
178
+
179
+ /*!
180
+ * Primary Exports
181
+ */
182
+
183
+ module.exports = AssertionError;
184
+
185
+ /**
186
+ * ### AssertionError
187
+ *
188
+ * An extension of the JavaScript `Error` constructor for
189
+ * assertion and validation scenarios.
190
+ *
191
+ * @param {String} message
192
+ * @param {Object} properties to include (optional)
193
+ * @param {callee} start stack function (optional)
194
+ */
195
+
196
+ function AssertionError (message, _props, ssf) {
197
+ var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON')
198
+ , props = extend(_props || {});
199
+
200
+ // default values
201
+ this.message = message || 'Unspecified AssertionError';
202
+ this.showDiff = false;
203
+
204
+ // copy from properties
205
+ for (var key in props) {
206
+ this[key] = props[key];
207
+ }
208
+
209
+ // capture stack trace
210
+ ssf = ssf || arguments.callee;
211
+ if (ssf && Error.captureStackTrace) {
212
+ Error.captureStackTrace(this, ssf);
213
+ }
214
+ }
215
+
216
+ /*!
217
+ * Inherit from Error.prototype
218
+ */
219
+
220
+ AssertionError.prototype = Object.create(Error.prototype);
221
+
222
+ /*!
223
+ * Statically set name
224
+ */
225
+
226
+ AssertionError.prototype.name = 'AssertionError';
227
+
228
+ /*!
229
+ * Ensure correct constructor
230
+ */
231
+
232
+ AssertionError.prototype.constructor = AssertionError;
233
+
234
+ /**
235
+ * Allow errors to be converted to JSON for static transfer.
236
+ *
237
+ * @param {Boolean} include stack (default: `true`)
238
+ * @return {Object} object that can be `JSON.stringify`
239
+ */
240
+
241
+ AssertionError.prototype.toJSON = function (stack) {
242
+ var extend = exclude('constructor', 'toJSON', 'stack')
243
+ , props = extend({ name: this.name }, this);
244
+
245
+ // include stack if exists and not turned off
246
+ if (false !== stack && this.stack) {
247
+ props.stack = this.stack;
248
+ }
249
+
250
+ return props;
251
+ };
252
+
253
+ });
254
+
255
+ require.register("chaijs~type-detect@0.1.1", function (exports, module) {
256
+ /*!
257
+ * type-detect
258
+ * Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
259
+ * MIT Licensed
260
+ */
261
+
262
+ /*!
263
+ * Primary Exports
264
+ */
265
+
266
+ var exports = module.exports = getType;
267
+
268
+ /*!
269
+ * Detectable javascript natives
270
+ */
271
+
272
+ var natives = {
273
+ '[object Array]': 'array'
274
+ , '[object RegExp]': 'regexp'
275
+ , '[object Function]': 'function'
276
+ , '[object Arguments]': 'arguments'
277
+ , '[object Date]': 'date'
278
+ };
279
+
280
+ /**
281
+ * ### typeOf (obj)
282
+ *
283
+ * Use several different techniques to determine
284
+ * the type of object being tested.
285
+ *
286
+ *
287
+ * @param {Mixed} object
288
+ * @return {String} object type
289
+ * @api public
290
+ */
291
+
292
+ function getType (obj) {
293
+ var str = Object.prototype.toString.call(obj);
294
+ if (natives[str]) return natives[str];
295
+ if (obj === null) return 'null';
296
+ if (obj === undefined) return 'undefined';
297
+ if (obj === Object(obj)) return 'object';
298
+ return typeof obj;
299
+ }
300
+
301
+ exports.Library = Library;
302
+
303
+ /**
304
+ * ### Library
305
+ *
306
+ * Create a repository for custom type detection.
307
+ *
308
+ * ```js
309
+ * var lib = new type.Library;
310
+ * ```
311
+ *
312
+ */
313
+
314
+ function Library () {
315
+ this.tests = {};
316
+ }
317
+
318
+ /**
319
+ * #### .of (obj)
320
+ *
321
+ * Expose replacement `typeof` detection to the library.
322
+ *
323
+ * ```js
324
+ * if ('string' === lib.of('hello world')) {
325
+ * // ...
326
+ * }
327
+ * ```
328
+ *
329
+ * @param {Mixed} object to test
330
+ * @return {String} type
331
+ */
332
+
333
+ Library.prototype.of = getType;
334
+
335
+ /**
336
+ * #### .define (type, test)
337
+ *
338
+ * Add a test to for the `.test()` assertion.
339
+ *
340
+ * Can be defined as a regular expression:
341
+ *
342
+ * ```js
343
+ * lib.define('int', /^[0-9]+$/);
344
+ * ```
345
+ *
346
+ * ... or as a function:
347
+ *
348
+ * ```js
349
+ * lib.define('bln', function (obj) {
350
+ * if ('boolean' === lib.of(obj)) return true;
351
+ * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ];
352
+ * if ('string' === lib.of(obj)) obj = obj.toLowerCase();
353
+ * return !! ~blns.indexOf(obj);
354
+ * });
355
+ * ```
356
+ *
357
+ * @param {String} type
358
+ * @param {RegExp|Function} test
359
+ * @api public
360
+ */
361
+
362
+ Library.prototype.define = function (type, test) {
363
+ if (arguments.length === 1) return this.tests[type];
364
+ this.tests[type] = test;
365
+ return this;
366
+ };
367
+
368
+ /**
369
+ * #### .test (obj, test)
370
+ *
371
+ * Assert that an object is of type. Will first
372
+ * check natives, and if that does not pass it will
373
+ * use the user defined custom tests.
374
+ *
375
+ * ```js
376
+ * assert(lib.test('1', 'int'));
377
+ * assert(lib.test('yes', 'bln'));
378
+ * ```
379
+ *
380
+ * @param {Mixed} object
381
+ * @param {String} type
382
+ * @return {Boolean} result
383
+ * @api public
384
+ */
385
+
386
+ Library.prototype.test = function (obj, type) {
387
+ if (type === getType(obj)) return true;
388
+ var test = this.tests[type];
389
+
390
+ if (test && 'regexp' === getType(test)) {
391
+ return test.test(obj);
392
+ } else if (test && 'function' === getType(test)) {
393
+ return test(obj);
394
+ } else {
395
+ throw new ReferenceError('Type test "' + type + '" not defined or invalid.');
396
+ }
397
+ };
398
+
399
+ });
400
+
401
+ require.register("chaijs~deep-eql@0.1.3", function (exports, module) {
402
+ /*!
403
+ * deep-eql
404
+ * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com>
405
+ * MIT Licensed
406
+ */
407
+
408
+ /*!
409
+ * Module dependencies
410
+ */
411
+
412
+ var type = require('chaijs~type-detect@0.1.1');
413
+
414
+ /*!
415
+ * Buffer.isBuffer browser shim
416
+ */
417
+
418
+ var Buffer;
419
+ try { Buffer = require('buffer').Buffer; }
420
+ catch(ex) {
421
+ Buffer = {};
422
+ Buffer.isBuffer = function() { return false; }
423
+ }
424
+
425
+ /*!
426
+ * Primary Export
427
+ */
428
+
429
+ module.exports = deepEqual;
430
+
431
+ /**
432
+ * Assert super-strict (egal) equality between
433
+ * two objects of any type.
434
+ *
435
+ * @param {Mixed} a
436
+ * @param {Mixed} b
437
+ * @param {Array} memoised (optional)
438
+ * @return {Boolean} equal match
439
+ */
440
+
441
+ function deepEqual(a, b, m) {
442
+ if (sameValue(a, b)) {
443
+ return true;
444
+ } else if ('date' === type(a)) {
445
+ return dateEqual(a, b);
446
+ } else if ('regexp' === type(a)) {
447
+ return regexpEqual(a, b);
448
+ } else if (Buffer.isBuffer(a)) {
449
+ return bufferEqual(a, b);
450
+ } else if ('arguments' === type(a)) {
451
+ return argumentsEqual(a, b, m);
452
+ } else if (!typeEqual(a, b)) {
453
+ return false;
454
+ } else if (('object' !== type(a) && 'object' !== type(b))
455
+ && ('array' !== type(a) && 'array' !== type(b))) {
456
+ return sameValue(a, b);
457
+ } else {
458
+ return objectEqual(a, b, m);
459
+ }
460
+ }
461
+
462
+ /*!
463
+ * Strict (egal) equality test. Ensures that NaN always
464
+ * equals NaN and `-0` does not equal `+0`.
465
+ *
466
+ * @param {Mixed} a
467
+ * @param {Mixed} b
468
+ * @return {Boolean} equal match
469
+ */
470
+
471
+ function sameValue(a, b) {
472
+ if (a === b) return a !== 0 || 1 / a === 1 / b;
473
+ return a !== a && b !== b;
474
+ }
475
+
476
+ /*!
477
+ * Compare the types of two given objects and
478
+ * return if they are equal. Note that an Array
479
+ * has a type of `array` (not `object`) and arguments
480
+ * have a type of `arguments` (not `array`/`object`).
481
+ *
482
+ * @param {Mixed} a
483
+ * @param {Mixed} b
484
+ * @return {Boolean} result
485
+ */
486
+
487
+ function typeEqual(a, b) {
488
+ return type(a) === type(b);
489
+ }
490
+
491
+ /*!
492
+ * Compare two Date objects by asserting that
493
+ * the time values are equal using `saveValue`.
494
+ *
495
+ * @param {Date} a
496
+ * @param {Date} b
497
+ * @return {Boolean} result
498
+ */
499
+
500
+ function dateEqual(a, b) {
501
+ if ('date' !== type(b)) return false;
502
+ return sameValue(a.getTime(), b.getTime());
503
+ }
504
+
505
+ /*!
506
+ * Compare two regular expressions by converting them
507
+ * to string and checking for `sameValue`.
508
+ *
509
+ * @param {RegExp} a
510
+ * @param {RegExp} b
511
+ * @return {Boolean} result
512
+ */
513
+
514
+ function regexpEqual(a, b) {
515
+ if ('regexp' !== type(b)) return false;
516
+ return sameValue(a.toString(), b.toString());
517
+ }
518
+
519
+ /*!
520
+ * Assert deep equality of two `arguments` objects.
521
+ * Unfortunately, these must be sliced to arrays
522
+ * prior to test to ensure no bad behavior.
523
+ *
524
+ * @param {Arguments} a
525
+ * @param {Arguments} b
526
+ * @param {Array} memoize (optional)
527
+ * @return {Boolean} result
528
+ */
529
+
530
+ function argumentsEqual(a, b, m) {
531
+ if ('arguments' !== type(b)) return false;
532
+ a = [].slice.call(a);
533
+ b = [].slice.call(b);
534
+ return deepEqual(a, b, m);
535
+ }
536
+
537
+ /*!
538
+ * Get enumerable properties of a given object.
539
+ *
540
+ * @param {Object} a
541
+ * @return {Array} property names
542
+ */
543
+
544
+ function enumerable(a) {
545
+ var res = [];
546
+ for (var key in a) res.push(key);
547
+ return res;
548
+ }
549
+
550
+ /*!
551
+ * Simple equality for flat iterable objects
552
+ * such as Arrays or Node.js buffers.
553
+ *
554
+ * @param {Iterable} a
555
+ * @param {Iterable} b
556
+ * @return {Boolean} result
557
+ */
558
+
559
+ function iterableEqual(a, b) {
560
+ if (a.length !== b.length) return false;
561
+
562
+ var i = 0;
563
+ var match = true;
564
+
565
+ for (; i < a.length; i++) {
566
+ if (a[i] !== b[i]) {
567
+ match = false;
568
+ break;
569
+ }
570
+ }
571
+
572
+ return match;
573
+ }
574
+
575
+ /*!
576
+ * Extension to `iterableEqual` specifically
577
+ * for Node.js Buffers.
578
+ *
579
+ * @param {Buffer} a
580
+ * @param {Mixed} b
581
+ * @return {Boolean} result
582
+ */
583
+
584
+ function bufferEqual(a, b) {
585
+ if (!Buffer.isBuffer(b)) return false;
586
+ return iterableEqual(a, b);
587
+ }
588
+
589
+ /*!
590
+ * Block for `objectEqual` ensuring non-existing
591
+ * values don't get in.
592
+ *
593
+ * @param {Mixed} object
594
+ * @return {Boolean} result
595
+ */
596
+
597
+ function isValue(a) {
598
+ return a !== null && a !== undefined;
599
+ }
600
+
601
+ /*!
602
+ * Recursively check the equality of two objects.
603
+ * Once basic sameness has been established it will
604
+ * defer to `deepEqual` for each enumerable key
605
+ * in the object.
606
+ *
607
+ * @param {Mixed} a
608
+ * @param {Mixed} b
609
+ * @return {Boolean} result
610
+ */
611
+
612
+ function objectEqual(a, b, m) {
613
+ if (!isValue(a) || !isValue(b)) {
614
+ return false;
615
+ }
616
+
617
+ if (a.prototype !== b.prototype) {
618
+ return false;
619
+ }
620
+
621
+ var i;
622
+ if (m) {
623
+ for (i = 0; i < m.length; i++) {
624
+ if ((m[i][0] === a && m[i][1] === b)
625
+ || (m[i][0] === b && m[i][1] === a)) {
626
+ return true;
627
+ }
628
+ }
629
+ } else {
630
+ m = [];
631
+ }
632
+
633
+ try {
634
+ var ka = enumerable(a);
635
+ var kb = enumerable(b);
636
+ } catch (ex) {
637
+ return false;
638
+ }
639
+
640
+ ka.sort();
641
+ kb.sort();
642
+
643
+ if (!iterableEqual(ka, kb)) {
644
+ return false;
645
+ }
646
+
647
+ m.push([ a, b ]);
648
+
649
+ var key;
650
+ for (i = ka.length - 1; i >= 0; i--) {
651
+ key = ka[i];
652
+ if (!deepEqual(a[key], b[key], m)) {
653
+ return false;
654
+ }
655
+ }
656
+
657
+ return true;
658
+ }
659
+
660
+ });
661
+
662
+ require.register("chai", function (exports, module) {
663
+ module.exports = require('chai/lib/chai.js');
664
+
665
+ });
666
+
667
+ require.register("chai/lib/chai.js", function (exports, module) {
668
+ /*!
669
+ * chai
670
+ * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
671
+ * MIT Licensed
672
+ */
673
+
674
+ var used = []
675
+ , exports = module.exports = {};
676
+
677
+ /*!
678
+ * Chai version
679
+ */
680
+
681
+ exports.version = '1.10.0';
682
+
683
+ /*!
684
+ * Assertion Error
685
+ */
686
+
687
+ exports.AssertionError = require('chaijs~assertion-error@1.0.0');
688
+
689
+ /*!
690
+ * Utils for plugins (not exported)
691
+ */
692
+
693
+ var util = require('chai/lib/chai/utils/index.js');
694
+
695
+ /**
696
+ * # .use(function)
697
+ *
698
+ * Provides a way to extend the internals of Chai
699
+ *
700
+ * @param {Function}
701
+ * @returns {this} for chaining
702
+ * @api public
703
+ */
704
+
705
+ exports.use = function (fn) {
706
+ if (!~used.indexOf(fn)) {
707
+ fn(this, util);
708
+ used.push(fn);
709
+ }
710
+
711
+ return this;
712
+ };
713
+
714
+ /*!
715
+ * Configuration
716
+ */
717
+
718
+ var config = require('chai/lib/chai/config.js');
719
+ exports.config = config;
720
+
721
+ /*!
722
+ * Primary `Assertion` prototype
723
+ */
724
+
725
+ var assertion = require('chai/lib/chai/assertion.js');
726
+ exports.use(assertion);
727
+
728
+ /*!
729
+ * Core Assertions
730
+ */
731
+
732
+ var core = require('chai/lib/chai/core/assertions.js');
733
+ exports.use(core);
734
+
735
+ /*!
736
+ * Expect interface
737
+ */
738
+
739
+ var expect = require('chai/lib/chai/interface/expect.js');
740
+ exports.use(expect);
741
+
742
+ /*!
743
+ * Should interface
744
+ */
745
+
746
+ var should = require('chai/lib/chai/interface/should.js');
747
+ exports.use(should);
748
+
749
+ /*!
750
+ * Assert interface
751
+ */
752
+
753
+ var assert = require('chai/lib/chai/interface/assert.js');
754
+ exports.use(assert);
755
+
756
+ });
757
+
758
+ require.register("chai/lib/chai/assertion.js", function (exports, module) {
759
+ /*!
760
+ * chai
761
+ * http://chaijs.com
762
+ * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
763
+ * MIT Licensed
764
+ */
765
+
766
+ var config = require('chai/lib/chai/config.js');
767
+ var NOOP = function() { };
768
+
769
+ module.exports = function (_chai, util) {
770
+ /*!
771
+ * Module dependencies.
772
+ */
773
+
774
+ var AssertionError = _chai.AssertionError
775
+ , flag = util.flag;
776
+
777
+ /*!
778
+ * Module export.
779
+ */
780
+
781
+ _chai.Assertion = Assertion;
782
+
783
+ /*!
784
+ * Assertion Constructor
785
+ *
786
+ * Creates object for chaining.
787
+ *
788
+ * @api private
789
+ */
790
+
791
+ function Assertion (obj, msg, stack) {
792
+ flag(this, 'ssfi', stack || arguments.callee);
793
+ flag(this, 'object', obj);
794
+ flag(this, 'message', msg);
795
+ }
796
+
797
+ Object.defineProperty(Assertion, 'includeStack', {
798
+ get: function() {
799
+ console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
800
+ return config.includeStack;
801
+ },
802
+ set: function(value) {
803
+ console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.');
804
+ config.includeStack = value;
805
+ }
806
+ });
807
+
808
+ Object.defineProperty(Assertion, 'showDiff', {
809
+ get: function() {
810
+ console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
811
+ return config.showDiff;
812
+ },
813
+ set: function(value) {
814
+ console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.');
815
+ config.showDiff = value;
816
+ }
817
+ });
818
+
819
+ Assertion.addProperty = function (name, fn) {
820
+ util.addProperty(this.prototype, name, fn);
821
+ };
822
+
823
+ Assertion.addMethod = function (name, fn) {
824
+ util.addMethod(this.prototype, name, fn);
825
+ };
826
+
827
+ Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
828
+ util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
829
+ };
830
+
831
+ Assertion.addChainableNoop = function(name, fn) {
832
+ util.addChainableMethod(this.prototype, name, NOOP, fn);
833
+ };
834
+
835
+ Assertion.overwriteProperty = function (name, fn) {
836
+ util.overwriteProperty(this.prototype, name, fn);
837
+ };
838
+
839
+ Assertion.overwriteMethod = function (name, fn) {
840
+ util.overwriteMethod(this.prototype, name, fn);
841
+ };
842
+
843
+ Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {
844
+ util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
845
+ };
846
+
847
+ /*!
848
+ * ### .assert(expression, message, negateMessage, expected, actual)
849
+ *
850
+ * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
851
+ *
852
+ * @name assert
853
+ * @param {Philosophical} expression to be tested
854
+ * @param {String or Function} message or function that returns message to display if fails
855
+ * @param {String or Function} negatedMessage or function that returns negatedMessage to display if negated expression fails
856
+ * @param {Mixed} expected value (remember to check for negation)
857
+ * @param {Mixed} actual (optional) will default to `this.obj`
858
+ * @api private
859
+ */
860
+
861
+ Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) {
862
+ var ok = util.test(this, arguments);
863
+ if (true !== showDiff) showDiff = false;
864
+ if (true !== config.showDiff) showDiff = false;
865
+
866
+ if (!ok) {
867
+ var msg = util.getMessage(this, arguments)
868
+ , actual = util.getActual(this, arguments);
869
+ throw new AssertionError(msg, {
870
+ actual: actual
871
+ , expected: expected
872
+ , showDiff: showDiff
873
+ }, (config.includeStack) ? this.assert : flag(this, 'ssfi'));
874
+ }
875
+ };
876
+
877
+ /*!
878
+ * ### ._obj
879
+ *
880
+ * Quick reference to stored `actual` value for plugin developers.
881
+ *
882
+ * @api private
883
+ */
884
+
885
+ Object.defineProperty(Assertion.prototype, '_obj',
886
+ { get: function () {
887
+ return flag(this, 'object');
888
+ }
889
+ , set: function (val) {
890
+ flag(this, 'object', val);
891
+ }
892
+ });
893
+ };
894
+
895
+ });
896
+
897
+ require.register("chai/lib/chai/config.js", function (exports, module) {
898
+ module.exports = {
899
+
900
+ /**
901
+ * ### config.includeStack
902
+ *
903
+ * User configurable property, influences whether stack trace
904
+ * is included in Assertion error message. Default of false
905
+ * suppresses stack trace in the error message.
906
+ *
907
+ * chai.config.includeStack = true; // enable stack on error
908
+ *
909
+ * @param {Boolean}
910
+ * @api public
911
+ */
912
+
913
+ includeStack: false,
914
+
915
+ /**
916
+ * ### config.showDiff
917
+ *
918
+ * User configurable property, influences whether or not
919
+ * the `showDiff` flag should be included in the thrown
920
+ * AssertionErrors. `false` will always be `false`; `true`
921
+ * will be true when the assertion has requested a diff
922
+ * be shown.
923
+ *
924
+ * @param {Boolean}
925
+ * @api public
926
+ */
927
+
928
+ showDiff: true,
929
+
930
+ /**
931
+ * ### config.truncateThreshold
932
+ *
933
+ * User configurable property, sets length threshold for actual and
934
+ * expected values in assertion errors. If this threshold is exceeded,
935
+ * the value is truncated.
936
+ *
937
+ * Set it to zero if you want to disable truncating altogether.
938
+ *
939
+ * chai.config.truncateThreshold = 0; // disable truncating
940
+ *
941
+ * @param {Number}
942
+ * @api public
943
+ */
944
+
945
+ truncateThreshold: 40
946
+
947
+ };
948
+
949
+ });
950
+
951
+ require.register("chai/lib/chai/core/assertions.js", function (exports, module) {
952
+ /*!
953
+ * chai
954
+ * http://chaijs.com
955
+ * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
956
+ * MIT Licensed
957
+ */
958
+
959
+ module.exports = function (chai, _) {
960
+ var Assertion = chai.Assertion
961
+ , toString = Object.prototype.toString
962
+ , flag = _.flag;
963
+
964
+ /**
965
+ * ### Language Chains
966
+ *
967
+ * The following are provided as chainable getters to
968
+ * improve the readability of your assertions. They
969
+ * do not provide testing capabilities unless they
970
+ * have been overwritten by a plugin.
971
+ *
972
+ * **Chains**
973
+ *
974
+ * - to
975
+ * - be
976
+ * - been
977
+ * - is
978
+ * - that
979
+ * - and
980
+ * - has
981
+ * - have
982
+ * - with
983
+ * - at
984
+ * - of
985
+ * - same
986
+ *
987
+ * @name language chains
988
+ * @api public
989
+ */
990
+
991
+ [ 'to', 'be', 'been'
992
+ , 'is', 'and', 'has', 'have'
993
+ , 'with', 'that', 'at'
994
+ , 'of', 'same' ].forEach(function (chain) {
995
+ Assertion.addProperty(chain, function () {
996
+ return this;
997
+ });
998
+ });
999
+
1000
+ /**
1001
+ * ### .not
1002
+ *
1003
+ * Negates any of assertions following in the chain.
1004
+ *
1005
+ * expect(foo).to.not.equal('bar');
1006
+ * expect(goodFn).to.not.throw(Error);
1007
+ * expect({ foo: 'baz' }).to.have.property('foo')
1008
+ * .and.not.equal('bar');
1009
+ *
1010
+ * @name not
1011
+ * @api public
1012
+ */
1013
+
1014
+ Assertion.addProperty('not', function () {
1015
+ flag(this, 'negate', true);
1016
+ });
1017
+
1018
+ /**
1019
+ * ### .deep
1020
+ *
1021
+ * Sets the `deep` flag, later used by the `equal` and
1022
+ * `property` assertions.
1023
+ *
1024
+ * expect(foo).to.deep.equal({ bar: 'baz' });
1025
+ * expect({ foo: { bar: { baz: 'quux' } } })
1026
+ * .to.have.deep.property('foo.bar.baz', 'quux');
1027
+ *
1028
+ * @name deep
1029
+ * @api public
1030
+ */
1031
+
1032
+ Assertion.addProperty('deep', function () {
1033
+ flag(this, 'deep', true);
1034
+ });
1035
+
1036
+ /**
1037
+ * ### .a(type)
1038
+ *
1039
+ * The `a` and `an` assertions are aliases that can be
1040
+ * used either as language chains or to assert a value's
1041
+ * type.
1042
+ *
1043
+ * // typeof
1044
+ * expect('test').to.be.a('string');
1045
+ * expect({ foo: 'bar' }).to.be.an('object');
1046
+ * expect(null).to.be.a('null');
1047
+ * expect(undefined).to.be.an('undefined');
1048
+ *
1049
+ * // language chain
1050
+ * expect(foo).to.be.an.instanceof(Foo);
1051
+ *
1052
+ * @name a
1053
+ * @alias an
1054
+ * @param {String} type
1055
+ * @param {String} message _optional_
1056
+ * @api public
1057
+ */
1058
+
1059
+ function an (type, msg) {
1060
+ if (msg) flag(this, 'message', msg);
1061
+ type = type.toLowerCase();
1062
+ var obj = flag(this, 'object')
1063
+ , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a ';
1064
+
1065
+ this.assert(
1066
+ type === _.type(obj)
1067
+ , 'expected #{this} to be ' + article + type
1068
+ , 'expected #{this} not to be ' + article + type
1069
+ );
1070
+ }
1071
+
1072
+ Assertion.addChainableMethod('an', an);
1073
+ Assertion.addChainableMethod('a', an);
1074
+
1075
+ /**
1076
+ * ### .include(value)
1077
+ *
1078
+ * The `include` and `contain` assertions can be used as either property
1079
+ * based language chains or as methods to assert the inclusion of an object
1080
+ * in an array or a substring in a string. When used as language chains,
1081
+ * they toggle the `contain` flag for the `keys` assertion.
1082
+ *
1083
+ * expect([1,2,3]).to.include(2);
1084
+ * expect('foobar').to.contain('foo');
1085
+ * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo');
1086
+ *
1087
+ * @name include
1088
+ * @alias contain
1089
+ * @param {Object|String|Number} obj
1090
+ * @param {String} message _optional_
1091
+ * @api public
1092
+ */
1093
+
1094
+ function includeChainingBehavior () {
1095
+ flag(this, 'contains', true);
1096
+ }
1097
+
1098
+ function include (val, msg) {
1099
+ if (msg) flag(this, 'message', msg);
1100
+ var obj = flag(this, 'object');
1101
+ var expected = false;
1102
+ if (_.type(obj) === 'array' && _.type(val) === 'object') {
1103
+ for (var i in obj) {
1104
+ if (_.eql(obj[i], val)) {
1105
+ expected = true;
1106
+ break;
1107
+ }
1108
+ }
1109
+ } else if (_.type(val) === 'object') {
1110
+ if (!flag(this, 'negate')) {
1111
+ for (var k in val) new Assertion(obj).property(k, val[k]);
1112
+ return;
1113
+ }
1114
+ var subset = {}
1115
+ for (var k in val) subset[k] = obj[k]
1116
+ expected = _.eql(subset, val);
1117
+ } else {
1118
+ expected = obj && ~obj.indexOf(val)
1119
+ }
1120
+ this.assert(
1121
+ expected
1122
+ , 'expected #{this} to include ' + _.inspect(val)
1123
+ , 'expected #{this} to not include ' + _.inspect(val));
1124
+ }
1125
+
1126
+ Assertion.addChainableMethod('include', include, includeChainingBehavior);
1127
+ Assertion.addChainableMethod('contain', include, includeChainingBehavior);
1128
+
1129
+ /**
1130
+ * ### .ok
1131
+ *
1132
+ * Asserts that the target is truthy.
1133
+ *
1134
+ * expect('everthing').to.be.ok;
1135
+ * expect(1).to.be.ok;
1136
+ * expect(false).to.not.be.ok;
1137
+ * expect(undefined).to.not.be.ok;
1138
+ * expect(null).to.not.be.ok;
1139
+ *
1140
+ * Can also be used as a function, which prevents some linter errors.
1141
+ *
1142
+ * expect('everthing').to.be.ok();
1143
+ *
1144
+ * @name ok
1145
+ * @api public
1146
+ */
1147
+
1148
+ Assertion.addChainableNoop('ok', function () {
1149
+ this.assert(
1150
+ flag(this, 'object')
1151
+ , 'expected #{this} to be truthy'
1152
+ , 'expected #{this} to be falsy');
1153
+ });
1154
+
1155
+ /**
1156
+ * ### .true
1157
+ *
1158
+ * Asserts that the target is `true`.
1159
+ *
1160
+ * expect(true).to.be.true;
1161
+ * expect(1).to.not.be.true;
1162
+ *
1163
+ * Can also be used as a function, which prevents some linter errors.
1164
+ *
1165
+ * expect(true).to.be.true();
1166
+ *
1167
+ * @name true
1168
+ * @api public
1169
+ */
1170
+
1171
+ Assertion.addChainableNoop('true', function () {
1172
+ this.assert(
1173
+ true === flag(this, 'object')
1174
+ , 'expected #{this} to be true'
1175
+ , 'expected #{this} to be false'
1176
+ , this.negate ? false : true
1177
+ );
1178
+ });
1179
+
1180
+ /**
1181
+ * ### .false
1182
+ *
1183
+ * Asserts that the target is `false`.
1184
+ *
1185
+ * expect(false).to.be.false;
1186
+ * expect(0).to.not.be.false;
1187
+ *
1188
+ * Can also be used as a function, which prevents some linter errors.
1189
+ *
1190
+ * expect(false).to.be.false();
1191
+ *
1192
+ * @name false
1193
+ * @api public
1194
+ */
1195
+
1196
+ Assertion.addChainableNoop('false', function () {
1197
+ this.assert(
1198
+ false === flag(this, 'object')
1199
+ , 'expected #{this} to be false'
1200
+ , 'expected #{this} to be true'
1201
+ , this.negate ? true : false
1202
+ );
1203
+ });
1204
+
1205
+ /**
1206
+ * ### .null
1207
+ *
1208
+ * Asserts that the target is `null`.
1209
+ *
1210
+ * expect(null).to.be.null;
1211
+ * expect(undefined).not.to.be.null;
1212
+ *
1213
+ * Can also be used as a function, which prevents some linter errors.
1214
+ *
1215
+ * expect(null).to.be.null();
1216
+ *
1217
+ * @name null
1218
+ * @api public
1219
+ */
1220
+
1221
+ Assertion.addChainableNoop('null', function () {
1222
+ this.assert(
1223
+ null === flag(this, 'object')
1224
+ , 'expected #{this} to be null'
1225
+ , 'expected #{this} not to be null'
1226
+ );
1227
+ });
1228
+
1229
+ /**
1230
+ * ### .undefined
1231
+ *
1232
+ * Asserts that the target is `undefined`.
1233
+ *
1234
+ * expect(undefined).to.be.undefined;
1235
+ * expect(null).to.not.be.undefined;
1236
+ *
1237
+ * Can also be used as a function, which prevents some linter errors.
1238
+ *
1239
+ * expect(undefined).to.be.undefined();
1240
+ *
1241
+ * @name undefined
1242
+ * @api public
1243
+ */
1244
+
1245
+ Assertion.addChainableNoop('undefined', function () {
1246
+ this.assert(
1247
+ undefined === flag(this, 'object')
1248
+ , 'expected #{this} to be undefined'
1249
+ , 'expected #{this} not to be undefined'
1250
+ );
1251
+ });
1252
+
1253
+ /**
1254
+ * ### .exist
1255
+ *
1256
+ * Asserts that the target is neither `null` nor `undefined`.
1257
+ *
1258
+ * var foo = 'hi'
1259
+ * , bar = null
1260
+ * , baz;
1261
+ *
1262
+ * expect(foo).to.exist;
1263
+ * expect(bar).to.not.exist;
1264
+ * expect(baz).to.not.exist;
1265
+ *
1266
+ * Can also be used as a function, which prevents some linter errors.
1267
+ *
1268
+ * expect(foo).to.exist();
1269
+ *
1270
+ * @name exist
1271
+ * @api public
1272
+ */
1273
+
1274
+ Assertion.addChainableNoop('exist', function () {
1275
+ this.assert(
1276
+ null != flag(this, 'object')
1277
+ , 'expected #{this} to exist'
1278
+ , 'expected #{this} to not exist'
1279
+ );
1280
+ });
1281
+
1282
+
1283
+ /**
1284
+ * ### .empty
1285
+ *
1286
+ * Asserts that the target's length is `0`. For arrays, it checks
1287
+ * the `length` property. For objects, it gets the count of
1288
+ * enumerable keys.
1289
+ *
1290
+ * expect([]).to.be.empty;
1291
+ * expect('').to.be.empty;
1292
+ * expect({}).to.be.empty;
1293
+ *
1294
+ * Can also be used as a function, which prevents some linter errors.
1295
+ *
1296
+ * expect([]).to.be.empty();
1297
+ *
1298
+ * @name empty
1299
+ * @api public
1300
+ */
1301
+
1302
+ Assertion.addChainableNoop('empty', function () {
1303
+ var obj = flag(this, 'object')
1304
+ , expected = obj;
1305
+
1306
+ if (Array.isArray(obj) || 'string' === typeof object) {
1307
+ expected = obj.length;
1308
+ } else if (typeof obj === 'object') {
1309
+ expected = Object.keys(obj).length;
1310
+ }
1311
+
1312
+ this.assert(
1313
+ !expected
1314
+ , 'expected #{this} to be empty'
1315
+ , 'expected #{this} not to be empty'
1316
+ );
1317
+ });
1318
+
1319
+ /**
1320
+ * ### .arguments
1321
+ *
1322
+ * Asserts that the target is an arguments object.
1323
+ *
1324
+ * function test () {
1325
+ * expect(arguments).to.be.arguments;
1326
+ * }
1327
+ *
1328
+ * Can also be used as a function, which prevents some linter errors.
1329
+ *
1330
+ * function test () {
1331
+ * expect(arguments).to.be.arguments();
1332
+ * }
1333
+ *
1334
+ * @name arguments
1335
+ * @alias Arguments
1336
+ * @api public
1337
+ */
1338
+
1339
+ function checkArguments () {
1340
+ var obj = flag(this, 'object')
1341
+ , type = Object.prototype.toString.call(obj);
1342
+ this.assert(
1343
+ '[object Arguments]' === type
1344
+ , 'expected #{this} to be arguments but got ' + type
1345
+ , 'expected #{this} to not be arguments'
1346
+ );
1347
+ }
1348
+
1349
+ Assertion.addChainableNoop('arguments', checkArguments);
1350
+ Assertion.addChainableNoop('Arguments', checkArguments);
1351
+
1352
+ /**
1353
+ * ### .equal(value)
1354
+ *
1355
+ * Asserts that the target is strictly equal (`===`) to `value`.
1356
+ * Alternately, if the `deep` flag is set, asserts that
1357
+ * the target is deeply equal to `value`.
1358
+ *
1359
+ * expect('hello').to.equal('hello');
1360
+ * expect(42).to.equal(42);
1361
+ * expect(1).to.not.equal(true);
1362
+ * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' });
1363
+ * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' });
1364
+ *
1365
+ * @name equal
1366
+ * @alias equals
1367
+ * @alias eq
1368
+ * @alias deep.equal
1369
+ * @param {Mixed} value
1370
+ * @param {String} message _optional_
1371
+ * @api public
1372
+ */
1373
+
1374
+ function assertEqual (val, msg) {
1375
+ if (msg) flag(this, 'message', msg);
1376
+ var obj = flag(this, 'object');
1377
+ if (flag(this, 'deep')) {
1378
+ return this.eql(val);
1379
+ } else {
1380
+ this.assert(
1381
+ val === obj
1382
+ , 'expected #{this} to equal #{exp}'
1383
+ , 'expected #{this} to not equal #{exp}'
1384
+ , val
1385
+ , this._obj
1386
+ , true
1387
+ );
1388
+ }
1389
+ }
1390
+
1391
+ Assertion.addMethod('equal', assertEqual);
1392
+ Assertion.addMethod('equals', assertEqual);
1393
+ Assertion.addMethod('eq', assertEqual);
1394
+
1395
+ /**
1396
+ * ### .eql(value)
1397
+ *
1398
+ * Asserts that the target is deeply equal to `value`.
1399
+ *
1400
+ * expect({ foo: 'bar' }).to.eql({ foo: 'bar' });
1401
+ * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]);
1402
+ *
1403
+ * @name eql
1404
+ * @alias eqls
1405
+ * @param {Mixed} value
1406
+ * @param {String} message _optional_
1407
+ * @api public
1408
+ */
1409
+
1410
+ function assertEql(obj, msg) {
1411
+ if (msg) flag(this, 'message', msg);
1412
+ this.assert(
1413
+ _.eql(obj, flag(this, 'object'))
1414
+ , 'expected #{this} to deeply equal #{exp}'
1415
+ , 'expected #{this} to not deeply equal #{exp}'
1416
+ , obj
1417
+ , this._obj
1418
+ , true
1419
+ );
1420
+ }
1421
+
1422
+ Assertion.addMethod('eql', assertEql);
1423
+ Assertion.addMethod('eqls', assertEql);
1424
+
1425
+ /**
1426
+ * ### .above(value)
1427
+ *
1428
+ * Asserts that the target is greater than `value`.
1429
+ *
1430
+ * expect(10).to.be.above(5);
1431
+ *
1432
+ * Can also be used in conjunction with `length` to
1433
+ * assert a minimum length. The benefit being a
1434
+ * more informative error message than if the length
1435
+ * was supplied directly.
1436
+ *
1437
+ * expect('foo').to.have.length.above(2);
1438
+ * expect([ 1, 2, 3 ]).to.have.length.above(2);
1439
+ *
1440
+ * @name above
1441
+ * @alias gt
1442
+ * @alias greaterThan
1443
+ * @param {Number} value
1444
+ * @param {String} message _optional_
1445
+ * @api public
1446
+ */
1447
+
1448
+ function assertAbove (n, msg) {
1449
+ if (msg) flag(this, 'message', msg);
1450
+ var obj = flag(this, 'object');
1451
+ if (flag(this, 'doLength')) {
1452
+ new Assertion(obj, msg).to.have.property('length');
1453
+ var len = obj.length;
1454
+ this.assert(
1455
+ len > n
1456
+ , 'expected #{this} to have a length above #{exp} but got #{act}'
1457
+ , 'expected #{this} to not have a length above #{exp}'
1458
+ , n
1459
+ , len
1460
+ );
1461
+ } else {
1462
+ this.assert(
1463
+ obj > n
1464
+ , 'expected #{this} to be above ' + n
1465
+ , 'expected #{this} to be at most ' + n
1466
+ );
1467
+ }
1468
+ }
1469
+
1470
+ Assertion.addMethod('above', assertAbove);
1471
+ Assertion.addMethod('gt', assertAbove);
1472
+ Assertion.addMethod('greaterThan', assertAbove);
1473
+
1474
+ /**
1475
+ * ### .least(value)
1476
+ *
1477
+ * Asserts that the target is greater than or equal to `value`.
1478
+ *
1479
+ * expect(10).to.be.at.least(10);
1480
+ *
1481
+ * Can also be used in conjunction with `length` to
1482
+ * assert a minimum length. The benefit being a
1483
+ * more informative error message than if the length
1484
+ * was supplied directly.
1485
+ *
1486
+ * expect('foo').to.have.length.of.at.least(2);
1487
+ * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3);
1488
+ *
1489
+ * @name least
1490
+ * @alias gte
1491
+ * @param {Number} value
1492
+ * @param {String} message _optional_
1493
+ * @api public
1494
+ */
1495
+
1496
+ function assertLeast (n, msg) {
1497
+ if (msg) flag(this, 'message', msg);
1498
+ var obj = flag(this, 'object');
1499
+ if (flag(this, 'doLength')) {
1500
+ new Assertion(obj, msg).to.have.property('length');
1501
+ var len = obj.length;
1502
+ this.assert(
1503
+ len >= n
1504
+ , 'expected #{this} to have a length at least #{exp} but got #{act}'
1505
+ , 'expected #{this} to have a length below #{exp}'
1506
+ , n
1507
+ , len
1508
+ );
1509
+ } else {
1510
+ this.assert(
1511
+ obj >= n
1512
+ , 'expected #{this} to be at least ' + n
1513
+ , 'expected #{this} to be below ' + n
1514
+ );
1515
+ }
1516
+ }
1517
+
1518
+ Assertion.addMethod('least', assertLeast);
1519
+ Assertion.addMethod('gte', assertLeast);
1520
+
1521
+ /**
1522
+ * ### .below(value)
1523
+ *
1524
+ * Asserts that the target is less than `value`.
1525
+ *
1526
+ * expect(5).to.be.below(10);
1527
+ *
1528
+ * Can also be used in conjunction with `length` to
1529
+ * assert a maximum length. The benefit being a
1530
+ * more informative error message than if the length
1531
+ * was supplied directly.
1532
+ *
1533
+ * expect('foo').to.have.length.below(4);
1534
+ * expect([ 1, 2, 3 ]).to.have.length.below(4);
1535
+ *
1536
+ * @name below
1537
+ * @alias lt
1538
+ * @alias lessThan
1539
+ * @param {Number} value
1540
+ * @param {String} message _optional_
1541
+ * @api public
1542
+ */
1543
+
1544
+ function assertBelow (n, msg) {
1545
+ if (msg) flag(this, 'message', msg);
1546
+ var obj = flag(this, 'object');
1547
+ if (flag(this, 'doLength')) {
1548
+ new Assertion(obj, msg).to.have.property('length');
1549
+ var len = obj.length;
1550
+ this.assert(
1551
+ len < n
1552
+ , 'expected #{this} to have a length below #{exp} but got #{act}'
1553
+ , 'expected #{this} to not have a length below #{exp}'
1554
+ , n
1555
+ , len
1556
+ );
1557
+ } else {
1558
+ this.assert(
1559
+ obj < n
1560
+ , 'expected #{this} to be below ' + n
1561
+ , 'expected #{this} to be at least ' + n
1562
+ );
1563
+ }
1564
+ }
1565
+
1566
+ Assertion.addMethod('below', assertBelow);
1567
+ Assertion.addMethod('lt', assertBelow);
1568
+ Assertion.addMethod('lessThan', assertBelow);
1569
+
1570
+ /**
1571
+ * ### .most(value)
1572
+ *
1573
+ * Asserts that the target is less than or equal to `value`.
1574
+ *
1575
+ * expect(5).to.be.at.most(5);
1576
+ *
1577
+ * Can also be used in conjunction with `length` to
1578
+ * assert a maximum length. The benefit being a
1579
+ * more informative error message than if the length
1580
+ * was supplied directly.
1581
+ *
1582
+ * expect('foo').to.have.length.of.at.most(4);
1583
+ * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3);
1584
+ *
1585
+ * @name most
1586
+ * @alias lte
1587
+ * @param {Number} value
1588
+ * @param {String} message _optional_
1589
+ * @api public
1590
+ */
1591
+
1592
+ function assertMost (n, msg) {
1593
+ if (msg) flag(this, 'message', msg);
1594
+ var obj = flag(this, 'object');
1595
+ if (flag(this, 'doLength')) {
1596
+ new Assertion(obj, msg).to.have.property('length');
1597
+ var len = obj.length;
1598
+ this.assert(
1599
+ len <= n
1600
+ , 'expected #{this} to have a length at most #{exp} but got #{act}'
1601
+ , 'expected #{this} to have a length above #{exp}'
1602
+ , n
1603
+ , len
1604
+ );
1605
+ } else {
1606
+ this.assert(
1607
+ obj <= n
1608
+ , 'expected #{this} to be at most ' + n
1609
+ , 'expected #{this} to be above ' + n
1610
+ );
1611
+ }
1612
+ }
1613
+
1614
+ Assertion.addMethod('most', assertMost);
1615
+ Assertion.addMethod('lte', assertMost);
1616
+
1617
+ /**
1618
+ * ### .within(start, finish)
1619
+ *
1620
+ * Asserts that the target is within a range.
1621
+ *
1622
+ * expect(7).to.be.within(5,10);
1623
+ *
1624
+ * Can also be used in conjunction with `length` to
1625
+ * assert a length range. The benefit being a
1626
+ * more informative error message than if the length
1627
+ * was supplied directly.
1628
+ *
1629
+ * expect('foo').to.have.length.within(2,4);
1630
+ * expect([ 1, 2, 3 ]).to.have.length.within(2,4);
1631
+ *
1632
+ * @name within
1633
+ * @param {Number} start lowerbound inclusive
1634
+ * @param {Number} finish upperbound inclusive
1635
+ * @param {String} message _optional_
1636
+ * @api public
1637
+ */
1638
+
1639
+ Assertion.addMethod('within', function (start, finish, msg) {
1640
+ if (msg) flag(this, 'message', msg);
1641
+ var obj = flag(this, 'object')
1642
+ , range = start + '..' + finish;
1643
+ if (flag(this, 'doLength')) {
1644
+ new Assertion(obj, msg).to.have.property('length');
1645
+ var len = obj.length;
1646
+ this.assert(
1647
+ len >= start && len <= finish
1648
+ , 'expected #{this} to have a length within ' + range
1649
+ , 'expected #{this} to not have a length within ' + range
1650
+ );
1651
+ } else {
1652
+ this.assert(
1653
+ obj >= start && obj <= finish
1654
+ , 'expected #{this} to be within ' + range
1655
+ , 'expected #{this} to not be within ' + range
1656
+ );
1657
+ }
1658
+ });
1659
+
1660
+ /**
1661
+ * ### .instanceof(constructor)
1662
+ *
1663
+ * Asserts that the target is an instance of `constructor`.
1664
+ *
1665
+ * var Tea = function (name) { this.name = name; }
1666
+ * , Chai = new Tea('chai');
1667
+ *
1668
+ * expect(Chai).to.be.an.instanceof(Tea);
1669
+ * expect([ 1, 2, 3 ]).to.be.instanceof(Array);
1670
+ *
1671
+ * @name instanceof
1672
+ * @param {Constructor} constructor
1673
+ * @param {String} message _optional_
1674
+ * @alias instanceOf
1675
+ * @api public
1676
+ */
1677
+
1678
+ function assertInstanceOf (constructor, msg) {
1679
+ if (msg) flag(this, 'message', msg);
1680
+ var name = _.getName(constructor);
1681
+ this.assert(
1682
+ flag(this, 'object') instanceof constructor
1683
+ , 'expected #{this} to be an instance of ' + name
1684
+ , 'expected #{this} to not be an instance of ' + name
1685
+ );
1686
+ };
1687
+
1688
+ Assertion.addMethod('instanceof', assertInstanceOf);
1689
+ Assertion.addMethod('instanceOf', assertInstanceOf);
1690
+
1691
+ /**
1692
+ * ### .property(name, [value])
1693
+ *
1694
+ * Asserts that the target has a property `name`, optionally asserting that
1695
+ * the value of that property is strictly equal to `value`.
1696
+ * If the `deep` flag is set, you can use dot- and bracket-notation for deep
1697
+ * references into objects and arrays.
1698
+ *
1699
+ * // simple referencing
1700
+ * var obj = { foo: 'bar' };
1701
+ * expect(obj).to.have.property('foo');
1702
+ * expect(obj).to.have.property('foo', 'bar');
1703
+ *
1704
+ * // deep referencing
1705
+ * var deepObj = {
1706
+ * green: { tea: 'matcha' }
1707
+ * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ]
1708
+ * };
1709
+
1710
+ * expect(deepObj).to.have.deep.property('green.tea', 'matcha');
1711
+ * expect(deepObj).to.have.deep.property('teas[1]', 'matcha');
1712
+ * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha');
1713
+ *
1714
+ * You can also use an array as the starting point of a `deep.property`
1715
+ * assertion, or traverse nested arrays.
1716
+ *
1717
+ * var arr = [
1718
+ * [ 'chai', 'matcha', 'konacha' ]
1719
+ * , [ { tea: 'chai' }
1720
+ * , { tea: 'matcha' }
1721
+ * , { tea: 'konacha' } ]
1722
+ * ];
1723
+ *
1724
+ * expect(arr).to.have.deep.property('[0][1]', 'matcha');
1725
+ * expect(arr).to.have.deep.property('[1][2].tea', 'konacha');
1726
+ *
1727
+ * Furthermore, `property` changes the subject of the assertion
1728
+ * to be the value of that property from the original object. This
1729
+ * permits for further chainable assertions on that property.
1730
+ *
1731
+ * expect(obj).to.have.property('foo')
1732
+ * .that.is.a('string');
1733
+ * expect(deepObj).to.have.property('green')
1734
+ * .that.is.an('object')
1735
+ * .that.deep.equals({ tea: 'matcha' });
1736
+ * expect(deepObj).to.have.property('teas')
1737
+ * .that.is.an('array')
1738
+ * .with.deep.property('[2]')
1739
+ * .that.deep.equals({ tea: 'konacha' });
1740
+ *
1741
+ * @name property
1742
+ * @alias deep.property
1743
+ * @param {String} name
1744
+ * @param {Mixed} value (optional)
1745
+ * @param {String} message _optional_
1746
+ * @returns value of property for chaining
1747
+ * @api public
1748
+ */
1749
+
1750
+ Assertion.addMethod('property', function (name, val, msg) {
1751
+ if (msg) flag(this, 'message', msg);
1752
+
1753
+ var descriptor = flag(this, 'deep') ? 'deep property ' : 'property '
1754
+ , negate = flag(this, 'negate')
1755
+ , obj = flag(this, 'object')
1756
+ , value = flag(this, 'deep')
1757
+ ? _.getPathValue(name, obj)
1758
+ : obj[name];
1759
+
1760
+ if (negate && undefined !== val) {
1761
+ if (undefined === value) {
1762
+ msg = (msg != null) ? msg + ': ' : '';
1763
+ throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspect(name));
1764
+ }
1765
+ } else {
1766
+ this.assert(
1767
+ undefined !== value
1768
+ , 'expected #{this} to have a ' + descriptor + _.inspect(name)
1769
+ , 'expected #{this} to not have ' + descriptor + _.inspect(name));
1770
+ }
1771
+
1772
+ if (undefined !== val) {
1773
+ this.assert(
1774
+ val === value
1775
+ , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}'
1776
+ , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' of #{act}'
1777
+ , val
1778
+ , value
1779
+ );
1780
+ }
1781
+
1782
+ flag(this, 'object', value);
1783
+ });
1784
+
1785
+
1786
+ /**
1787
+ * ### .ownProperty(name)
1788
+ *
1789
+ * Asserts that the target has an own property `name`.
1790
+ *
1791
+ * expect('test').to.have.ownProperty('length');
1792
+ *
1793
+ * @name ownProperty
1794
+ * @alias haveOwnProperty
1795
+ * @param {String} name
1796
+ * @param {String} message _optional_
1797
+ * @api public
1798
+ */
1799
+
1800
+ function assertOwnProperty (name, msg) {
1801
+ if (msg) flag(this, 'message', msg);
1802
+ var obj = flag(this, 'object');
1803
+ this.assert(
1804
+ obj.hasOwnProperty(name)
1805
+ , 'expected #{this} to have own property ' + _.inspect(name)
1806
+ , 'expected #{this} to not have own property ' + _.inspect(name)
1807
+ );
1808
+ }
1809
+
1810
+ Assertion.addMethod('ownProperty', assertOwnProperty);
1811
+ Assertion.addMethod('haveOwnProperty', assertOwnProperty);
1812
+
1813
+ /**
1814
+ * ### .length(value)
1815
+ *
1816
+ * Asserts that the target's `length` property has
1817
+ * the expected value.
1818
+ *
1819
+ * expect([ 1, 2, 3]).to.have.length(3);
1820
+ * expect('foobar').to.have.length(6);
1821
+ *
1822
+ * Can also be used as a chain precursor to a value
1823
+ * comparison for the length property.
1824
+ *
1825
+ * expect('foo').to.have.length.above(2);
1826
+ * expect([ 1, 2, 3 ]).to.have.length.above(2);
1827
+ * expect('foo').to.have.length.below(4);
1828
+ * expect([ 1, 2, 3 ]).to.have.length.below(4);
1829
+ * expect('foo').to.have.length.within(2,4);
1830
+ * expect([ 1, 2, 3 ]).to.have.length.within(2,4);
1831
+ *
1832
+ * @name length
1833
+ * @alias lengthOf
1834
+ * @param {Number} length
1835
+ * @param {String} message _optional_
1836
+ * @api public
1837
+ */
1838
+
1839
+ function assertLengthChain () {
1840
+ flag(this, 'doLength', true);
1841
+ }
1842
+
1843
+ function assertLength (n, msg) {
1844
+ if (msg) flag(this, 'message', msg);
1845
+ var obj = flag(this, 'object');
1846
+ new Assertion(obj, msg).to.have.property('length');
1847
+ var len = obj.length;
1848
+
1849
+ this.assert(
1850
+ len == n
1851
+ , 'expected #{this} to have a length of #{exp} but got #{act}'
1852
+ , 'expected #{this} to not have a length of #{act}'
1853
+ , n
1854
+ , len
1855
+ );
1856
+ }
1857
+
1858
+ Assertion.addChainableMethod('length', assertLength, assertLengthChain);
1859
+ Assertion.addMethod('lengthOf', assertLength);
1860
+
1861
+ /**
1862
+ * ### .match(regexp)
1863
+ *
1864
+ * Asserts that the target matches a regular expression.
1865
+ *
1866
+ * expect('foobar').to.match(/^foo/);
1867
+ *
1868
+ * @name match
1869
+ * @param {RegExp} RegularExpression
1870
+ * @param {String} message _optional_
1871
+ * @api public
1872
+ */
1873
+
1874
+ Assertion.addMethod('match', function (re, msg) {
1875
+ if (msg) flag(this, 'message', msg);
1876
+ var obj = flag(this, 'object');
1877
+ this.assert(
1878
+ re.exec(obj)
1879
+ , 'expected #{this} to match ' + re
1880
+ , 'expected #{this} not to match ' + re
1881
+ );
1882
+ });
1883
+
1884
+ /**
1885
+ * ### .string(string)
1886
+ *
1887
+ * Asserts that the string target contains another string.
1888
+ *
1889
+ * expect('foobar').to.have.string('bar');
1890
+ *
1891
+ * @name string
1892
+ * @param {String} string
1893
+ * @param {String} message _optional_
1894
+ * @api public
1895
+ */
1896
+
1897
+ Assertion.addMethod('string', function (str, msg) {
1898
+ if (msg) flag(this, 'message', msg);
1899
+ var obj = flag(this, 'object');
1900
+ new Assertion(obj, msg).is.a('string');
1901
+
1902
+ this.assert(
1903
+ ~obj.indexOf(str)
1904
+ , 'expected #{this} to contain ' + _.inspect(str)
1905
+ , 'expected #{this} to not contain ' + _.inspect(str)
1906
+ );
1907
+ });
1908
+
1909
+
1910
+ /**
1911
+ * ### .keys(key1, [key2], [...])
1912
+ *
1913
+ * Asserts that the target has exactly the given keys, or
1914
+ * asserts the inclusion of some keys when using the
1915
+ * `include` or `contain` modifiers.
1916
+ *
1917
+ * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']);
1918
+ * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar');
1919
+ *
1920
+ * @name keys
1921
+ * @alias key
1922
+ * @param {String...|Array} keys
1923
+ * @api public
1924
+ */
1925
+
1926
+ function assertKeys (keys) {
1927
+ var obj = flag(this, 'object')
1928
+ , str
1929
+ , ok = true;
1930
+
1931
+ keys = keys instanceof Array
1932
+ ? keys
1933
+ : Array.prototype.slice.call(arguments);
1934
+
1935
+ if (!keys.length) throw new Error('keys required');
1936
+
1937
+ var actual = Object.keys(obj)
1938
+ , expected = keys
1939
+ , len = keys.length;
1940
+
1941
+ // Inclusion
1942
+ ok = keys.every(function(key){
1943
+ return ~actual.indexOf(key);
1944
+ });
1945
+
1946
+ // Strict
1947
+ if (!flag(this, 'negate') && !flag(this, 'contains')) {
1948
+ ok = ok && keys.length == actual.length;
1949
+ }
1950
+
1951
+ // Key string
1952
+ if (len > 1) {
1953
+ keys = keys.map(function(key){
1954
+ return _.inspect(key);
1955
+ });
1956
+ var last = keys.pop();
1957
+ str = keys.join(', ') + ', and ' + last;
1958
+ } else {
1959
+ str = _.inspect(keys[0]);
1960
+ }
1961
+
1962
+ // Form
1963
+ str = (len > 1 ? 'keys ' : 'key ') + str;
1964
+
1965
+ // Have / include
1966
+ str = (flag(this, 'contains') ? 'contain ' : 'have ') + str;
1967
+
1968
+ // Assertion
1969
+ this.assert(
1970
+ ok
1971
+ , 'expected #{this} to ' + str
1972
+ , 'expected #{this} to not ' + str
1973
+ , expected.sort()
1974
+ , actual.sort()
1975
+ , true
1976
+ );
1977
+ }
1978
+
1979
+ Assertion.addMethod('keys', assertKeys);
1980
+ Assertion.addMethod('key', assertKeys);
1981
+
1982
+ /**
1983
+ * ### .throw(constructor)
1984
+ *
1985
+ * Asserts that the function target will throw a specific error, or specific type of error
1986
+ * (as determined using `instanceof`), optionally with a RegExp or string inclusion test
1987
+ * for the error's message.
1988
+ *
1989
+ * var err = new ReferenceError('This is a bad function.');
1990
+ * var fn = function () { throw err; }
1991
+ * expect(fn).to.throw(ReferenceError);
1992
+ * expect(fn).to.throw(Error);
1993
+ * expect(fn).to.throw(/bad function/);
1994
+ * expect(fn).to.not.throw('good function');
1995
+ * expect(fn).to.throw(ReferenceError, /bad function/);
1996
+ * expect(fn).to.throw(err);
1997
+ * expect(fn).to.not.throw(new RangeError('Out of range.'));
1998
+ *
1999
+ * Please note that when a throw expectation is negated, it will check each
2000
+ * parameter independently, starting with error constructor type. The appropriate way
2001
+ * to check for the existence of a type of error but for a message that does not match
2002
+ * is to use `and`.
2003
+ *
2004
+ * expect(fn).to.throw(ReferenceError)
2005
+ * .and.not.throw(/good function/);
2006
+ *
2007
+ * @name throw
2008
+ * @alias throws
2009
+ * @alias Throw
2010
+ * @param {ErrorConstructor} constructor
2011
+ * @param {String|RegExp} expected error message
2012
+ * @param {String} message _optional_
2013
+ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
2014
+ * @returns error for chaining (null if no error)
2015
+ * @api public
2016
+ */
2017
+
2018
+ function assertThrows (constructor, errMsg, msg) {
2019
+ if (msg) flag(this, 'message', msg);
2020
+ var obj = flag(this, 'object');
2021
+ new Assertion(obj, msg).is.a('function');
2022
+
2023
+ var thrown = false
2024
+ , desiredError = null
2025
+ , name = null
2026
+ , thrownError = null;
2027
+
2028
+ if (arguments.length === 0) {
2029
+ errMsg = null;
2030
+ constructor = null;
2031
+ } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) {
2032
+ errMsg = constructor;
2033
+ constructor = null;
2034
+ } else if (constructor && constructor instanceof Error) {
2035
+ desiredError = constructor;
2036
+ constructor = null;
2037
+ errMsg = null;
2038
+ } else if (typeof constructor === 'function') {
2039
+ name = constructor.prototype.name || constructor.name;
2040
+ if (name === 'Error' && constructor !== Error) {
2041
+ name = (new constructor()).name;
2042
+ }
2043
+ } else {
2044
+ constructor = null;
2045
+ }
2046
+
2047
+ try {
2048
+ obj();
2049
+ } catch (err) {
2050
+ // first, check desired error
2051
+ if (desiredError) {
2052
+ this.assert(
2053
+ err === desiredError
2054
+ , 'expected #{this} to throw #{exp} but #{act} was thrown'
2055
+ , 'expected #{this} to not throw #{exp}'
2056
+ , (desiredError instanceof Error ? desiredError.toString() : desiredError)
2057
+ , (err instanceof Error ? err.toString() : err)
2058
+ );
2059
+
2060
+ flag(this, 'object', err);
2061
+ return this;
2062
+ }
2063
+
2064
+ // next, check constructor
2065
+ if (constructor) {
2066
+ this.assert(
2067
+ err instanceof constructor
2068
+ , 'expected #{this} to throw #{exp} but #{act} was thrown'
2069
+ , 'expected #{this} to not throw #{exp} but #{act} was thrown'
2070
+ , name
2071
+ , (err instanceof Error ? err.toString() : err)
2072
+ );
2073
+
2074
+ if (!errMsg) {
2075
+ flag(this, 'object', err);
2076
+ return this;
2077
+ }
2078
+ }
2079
+
2080
+ // next, check message
2081
+ var message = 'object' === _.type(err) && "message" in err
2082
+ ? err.message
2083
+ : '' + err;
2084
+
2085
+ if ((message != null) && errMsg && errMsg instanceof RegExp) {
2086
+ this.assert(
2087
+ errMsg.exec(message)
2088
+ , 'expected #{this} to throw error matching #{exp} but got #{act}'
2089
+ , 'expected #{this} to throw error not matching #{exp}'
2090
+ , errMsg
2091
+ , message
2092
+ );
2093
+
2094
+ flag(this, 'object', err);
2095
+ return this;
2096
+ } else if ((message != null) && errMsg && 'string' === typeof errMsg) {
2097
+ this.assert(
2098
+ ~message.indexOf(errMsg)
2099
+ , 'expected #{this} to throw error including #{exp} but got #{act}'
2100
+ , 'expected #{this} to throw error not including #{act}'
2101
+ , errMsg
2102
+ , message
2103
+ );
2104
+
2105
+ flag(this, 'object', err);
2106
+ return this;
2107
+ } else {
2108
+ thrown = true;
2109
+ thrownError = err;
2110
+ }
2111
+ }
2112
+
2113
+ var actuallyGot = ''
2114
+ , expectedThrown = name !== null
2115
+ ? name
2116
+ : desiredError
2117
+ ? '#{exp}' //_.inspect(desiredError)
2118
+ : 'an error';
2119
+
2120
+ if (thrown) {
2121
+ actuallyGot = ' but #{act} was thrown'
2122
+ }
2123
+
2124
+ this.assert(
2125
+ thrown === true
2126
+ , 'expected #{this} to throw ' + expectedThrown + actuallyGot
2127
+ , 'expected #{this} to not throw ' + expectedThrown + actuallyGot
2128
+ , (desiredError instanceof Error ? desiredError.toString() : desiredError)
2129
+ , (thrownError instanceof Error ? thrownError.toString() : thrownError)
2130
+ );
2131
+
2132
+ flag(this, 'object', thrownError);
2133
+ };
2134
+
2135
+ Assertion.addMethod('throw', assertThrows);
2136
+ Assertion.addMethod('throws', assertThrows);
2137
+ Assertion.addMethod('Throw', assertThrows);
2138
+
2139
+ /**
2140
+ * ### .respondTo(method)
2141
+ *
2142
+ * Asserts that the object or class target will respond to a method.
2143
+ *
2144
+ * Klass.prototype.bar = function(){};
2145
+ * expect(Klass).to.respondTo('bar');
2146
+ * expect(obj).to.respondTo('bar');
2147
+ *
2148
+ * To check if a constructor will respond to a static function,
2149
+ * set the `itself` flag.
2150
+ *
2151
+ * Klass.baz = function(){};
2152
+ * expect(Klass).itself.to.respondTo('baz');
2153
+ *
2154
+ * @name respondTo
2155
+ * @param {String} method
2156
+ * @param {String} message _optional_
2157
+ * @api public
2158
+ */
2159
+
2160
+ Assertion.addMethod('respondTo', function (method, msg) {
2161
+ if (msg) flag(this, 'message', msg);
2162
+ var obj = flag(this, 'object')
2163
+ , itself = flag(this, 'itself')
2164
+ , context = ('function' === _.type(obj) && !itself)
2165
+ ? obj.prototype[method]
2166
+ : obj[method];
2167
+
2168
+ this.assert(
2169
+ 'function' === typeof context
2170
+ , 'expected #{this} to respond to ' + _.inspect(method)
2171
+ , 'expected #{this} to not respond to ' + _.inspect(method)
2172
+ );
2173
+ });
2174
+
2175
+ /**
2176
+ * ### .itself
2177
+ *
2178
+ * Sets the `itself` flag, later used by the `respondTo` assertion.
2179
+ *
2180
+ * function Foo() {}
2181
+ * Foo.bar = function() {}
2182
+ * Foo.prototype.baz = function() {}
2183
+ *
2184
+ * expect(Foo).itself.to.respondTo('bar');
2185
+ * expect(Foo).itself.not.to.respondTo('baz');
2186
+ *
2187
+ * @name itself
2188
+ * @api public
2189
+ */
2190
+
2191
+ Assertion.addProperty('itself', function () {
2192
+ flag(this, 'itself', true);
2193
+ });
2194
+
2195
+ /**
2196
+ * ### .satisfy(method)
2197
+ *
2198
+ * Asserts that the target passes a given truth test.
2199
+ *
2200
+ * expect(1).to.satisfy(function(num) { return num > 0; });
2201
+ *
2202
+ * @name satisfy
2203
+ * @param {Function} matcher
2204
+ * @param {String} message _optional_
2205
+ * @api public
2206
+ */
2207
+
2208
+ Assertion.addMethod('satisfy', function (matcher, msg) {
2209
+ if (msg) flag(this, 'message', msg);
2210
+ var obj = flag(this, 'object');
2211
+ var result = matcher(obj);
2212
+ this.assert(
2213
+ result
2214
+ , 'expected #{this} to satisfy ' + _.objDisplay(matcher)
2215
+ , 'expected #{this} to not satisfy' + _.objDisplay(matcher)
2216
+ , this.negate ? false : true
2217
+ , result
2218
+ );
2219
+ });
2220
+
2221
+ /**
2222
+ * ### .closeTo(expected, delta)
2223
+ *
2224
+ * Asserts that the target is equal `expected`, to within a +/- `delta` range.
2225
+ *
2226
+ * expect(1.5).to.be.closeTo(1, 0.5);
2227
+ *
2228
+ * @name closeTo
2229
+ * @param {Number} expected
2230
+ * @param {Number} delta
2231
+ * @param {String} message _optional_
2232
+ * @api public
2233
+ */
2234
+
2235
+ Assertion.addMethod('closeTo', function (expected, delta, msg) {
2236
+ if (msg) flag(this, 'message', msg);
2237
+ var obj = flag(this, 'object');
2238
+
2239
+ new Assertion(obj, msg).is.a('number');
2240
+ if (_.type(expected) !== 'number' || _.type(delta) !== 'number') {
2241
+ throw new Error('the arguments to closeTo must be numbers');
2242
+ }
2243
+
2244
+ this.assert(
2245
+ Math.abs(obj - expected) <= delta
2246
+ , 'expected #{this} to be close to ' + expected + ' +/- ' + delta
2247
+ , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta
2248
+ );
2249
+ });
2250
+
2251
+ function isSubsetOf(subset, superset, cmp) {
2252
+ return subset.every(function(elem) {
2253
+ if (!cmp) return superset.indexOf(elem) !== -1;
2254
+
2255
+ return superset.some(function(elem2) {
2256
+ return cmp(elem, elem2);
2257
+ });
2258
+ })
2259
+ }
2260
+
2261
+ /**
2262
+ * ### .members(set)
2263
+ *
2264
+ * Asserts that the target is a superset of `set`,
2265
+ * or that the target and `set` have the same strictly-equal (===) members.
2266
+ * Alternately, if the `deep` flag is set, set members are compared for deep
2267
+ * equality.
2268
+ *
2269
+ * expect([1, 2, 3]).to.include.members([3, 2]);
2270
+ * expect([1, 2, 3]).to.not.include.members([3, 2, 8]);
2271
+ *
2272
+ * expect([4, 2]).to.have.members([2, 4]);
2273
+ * expect([5, 2]).to.not.have.members([5, 2, 1]);
2274
+ *
2275
+ * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]);
2276
+ *
2277
+ * @name members
2278
+ * @param {Array} set
2279
+ * @param {String} message _optional_
2280
+ * @api public
2281
+ */
2282
+
2283
+ Assertion.addMethod('members', function (subset, msg) {
2284
+ if (msg) flag(this, 'message', msg);
2285
+ var obj = flag(this, 'object');
2286
+
2287
+ new Assertion(obj).to.be.an('array');
2288
+ new Assertion(subset).to.be.an('array');
2289
+
2290
+ var cmp = flag(this, 'deep') ? _.eql : undefined;
2291
+
2292
+ if (flag(this, 'contains')) {
2293
+ return this.assert(
2294
+ isSubsetOf(subset, obj, cmp)
2295
+ , 'expected #{this} to be a superset of #{act}'
2296
+ , 'expected #{this} to not be a superset of #{act}'
2297
+ , obj
2298
+ , subset
2299
+ );
2300
+ }
2301
+
2302
+ this.assert(
2303
+ isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp)
2304
+ , 'expected #{this} to have the same members as #{act}'
2305
+ , 'expected #{this} to not have the same members as #{act}'
2306
+ , obj
2307
+ , subset
2308
+ );
2309
+ });
2310
+ };
2311
+
2312
+ });
2313
+
2314
+ require.register("chai/lib/chai/interface/assert.js", function (exports, module) {
2315
+ /*!
2316
+ * chai
2317
+ * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
2318
+ * MIT Licensed
2319
+ */
2320
+
2321
+
2322
+ module.exports = function (chai, util) {
2323
+
2324
+ /*!
2325
+ * Chai dependencies.
2326
+ */
2327
+
2328
+ var Assertion = chai.Assertion
2329
+ , flag = util.flag;
2330
+
2331
+ /*!
2332
+ * Module export.
2333
+ */
2334
+
2335
+ /**
2336
+ * ### assert(expression, message)
2337
+ *
2338
+ * Write your own test expressions.
2339
+ *
2340
+ * assert('foo' !== 'bar', 'foo is not bar');
2341
+ * assert(Array.isArray([]), 'empty arrays are arrays');
2342
+ *
2343
+ * @param {Mixed} expression to test for truthiness
2344
+ * @param {String} message to display on error
2345
+ * @name assert
2346
+ * @api public
2347
+ */
2348
+
2349
+ var assert = chai.assert = function (express, errmsg) {
2350
+ var test = new Assertion(null, null, chai.assert);
2351
+ test.assert(
2352
+ express
2353
+ , errmsg
2354
+ , '[ negation message unavailable ]'
2355
+ );
2356
+ };
2357
+
2358
+ /**
2359
+ * ### .fail(actual, expected, [message], [operator])
2360
+ *
2361
+ * Throw a failure. Node.js `assert` module-compatible.
2362
+ *
2363
+ * @name fail
2364
+ * @param {Mixed} actual
2365
+ * @param {Mixed} expected
2366
+ * @param {String} message
2367
+ * @param {String} operator
2368
+ * @api public
2369
+ */
2370
+
2371
+ assert.fail = function (actual, expected, message, operator) {
2372
+ message = message || 'assert.fail()';
2373
+ throw new chai.AssertionError(message, {
2374
+ actual: actual
2375
+ , expected: expected
2376
+ , operator: operator
2377
+ }, assert.fail);
2378
+ };
2379
+
2380
+ /**
2381
+ * ### .ok(object, [message])
2382
+ *
2383
+ * Asserts that `object` is truthy.
2384
+ *
2385
+ * assert.ok('everything', 'everything is ok');
2386
+ * assert.ok(false, 'this will fail');
2387
+ *
2388
+ * @name ok
2389
+ * @param {Mixed} object to test
2390
+ * @param {String} message
2391
+ * @api public
2392
+ */
2393
+
2394
+ assert.ok = function (val, msg) {
2395
+ new Assertion(val, msg).is.ok;
2396
+ };
2397
+
2398
+ /**
2399
+ * ### .notOk(object, [message])
2400
+ *
2401
+ * Asserts that `object` is falsy.
2402
+ *
2403
+ * assert.notOk('everything', 'this will fail');
2404
+ * assert.notOk(false, 'this will pass');
2405
+ *
2406
+ * @name notOk
2407
+ * @param {Mixed} object to test
2408
+ * @param {String} message
2409
+ * @api public
2410
+ */
2411
+
2412
+ assert.notOk = function (val, msg) {
2413
+ new Assertion(val, msg).is.not.ok;
2414
+ };
2415
+
2416
+ /**
2417
+ * ### .equal(actual, expected, [message])
2418
+ *
2419
+ * Asserts non-strict equality (`==`) of `actual` and `expected`.
2420
+ *
2421
+ * assert.equal(3, '3', '== coerces values to strings');
2422
+ *
2423
+ * @name equal
2424
+ * @param {Mixed} actual
2425
+ * @param {Mixed} expected
2426
+ * @param {String} message
2427
+ * @api public
2428
+ */
2429
+
2430
+ assert.equal = function (act, exp, msg) {
2431
+ var test = new Assertion(act, msg, assert.equal);
2432
+
2433
+ test.assert(
2434
+ exp == flag(test, 'object')
2435
+ , 'expected #{this} to equal #{exp}'
2436
+ , 'expected #{this} to not equal #{act}'
2437
+ , exp
2438
+ , act
2439
+ );
2440
+ };
2441
+
2442
+ /**
2443
+ * ### .notEqual(actual, expected, [message])
2444
+ *
2445
+ * Asserts non-strict inequality (`!=`) of `actual` and `expected`.
2446
+ *
2447
+ * assert.notEqual(3, 4, 'these numbers are not equal');
2448
+ *
2449
+ * @name notEqual
2450
+ * @param {Mixed} actual
2451
+ * @param {Mixed} expected
2452
+ * @param {String} message
2453
+ * @api public
2454
+ */
2455
+
2456
+ assert.notEqual = function (act, exp, msg) {
2457
+ var test = new Assertion(act, msg, assert.notEqual);
2458
+
2459
+ test.assert(
2460
+ exp != flag(test, 'object')
2461
+ , 'expected #{this} to not equal #{exp}'
2462
+ , 'expected #{this} to equal #{act}'
2463
+ , exp
2464
+ , act
2465
+ );
2466
+ };
2467
+
2468
+ /**
2469
+ * ### .strictEqual(actual, expected, [message])
2470
+ *
2471
+ * Asserts strict equality (`===`) of `actual` and `expected`.
2472
+ *
2473
+ * assert.strictEqual(true, true, 'these booleans are strictly equal');
2474
+ *
2475
+ * @name strictEqual
2476
+ * @param {Mixed} actual
2477
+ * @param {Mixed} expected
2478
+ * @param {String} message
2479
+ * @api public
2480
+ */
2481
+
2482
+ assert.strictEqual = function (act, exp, msg) {
2483
+ new Assertion(act, msg).to.equal(exp);
2484
+ };
2485
+
2486
+ /**
2487
+ * ### .notStrictEqual(actual, expected, [message])
2488
+ *
2489
+ * Asserts strict inequality (`!==`) of `actual` and `expected`.
2490
+ *
2491
+ * assert.notStrictEqual(3, '3', 'no coercion for strict equality');
2492
+ *
2493
+ * @name notStrictEqual
2494
+ * @param {Mixed} actual
2495
+ * @param {Mixed} expected
2496
+ * @param {String} message
2497
+ * @api public
2498
+ */
2499
+
2500
+ assert.notStrictEqual = function (act, exp, msg) {
2501
+ new Assertion(act, msg).to.not.equal(exp);
2502
+ };
2503
+
2504
+ /**
2505
+ * ### .deepEqual(actual, expected, [message])
2506
+ *
2507
+ * Asserts that `actual` is deeply equal to `expected`.
2508
+ *
2509
+ * assert.deepEqual({ tea: 'green' }, { tea: 'green' });
2510
+ *
2511
+ * @name deepEqual
2512
+ * @param {Mixed} actual
2513
+ * @param {Mixed} expected
2514
+ * @param {String} message
2515
+ * @api public
2516
+ */
2517
+
2518
+ assert.deepEqual = function (act, exp, msg) {
2519
+ new Assertion(act, msg).to.eql(exp);
2520
+ };
2521
+
2522
+ /**
2523
+ * ### .notDeepEqual(actual, expected, [message])
2524
+ *
2525
+ * Assert that `actual` is not deeply equal to `expected`.
2526
+ *
2527
+ * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' });
2528
+ *
2529
+ * @name notDeepEqual
2530
+ * @param {Mixed} actual
2531
+ * @param {Mixed} expected
2532
+ * @param {String} message
2533
+ * @api public
2534
+ */
2535
+
2536
+ assert.notDeepEqual = function (act, exp, msg) {
2537
+ new Assertion(act, msg).to.not.eql(exp);
2538
+ };
2539
+
2540
+ /**
2541
+ * ### .isTrue(value, [message])
2542
+ *
2543
+ * Asserts that `value` is true.
2544
+ *
2545
+ * var teaServed = true;
2546
+ * assert.isTrue(teaServed, 'the tea has been served');
2547
+ *
2548
+ * @name isTrue
2549
+ * @param {Mixed} value
2550
+ * @param {String} message
2551
+ * @api public
2552
+ */
2553
+
2554
+ assert.isTrue = function (val, msg) {
2555
+ new Assertion(val, msg).is['true'];
2556
+ };
2557
+
2558
+ /**
2559
+ * ### .isFalse(value, [message])
2560
+ *
2561
+ * Asserts that `value` is false.
2562
+ *
2563
+ * var teaServed = false;
2564
+ * assert.isFalse(teaServed, 'no tea yet? hmm...');
2565
+ *
2566
+ * @name isFalse
2567
+ * @param {Mixed} value
2568
+ * @param {String} message
2569
+ * @api public
2570
+ */
2571
+
2572
+ assert.isFalse = function (val, msg) {
2573
+ new Assertion(val, msg).is['false'];
2574
+ };
2575
+
2576
+ /**
2577
+ * ### .isNull(value, [message])
2578
+ *
2579
+ * Asserts that `value` is null.
2580
+ *
2581
+ * assert.isNull(err, 'there was no error');
2582
+ *
2583
+ * @name isNull
2584
+ * @param {Mixed} value
2585
+ * @param {String} message
2586
+ * @api public
2587
+ */
2588
+
2589
+ assert.isNull = function (val, msg) {
2590
+ new Assertion(val, msg).to.equal(null);
2591
+ };
2592
+
2593
+ /**
2594
+ * ### .isNotNull(value, [message])
2595
+ *
2596
+ * Asserts that `value` is not null.
2597
+ *
2598
+ * var tea = 'tasty chai';
2599
+ * assert.isNotNull(tea, 'great, time for tea!');
2600
+ *
2601
+ * @name isNotNull
2602
+ * @param {Mixed} value
2603
+ * @param {String} message
2604
+ * @api public
2605
+ */
2606
+
2607
+ assert.isNotNull = function (val, msg) {
2608
+ new Assertion(val, msg).to.not.equal(null);
2609
+ };
2610
+
2611
+ /**
2612
+ * ### .isUndefined(value, [message])
2613
+ *
2614
+ * Asserts that `value` is `undefined`.
2615
+ *
2616
+ * var tea;
2617
+ * assert.isUndefined(tea, 'no tea defined');
2618
+ *
2619
+ * @name isUndefined
2620
+ * @param {Mixed} value
2621
+ * @param {String} message
2622
+ * @api public
2623
+ */
2624
+
2625
+ assert.isUndefined = function (val, msg) {
2626
+ new Assertion(val, msg).to.equal(undefined);
2627
+ };
2628
+
2629
+ /**
2630
+ * ### .isDefined(value, [message])
2631
+ *
2632
+ * Asserts that `value` is not `undefined`.
2633
+ *
2634
+ * var tea = 'cup of chai';
2635
+ * assert.isDefined(tea, 'tea has been defined');
2636
+ *
2637
+ * @name isDefined
2638
+ * @param {Mixed} value
2639
+ * @param {String} message
2640
+ * @api public
2641
+ */
2642
+
2643
+ assert.isDefined = function (val, msg) {
2644
+ new Assertion(val, msg).to.not.equal(undefined);
2645
+ };
2646
+
2647
+ /**
2648
+ * ### .isFunction(value, [message])
2649
+ *
2650
+ * Asserts that `value` is a function.
2651
+ *
2652
+ * function serveTea() { return 'cup of tea'; };
2653
+ * assert.isFunction(serveTea, 'great, we can have tea now');
2654
+ *
2655
+ * @name isFunction
2656
+ * @param {Mixed} value
2657
+ * @param {String} message
2658
+ * @api public
2659
+ */
2660
+
2661
+ assert.isFunction = function (val, msg) {
2662
+ new Assertion(val, msg).to.be.a('function');
2663
+ };
2664
+
2665
+ /**
2666
+ * ### .isNotFunction(value, [message])
2667
+ *
2668
+ * Asserts that `value` is _not_ a function.
2669
+ *
2670
+ * var serveTea = [ 'heat', 'pour', 'sip' ];
2671
+ * assert.isNotFunction(serveTea, 'great, we have listed the steps');
2672
+ *
2673
+ * @name isNotFunction
2674
+ * @param {Mixed} value
2675
+ * @param {String} message
2676
+ * @api public
2677
+ */
2678
+
2679
+ assert.isNotFunction = function (val, msg) {
2680
+ new Assertion(val, msg).to.not.be.a('function');
2681
+ };
2682
+
2683
+ /**
2684
+ * ### .isObject(value, [message])
2685
+ *
2686
+ * Asserts that `value` is an object (as revealed by
2687
+ * `Object.prototype.toString`).
2688
+ *
2689
+ * var selection = { name: 'Chai', serve: 'with spices' };
2690
+ * assert.isObject(selection, 'tea selection is an object');
2691
+ *
2692
+ * @name isObject
2693
+ * @param {Mixed} value
2694
+ * @param {String} message
2695
+ * @api public
2696
+ */
2697
+
2698
+ assert.isObject = function (val, msg) {
2699
+ new Assertion(val, msg).to.be.a('object');
2700
+ };
2701
+
2702
+ /**
2703
+ * ### .isNotObject(value, [message])
2704
+ *
2705
+ * Asserts that `value` is _not_ an object.
2706
+ *
2707
+ * var selection = 'chai'
2708
+ * assert.isNotObject(selection, 'tea selection is not an object');
2709
+ * assert.isNotObject(null, 'null is not an object');
2710
+ *
2711
+ * @name isNotObject
2712
+ * @param {Mixed} value
2713
+ * @param {String} message
2714
+ * @api public
2715
+ */
2716
+
2717
+ assert.isNotObject = function (val, msg) {
2718
+ new Assertion(val, msg).to.not.be.a('object');
2719
+ };
2720
+
2721
+ /**
2722
+ * ### .isArray(value, [message])
2723
+ *
2724
+ * Asserts that `value` is an array.
2725
+ *
2726
+ * var menu = [ 'green', 'chai', 'oolong' ];
2727
+ * assert.isArray(menu, 'what kind of tea do we want?');
2728
+ *
2729
+ * @name isArray
2730
+ * @param {Mixed} value
2731
+ * @param {String} message
2732
+ * @api public
2733
+ */
2734
+
2735
+ assert.isArray = function (val, msg) {
2736
+ new Assertion(val, msg).to.be.an('array');
2737
+ };
2738
+
2739
+ /**
2740
+ * ### .isNotArray(value, [message])
2741
+ *
2742
+ * Asserts that `value` is _not_ an array.
2743
+ *
2744
+ * var menu = 'green|chai|oolong';
2745
+ * assert.isNotArray(menu, 'what kind of tea do we want?');
2746
+ *
2747
+ * @name isNotArray
2748
+ * @param {Mixed} value
2749
+ * @param {String} message
2750
+ * @api public
2751
+ */
2752
+
2753
+ assert.isNotArray = function (val, msg) {
2754
+ new Assertion(val, msg).to.not.be.an('array');
2755
+ };
2756
+
2757
+ /**
2758
+ * ### .isString(value, [message])
2759
+ *
2760
+ * Asserts that `value` is a string.
2761
+ *
2762
+ * var teaOrder = 'chai';
2763
+ * assert.isString(teaOrder, 'order placed');
2764
+ *
2765
+ * @name isString
2766
+ * @param {Mixed} value
2767
+ * @param {String} message
2768
+ * @api public
2769
+ */
2770
+
2771
+ assert.isString = function (val, msg) {
2772
+ new Assertion(val, msg).to.be.a('string');
2773
+ };
2774
+
2775
+ /**
2776
+ * ### .isNotString(value, [message])
2777
+ *
2778
+ * Asserts that `value` is _not_ a string.
2779
+ *
2780
+ * var teaOrder = 4;
2781
+ * assert.isNotString(teaOrder, 'order placed');
2782
+ *
2783
+ * @name isNotString
2784
+ * @param {Mixed} value
2785
+ * @param {String} message
2786
+ * @api public
2787
+ */
2788
+
2789
+ assert.isNotString = function (val, msg) {
2790
+ new Assertion(val, msg).to.not.be.a('string');
2791
+ };
2792
+
2793
+ /**
2794
+ * ### .isNumber(value, [message])
2795
+ *
2796
+ * Asserts that `value` is a number.
2797
+ *
2798
+ * var cups = 2;
2799
+ * assert.isNumber(cups, 'how many cups');
2800
+ *
2801
+ * @name isNumber
2802
+ * @param {Number} value
2803
+ * @param {String} message
2804
+ * @api public
2805
+ */
2806
+
2807
+ assert.isNumber = function (val, msg) {
2808
+ new Assertion(val, msg).to.be.a('number');
2809
+ };
2810
+
2811
+ /**
2812
+ * ### .isNotNumber(value, [message])
2813
+ *
2814
+ * Asserts that `value` is _not_ a number.
2815
+ *
2816
+ * var cups = '2 cups please';
2817
+ * assert.isNotNumber(cups, 'how many cups');
2818
+ *
2819
+ * @name isNotNumber
2820
+ * @param {Mixed} value
2821
+ * @param {String} message
2822
+ * @api public
2823
+ */
2824
+
2825
+ assert.isNotNumber = function (val, msg) {
2826
+ new Assertion(val, msg).to.not.be.a('number');
2827
+ };
2828
+
2829
+ /**
2830
+ * ### .isBoolean(value, [message])
2831
+ *
2832
+ * Asserts that `value` is a boolean.
2833
+ *
2834
+ * var teaReady = true
2835
+ * , teaServed = false;
2836
+ *
2837
+ * assert.isBoolean(teaReady, 'is the tea ready');
2838
+ * assert.isBoolean(teaServed, 'has tea been served');
2839
+ *
2840
+ * @name isBoolean
2841
+ * @param {Mixed} value
2842
+ * @param {String} message
2843
+ * @api public
2844
+ */
2845
+
2846
+ assert.isBoolean = function (val, msg) {
2847
+ new Assertion(val, msg).to.be.a('boolean');
2848
+ };
2849
+
2850
+ /**
2851
+ * ### .isNotBoolean(value, [message])
2852
+ *
2853
+ * Asserts that `value` is _not_ a boolean.
2854
+ *
2855
+ * var teaReady = 'yep'
2856
+ * , teaServed = 'nope';
2857
+ *
2858
+ * assert.isNotBoolean(teaReady, 'is the tea ready');
2859
+ * assert.isNotBoolean(teaServed, 'has tea been served');
2860
+ *
2861
+ * @name isNotBoolean
2862
+ * @param {Mixed} value
2863
+ * @param {String} message
2864
+ * @api public
2865
+ */
2866
+
2867
+ assert.isNotBoolean = function (val, msg) {
2868
+ new Assertion(val, msg).to.not.be.a('boolean');
2869
+ };
2870
+
2871
+ /**
2872
+ * ### .typeOf(value, name, [message])
2873
+ *
2874
+ * Asserts that `value`'s type is `name`, as determined by
2875
+ * `Object.prototype.toString`.
2876
+ *
2877
+ * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object');
2878
+ * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array');
2879
+ * assert.typeOf('tea', 'string', 'we have a string');
2880
+ * assert.typeOf(/tea/, 'regexp', 'we have a regular expression');
2881
+ * assert.typeOf(null, 'null', 'we have a null');
2882
+ * assert.typeOf(undefined, 'undefined', 'we have an undefined');
2883
+ *
2884
+ * @name typeOf
2885
+ * @param {Mixed} value
2886
+ * @param {String} name
2887
+ * @param {String} message
2888
+ * @api public
2889
+ */
2890
+
2891
+ assert.typeOf = function (val, type, msg) {
2892
+ new Assertion(val, msg).to.be.a(type);
2893
+ };
2894
+
2895
+ /**
2896
+ * ### .notTypeOf(value, name, [message])
2897
+ *
2898
+ * Asserts that `value`'s type is _not_ `name`, as determined by
2899
+ * `Object.prototype.toString`.
2900
+ *
2901
+ * assert.notTypeOf('tea', 'number', 'strings are not numbers');
2902
+ *
2903
+ * @name notTypeOf
2904
+ * @param {Mixed} value
2905
+ * @param {String} typeof name
2906
+ * @param {String} message
2907
+ * @api public
2908
+ */
2909
+
2910
+ assert.notTypeOf = function (val, type, msg) {
2911
+ new Assertion(val, msg).to.not.be.a(type);
2912
+ };
2913
+
2914
+ /**
2915
+ * ### .instanceOf(object, constructor, [message])
2916
+ *
2917
+ * Asserts that `value` is an instance of `constructor`.
2918
+ *
2919
+ * var Tea = function (name) { this.name = name; }
2920
+ * , chai = new Tea('chai');
2921
+ *
2922
+ * assert.instanceOf(chai, Tea, 'chai is an instance of tea');
2923
+ *
2924
+ * @name instanceOf
2925
+ * @param {Object} object
2926
+ * @param {Constructor} constructor
2927
+ * @param {String} message
2928
+ * @api public
2929
+ */
2930
+
2931
+ assert.instanceOf = function (val, type, msg) {
2932
+ new Assertion(val, msg).to.be.instanceOf(type);
2933
+ };
2934
+
2935
+ /**
2936
+ * ### .notInstanceOf(object, constructor, [message])
2937
+ *
2938
+ * Asserts `value` is not an instance of `constructor`.
2939
+ *
2940
+ * var Tea = function (name) { this.name = name; }
2941
+ * , chai = new String('chai');
2942
+ *
2943
+ * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea');
2944
+ *
2945
+ * @name notInstanceOf
2946
+ * @param {Object} object
2947
+ * @param {Constructor} constructor
2948
+ * @param {String} message
2949
+ * @api public
2950
+ */
2951
+
2952
+ assert.notInstanceOf = function (val, type, msg) {
2953
+ new Assertion(val, msg).to.not.be.instanceOf(type);
2954
+ };
2955
+
2956
+ /**
2957
+ * ### .include(haystack, needle, [message])
2958
+ *
2959
+ * Asserts that `haystack` includes `needle`. Works
2960
+ * for strings and arrays.
2961
+ *
2962
+ * assert.include('foobar', 'bar', 'foobar contains string "bar"');
2963
+ * assert.include([ 1, 2, 3 ], 3, 'array contains value');
2964
+ *
2965
+ * @name include
2966
+ * @param {Array|String} haystack
2967
+ * @param {Mixed} needle
2968
+ * @param {String} message
2969
+ * @api public
2970
+ */
2971
+
2972
+ assert.include = function (exp, inc, msg) {
2973
+ new Assertion(exp, msg, assert.include).include(inc);
2974
+ };
2975
+
2976
+ /**
2977
+ * ### .notInclude(haystack, needle, [message])
2978
+ *
2979
+ * Asserts that `haystack` does not include `needle`. Works
2980
+ * for strings and arrays.
2981
+ *i
2982
+ * assert.notInclude('foobar', 'baz', 'string not include substring');
2983
+ * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value');
2984
+ *
2985
+ * @name notInclude
2986
+ * @param {Array|String} haystack
2987
+ * @param {Mixed} needle
2988
+ * @param {String} message
2989
+ * @api public
2990
+ */
2991
+
2992
+ assert.notInclude = function (exp, inc, msg) {
2993
+ new Assertion(exp, msg, assert.notInclude).not.include(inc);
2994
+ };
2995
+
2996
+ /**
2997
+ * ### .match(value, regexp, [message])
2998
+ *
2999
+ * Asserts that `value` matches the regular expression `regexp`.
3000
+ *
3001
+ * assert.match('foobar', /^foo/, 'regexp matches');
3002
+ *
3003
+ * @name match
3004
+ * @param {Mixed} value
3005
+ * @param {RegExp} regexp
3006
+ * @param {String} message
3007
+ * @api public
3008
+ */
3009
+
3010
+ assert.match = function (exp, re, msg) {
3011
+ new Assertion(exp, msg).to.match(re);
3012
+ };
3013
+
3014
+ /**
3015
+ * ### .notMatch(value, regexp, [message])
3016
+ *
3017
+ * Asserts that `value` does not match the regular expression `regexp`.
3018
+ *
3019
+ * assert.notMatch('foobar', /^foo/, 'regexp does not match');
3020
+ *
3021
+ * @name notMatch
3022
+ * @param {Mixed} value
3023
+ * @param {RegExp} regexp
3024
+ * @param {String} message
3025
+ * @api public
3026
+ */
3027
+
3028
+ assert.notMatch = function (exp, re, msg) {
3029
+ new Assertion(exp, msg).to.not.match(re);
3030
+ };
3031
+
3032
+ /**
3033
+ * ### .property(object, property, [message])
3034
+ *
3035
+ * Asserts that `object` has a property named by `property`.
3036
+ *
3037
+ * assert.property({ tea: { green: 'matcha' }}, 'tea');
3038
+ *
3039
+ * @name property
3040
+ * @param {Object} object
3041
+ * @param {String} property
3042
+ * @param {String} message
3043
+ * @api public
3044
+ */
3045
+
3046
+ assert.property = function (obj, prop, msg) {
3047
+ new Assertion(obj, msg).to.have.property(prop);
3048
+ };
3049
+
3050
+ /**
3051
+ * ### .notProperty(object, property, [message])
3052
+ *
3053
+ * Asserts that `object` does _not_ have a property named by `property`.
3054
+ *
3055
+ * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee');
3056
+ *
3057
+ * @name notProperty
3058
+ * @param {Object} object
3059
+ * @param {String} property
3060
+ * @param {String} message
3061
+ * @api public
3062
+ */
3063
+
3064
+ assert.notProperty = function (obj, prop, msg) {
3065
+ new Assertion(obj, msg).to.not.have.property(prop);
3066
+ };
3067
+
3068
+ /**
3069
+ * ### .deepProperty(object, property, [message])
3070
+ *
3071
+ * Asserts that `object` has a property named by `property`, which can be a
3072
+ * string using dot- and bracket-notation for deep reference.
3073
+ *
3074
+ * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green');
3075
+ *
3076
+ * @name deepProperty
3077
+ * @param {Object} object
3078
+ * @param {String} property
3079
+ * @param {String} message
3080
+ * @api public
3081
+ */
3082
+
3083
+ assert.deepProperty = function (obj, prop, msg) {
3084
+ new Assertion(obj, msg).to.have.deep.property(prop);
3085
+ };
3086
+
3087
+ /**
3088
+ * ### .notDeepProperty(object, property, [message])
3089
+ *
3090
+ * Asserts that `object` does _not_ have a property named by `property`, which
3091
+ * can be a string using dot- and bracket-notation for deep reference.
3092
+ *
3093
+ * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong');
3094
+ *
3095
+ * @name notDeepProperty
3096
+ * @param {Object} object
3097
+ * @param {String} property
3098
+ * @param {String} message
3099
+ * @api public
3100
+ */
3101
+
3102
+ assert.notDeepProperty = function (obj, prop, msg) {
3103
+ new Assertion(obj, msg).to.not.have.deep.property(prop);
3104
+ };
3105
+
3106
+ /**
3107
+ * ### .propertyVal(object, property, value, [message])
3108
+ *
3109
+ * Asserts that `object` has a property named by `property` with value given
3110
+ * by `value`.
3111
+ *
3112
+ * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good');
3113
+ *
3114
+ * @name propertyVal
3115
+ * @param {Object} object
3116
+ * @param {String} property
3117
+ * @param {Mixed} value
3118
+ * @param {String} message
3119
+ * @api public
3120
+ */
3121
+
3122
+ assert.propertyVal = function (obj, prop, val, msg) {
3123
+ new Assertion(obj, msg).to.have.property(prop, val);
3124
+ };
3125
+
3126
+ /**
3127
+ * ### .propertyNotVal(object, property, value, [message])
3128
+ *
3129
+ * Asserts that `object` has a property named by `property`, but with a value
3130
+ * different from that given by `value`.
3131
+ *
3132
+ * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad');
3133
+ *
3134
+ * @name propertyNotVal
3135
+ * @param {Object} object
3136
+ * @param {String} property
3137
+ * @param {Mixed} value
3138
+ * @param {String} message
3139
+ * @api public
3140
+ */
3141
+
3142
+ assert.propertyNotVal = function (obj, prop, val, msg) {
3143
+ new Assertion(obj, msg).to.not.have.property(prop, val);
3144
+ };
3145
+
3146
+ /**
3147
+ * ### .deepPropertyVal(object, property, value, [message])
3148
+ *
3149
+ * Asserts that `object` has a property named by `property` with value given
3150
+ * by `value`. `property` can use dot- and bracket-notation for deep
3151
+ * reference.
3152
+ *
3153
+ * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha');
3154
+ *
3155
+ * @name deepPropertyVal
3156
+ * @param {Object} object
3157
+ * @param {String} property
3158
+ * @param {Mixed} value
3159
+ * @param {String} message
3160
+ * @api public
3161
+ */
3162
+
3163
+ assert.deepPropertyVal = function (obj, prop, val, msg) {
3164
+ new Assertion(obj, msg).to.have.deep.property(prop, val);
3165
+ };
3166
+
3167
+ /**
3168
+ * ### .deepPropertyNotVal(object, property, value, [message])
3169
+ *
3170
+ * Asserts that `object` has a property named by `property`, but with a value
3171
+ * different from that given by `value`. `property` can use dot- and
3172
+ * bracket-notation for deep reference.
3173
+ *
3174
+ * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha');
3175
+ *
3176
+ * @name deepPropertyNotVal
3177
+ * @param {Object} object
3178
+ * @param {String} property
3179
+ * @param {Mixed} value
3180
+ * @param {String} message
3181
+ * @api public
3182
+ */
3183
+
3184
+ assert.deepPropertyNotVal = function (obj, prop, val, msg) {
3185
+ new Assertion(obj, msg).to.not.have.deep.property(prop, val);
3186
+ };
3187
+
3188
+ /**
3189
+ * ### .lengthOf(object, length, [message])
3190
+ *
3191
+ * Asserts that `object` has a `length` property with the expected value.
3192
+ *
3193
+ * assert.lengthOf([1,2,3], 3, 'array has length of 3');
3194
+ * assert.lengthOf('foobar', 5, 'string has length of 6');
3195
+ *
3196
+ * @name lengthOf
3197
+ * @param {Mixed} object
3198
+ * @param {Number} length
3199
+ * @param {String} message
3200
+ * @api public
3201
+ */
3202
+
3203
+ assert.lengthOf = function (exp, len, msg) {
3204
+ new Assertion(exp, msg).to.have.length(len);
3205
+ };
3206
+
3207
+ /**
3208
+ * ### .throws(function, [constructor/string/regexp], [string/regexp], [message])
3209
+ *
3210
+ * Asserts that `function` will throw an error that is an instance of
3211
+ * `constructor`, or alternately that it will throw an error with message
3212
+ * matching `regexp`.
3213
+ *
3214
+ * assert.throw(fn, 'function throws a reference error');
3215
+ * assert.throw(fn, /function throws a reference error/);
3216
+ * assert.throw(fn, ReferenceError);
3217
+ * assert.throw(fn, ReferenceError, 'function throws a reference error');
3218
+ * assert.throw(fn, ReferenceError, /function throws a reference error/);
3219
+ *
3220
+ * @name throws
3221
+ * @alias throw
3222
+ * @alias Throw
3223
+ * @param {Function} function
3224
+ * @param {ErrorConstructor} constructor
3225
+ * @param {RegExp} regexp
3226
+ * @param {String} message
3227
+ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
3228
+ * @api public
3229
+ */
3230
+
3231
+ assert.Throw = function (fn, errt, errs, msg) {
3232
+ if ('string' === typeof errt || errt instanceof RegExp) {
3233
+ errs = errt;
3234
+ errt = null;
3235
+ }
3236
+
3237
+ var assertErr = new Assertion(fn, msg).to.Throw(errt, errs);
3238
+ return flag(assertErr, 'object');
3239
+ };
3240
+
3241
+ /**
3242
+ * ### .doesNotThrow(function, [constructor/regexp], [message])
3243
+ *
3244
+ * Asserts that `function` will _not_ throw an error that is an instance of
3245
+ * `constructor`, or alternately that it will not throw an error with message
3246
+ * matching `regexp`.
3247
+ *
3248
+ * assert.doesNotThrow(fn, Error, 'function does not throw');
3249
+ *
3250
+ * @name doesNotThrow
3251
+ * @param {Function} function
3252
+ * @param {ErrorConstructor} constructor
3253
+ * @param {RegExp} regexp
3254
+ * @param {String} message
3255
+ * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types
3256
+ * @api public
3257
+ */
3258
+
3259
+ assert.doesNotThrow = function (fn, type, msg) {
3260
+ if ('string' === typeof type) {
3261
+ msg = type;
3262
+ type = null;
3263
+ }
3264
+
3265
+ new Assertion(fn, msg).to.not.Throw(type);
3266
+ };
3267
+
3268
+ /**
3269
+ * ### .operator(val1, operator, val2, [message])
3270
+ *
3271
+ * Compares two values using `operator`.
3272
+ *
3273
+ * assert.operator(1, '<', 2, 'everything is ok');
3274
+ * assert.operator(1, '>', 2, 'this will fail');
3275
+ *
3276
+ * @name operator
3277
+ * @param {Mixed} val1
3278
+ * @param {String} operator
3279
+ * @param {Mixed} val2
3280
+ * @param {String} message
3281
+ * @api public
3282
+ */
3283
+
3284
+ assert.operator = function (val, operator, val2, msg) {
3285
+ if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) {
3286
+ throw new Error('Invalid operator "' + operator + '"');
3287
+ }
3288
+ var test = new Assertion(eval(val + operator + val2), msg);
3289
+ test.assert(
3290
+ true === flag(test, 'object')
3291
+ , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2)
3292
+ , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) );
3293
+ };
3294
+
3295
+ /**
3296
+ * ### .closeTo(actual, expected, delta, [message])
3297
+ *
3298
+ * Asserts that the target is equal `expected`, to within a +/- `delta` range.
3299
+ *
3300
+ * assert.closeTo(1.5, 1, 0.5, 'numbers are close');
3301
+ *
3302
+ * @name closeTo
3303
+ * @param {Number} actual
3304
+ * @param {Number} expected
3305
+ * @param {Number} delta
3306
+ * @param {String} message
3307
+ * @api public
3308
+ */
3309
+
3310
+ assert.closeTo = function (act, exp, delta, msg) {
3311
+ new Assertion(act, msg).to.be.closeTo(exp, delta);
3312
+ };
3313
+
3314
+ /**
3315
+ * ### .sameMembers(set1, set2, [message])
3316
+ *
3317
+ * Asserts that `set1` and `set2` have the same members.
3318
+ * Order is not taken into account.
3319
+ *
3320
+ * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members');
3321
+ *
3322
+ * @name sameMembers
3323
+ * @param {Array} set1
3324
+ * @param {Array} set2
3325
+ * @param {String} message
3326
+ * @api public
3327
+ */
3328
+
3329
+ assert.sameMembers = function (set1, set2, msg) {
3330
+ new Assertion(set1, msg).to.have.same.members(set2);
3331
+ }
3332
+
3333
+ /**
3334
+ * ### .includeMembers(superset, subset, [message])
3335
+ *
3336
+ * Asserts that `subset` is included in `superset`.
3337
+ * Order is not taken into account.
3338
+ *
3339
+ * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members');
3340
+ *
3341
+ * @name includeMembers
3342
+ * @param {Array} superset
3343
+ * @param {Array} subset
3344
+ * @param {String} message
3345
+ * @api public
3346
+ */
3347
+
3348
+ assert.includeMembers = function (superset, subset, msg) {
3349
+ new Assertion(superset, msg).to.include.members(subset);
3350
+ }
3351
+
3352
+ /*!
3353
+ * Undocumented / untested
3354
+ */
3355
+
3356
+ assert.ifError = function (val, msg) {
3357
+ new Assertion(val, msg).to.not.be.ok;
3358
+ };
3359
+
3360
+ /*!
3361
+ * Aliases.
3362
+ */
3363
+
3364
+ (function alias(name, as){
3365
+ assert[as] = assert[name];
3366
+ return alias;
3367
+ })
3368
+ ('Throw', 'throw')
3369
+ ('Throw', 'throws');
3370
+ };
3371
+
3372
+ });
3373
+
3374
+ require.register("chai/lib/chai/interface/expect.js", function (exports, module) {
3375
+ /*!
3376
+ * chai
3377
+ * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
3378
+ * MIT Licensed
3379
+ */
3380
+
3381
+ module.exports = function (chai, util) {
3382
+ chai.expect = function (val, message) {
3383
+ return new chai.Assertion(val, message);
3384
+ };
3385
+ };
3386
+
3387
+
3388
+ });
3389
+
3390
+ require.register("chai/lib/chai/interface/should.js", function (exports, module) {
3391
+ /*!
3392
+ * chai
3393
+ * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com>
3394
+ * MIT Licensed
3395
+ */
3396
+
3397
+ module.exports = function (chai, util) {
3398
+ var Assertion = chai.Assertion;
3399
+
3400
+ function loadShould () {
3401
+ // explicitly define this method as function as to have it's name to include as `ssfi`
3402
+ function shouldGetter() {
3403
+ if (this instanceof String || this instanceof Number) {
3404
+ return new Assertion(this.constructor(this), null, shouldGetter);
3405
+ } else if (this instanceof Boolean) {
3406
+ return new Assertion(this == true, null, shouldGetter);
3407
+ }
3408
+ return new Assertion(this, null, shouldGetter);
3409
+ }
3410
+ function shouldSetter(value) {
3411
+ // See https://github.com/chaijs/chai/issues/86: this makes
3412
+ // `whatever.should = someValue` actually set `someValue`, which is
3413
+ // especially useful for `global.should = require('chai').should()`.
3414
+ //
3415
+ // Note that we have to use [[DefineProperty]] instead of [[Put]]
3416
+ // since otherwise we would trigger this very setter!
3417
+ Object.defineProperty(this, 'should', {
3418
+ value: value,
3419
+ enumerable: true,
3420
+ configurable: true,
3421
+ writable: true
3422
+ });
3423
+ }
3424
+ // modify Object.prototype to have `should`
3425
+ Object.defineProperty(Object.prototype, 'should', {
3426
+ set: shouldSetter
3427
+ , get: shouldGetter
3428
+ , configurable: true
3429
+ });
3430
+
3431
+ var should = {};
3432
+
3433
+ should.equal = function (val1, val2, msg) {
3434
+ new Assertion(val1, msg).to.equal(val2);
3435
+ };
3436
+
3437
+ should.Throw = function (fn, errt, errs, msg) {
3438
+ new Assertion(fn, msg).to.Throw(errt, errs);
3439
+ };
3440
+
3441
+ should.exist = function (val, msg) {
3442
+ new Assertion(val, msg).to.exist;
3443
+ }
3444
+
3445
+ // negation
3446
+ should.not = {}
3447
+
3448
+ should.not.equal = function (val1, val2, msg) {
3449
+ new Assertion(val1, msg).to.not.equal(val2);
3450
+ };
3451
+
3452
+ should.not.Throw = function (fn, errt, errs, msg) {
3453
+ new Assertion(fn, msg).to.not.Throw(errt, errs);
3454
+ };
3455
+
3456
+ should.not.exist = function (val, msg) {
3457
+ new Assertion(val, msg).to.not.exist;
3458
+ }
3459
+
3460
+ should['throw'] = should['Throw'];
3461
+ should.not['throw'] = should.not['Throw'];
3462
+
3463
+ return should;
3464
+ };
3465
+
3466
+ chai.should = loadShould;
3467
+ chai.Should = loadShould;
3468
+ };
3469
+
3470
+ });
3471
+
3472
+ require.register("chai/lib/chai/utils/addChainableMethod.js", function (exports, module) {
3473
+ /*!
3474
+ * Chai - addChainingMethod utility
3475
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
3476
+ * MIT Licensed
3477
+ */
3478
+
3479
+ /*!
3480
+ * Module dependencies
3481
+ */
3482
+
3483
+ var transferFlags = require('chai/lib/chai/utils/transferFlags.js');
3484
+ var flag = require('chai/lib/chai/utils/flag.js');
3485
+ var config = require('chai/lib/chai/config.js');
3486
+
3487
+ /*!
3488
+ * Module variables
3489
+ */
3490
+
3491
+ // Check whether `__proto__` is supported
3492
+ var hasProtoSupport = '__proto__' in Object;
3493
+
3494
+ // Without `__proto__` support, this module will need to add properties to a function.
3495
+ // However, some Function.prototype methods cannot be overwritten,
3496
+ // and there seems no easy cross-platform way to detect them (@see chaijs/chai/issues/69).
3497
+ var excludeNames = /^(?:length|name|arguments|caller)$/;
3498
+
3499
+ // Cache `Function` properties
3500
+ var call = Function.prototype.call,
3501
+ apply = Function.prototype.apply;
3502
+
3503
+ /**
3504
+ * ### addChainableMethod (ctx, name, method, chainingBehavior)
3505
+ *
3506
+ * Adds a method to an object, such that the method can also be chained.
3507
+ *
3508
+ * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) {
3509
+ * var obj = utils.flag(this, 'object');
3510
+ * new chai.Assertion(obj).to.be.equal(str);
3511
+ * });
3512
+ *
3513
+ * Can also be accessed directly from `chai.Assertion`.
3514
+ *
3515
+ * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior);
3516
+ *
3517
+ * The result can then be used as both a method assertion, executing both `method` and
3518
+ * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`.
3519
+ *
3520
+ * expect(fooStr).to.be.foo('bar');
3521
+ * expect(fooStr).to.be.foo.equal('foo');
3522
+ *
3523
+ * @param {Object} ctx object to which the method is added
3524
+ * @param {String} name of method to add
3525
+ * @param {Function} method function to be used for `name`, when called
3526
+ * @param {Function} chainingBehavior function to be called every time the property is accessed
3527
+ * @name addChainableMethod
3528
+ * @api public
3529
+ */
3530
+
3531
+ module.exports = function (ctx, name, method, chainingBehavior) {
3532
+ if (typeof chainingBehavior !== 'function') {
3533
+ chainingBehavior = function () { };
3534
+ }
3535
+
3536
+ var chainableBehavior = {
3537
+ method: method
3538
+ , chainingBehavior: chainingBehavior
3539
+ };
3540
+
3541
+ // save the methods so we can overwrite them later, if we need to.
3542
+ if (!ctx.__methods) {
3543
+ ctx.__methods = {};
3544
+ }
3545
+ ctx.__methods[name] = chainableBehavior;
3546
+
3547
+ Object.defineProperty(ctx, name,
3548
+ { get: function () {
3549
+ chainableBehavior.chainingBehavior.call(this);
3550
+
3551
+ var assert = function assert() {
3552
+ var old_ssfi = flag(this, 'ssfi');
3553
+ if (old_ssfi && config.includeStack === false)
3554
+ flag(this, 'ssfi', assert);
3555
+ var result = chainableBehavior.method.apply(this, arguments);
3556
+ return result === undefined ? this : result;
3557
+ };
3558
+
3559
+ // Use `__proto__` if available
3560
+ if (hasProtoSupport) {
3561
+ // Inherit all properties from the object by replacing the `Function` prototype
3562
+ var prototype = assert.__proto__ = Object.create(this);
3563
+ // Restore the `call` and `apply` methods from `Function`
3564
+ prototype.call = call;
3565
+ prototype.apply = apply;
3566
+ }
3567
+ // Otherwise, redefine all properties (slow!)
3568
+ else {
3569
+ var asserterNames = Object.getOwnPropertyNames(ctx);
3570
+ asserterNames.forEach(function (asserterName) {
3571
+ if (!excludeNames.test(asserterName)) {
3572
+ var pd = Object.getOwnPropertyDescriptor(ctx, asserterName);
3573
+ Object.defineProperty(assert, asserterName, pd);
3574
+ }
3575
+ });
3576
+ }
3577
+
3578
+ transferFlags(this, assert);
3579
+ return assert;
3580
+ }
3581
+ , configurable: true
3582
+ });
3583
+ };
3584
+
3585
+ });
3586
+
3587
+ require.register("chai/lib/chai/utils/addMethod.js", function (exports, module) {
3588
+ /*!
3589
+ * Chai - addMethod utility
3590
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
3591
+ * MIT Licensed
3592
+ */
3593
+
3594
+ var config = require('chai/lib/chai/config.js');
3595
+
3596
+ /**
3597
+ * ### .addMethod (ctx, name, method)
3598
+ *
3599
+ * Adds a method to the prototype of an object.
3600
+ *
3601
+ * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) {
3602
+ * var obj = utils.flag(this, 'object');
3603
+ * new chai.Assertion(obj).to.be.equal(str);
3604
+ * });
3605
+ *
3606
+ * Can also be accessed directly from `chai.Assertion`.
3607
+ *
3608
+ * chai.Assertion.addMethod('foo', fn);
3609
+ *
3610
+ * Then can be used as any other assertion.
3611
+ *
3612
+ * expect(fooStr).to.be.foo('bar');
3613
+ *
3614
+ * @param {Object} ctx object to which the method is added
3615
+ * @param {String} name of method to add
3616
+ * @param {Function} method function to be used for name
3617
+ * @name addMethod
3618
+ * @api public
3619
+ */
3620
+ var flag = require('chai/lib/chai/utils/flag.js');
3621
+
3622
+ module.exports = function (ctx, name, method) {
3623
+ ctx[name] = function () {
3624
+ var old_ssfi = flag(this, 'ssfi');
3625
+ if (old_ssfi && config.includeStack === false)
3626
+ flag(this, 'ssfi', ctx[name]);
3627
+ var result = method.apply(this, arguments);
3628
+ return result === undefined ? this : result;
3629
+ };
3630
+ };
3631
+
3632
+ });
3633
+
3634
+ require.register("chai/lib/chai/utils/addProperty.js", function (exports, module) {
3635
+ /*!
3636
+ * Chai - addProperty utility
3637
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
3638
+ * MIT Licensed
3639
+ */
3640
+
3641
+ /**
3642
+ * ### addProperty (ctx, name, getter)
3643
+ *
3644
+ * Adds a property to the prototype of an object.
3645
+ *
3646
+ * utils.addProperty(chai.Assertion.prototype, 'foo', function () {
3647
+ * var obj = utils.flag(this, 'object');
3648
+ * new chai.Assertion(obj).to.be.instanceof(Foo);
3649
+ * });
3650
+ *
3651
+ * Can also be accessed directly from `chai.Assertion`.
3652
+ *
3653
+ * chai.Assertion.addProperty('foo', fn);
3654
+ *
3655
+ * Then can be used as any other assertion.
3656
+ *
3657
+ * expect(myFoo).to.be.foo;
3658
+ *
3659
+ * @param {Object} ctx object to which the property is added
3660
+ * @param {String} name of property to add
3661
+ * @param {Function} getter function to be used for name
3662
+ * @name addProperty
3663
+ * @api public
3664
+ */
3665
+
3666
+ module.exports = function (ctx, name, getter) {
3667
+ Object.defineProperty(ctx, name,
3668
+ { get: function () {
3669
+ var result = getter.call(this);
3670
+ return result === undefined ? this : result;
3671
+ }
3672
+ , configurable: true
3673
+ });
3674
+ };
3675
+
3676
+ });
3677
+
3678
+ require.register("chai/lib/chai/utils/flag.js", function (exports, module) {
3679
+ /*!
3680
+ * Chai - flag utility
3681
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
3682
+ * MIT Licensed
3683
+ */
3684
+
3685
+ /**
3686
+ * ### flag(object ,key, [value])
3687
+ *
3688
+ * Get or set a flag value on an object. If a
3689
+ * value is provided it will be set, else it will
3690
+ * return the currently set value or `undefined` if
3691
+ * the value is not set.
3692
+ *
3693
+ * utils.flag(this, 'foo', 'bar'); // setter
3694
+ * utils.flag(this, 'foo'); // getter, returns `bar`
3695
+ *
3696
+ * @param {Object} object (constructed Assertion
3697
+ * @param {String} key
3698
+ * @param {Mixed} value (optional)
3699
+ * @name flag
3700
+ * @api private
3701
+ */
3702
+
3703
+ module.exports = function (obj, key, value) {
3704
+ var flags = obj.__flags || (obj.__flags = Object.create(null));
3705
+ if (arguments.length === 3) {
3706
+ flags[key] = value;
3707
+ } else {
3708
+ return flags[key];
3709
+ }
3710
+ };
3711
+
3712
+ });
3713
+
3714
+ require.register("chai/lib/chai/utils/getActual.js", function (exports, module) {
3715
+ /*!
3716
+ * Chai - getActual utility
3717
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
3718
+ * MIT Licensed
3719
+ */
3720
+
3721
+ /**
3722
+ * # getActual(object, [actual])
3723
+ *
3724
+ * Returns the `actual` value for an Assertion
3725
+ *
3726
+ * @param {Object} object (constructed Assertion)
3727
+ * @param {Arguments} chai.Assertion.prototype.assert arguments
3728
+ */
3729
+
3730
+ module.exports = function (obj, args) {
3731
+ return args.length > 4 ? args[4] : obj._obj;
3732
+ };
3733
+
3734
+ });
3735
+
3736
+ require.register("chai/lib/chai/utils/getEnumerableProperties.js", function (exports, module) {
3737
+ /*!
3738
+ * Chai - getEnumerableProperties utility
3739
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
3740
+ * MIT Licensed
3741
+ */
3742
+
3743
+ /**
3744
+ * ### .getEnumerableProperties(object)
3745
+ *
3746
+ * This allows the retrieval of enumerable property names of an object,
3747
+ * inherited or not.
3748
+ *
3749
+ * @param {Object} object
3750
+ * @returns {Array}
3751
+ * @name getEnumerableProperties
3752
+ * @api public
3753
+ */
3754
+
3755
+ module.exports = function getEnumerableProperties(object) {
3756
+ var result = [];
3757
+ for (var name in object) {
3758
+ result.push(name);
3759
+ }
3760
+ return result;
3761
+ };
3762
+
3763
+ });
3764
+
3765
+ require.register("chai/lib/chai/utils/getMessage.js", function (exports, module) {
3766
+ /*!
3767
+ * Chai - message composition utility
3768
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
3769
+ * MIT Licensed
3770
+ */
3771
+
3772
+ /*!
3773
+ * Module dependancies
3774
+ */
3775
+
3776
+ var flag = require('chai/lib/chai/utils/flag.js')
3777
+ , getActual = require('chai/lib/chai/utils/getActual.js')
3778
+ , inspect = require('chai/lib/chai/utils/inspect.js')
3779
+ , objDisplay = require('chai/lib/chai/utils/objDisplay.js');
3780
+
3781
+ /**
3782
+ * ### .getMessage(object, message, negateMessage)
3783
+ *
3784
+ * Construct the error message based on flags
3785
+ * and template tags. Template tags will return
3786
+ * a stringified inspection of the object referenced.
3787
+ *
3788
+ * Message template tags:
3789
+ * - `#{this}` current asserted object
3790
+ * - `#{act}` actual value
3791
+ * - `#{exp}` expected value
3792
+ *
3793
+ * @param {Object} object (constructed Assertion)
3794
+ * @param {Arguments} chai.Assertion.prototype.assert arguments
3795
+ * @name getMessage
3796
+ * @api public
3797
+ */
3798
+
3799
+ module.exports = function (obj, args) {
3800
+ var negate = flag(obj, 'negate')
3801
+ , val = flag(obj, 'object')
3802
+ , expected = args[3]
3803
+ , actual = getActual(obj, args)
3804
+ , msg = negate ? args[2] : args[1]
3805
+ , flagMsg = flag(obj, 'message');
3806
+
3807
+ if(typeof msg === "function") msg = msg();
3808
+ msg = msg || '';
3809
+ msg = msg
3810
+ .replace(/#{this}/g, objDisplay(val))
3811
+ .replace(/#{act}/g, objDisplay(actual))
3812
+ .replace(/#{exp}/g, objDisplay(expected));
3813
+
3814
+ return flagMsg ? flagMsg + ': ' + msg : msg;
3815
+ };
3816
+
3817
+ });
3818
+
3819
+ require.register("chai/lib/chai/utils/getName.js", function (exports, module) {
3820
+ /*!
3821
+ * Chai - getName utility
3822
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
3823
+ * MIT Licensed
3824
+ */
3825
+
3826
+ /**
3827
+ * # getName(func)
3828
+ *
3829
+ * Gets the name of a function, in a cross-browser way.
3830
+ *
3831
+ * @param {Function} a function (usually a constructor)
3832
+ */
3833
+
3834
+ module.exports = function (func) {
3835
+ if (func.name) return func.name;
3836
+
3837
+ var match = /^\s?function ([^(]*)\(/.exec(func);
3838
+ return match && match[1] ? match[1] : "";
3839
+ };
3840
+
3841
+ });
3842
+
3843
+ require.register("chai/lib/chai/utils/getPathValue.js", function (exports, module) {
3844
+ /*!
3845
+ * Chai - getPathValue utility
3846
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
3847
+ * @see https://github.com/logicalparadox/filtr
3848
+ * MIT Licensed
3849
+ */
3850
+
3851
+ /**
3852
+ * ### .getPathValue(path, object)
3853
+ *
3854
+ * This allows the retrieval of values in an
3855
+ * object given a string path.
3856
+ *
3857
+ * var obj = {
3858
+ * prop1: {
3859
+ * arr: ['a', 'b', 'c']
3860
+ * , str: 'Hello'
3861
+ * }
3862
+ * , prop2: {
3863
+ * arr: [ { nested: 'Universe' } ]
3864
+ * , str: 'Hello again!'
3865
+ * }
3866
+ * }
3867
+ *
3868
+ * The following would be the results.
3869
+ *
3870
+ * getPathValue('prop1.str', obj); // Hello
3871
+ * getPathValue('prop1.att[2]', obj); // b
3872
+ * getPathValue('prop2.arr[0].nested', obj); // Universe
3873
+ *
3874
+ * @param {String} path
3875
+ * @param {Object} object
3876
+ * @returns {Object} value or `undefined`
3877
+ * @name getPathValue
3878
+ * @api public
3879
+ */
3880
+
3881
+ var getPathValue = module.exports = function (path, obj) {
3882
+ var parsed = parsePath(path);
3883
+ return _getPathValue(parsed, obj);
3884
+ };
3885
+
3886
+ /*!
3887
+ * ## parsePath(path)
3888
+ *
3889
+ * Helper function used to parse string object
3890
+ * paths. Use in conjunction with `_getPathValue`.
3891
+ *
3892
+ * var parsed = parsePath('myobject.property.subprop');
3893
+ *
3894
+ * ### Paths:
3895
+ *
3896
+ * * Can be as near infinitely deep and nested
3897
+ * * Arrays are also valid using the formal `myobject.document[3].property`.
3898
+ *
3899
+ * @param {String} path
3900
+ * @returns {Object} parsed
3901
+ * @api private
3902
+ */
3903
+
3904
+ function parsePath (path) {
3905
+ var str = path.replace(/\[/g, '.[')
3906
+ , parts = str.match(/(\\\.|[^.]+?)+/g);
3907
+ return parts.map(function (value) {
3908
+ var re = /\[(\d+)\]$/
3909
+ , mArr = re.exec(value)
3910
+ if (mArr) return { i: parseFloat(mArr[1]) };
3911
+ else return { p: value };
3912
+ });
3913
+ };
3914
+
3915
+ /*!
3916
+ * ## _getPathValue(parsed, obj)
3917
+ *
3918
+ * Helper companion function for `.parsePath` that returns
3919
+ * the value located at the parsed address.
3920
+ *
3921
+ * var value = getPathValue(parsed, obj);
3922
+ *
3923
+ * @param {Object} parsed definition from `parsePath`.
3924
+ * @param {Object} object to search against
3925
+ * @returns {Object|Undefined} value
3926
+ * @api private
3927
+ */
3928
+
3929
+ function _getPathValue (parsed, obj) {
3930
+ var tmp = obj
3931
+ , res;
3932
+ for (var i = 0, l = parsed.length; i < l; i++) {
3933
+ var part = parsed[i];
3934
+ if (tmp) {
3935
+ if ('undefined' !== typeof part.p)
3936
+ tmp = tmp[part.p];
3937
+ else if ('undefined' !== typeof part.i)
3938
+ tmp = tmp[part.i];
3939
+ if (i == (l - 1)) res = tmp;
3940
+ } else {
3941
+ res = undefined;
3942
+ }
3943
+ }
3944
+ return res;
3945
+ };
3946
+
3947
+ });
3948
+
3949
+ require.register("chai/lib/chai/utils/getProperties.js", function (exports, module) {
3950
+ /*!
3951
+ * Chai - getProperties utility
3952
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
3953
+ * MIT Licensed
3954
+ */
3955
+
3956
+ /**
3957
+ * ### .getProperties(object)
3958
+ *
3959
+ * This allows the retrieval of property names of an object, enumerable or not,
3960
+ * inherited or not.
3961
+ *
3962
+ * @param {Object} object
3963
+ * @returns {Array}
3964
+ * @name getProperties
3965
+ * @api public
3966
+ */
3967
+
3968
+ module.exports = function getProperties(object) {
3969
+ var result = Object.getOwnPropertyNames(subject);
3970
+
3971
+ function addProperty(property) {
3972
+ if (result.indexOf(property) === -1) {
3973
+ result.push(property);
3974
+ }
3975
+ }
3976
+
3977
+ var proto = Object.getPrototypeOf(subject);
3978
+ while (proto !== null) {
3979
+ Object.getOwnPropertyNames(proto).forEach(addProperty);
3980
+ proto = Object.getPrototypeOf(proto);
3981
+ }
3982
+
3983
+ return result;
3984
+ };
3985
+
3986
+ });
3987
+
3988
+ require.register("chai/lib/chai/utils/index.js", function (exports, module) {
3989
+ /*!
3990
+ * chai
3991
+ * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com>
3992
+ * MIT Licensed
3993
+ */
3994
+
3995
+ /*!
3996
+ * Main exports
3997
+ */
3998
+
3999
+ var exports = module.exports = {};
4000
+
4001
+ /*!
4002
+ * test utility
4003
+ */
4004
+
4005
+ exports.test = require('chai/lib/chai/utils/test.js');
4006
+
4007
+ /*!
4008
+ * type utility
4009
+ */
4010
+
4011
+ exports.type = require('chai/lib/chai/utils/type.js');
4012
+
4013
+ /*!
4014
+ * message utility
4015
+ */
4016
+
4017
+ exports.getMessage = require('chai/lib/chai/utils/getMessage.js');
4018
+
4019
+ /*!
4020
+ * actual utility
4021
+ */
4022
+
4023
+ exports.getActual = require('chai/lib/chai/utils/getActual.js');
4024
+
4025
+ /*!
4026
+ * Inspect util
4027
+ */
4028
+
4029
+ exports.inspect = require('chai/lib/chai/utils/inspect.js');
4030
+
4031
+ /*!
4032
+ * Object Display util
4033
+ */
4034
+
4035
+ exports.objDisplay = require('chai/lib/chai/utils/objDisplay.js');
4036
+
4037
+ /*!
4038
+ * Flag utility
4039
+ */
4040
+
4041
+ exports.flag = require('chai/lib/chai/utils/flag.js');
4042
+
4043
+ /*!
4044
+ * Flag transferring utility
4045
+ */
4046
+
4047
+ exports.transferFlags = require('chai/lib/chai/utils/transferFlags.js');
4048
+
4049
+ /*!
4050
+ * Deep equal utility
4051
+ */
4052
+
4053
+ exports.eql = require('chaijs~deep-eql@0.1.3');
4054
+
4055
+ /*!
4056
+ * Deep path value
4057
+ */
4058
+
4059
+ exports.getPathValue = require('chai/lib/chai/utils/getPathValue.js');
4060
+
4061
+ /*!
4062
+ * Function name
4063
+ */
4064
+
4065
+ exports.getName = require('chai/lib/chai/utils/getName.js');
4066
+
4067
+ /*!
4068
+ * add Property
4069
+ */
4070
+
4071
+ exports.addProperty = require('chai/lib/chai/utils/addProperty.js');
4072
+
4073
+ /*!
4074
+ * add Method
4075
+ */
4076
+
4077
+ exports.addMethod = require('chai/lib/chai/utils/addMethod.js');
4078
+
4079
+ /*!
4080
+ * overwrite Property
4081
+ */
4082
+
4083
+ exports.overwriteProperty = require('chai/lib/chai/utils/overwriteProperty.js');
4084
+
4085
+ /*!
4086
+ * overwrite Method
4087
+ */
4088
+
4089
+ exports.overwriteMethod = require('chai/lib/chai/utils/overwriteMethod.js');
4090
+
4091
+ /*!
4092
+ * Add a chainable method
4093
+ */
4094
+
4095
+ exports.addChainableMethod = require('chai/lib/chai/utils/addChainableMethod.js');
4096
+
4097
+ /*!
4098
+ * Overwrite chainable method
4099
+ */
4100
+
4101
+ exports.overwriteChainableMethod = require('chai/lib/chai/utils/overwriteChainableMethod.js');
4102
+
4103
+
4104
+ });
4105
+
4106
+ require.register("chai/lib/chai/utils/inspect.js", function (exports, module) {
4107
+ // This is (almost) directly from Node.js utils
4108
+ // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
4109
+
4110
+ var getName = require('chai/lib/chai/utils/getName.js');
4111
+ var getProperties = require('chai/lib/chai/utils/getProperties.js');
4112
+ var getEnumerableProperties = require('chai/lib/chai/utils/getEnumerableProperties.js');
4113
+
4114
+ module.exports = inspect;
4115
+
4116
+ /**
4117
+ * Echos the value of a value. Trys to print the value out
4118
+ * in the best way possible given the different types.
4119
+ *
4120
+ * @param {Object} obj The object to print out.
4121
+ * @param {Boolean} showHidden Flag that shows hidden (not enumerable)
4122
+ * properties of objects.
4123
+ * @param {Number} depth Depth in which to descend in object. Default is 2.
4124
+ * @param {Boolean} colors Flag to turn on ANSI escape codes to color the
4125
+ * output. Default is false (no coloring).
4126
+ */
4127
+ function inspect(obj, showHidden, depth, colors) {
4128
+ var ctx = {
4129
+ showHidden: showHidden,
4130
+ seen: [],
4131
+ stylize: function (str) { return str; }
4132
+ };
4133
+ return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth));
4134
+ }
4135
+
4136
+ // Returns true if object is a DOM element.
4137
+ var isDOMElement = function (object) {
4138
+ if (typeof HTMLElement === 'object') {
4139
+ return object instanceof HTMLElement;
4140
+ } else {
4141
+ return object &&
4142
+ typeof object === 'object' &&
4143
+ object.nodeType === 1 &&
4144
+ typeof object.nodeName === 'string';
4145
+ }
4146
+ };
4147
+
4148
+ function formatValue(ctx, value, recurseTimes) {
4149
+ // Provide a hook for user-specified inspect functions.
4150
+ // Check that value is an object with an inspect function on it
4151
+ if (value && typeof value.inspect === 'function' &&
4152
+ // Filter out the util module, it's inspect function is special
4153
+ value.inspect !== exports.inspect &&
4154
+ // Also filter out any prototype objects using the circular check.
4155
+ !(value.constructor && value.constructor.prototype === value)) {
4156
+ var ret = value.inspect(recurseTimes);
4157
+ if (typeof ret !== 'string') {
4158
+ ret = formatValue(ctx, ret, recurseTimes);
4159
+ }
4160
+ return ret;
4161
+ }
4162
+
4163
+ // Primitive types cannot have properties
4164
+ var primitive = formatPrimitive(ctx, value);
4165
+ if (primitive) {
4166
+ return primitive;
4167
+ }
4168
+
4169
+ // If this is a DOM element, try to get the outer HTML.
4170
+ if (isDOMElement(value)) {
4171
+ if ('outerHTML' in value) {
4172
+ return value.outerHTML;
4173
+ // This value does not have an outerHTML attribute,
4174
+ // it could still be an XML element
4175
+ } else {
4176
+ // Attempt to serialize it
4177
+ try {
4178
+ if (document.xmlVersion) {
4179
+ var xmlSerializer = new XMLSerializer();
4180
+ return xmlSerializer.serializeToString(value);
4181
+ } else {
4182
+ // Firefox 11- do not support outerHTML
4183
+ // It does, however, support innerHTML
4184
+ // Use the following to render the element
4185
+ var ns = "http://www.w3.org/1999/xhtml";
4186
+ var container = document.createElementNS(ns, '_');
4187
+
4188
+ container.appendChild(value.cloneNode(false));
4189
+ html = container.innerHTML
4190
+ .replace('><', '>' + value.innerHTML + '<');
4191
+ container.innerHTML = '';
4192
+ return html;
4193
+ }
4194
+ } catch (err) {
4195
+ // This could be a non-native DOM implementation,
4196
+ // continue with the normal flow:
4197
+ // printing the element as if it is an object.
4198
+ }
4199
+ }
4200
+ }
4201
+
4202
+ // Look up the keys of the object.
4203
+ var visibleKeys = getEnumerableProperties(value);
4204
+ var keys = ctx.showHidden ? getProperties(value) : visibleKeys;
4205
+
4206
+ // Some type of object without properties can be shortcutted.
4207
+ // In IE, errors have a single `stack` property, or if they are vanilla `Error`,
4208
+ // a `stack` plus `description` property; ignore those for consistency.
4209
+ if (keys.length === 0 || (isError(value) && (
4210
+ (keys.length === 1 && keys[0] === 'stack') ||
4211
+ (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')
4212
+ ))) {
4213
+ if (typeof value === 'function') {
4214
+ var name = getName(value);
4215
+ var nameSuffix = name ? ': ' + name : '';
4216
+ return ctx.stylize('[Function' + nameSuffix + ']', 'special');
4217
+ }
4218
+ if (isRegExp(value)) {
4219
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
4220
+ }
4221
+ if (isDate(value)) {
4222
+ return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
4223
+ }
4224
+ if (isError(value)) {
4225
+ return formatError(value);
4226
+ }
4227
+ }
4228
+
4229
+ var base = '', array = false, braces = ['{', '}'];
4230
+
4231
+ // Make Array say that they are Array
4232
+ if (isArray(value)) {
4233
+ array = true;
4234
+ braces = ['[', ']'];
4235
+ }
4236
+
4237
+ // Make functions say that they are functions
4238
+ if (typeof value === 'function') {
4239
+ var name = getName(value);
4240
+ var nameSuffix = name ? ': ' + name : '';
4241
+ base = ' [Function' + nameSuffix + ']';
4242
+ }
4243
+
4244
+ // Make RegExps say that they are RegExps
4245
+ if (isRegExp(value)) {
4246
+ base = ' ' + RegExp.prototype.toString.call(value);
4247
+ }
4248
+
4249
+ // Make dates with properties first say the date
4250
+ if (isDate(value)) {
4251
+ base = ' ' + Date.prototype.toUTCString.call(value);
4252
+ }
4253
+
4254
+ // Make error with message first say the error
4255
+ if (isError(value)) {
4256
+ return formatError(value);
4257
+ }
4258
+
4259
+ if (keys.length === 0 && (!array || value.length == 0)) {
4260
+ return braces[0] + base + braces[1];
4261
+ }
4262
+
4263
+ if (recurseTimes < 0) {
4264
+ if (isRegExp(value)) {
4265
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
4266
+ } else {
4267
+ return ctx.stylize('[Object]', 'special');
4268
+ }
4269
+ }
4270
+
4271
+ ctx.seen.push(value);
4272
+
4273
+ var output;
4274
+ if (array) {
4275
+ output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
4276
+ } else {
4277
+ output = keys.map(function(key) {
4278
+ return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
4279
+ });
4280
+ }
4281
+
4282
+ ctx.seen.pop();
4283
+
4284
+ return reduceToSingleString(output, base, braces);
4285
+ }
4286
+
4287
+
4288
+ function formatPrimitive(ctx, value) {
4289
+ switch (typeof value) {
4290
+ case 'undefined':
4291
+ return ctx.stylize('undefined', 'undefined');
4292
+
4293
+ case 'string':
4294
+ var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
4295
+ .replace(/'/g, "\\'")
4296
+ .replace(/\\"/g, '"') + '\'';
4297
+ return ctx.stylize(simple, 'string');
4298
+
4299
+ case 'number':
4300
+ if (value === 0 && (1/value) === -Infinity) {
4301
+ return ctx.stylize('-0', 'number');
4302
+ }
4303
+ return ctx.stylize('' + value, 'number');
4304
+
4305
+ case 'boolean':
4306
+ return ctx.stylize('' + value, 'boolean');
4307
+ }
4308
+ // For some reason typeof null is "object", so special case here.
4309
+ if (value === null) {
4310
+ return ctx.stylize('null', 'null');
4311
+ }
4312
+ }
4313
+
4314
+
4315
+ function formatError(value) {
4316
+ return '[' + Error.prototype.toString.call(value) + ']';
4317
+ }
4318
+
4319
+
4320
+ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
4321
+ var output = [];
4322
+ for (var i = 0, l = value.length; i < l; ++i) {
4323
+ if (Object.prototype.hasOwnProperty.call(value, String(i))) {
4324
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
4325
+ String(i), true));
4326
+ } else {
4327
+ output.push('');
4328
+ }
4329
+ }
4330
+ keys.forEach(function(key) {
4331
+ if (!key.match(/^\d+$/)) {
4332
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
4333
+ key, true));
4334
+ }
4335
+ });
4336
+ return output;
4337
+ }
4338
+
4339
+
4340
+ function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
4341
+ var name, str;
4342
+ if (value.__lookupGetter__) {
4343
+ if (value.__lookupGetter__(key)) {
4344
+ if (value.__lookupSetter__(key)) {
4345
+ str = ctx.stylize('[Getter/Setter]', 'special');
4346
+ } else {
4347
+ str = ctx.stylize('[Getter]', 'special');
4348
+ }
4349
+ } else {
4350
+ if (value.__lookupSetter__(key)) {
4351
+ str = ctx.stylize('[Setter]', 'special');
4352
+ }
4353
+ }
4354
+ }
4355
+ if (visibleKeys.indexOf(key) < 0) {
4356
+ name = '[' + key + ']';
4357
+ }
4358
+ if (!str) {
4359
+ if (ctx.seen.indexOf(value[key]) < 0) {
4360
+ if (recurseTimes === null) {
4361
+ str = formatValue(ctx, value[key], null);
4362
+ } else {
4363
+ str = formatValue(ctx, value[key], recurseTimes - 1);
4364
+ }
4365
+ if (str.indexOf('\n') > -1) {
4366
+ if (array) {
4367
+ str = str.split('\n').map(function(line) {
4368
+ return ' ' + line;
4369
+ }).join('\n').substr(2);
4370
+ } else {
4371
+ str = '\n' + str.split('\n').map(function(line) {
4372
+ return ' ' + line;
4373
+ }).join('\n');
4374
+ }
4375
+ }
4376
+ } else {
4377
+ str = ctx.stylize('[Circular]', 'special');
4378
+ }
4379
+ }
4380
+ if (typeof name === 'undefined') {
4381
+ if (array && key.match(/^\d+$/)) {
4382
+ return str;
4383
+ }
4384
+ name = JSON.stringify('' + key);
4385
+ if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
4386
+ name = name.substr(1, name.length - 2);
4387
+ name = ctx.stylize(name, 'name');
4388
+ } else {
4389
+ name = name.replace(/'/g, "\\'")
4390
+ .replace(/\\"/g, '"')
4391
+ .replace(/(^"|"$)/g, "'");
4392
+ name = ctx.stylize(name, 'string');
4393
+ }
4394
+ }
4395
+
4396
+ return name + ': ' + str;
4397
+ }
4398
+
4399
+
4400
+ function reduceToSingleString(output, base, braces) {
4401
+ var numLinesEst = 0;
4402
+ var length = output.reduce(function(prev, cur) {
4403
+ numLinesEst++;
4404
+ if (cur.indexOf('\n') >= 0) numLinesEst++;
4405
+ return prev + cur.length + 1;
4406
+ }, 0);
4407
+
4408
+ if (length > 60) {
4409
+ return braces[0] +
4410
+ (base === '' ? '' : base + '\n ') +
4411
+ ' ' +
4412
+ output.join(',\n ') +
4413
+ ' ' +
4414
+ braces[1];
4415
+ }
4416
+
4417
+ return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
4418
+ }
4419
+
4420
+ function isArray(ar) {
4421
+ return Array.isArray(ar) ||
4422
+ (typeof ar === 'object' && objectToString(ar) === '[object Array]');
4423
+ }
4424
+
4425
+ function isRegExp(re) {
4426
+ return typeof re === 'object' && objectToString(re) === '[object RegExp]';
4427
+ }
4428
+
4429
+ function isDate(d) {
4430
+ return typeof d === 'object' && objectToString(d) === '[object Date]';
4431
+ }
4432
+
4433
+ function isError(e) {
4434
+ return typeof e === 'object' && objectToString(e) === '[object Error]';
4435
+ }
4436
+
4437
+ function objectToString(o) {
4438
+ return Object.prototype.toString.call(o);
4439
+ }
4440
+
4441
+ });
4442
+
4443
+ require.register("chai/lib/chai/utils/objDisplay.js", function (exports, module) {
4444
+ /*!
4445
+ * Chai - flag utility
4446
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
4447
+ * MIT Licensed
4448
+ */
4449
+
4450
+ /*!
4451
+ * Module dependancies
4452
+ */
4453
+
4454
+ var inspect = require('chai/lib/chai/utils/inspect.js');
4455
+ var config = require('chai/lib/chai/config.js');
4456
+
4457
+ /**
4458
+ * ### .objDisplay (object)
4459
+ *
4460
+ * Determines if an object or an array matches
4461
+ * criteria to be inspected in-line for error
4462
+ * messages or should be truncated.
4463
+ *
4464
+ * @param {Mixed} javascript object to inspect
4465
+ * @name objDisplay
4466
+ * @api public
4467
+ */
4468
+
4469
+ module.exports = function (obj) {
4470
+ var str = inspect(obj)
4471
+ , type = Object.prototype.toString.call(obj);
4472
+
4473
+ if (config.truncateThreshold && str.length >= config.truncateThreshold) {
4474
+ if (type === '[object Function]') {
4475
+ return !obj.name || obj.name === ''
4476
+ ? '[Function]'
4477
+ : '[Function: ' + obj.name + ']';
4478
+ } else if (type === '[object Array]') {
4479
+ return '[ Array(' + obj.length + ') ]';
4480
+ } else if (type === '[object Object]') {
4481
+ var keys = Object.keys(obj)
4482
+ , kstr = keys.length > 2
4483
+ ? keys.splice(0, 2).join(', ') + ', ...'
4484
+ : keys.join(', ');
4485
+ return '{ Object (' + kstr + ') }';
4486
+ } else {
4487
+ return str;
4488
+ }
4489
+ } else {
4490
+ return str;
4491
+ }
4492
+ };
4493
+
4494
+ });
4495
+
4496
+ require.register("chai/lib/chai/utils/overwriteMethod.js", function (exports, module) {
4497
+ /*!
4498
+ * Chai - overwriteMethod utility
4499
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
4500
+ * MIT Licensed
4501
+ */
4502
+
4503
+ /**
4504
+ * ### overwriteMethod (ctx, name, fn)
4505
+ *
4506
+ * Overwites an already existing method and provides
4507
+ * access to previous function. Must return function
4508
+ * to be used for name.
4509
+ *
4510
+ * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) {
4511
+ * return function (str) {
4512
+ * var obj = utils.flag(this, 'object');
4513
+ * if (obj instanceof Foo) {
4514
+ * new chai.Assertion(obj.value).to.equal(str);
4515
+ * } else {
4516
+ * _super.apply(this, arguments);
4517
+ * }
4518
+ * }
4519
+ * });
4520
+ *
4521
+ * Can also be accessed directly from `chai.Assertion`.
4522
+ *
4523
+ * chai.Assertion.overwriteMethod('foo', fn);
4524
+ *
4525
+ * Then can be used as any other assertion.
4526
+ *
4527
+ * expect(myFoo).to.equal('bar');
4528
+ *
4529
+ * @param {Object} ctx object whose method is to be overwritten
4530
+ * @param {String} name of method to overwrite
4531
+ * @param {Function} method function that returns a function to be used for name
4532
+ * @name overwriteMethod
4533
+ * @api public
4534
+ */
4535
+
4536
+ module.exports = function (ctx, name, method) {
4537
+ var _method = ctx[name]
4538
+ , _super = function () { return this; };
4539
+
4540
+ if (_method && 'function' === typeof _method)
4541
+ _super = _method;
4542
+
4543
+ ctx[name] = function () {
4544
+ var result = method(_super).apply(this, arguments);
4545
+ return result === undefined ? this : result;
4546
+ }
4547
+ };
4548
+
4549
+ });
4550
+
4551
+ require.register("chai/lib/chai/utils/overwriteProperty.js", function (exports, module) {
4552
+ /*!
4553
+ * Chai - overwriteProperty utility
4554
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
4555
+ * MIT Licensed
4556
+ */
4557
+
4558
+ /**
4559
+ * ### overwriteProperty (ctx, name, fn)
4560
+ *
4561
+ * Overwites an already existing property getter and provides
4562
+ * access to previous value. Must return function to use as getter.
4563
+ *
4564
+ * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) {
4565
+ * return function () {
4566
+ * var obj = utils.flag(this, 'object');
4567
+ * if (obj instanceof Foo) {
4568
+ * new chai.Assertion(obj.name).to.equal('bar');
4569
+ * } else {
4570
+ * _super.call(this);
4571
+ * }
4572
+ * }
4573
+ * });
4574
+ *
4575
+ *
4576
+ * Can also be accessed directly from `chai.Assertion`.
4577
+ *
4578
+ * chai.Assertion.overwriteProperty('foo', fn);
4579
+ *
4580
+ * Then can be used as any other assertion.
4581
+ *
4582
+ * expect(myFoo).to.be.ok;
4583
+ *
4584
+ * @param {Object} ctx object whose property is to be overwritten
4585
+ * @param {String} name of property to overwrite
4586
+ * @param {Function} getter function that returns a getter function to be used for name
4587
+ * @name overwriteProperty
4588
+ * @api public
4589
+ */
4590
+
4591
+ module.exports = function (ctx, name, getter) {
4592
+ var _get = Object.getOwnPropertyDescriptor(ctx, name)
4593
+ , _super = function () {};
4594
+
4595
+ if (_get && 'function' === typeof _get.get)
4596
+ _super = _get.get
4597
+
4598
+ Object.defineProperty(ctx, name,
4599
+ { get: function () {
4600
+ var result = getter(_super).call(this);
4601
+ return result === undefined ? this : result;
4602
+ }
4603
+ , configurable: true
4604
+ });
4605
+ };
4606
+
4607
+ });
4608
+
4609
+ require.register("chai/lib/chai/utils/overwriteChainableMethod.js", function (exports, module) {
4610
+ /*!
4611
+ * Chai - overwriteChainableMethod utility
4612
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
4613
+ * MIT Licensed
4614
+ */
4615
+
4616
+ /**
4617
+ * ### overwriteChainableMethod (ctx, name, fn)
4618
+ *
4619
+ * Overwites an already existing chainable method
4620
+ * and provides access to the previous function or
4621
+ * property. Must return functions to be used for
4622
+ * name.
4623
+ *
4624
+ * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length',
4625
+ * function (_super) {
4626
+ * }
4627
+ * , function (_super) {
4628
+ * }
4629
+ * );
4630
+ *
4631
+ * Can also be accessed directly from `chai.Assertion`.
4632
+ *
4633
+ * chai.Assertion.overwriteChainableMethod('foo', fn, fn);
4634
+ *
4635
+ * Then can be used as any other assertion.
4636
+ *
4637
+ * expect(myFoo).to.have.length(3);
4638
+ * expect(myFoo).to.have.length.above(3);
4639
+ *
4640
+ * @param {Object} ctx object whose method / property is to be overwritten
4641
+ * @param {String} name of method / property to overwrite
4642
+ * @param {Function} method function that returns a function to be used for name
4643
+ * @param {Function} chainingBehavior function that returns a function to be used for property
4644
+ * @name overwriteChainableMethod
4645
+ * @api public
4646
+ */
4647
+
4648
+ module.exports = function (ctx, name, method, chainingBehavior) {
4649
+ var chainableBehavior = ctx.__methods[name];
4650
+
4651
+ var _chainingBehavior = chainableBehavior.chainingBehavior;
4652
+ chainableBehavior.chainingBehavior = function () {
4653
+ var result = chainingBehavior(_chainingBehavior).call(this);
4654
+ return result === undefined ? this : result;
4655
+ };
4656
+
4657
+ var _method = chainableBehavior.method;
4658
+ chainableBehavior.method = function () {
4659
+ var result = method(_method).apply(this, arguments);
4660
+ return result === undefined ? this : result;
4661
+ };
4662
+ };
4663
+
4664
+ });
4665
+
4666
+ require.register("chai/lib/chai/utils/test.js", function (exports, module) {
4667
+ /*!
4668
+ * Chai - test utility
4669
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
4670
+ * MIT Licensed
4671
+ */
4672
+
4673
+ /*!
4674
+ * Module dependancies
4675
+ */
4676
+
4677
+ var flag = require('chai/lib/chai/utils/flag.js');
4678
+
4679
+ /**
4680
+ * # test(object, expression)
4681
+ *
4682
+ * Test and object for expression.
4683
+ *
4684
+ * @param {Object} object (constructed Assertion)
4685
+ * @param {Arguments} chai.Assertion.prototype.assert arguments
4686
+ */
4687
+
4688
+ module.exports = function (obj, args) {
4689
+ var negate = flag(obj, 'negate')
4690
+ , expr = args[0];
4691
+ return negate ? !expr : expr;
4692
+ };
4693
+
4694
+ });
4695
+
4696
+ require.register("chai/lib/chai/utils/transferFlags.js", function (exports, module) {
4697
+ /*!
4698
+ * Chai - transferFlags utility
4699
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
4700
+ * MIT Licensed
4701
+ */
4702
+
4703
+ /**
4704
+ * ### transferFlags(assertion, object, includeAll = true)
4705
+ *
4706
+ * Transfer all the flags for `assertion` to `object`. If
4707
+ * `includeAll` is set to `false`, then the base Chai
4708
+ * assertion flags (namely `object`, `ssfi`, and `message`)
4709
+ * will not be transferred.
4710
+ *
4711
+ *
4712
+ * var newAssertion = new Assertion();
4713
+ * utils.transferFlags(assertion, newAssertion);
4714
+ *
4715
+ * var anotherAsseriton = new Assertion(myObj);
4716
+ * utils.transferFlags(assertion, anotherAssertion, false);
4717
+ *
4718
+ * @param {Assertion} assertion the assertion to transfer the flags from
4719
+ * @param {Object} object the object to transfer the flags too; usually a new assertion
4720
+ * @param {Boolean} includeAll
4721
+ * @name getAllFlags
4722
+ * @api private
4723
+ */
4724
+
4725
+ module.exports = function (assertion, object, includeAll) {
4726
+ var flags = assertion.__flags || (assertion.__flags = Object.create(null));
4727
+
4728
+ if (!object.__flags) {
4729
+ object.__flags = Object.create(null);
4730
+ }
4731
+
4732
+ includeAll = arguments.length === 3 ? includeAll : true;
4733
+
4734
+ for (var flag in flags) {
4735
+ if (includeAll ||
4736
+ (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) {
4737
+ object.__flags[flag] = flags[flag];
4738
+ }
4739
+ }
4740
+ };
4741
+
4742
+ });
4743
+
4744
+ require.register("chai/lib/chai/utils/type.js", function (exports, module) {
4745
+ /*!
4746
+ * Chai - type utility
4747
+ * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
4748
+ * MIT Licensed
4749
+ */
4750
+
4751
+ /*!
4752
+ * Detectable javascript natives
4753
+ */
4754
+
4755
+ var natives = {
4756
+ '[object Arguments]': 'arguments'
4757
+ , '[object Array]': 'array'
4758
+ , '[object Date]': 'date'
4759
+ , '[object Function]': 'function'
4760
+ , '[object Number]': 'number'
4761
+ , '[object RegExp]': 'regexp'
4762
+ , '[object String]': 'string'
4763
+ };
4764
+
4765
+ /**
4766
+ * ### type(object)
4767
+ *
4768
+ * Better implementation of `typeof` detection that can
4769
+ * be used cross-browser. Handles the inconsistencies of
4770
+ * Array, `null`, and `undefined` detection.
4771
+ *
4772
+ * utils.type({}) // 'object'
4773
+ * utils.type(null) // `null'
4774
+ * utils.type(undefined) // `undefined`
4775
+ * utils.type([]) // `array`
4776
+ *
4777
+ * @param {Mixed} object to detect type of
4778
+ * @name type
4779
+ * @api private
4780
+ */
4781
+
4782
+ module.exports = function (obj) {
4783
+ var str = Object.prototype.toString.call(obj);
4784
+ if (natives[str]) return natives[str];
4785
+ if (obj === null) return 'null';
4786
+ if (obj === undefined) return 'undefined';
4787
+ if (obj === Object(obj)) return 'object';
4788
+ return typeof obj;
4789
+ };
4790
+
4791
+ });
4792
+
4793
+ if (typeof exports == "object") {
4794
+ module.exports = require("chai");
4795
+ } else if (typeof define == "function" && define.amd) {
4796
+ define("chai", [], function(){ return require("chai"); });
4797
+ } else {
4798
+ (this || window)["chai"] = require("chai");
4799
+ }
4800
+ })()