chai.js (349596B)
1 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.chai = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ 2 module.exports = require('./lib/chai'); 3 4 },{"./lib/chai":2}],2:[function(require,module,exports){ 5 /*! 6 * chai 7 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> 8 * MIT Licensed 9 */ 10 11 var used = []; 12 13 /*! 14 * Chai version 15 */ 16 17 exports.version = '4.3.3'; 18 19 /*! 20 * Assertion Error 21 */ 22 23 exports.AssertionError = require('assertion-error'); 24 25 /*! 26 * Utils for plugins (not exported) 27 */ 28 29 var util = require('./chai/utils'); 30 31 /** 32 * # .use(function) 33 * 34 * Provides a way to extend the internals of Chai. 35 * 36 * @param {Function} 37 * @returns {this} for chaining 38 * @api public 39 */ 40 41 exports.use = function (fn) { 42 if (!~used.indexOf(fn)) { 43 fn(exports, util); 44 used.push(fn); 45 } 46 47 return exports; 48 }; 49 50 /*! 51 * Utility Functions 52 */ 53 54 exports.util = util; 55 56 /*! 57 * Configuration 58 */ 59 60 var config = require('./chai/config'); 61 exports.config = config; 62 63 /*! 64 * Primary `Assertion` prototype 65 */ 66 67 var assertion = require('./chai/assertion'); 68 exports.use(assertion); 69 70 /*! 71 * Core Assertions 72 */ 73 74 var core = require('./chai/core/assertions'); 75 exports.use(core); 76 77 /*! 78 * Expect interface 79 */ 80 81 var expect = require('./chai/interface/expect'); 82 exports.use(expect); 83 84 /*! 85 * Should interface 86 */ 87 88 var should = require('./chai/interface/should'); 89 exports.use(should); 90 91 /*! 92 * Assert interface 93 */ 94 95 var assert = require('./chai/interface/assert'); 96 exports.use(assert); 97 98 },{"./chai/assertion":3,"./chai/config":4,"./chai/core/assertions":5,"./chai/interface/assert":6,"./chai/interface/expect":7,"./chai/interface/should":8,"./chai/utils":23,"assertion-error":34}],3:[function(require,module,exports){ 99 /*! 100 * chai 101 * http://chaijs.com 102 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> 103 * MIT Licensed 104 */ 105 106 var config = require('./config'); 107 108 module.exports = function (_chai, util) { 109 /*! 110 * Module dependencies. 111 */ 112 113 var AssertionError = _chai.AssertionError 114 , flag = util.flag; 115 116 /*! 117 * Module export. 118 */ 119 120 _chai.Assertion = Assertion; 121 122 /*! 123 * Assertion Constructor 124 * 125 * Creates object for chaining. 126 * 127 * `Assertion` objects contain metadata in the form of flags. Three flags can 128 * be assigned during instantiation by passing arguments to this constructor: 129 * 130 * - `object`: This flag contains the target of the assertion. For example, in 131 * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will 132 * contain `numKittens` so that the `equal` assertion can reference it when 133 * needed. 134 * 135 * - `message`: This flag contains an optional custom error message to be 136 * prepended to the error message that's generated by the assertion when it 137 * fails. 138 * 139 * - `ssfi`: This flag stands for "start stack function indicator". It 140 * contains a function reference that serves as the starting point for 141 * removing frames from the stack trace of the error that's created by the 142 * assertion when it fails. The goal is to provide a cleaner stack trace to 143 * end users by removing Chai's internal functions. Note that it only works 144 * in environments that support `Error.captureStackTrace`, and only when 145 * `Chai.config.includeStack` hasn't been set to `false`. 146 * 147 * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag 148 * should retain its current value, even as assertions are chained off of 149 * this object. This is usually set to `true` when creating a new assertion 150 * from within another assertion. It's also temporarily set to `true` before 151 * an overwritten assertion gets called by the overwriting assertion. 152 * 153 * @param {Mixed} obj target of the assertion 154 * @param {String} msg (optional) custom error message 155 * @param {Function} ssfi (optional) starting point for removing stack frames 156 * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked 157 * @api private 158 */ 159 160 function Assertion (obj, msg, ssfi, lockSsfi) { 161 flag(this, 'ssfi', ssfi || Assertion); 162 flag(this, 'lockSsfi', lockSsfi); 163 flag(this, 'object', obj); 164 flag(this, 'message', msg); 165 166 return util.proxify(this); 167 } 168 169 Object.defineProperty(Assertion, 'includeStack', { 170 get: function() { 171 console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); 172 return config.includeStack; 173 }, 174 set: function(value) { 175 console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); 176 config.includeStack = value; 177 } 178 }); 179 180 Object.defineProperty(Assertion, 'showDiff', { 181 get: function() { 182 console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); 183 return config.showDiff; 184 }, 185 set: function(value) { 186 console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); 187 config.showDiff = value; 188 } 189 }); 190 191 Assertion.addProperty = function (name, fn) { 192 util.addProperty(this.prototype, name, fn); 193 }; 194 195 Assertion.addMethod = function (name, fn) { 196 util.addMethod(this.prototype, name, fn); 197 }; 198 199 Assertion.addChainableMethod = function (name, fn, chainingBehavior) { 200 util.addChainableMethod(this.prototype, name, fn, chainingBehavior); 201 }; 202 203 Assertion.overwriteProperty = function (name, fn) { 204 util.overwriteProperty(this.prototype, name, fn); 205 }; 206 207 Assertion.overwriteMethod = function (name, fn) { 208 util.overwriteMethod(this.prototype, name, fn); 209 }; 210 211 Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { 212 util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); 213 }; 214 215 /** 216 * ### .assert(expression, message, negateMessage, expected, actual, showDiff) 217 * 218 * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. 219 * 220 * @name assert 221 * @param {Philosophical} expression to be tested 222 * @param {String|Function} message or function that returns message to display if expression fails 223 * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails 224 * @param {Mixed} expected value (remember to check for negation) 225 * @param {Mixed} actual (optional) will default to `this.obj` 226 * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails 227 * @api private 228 */ 229 230 Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { 231 var ok = util.test(this, arguments); 232 if (false !== showDiff) showDiff = true; 233 if (undefined === expected && undefined === _actual) showDiff = false; 234 if (true !== config.showDiff) showDiff = false; 235 236 if (!ok) { 237 msg = util.getMessage(this, arguments); 238 var actual = util.getActual(this, arguments); 239 var assertionErrorObjectProperties = { 240 actual: actual 241 , expected: expected 242 , showDiff: showDiff 243 }; 244 245 var operator = util.getOperator(this, arguments); 246 if (operator) { 247 assertionErrorObjectProperties.operator = operator; 248 } 249 250 throw new AssertionError( 251 msg, 252 assertionErrorObjectProperties, 253 (config.includeStack) ? this.assert : flag(this, 'ssfi')); 254 } 255 }; 256 257 /*! 258 * ### ._obj 259 * 260 * Quick reference to stored `actual` value for plugin developers. 261 * 262 * @api private 263 */ 264 265 Object.defineProperty(Assertion.prototype, '_obj', 266 { get: function () { 267 return flag(this, 'object'); 268 } 269 , set: function (val) { 270 flag(this, 'object', val); 271 } 272 }); 273 }; 274 275 },{"./config":4}],4:[function(require,module,exports){ 276 module.exports = { 277 278 /** 279 * ### config.includeStack 280 * 281 * User configurable property, influences whether stack trace 282 * is included in Assertion error message. Default of false 283 * suppresses stack trace in the error message. 284 * 285 * chai.config.includeStack = true; // enable stack on error 286 * 287 * @param {Boolean} 288 * @api public 289 */ 290 291 includeStack: false, 292 293 /** 294 * ### config.showDiff 295 * 296 * User configurable property, influences whether or not 297 * the `showDiff` flag should be included in the thrown 298 * AssertionErrors. `false` will always be `false`; `true` 299 * will be true when the assertion has requested a diff 300 * be shown. 301 * 302 * @param {Boolean} 303 * @api public 304 */ 305 306 showDiff: true, 307 308 /** 309 * ### config.truncateThreshold 310 * 311 * User configurable property, sets length threshold for actual and 312 * expected values in assertion errors. If this threshold is exceeded, for 313 * example for large data structures, the value is replaced with something 314 * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. 315 * 316 * Set it to zero if you want to disable truncating altogether. 317 * 318 * This is especially userful when doing assertions on arrays: having this 319 * set to a reasonable large value makes the failure messages readily 320 * inspectable. 321 * 322 * chai.config.truncateThreshold = 0; // disable truncating 323 * 324 * @param {Number} 325 * @api public 326 */ 327 328 truncateThreshold: 40, 329 330 /** 331 * ### config.useProxy 332 * 333 * User configurable property, defines if chai will use a Proxy to throw 334 * an error when a non-existent property is read, which protects users 335 * from typos when using property-based assertions. 336 * 337 * Set it to false if you want to disable this feature. 338 * 339 * chai.config.useProxy = false; // disable use of Proxy 340 * 341 * This feature is automatically disabled regardless of this config value 342 * in environments that don't support proxies. 343 * 344 * @param {Boolean} 345 * @api public 346 */ 347 348 useProxy: true, 349 350 /** 351 * ### config.proxyExcludedKeys 352 * 353 * User configurable property, defines which properties should be ignored 354 * instead of throwing an error if they do not exist on the assertion. 355 * This is only applied if the environment Chai is running in supports proxies and 356 * if the `useProxy` configuration setting is enabled. 357 * By default, `then` and `inspect` will not throw an error if they do not exist on the 358 * assertion object because the `.inspect` property is read by `util.inspect` (for example, when 359 * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. 360 * 361 * // By default these keys will not throw an error if they do not exist on the assertion object 362 * chai.config.proxyExcludedKeys = ['then', 'inspect']; 363 * 364 * @param {Array} 365 * @api public 366 */ 367 368 proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON'] 369 }; 370 371 },{}],5:[function(require,module,exports){ 372 /*! 373 * chai 374 * http://chaijs.com 375 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> 376 * MIT Licensed 377 */ 378 379 module.exports = function (chai, _) { 380 var Assertion = chai.Assertion 381 , AssertionError = chai.AssertionError 382 , flag = _.flag; 383 384 /** 385 * ### Language Chains 386 * 387 * The following are provided as chainable getters to improve the readability 388 * of your assertions. 389 * 390 * **Chains** 391 * 392 * - to 393 * - be 394 * - been 395 * - is 396 * - that 397 * - which 398 * - and 399 * - has 400 * - have 401 * - with 402 * - at 403 * - of 404 * - same 405 * - but 406 * - does 407 * - still 408 * - also 409 * 410 * @name language chains 411 * @namespace BDD 412 * @api public 413 */ 414 415 [ 'to', 'be', 'been', 'is' 416 , 'and', 'has', 'have', 'with' 417 , 'that', 'which', 'at', 'of' 418 , 'same', 'but', 'does', 'still', "also" ].forEach(function (chain) { 419 Assertion.addProperty(chain); 420 }); 421 422 /** 423 * ### .not 424 * 425 * Negates all assertions that follow in the chain. 426 * 427 * expect(function () {}).to.not.throw(); 428 * expect({a: 1}).to.not.have.property('b'); 429 * expect([1, 2]).to.be.an('array').that.does.not.include(3); 430 * 431 * Just because you can negate any assertion with `.not` doesn't mean you 432 * should. With great power comes great responsibility. It's often best to 433 * assert that the one expected output was produced, rather than asserting 434 * that one of countless unexpected outputs wasn't produced. See individual 435 * assertions for specific guidance. 436 * 437 * expect(2).to.equal(2); // Recommended 438 * expect(2).to.not.equal(1); // Not recommended 439 * 440 * @name not 441 * @namespace BDD 442 * @api public 443 */ 444 445 Assertion.addProperty('not', function () { 446 flag(this, 'negate', true); 447 }); 448 449 /** 450 * ### .deep 451 * 452 * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property` 453 * assertions that follow in the chain to use deep equality instead of strict 454 * (`===`) equality. See the `deep-eql` project page for info on the deep 455 * equality algorithm: https://github.com/chaijs/deep-eql. 456 * 457 * // Target object deeply (but not strictly) equals `{a: 1}` 458 * expect({a: 1}).to.deep.equal({a: 1}); 459 * expect({a: 1}).to.not.equal({a: 1}); 460 * 461 * // Target array deeply (but not strictly) includes `{a: 1}` 462 * expect([{a: 1}]).to.deep.include({a: 1}); 463 * expect([{a: 1}]).to.not.include({a: 1}); 464 * 465 * // Target object deeply (but not strictly) includes `x: {a: 1}` 466 * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); 467 * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); 468 * 469 * // Target array deeply (but not strictly) has member `{a: 1}` 470 * expect([{a: 1}]).to.have.deep.members([{a: 1}]); 471 * expect([{a: 1}]).to.not.have.members([{a: 1}]); 472 * 473 * // Target set deeply (but not strictly) has key `{a: 1}` 474 * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]); 475 * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]); 476 * 477 * // Target object deeply (but not strictly) has property `x: {a: 1}` 478 * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); 479 * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); 480 * 481 * @name deep 482 * @namespace BDD 483 * @api public 484 */ 485 486 Assertion.addProperty('deep', function () { 487 flag(this, 'deep', true); 488 }); 489 490 /** 491 * ### .nested 492 * 493 * Enables dot- and bracket-notation in all `.property` and `.include` 494 * assertions that follow in the chain. 495 * 496 * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); 497 * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); 498 * 499 * If `.` or `[]` are part of an actual property name, they can be escaped by 500 * adding two backslashes before them. 501 * 502 * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); 503 * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'}); 504 * 505 * `.nested` cannot be combined with `.own`. 506 * 507 * @name nested 508 * @namespace BDD 509 * @api public 510 */ 511 512 Assertion.addProperty('nested', function () { 513 flag(this, 'nested', true); 514 }); 515 516 /** 517 * ### .own 518 * 519 * Causes all `.property` and `.include` assertions that follow in the chain 520 * to ignore inherited properties. 521 * 522 * Object.prototype.b = 2; 523 * 524 * expect({a: 1}).to.have.own.property('a'); 525 * expect({a: 1}).to.have.property('b'); 526 * expect({a: 1}).to.not.have.own.property('b'); 527 * 528 * expect({a: 1}).to.own.include({a: 1}); 529 * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); 530 * 531 * `.own` cannot be combined with `.nested`. 532 * 533 * @name own 534 * @namespace BDD 535 * @api public 536 */ 537 538 Assertion.addProperty('own', function () { 539 flag(this, 'own', true); 540 }); 541 542 /** 543 * ### .ordered 544 * 545 * Causes all `.members` assertions that follow in the chain to require that 546 * members be in the same order. 547 * 548 * expect([1, 2]).to.have.ordered.members([1, 2]) 549 * .but.not.have.ordered.members([2, 1]); 550 * 551 * When `.include` and `.ordered` are combined, the ordering begins at the 552 * start of both arrays. 553 * 554 * expect([1, 2, 3]).to.include.ordered.members([1, 2]) 555 * .but.not.include.ordered.members([2, 3]); 556 * 557 * @name ordered 558 * @namespace BDD 559 * @api public 560 */ 561 562 Assertion.addProperty('ordered', function () { 563 flag(this, 'ordered', true); 564 }); 565 566 /** 567 * ### .any 568 * 569 * Causes all `.keys` assertions that follow in the chain to only require that 570 * the target have at least one of the given keys. This is the opposite of 571 * `.all`, which requires that the target have all of the given keys. 572 * 573 * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); 574 * 575 * See the `.keys` doc for guidance on when to use `.any` or `.all`. 576 * 577 * @name any 578 * @namespace BDD 579 * @api public 580 */ 581 582 Assertion.addProperty('any', function () { 583 flag(this, 'any', true); 584 flag(this, 'all', false); 585 }); 586 587 /** 588 * ### .all 589 * 590 * Causes all `.keys` assertions that follow in the chain to require that the 591 * target have all of the given keys. This is the opposite of `.any`, which 592 * only requires that the target have at least one of the given keys. 593 * 594 * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); 595 * 596 * Note that `.all` is used by default when neither `.all` nor `.any` are 597 * added earlier in the chain. However, it's often best to add `.all` anyway 598 * because it improves readability. 599 * 600 * See the `.keys` doc for guidance on when to use `.any` or `.all`. 601 * 602 * @name all 603 * @namespace BDD 604 * @api public 605 */ 606 607 Assertion.addProperty('all', function () { 608 flag(this, 'all', true); 609 flag(this, 'any', false); 610 }); 611 612 /** 613 * ### .a(type[, msg]) 614 * 615 * Asserts that the target's type is equal to the given string `type`. Types 616 * are case insensitive. See the `type-detect` project page for info on the 617 * type detection algorithm: https://github.com/chaijs/type-detect. 618 * 619 * expect('foo').to.be.a('string'); 620 * expect({a: 1}).to.be.an('object'); 621 * expect(null).to.be.a('null'); 622 * expect(undefined).to.be.an('undefined'); 623 * expect(new Error).to.be.an('error'); 624 * expect(Promise.resolve()).to.be.a('promise'); 625 * expect(new Float32Array).to.be.a('float32array'); 626 * expect(Symbol()).to.be.a('symbol'); 627 * 628 * `.a` supports objects that have a custom type set via `Symbol.toStringTag`. 629 * 630 * var myObj = { 631 * [Symbol.toStringTag]: 'myCustomType' 632 * }; 633 * 634 * expect(myObj).to.be.a('myCustomType').but.not.an('object'); 635 * 636 * It's often best to use `.a` to check a target's type before making more 637 * assertions on the same target. That way, you avoid unexpected behavior from 638 * any assertion that does different things based on the target's type. 639 * 640 * expect([1, 2, 3]).to.be.an('array').that.includes(2); 641 * expect([]).to.be.an('array').that.is.empty; 642 * 643 * Add `.not` earlier in the chain to negate `.a`. However, it's often best to 644 * assert that the target is the expected type, rather than asserting that it 645 * isn't one of many unexpected types. 646 * 647 * expect('foo').to.be.a('string'); // Recommended 648 * expect('foo').to.not.be.an('array'); // Not recommended 649 * 650 * `.a` accepts an optional `msg` argument which is a custom error message to 651 * show when the assertion fails. The message can also be given as the second 652 * argument to `expect`. 653 * 654 * expect(1).to.be.a('string', 'nooo why fail??'); 655 * expect(1, 'nooo why fail??').to.be.a('string'); 656 * 657 * `.a` can also be used as a language chain to improve the readability of 658 * your assertions. 659 * 660 * expect({b: 2}).to.have.a.property('b'); 661 * 662 * The alias `.an` can be used interchangeably with `.a`. 663 * 664 * @name a 665 * @alias an 666 * @param {String} type 667 * @param {String} msg _optional_ 668 * @namespace BDD 669 * @api public 670 */ 671 672 function an (type, msg) { 673 if (msg) flag(this, 'message', msg); 674 type = type.toLowerCase(); 675 var obj = flag(this, 'object') 676 , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; 677 678 this.assert( 679 type === _.type(obj).toLowerCase() 680 , 'expected #{this} to be ' + article + type 681 , 'expected #{this} not to be ' + article + type 682 ); 683 } 684 685 Assertion.addChainableMethod('an', an); 686 Assertion.addChainableMethod('a', an); 687 688 /** 689 * ### .include(val[, msg]) 690 * 691 * When the target is a string, `.include` asserts that the given string `val` 692 * is a substring of the target. 693 * 694 * expect('foobar').to.include('foo'); 695 * 696 * When the target is an array, `.include` asserts that the given `val` is a 697 * member of the target. 698 * 699 * expect([1, 2, 3]).to.include(2); 700 * 701 * When the target is an object, `.include` asserts that the given object 702 * `val`'s properties are a subset of the target's properties. 703 * 704 * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2}); 705 * 706 * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a 707 * member of the target. SameValueZero equality algorithm is used. 708 * 709 * expect(new Set([1, 2])).to.include(2); 710 * 711 * When the target is a Map, `.include` asserts that the given `val` is one of 712 * the values of the target. SameValueZero equality algorithm is used. 713 * 714 * expect(new Map([['a', 1], ['b', 2]])).to.include(2); 715 * 716 * Because `.include` does different things based on the target's type, it's 717 * important to check the target's type before using `.include`. See the `.a` 718 * doc for info on testing a target's type. 719 * 720 * expect([1, 2, 3]).to.be.an('array').that.includes(2); 721 * 722 * By default, strict (`===`) equality is used to compare array members and 723 * object properties. Add `.deep` earlier in the chain to use deep equality 724 * instead (WeakSet targets are not supported). See the `deep-eql` project 725 * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. 726 * 727 * // Target array deeply (but not strictly) includes `{a: 1}` 728 * expect([{a: 1}]).to.deep.include({a: 1}); 729 * expect([{a: 1}]).to.not.include({a: 1}); 730 * 731 * // Target object deeply (but not strictly) includes `x: {a: 1}` 732 * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); 733 * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); 734 * 735 * By default, all of the target's properties are searched when working with 736 * objects. This includes properties that are inherited and/or non-enumerable. 737 * Add `.own` earlier in the chain to exclude the target's inherited 738 * properties from the search. 739 * 740 * Object.prototype.b = 2; 741 * 742 * expect({a: 1}).to.own.include({a: 1}); 743 * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); 744 * 745 * Note that a target object is always only searched for `val`'s own 746 * enumerable properties. 747 * 748 * `.deep` and `.own` can be combined. 749 * 750 * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}}); 751 * 752 * Add `.nested` earlier in the chain to enable dot- and bracket-notation when 753 * referencing nested properties. 754 * 755 * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); 756 * 757 * If `.` or `[]` are part of an actual property name, they can be escaped by 758 * adding two backslashes before them. 759 * 760 * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2}); 761 * 762 * `.deep` and `.nested` can be combined. 763 * 764 * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}}); 765 * 766 * `.own` and `.nested` cannot be combined. 767 * 768 * Add `.not` earlier in the chain to negate `.include`. 769 * 770 * expect('foobar').to.not.include('taco'); 771 * expect([1, 2, 3]).to.not.include(4); 772 * 773 * However, it's dangerous to negate `.include` when the target is an object. 774 * The problem is that it creates uncertain expectations by asserting that the 775 * target object doesn't have all of `val`'s key/value pairs but may or may 776 * not have some of them. It's often best to identify the exact output that's 777 * expected, and then write an assertion that only accepts that exact output. 778 * 779 * When the target object isn't even expected to have `val`'s keys, it's 780 * often best to assert exactly that. 781 * 782 * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended 783 * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended 784 * 785 * When the target object is expected to have `val`'s keys, it's often best to 786 * assert that each of the properties has its expected value, rather than 787 * asserting that each property doesn't have one of many unexpected values. 788 * 789 * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended 790 * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended 791 * 792 * `.include` accepts an optional `msg` argument which is a custom error 793 * message to show when the assertion fails. The message can also be given as 794 * the second argument to `expect`. 795 * 796 * expect([1, 2, 3]).to.include(4, 'nooo why fail??'); 797 * expect([1, 2, 3], 'nooo why fail??').to.include(4); 798 * 799 * `.include` can also be used as a language chain, causing all `.members` and 800 * `.keys` assertions that follow in the chain to require the target to be a 801 * superset of the expected set, rather than an identical set. Note that 802 * `.members` ignores duplicates in the subset when `.include` is added. 803 * 804 * // Target object's keys are a superset of ['a', 'b'] but not identical 805 * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); 806 * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); 807 * 808 * // Target array is a superset of [1, 2] but not identical 809 * expect([1, 2, 3]).to.include.members([1, 2]); 810 * expect([1, 2, 3]).to.not.have.members([1, 2]); 811 * 812 * // Duplicates in the subset are ignored 813 * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); 814 * 815 * Note that adding `.any` earlier in the chain causes the `.keys` assertion 816 * to ignore `.include`. 817 * 818 * // Both assertions are identical 819 * expect({a: 1}).to.include.any.keys('a', 'b'); 820 * expect({a: 1}).to.have.any.keys('a', 'b'); 821 * 822 * The aliases `.includes`, `.contain`, and `.contains` can be used 823 * interchangeably with `.include`. 824 * 825 * @name include 826 * @alias contain 827 * @alias includes 828 * @alias contains 829 * @param {Mixed} val 830 * @param {String} msg _optional_ 831 * @namespace BDD 832 * @api public 833 */ 834 835 function SameValueZero(a, b) { 836 return (_.isNaN(a) && _.isNaN(b)) || a === b; 837 } 838 839 function includeChainingBehavior () { 840 flag(this, 'contains', true); 841 } 842 843 function include (val, msg) { 844 if (msg) flag(this, 'message', msg); 845 846 var obj = flag(this, 'object') 847 , objType = _.type(obj).toLowerCase() 848 , flagMsg = flag(this, 'message') 849 , negate = flag(this, 'negate') 850 , ssfi = flag(this, 'ssfi') 851 , isDeep = flag(this, 'deep') 852 , descriptor = isDeep ? 'deep ' : ''; 853 854 flagMsg = flagMsg ? flagMsg + ': ' : ''; 855 856 var included = false; 857 858 switch (objType) { 859 case 'string': 860 included = obj.indexOf(val) !== -1; 861 break; 862 863 case 'weakset': 864 if (isDeep) { 865 throw new AssertionError( 866 flagMsg + 'unable to use .deep.include with WeakSet', 867 undefined, 868 ssfi 869 ); 870 } 871 872 included = obj.has(val); 873 break; 874 875 case 'map': 876 var isEql = isDeep ? _.eql : SameValueZero; 877 obj.forEach(function (item) { 878 included = included || isEql(item, val); 879 }); 880 break; 881 882 case 'set': 883 if (isDeep) { 884 obj.forEach(function (item) { 885 included = included || _.eql(item, val); 886 }); 887 } else { 888 included = obj.has(val); 889 } 890 break; 891 892 case 'array': 893 if (isDeep) { 894 included = obj.some(function (item) { 895 return _.eql(item, val); 896 }) 897 } else { 898 included = obj.indexOf(val) !== -1; 899 } 900 break; 901 902 default: 903 // This block is for asserting a subset of properties in an object. 904 // `_.expectTypes` isn't used here because `.include` should work with 905 // objects with a custom `@@toStringTag`. 906 if (val !== Object(val)) { 907 throw new AssertionError( 908 flagMsg + 'the given combination of arguments (' 909 + objType + ' and ' 910 + _.type(val).toLowerCase() + ')' 911 + ' is invalid for this assertion. ' 912 + 'You can use an array, a map, an object, a set, a string, ' 913 + 'or a weakset instead of a ' 914 + _.type(val).toLowerCase(), 915 undefined, 916 ssfi 917 ); 918 } 919 920 var props = Object.keys(val) 921 , firstErr = null 922 , numErrs = 0; 923 924 props.forEach(function (prop) { 925 var propAssertion = new Assertion(obj); 926 _.transferFlags(this, propAssertion, true); 927 flag(propAssertion, 'lockSsfi', true); 928 929 if (!negate || props.length === 1) { 930 propAssertion.property(prop, val[prop]); 931 return; 932 } 933 934 try { 935 propAssertion.property(prop, val[prop]); 936 } catch (err) { 937 if (!_.checkError.compatibleConstructor(err, AssertionError)) { 938 throw err; 939 } 940 if (firstErr === null) firstErr = err; 941 numErrs++; 942 } 943 }, this); 944 945 // When validating .not.include with multiple properties, we only want 946 // to throw an assertion error if all of the properties are included, 947 // in which case we throw the first property assertion error that we 948 // encountered. 949 if (negate && props.length > 1 && numErrs === props.length) { 950 throw firstErr; 951 } 952 return; 953 } 954 955 // Assert inclusion in collection or substring in a string. 956 this.assert( 957 included 958 , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val) 959 , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val)); 960 } 961 962 Assertion.addChainableMethod('include', include, includeChainingBehavior); 963 Assertion.addChainableMethod('contain', include, includeChainingBehavior); 964 Assertion.addChainableMethod('contains', include, includeChainingBehavior); 965 Assertion.addChainableMethod('includes', include, includeChainingBehavior); 966 967 /** 968 * ### .ok 969 * 970 * Asserts that the target is a truthy value (considered `true` in boolean context). 971 * However, it's often best to assert that the target is strictly (`===`) or 972 * deeply equal to its expected value. 973 * 974 * expect(1).to.equal(1); // Recommended 975 * expect(1).to.be.ok; // Not recommended 976 * 977 * expect(true).to.be.true; // Recommended 978 * expect(true).to.be.ok; // Not recommended 979 * 980 * Add `.not` earlier in the chain to negate `.ok`. 981 * 982 * expect(0).to.equal(0); // Recommended 983 * expect(0).to.not.be.ok; // Not recommended 984 * 985 * expect(false).to.be.false; // Recommended 986 * expect(false).to.not.be.ok; // Not recommended 987 * 988 * expect(null).to.be.null; // Recommended 989 * expect(null).to.not.be.ok; // Not recommended 990 * 991 * expect(undefined).to.be.undefined; // Recommended 992 * expect(undefined).to.not.be.ok; // Not recommended 993 * 994 * A custom error message can be given as the second argument to `expect`. 995 * 996 * expect(false, 'nooo why fail??').to.be.ok; 997 * 998 * @name ok 999 * @namespace BDD 1000 * @api public 1001 */ 1002 1003 Assertion.addProperty('ok', function () { 1004 this.assert( 1005 flag(this, 'object') 1006 , 'expected #{this} to be truthy' 1007 , 'expected #{this} to be falsy'); 1008 }); 1009 1010 /** 1011 * ### .true 1012 * 1013 * Asserts that the target is strictly (`===`) equal to `true`. 1014 * 1015 * expect(true).to.be.true; 1016 * 1017 * Add `.not` earlier in the chain to negate `.true`. However, it's often best 1018 * to assert that the target is equal to its expected value, rather than not 1019 * equal to `true`. 1020 * 1021 * expect(false).to.be.false; // Recommended 1022 * expect(false).to.not.be.true; // Not recommended 1023 * 1024 * expect(1).to.equal(1); // Recommended 1025 * expect(1).to.not.be.true; // Not recommended 1026 * 1027 * A custom error message can be given as the second argument to `expect`. 1028 * 1029 * expect(false, 'nooo why fail??').to.be.true; 1030 * 1031 * @name true 1032 * @namespace BDD 1033 * @api public 1034 */ 1035 1036 Assertion.addProperty('true', function () { 1037 this.assert( 1038 true === flag(this, 'object') 1039 , 'expected #{this} to be true' 1040 , 'expected #{this} to be false' 1041 , flag(this, 'negate') ? false : true 1042 ); 1043 }); 1044 1045 /** 1046 * ### .false 1047 * 1048 * Asserts that the target is strictly (`===`) equal to `false`. 1049 * 1050 * expect(false).to.be.false; 1051 * 1052 * Add `.not` earlier in the chain to negate `.false`. However, it's often 1053 * best to assert that the target is equal to its expected value, rather than 1054 * not equal to `false`. 1055 * 1056 * expect(true).to.be.true; // Recommended 1057 * expect(true).to.not.be.false; // Not recommended 1058 * 1059 * expect(1).to.equal(1); // Recommended 1060 * expect(1).to.not.be.false; // Not recommended 1061 * 1062 * A custom error message can be given as the second argument to `expect`. 1063 * 1064 * expect(true, 'nooo why fail??').to.be.false; 1065 * 1066 * @name false 1067 * @namespace BDD 1068 * @api public 1069 */ 1070 1071 Assertion.addProperty('false', function () { 1072 this.assert( 1073 false === flag(this, 'object') 1074 , 'expected #{this} to be false' 1075 , 'expected #{this} to be true' 1076 , flag(this, 'negate') ? true : false 1077 ); 1078 }); 1079 1080 /** 1081 * ### .null 1082 * 1083 * Asserts that the target is strictly (`===`) equal to `null`. 1084 * 1085 * expect(null).to.be.null; 1086 * 1087 * Add `.not` earlier in the chain to negate `.null`. However, it's often best 1088 * to assert that the target is equal to its expected value, rather than not 1089 * equal to `null`. 1090 * 1091 * expect(1).to.equal(1); // Recommended 1092 * expect(1).to.not.be.null; // Not recommended 1093 * 1094 * A custom error message can be given as the second argument to `expect`. 1095 * 1096 * expect(42, 'nooo why fail??').to.be.null; 1097 * 1098 * @name null 1099 * @namespace BDD 1100 * @api public 1101 */ 1102 1103 Assertion.addProperty('null', function () { 1104 this.assert( 1105 null === flag(this, 'object') 1106 , 'expected #{this} to be null' 1107 , 'expected #{this} not to be null' 1108 ); 1109 }); 1110 1111 /** 1112 * ### .undefined 1113 * 1114 * Asserts that the target is strictly (`===`) equal to `undefined`. 1115 * 1116 * expect(undefined).to.be.undefined; 1117 * 1118 * Add `.not` earlier in the chain to negate `.undefined`. However, it's often 1119 * best to assert that the target is equal to its expected value, rather than 1120 * not equal to `undefined`. 1121 * 1122 * expect(1).to.equal(1); // Recommended 1123 * expect(1).to.not.be.undefined; // Not recommended 1124 * 1125 * A custom error message can be given as the second argument to `expect`. 1126 * 1127 * expect(42, 'nooo why fail??').to.be.undefined; 1128 * 1129 * @name undefined 1130 * @namespace BDD 1131 * @api public 1132 */ 1133 1134 Assertion.addProperty('undefined', function () { 1135 this.assert( 1136 undefined === flag(this, 'object') 1137 , 'expected #{this} to be undefined' 1138 , 'expected #{this} not to be undefined' 1139 ); 1140 }); 1141 1142 /** 1143 * ### .NaN 1144 * 1145 * Asserts that the target is exactly `NaN`. 1146 * 1147 * expect(NaN).to.be.NaN; 1148 * 1149 * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best 1150 * to assert that the target is equal to its expected value, rather than not 1151 * equal to `NaN`. 1152 * 1153 * expect('foo').to.equal('foo'); // Recommended 1154 * expect('foo').to.not.be.NaN; // Not recommended 1155 * 1156 * A custom error message can be given as the second argument to `expect`. 1157 * 1158 * expect(42, 'nooo why fail??').to.be.NaN; 1159 * 1160 * @name NaN 1161 * @namespace BDD 1162 * @api public 1163 */ 1164 1165 Assertion.addProperty('NaN', function () { 1166 this.assert( 1167 _.isNaN(flag(this, 'object')) 1168 , 'expected #{this} to be NaN' 1169 , 'expected #{this} not to be NaN' 1170 ); 1171 }); 1172 1173 /** 1174 * ### .exist 1175 * 1176 * Asserts that the target is not strictly (`===`) equal to either `null` or 1177 * `undefined`. However, it's often best to assert that the target is equal to 1178 * its expected value. 1179 * 1180 * expect(1).to.equal(1); // Recommended 1181 * expect(1).to.exist; // Not recommended 1182 * 1183 * expect(0).to.equal(0); // Recommended 1184 * expect(0).to.exist; // Not recommended 1185 * 1186 * Add `.not` earlier in the chain to negate `.exist`. 1187 * 1188 * expect(null).to.be.null; // Recommended 1189 * expect(null).to.not.exist; // Not recommended 1190 * 1191 * expect(undefined).to.be.undefined; // Recommended 1192 * expect(undefined).to.not.exist; // Not recommended 1193 * 1194 * A custom error message can be given as the second argument to `expect`. 1195 * 1196 * expect(null, 'nooo why fail??').to.exist; 1197 * 1198 * The alias `.exists` can be used interchangeably with `.exist`. 1199 * 1200 * @name exist 1201 * @alias exists 1202 * @namespace BDD 1203 * @api public 1204 */ 1205 1206 function assertExist () { 1207 var val = flag(this, 'object'); 1208 this.assert( 1209 val !== null && val !== undefined 1210 , 'expected #{this} to exist' 1211 , 'expected #{this} to not exist' 1212 ); 1213 } 1214 1215 Assertion.addProperty('exist', assertExist); 1216 Assertion.addProperty('exists', assertExist); 1217 1218 /** 1219 * ### .empty 1220 * 1221 * When the target is a string or array, `.empty` asserts that the target's 1222 * `length` property is strictly (`===`) equal to `0`. 1223 * 1224 * expect([]).to.be.empty; 1225 * expect('').to.be.empty; 1226 * 1227 * When the target is a map or set, `.empty` asserts that the target's `size` 1228 * property is strictly equal to `0`. 1229 * 1230 * expect(new Set()).to.be.empty; 1231 * expect(new Map()).to.be.empty; 1232 * 1233 * When the target is a non-function object, `.empty` asserts that the target 1234 * doesn't have any own enumerable properties. Properties with Symbol-based 1235 * keys are excluded from the count. 1236 * 1237 * expect({}).to.be.empty; 1238 * 1239 * Because `.empty` does different things based on the target's type, it's 1240 * important to check the target's type before using `.empty`. See the `.a` 1241 * doc for info on testing a target's type. 1242 * 1243 * expect([]).to.be.an('array').that.is.empty; 1244 * 1245 * Add `.not` earlier in the chain to negate `.empty`. However, it's often 1246 * best to assert that the target contains its expected number of values, 1247 * rather than asserting that it's not empty. 1248 * 1249 * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended 1250 * expect([1, 2, 3]).to.not.be.empty; // Not recommended 1251 * 1252 * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended 1253 * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended 1254 * 1255 * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended 1256 * expect({a: 1}).to.not.be.empty; // Not recommended 1257 * 1258 * A custom error message can be given as the second argument to `expect`. 1259 * 1260 * expect([1, 2, 3], 'nooo why fail??').to.be.empty; 1261 * 1262 * @name empty 1263 * @namespace BDD 1264 * @api public 1265 */ 1266 1267 Assertion.addProperty('empty', function () { 1268 var val = flag(this, 'object') 1269 , ssfi = flag(this, 'ssfi') 1270 , flagMsg = flag(this, 'message') 1271 , itemsCount; 1272 1273 flagMsg = flagMsg ? flagMsg + ': ' : ''; 1274 1275 switch (_.type(val).toLowerCase()) { 1276 case 'array': 1277 case 'string': 1278 itemsCount = val.length; 1279 break; 1280 case 'map': 1281 case 'set': 1282 itemsCount = val.size; 1283 break; 1284 case 'weakmap': 1285 case 'weakset': 1286 throw new AssertionError( 1287 flagMsg + '.empty was passed a weak collection', 1288 undefined, 1289 ssfi 1290 ); 1291 case 'function': 1292 var msg = flagMsg + '.empty was passed a function ' + _.getName(val); 1293 throw new AssertionError(msg.trim(), undefined, ssfi); 1294 default: 1295 if (val !== Object(val)) { 1296 throw new AssertionError( 1297 flagMsg + '.empty was passed non-string primitive ' + _.inspect(val), 1298 undefined, 1299 ssfi 1300 ); 1301 } 1302 itemsCount = Object.keys(val).length; 1303 } 1304 1305 this.assert( 1306 0 === itemsCount 1307 , 'expected #{this} to be empty' 1308 , 'expected #{this} not to be empty' 1309 ); 1310 }); 1311 1312 /** 1313 * ### .arguments 1314 * 1315 * Asserts that the target is an `arguments` object. 1316 * 1317 * function test () { 1318 * expect(arguments).to.be.arguments; 1319 * } 1320 * 1321 * test(); 1322 * 1323 * Add `.not` earlier in the chain to negate `.arguments`. However, it's often 1324 * best to assert which type the target is expected to be, rather than 1325 * asserting that it’s not an `arguments` object. 1326 * 1327 * expect('foo').to.be.a('string'); // Recommended 1328 * expect('foo').to.not.be.arguments; // Not recommended 1329 * 1330 * A custom error message can be given as the second argument to `expect`. 1331 * 1332 * expect({}, 'nooo why fail??').to.be.arguments; 1333 * 1334 * The alias `.Arguments` can be used interchangeably with `.arguments`. 1335 * 1336 * @name arguments 1337 * @alias Arguments 1338 * @namespace BDD 1339 * @api public 1340 */ 1341 1342 function checkArguments () { 1343 var obj = flag(this, 'object') 1344 , type = _.type(obj); 1345 this.assert( 1346 'Arguments' === type 1347 , 'expected #{this} to be arguments but got ' + type 1348 , 'expected #{this} to not be arguments' 1349 ); 1350 } 1351 1352 Assertion.addProperty('arguments', checkArguments); 1353 Assertion.addProperty('Arguments', checkArguments); 1354 1355 /** 1356 * ### .equal(val[, msg]) 1357 * 1358 * Asserts that the target is strictly (`===`) equal to the given `val`. 1359 * 1360 * expect(1).to.equal(1); 1361 * expect('foo').to.equal('foo'); 1362 * 1363 * Add `.deep` earlier in the chain to use deep equality instead. See the 1364 * `deep-eql` project page for info on the deep equality algorithm: 1365 * https://github.com/chaijs/deep-eql. 1366 * 1367 * // Target object deeply (but not strictly) equals `{a: 1}` 1368 * expect({a: 1}).to.deep.equal({a: 1}); 1369 * expect({a: 1}).to.not.equal({a: 1}); 1370 * 1371 * // Target array deeply (but not strictly) equals `[1, 2]` 1372 * expect([1, 2]).to.deep.equal([1, 2]); 1373 * expect([1, 2]).to.not.equal([1, 2]); 1374 * 1375 * Add `.not` earlier in the chain to negate `.equal`. However, it's often 1376 * best to assert that the target is equal to its expected value, rather than 1377 * not equal to one of countless unexpected values. 1378 * 1379 * expect(1).to.equal(1); // Recommended 1380 * expect(1).to.not.equal(2); // Not recommended 1381 * 1382 * `.equal` accepts an optional `msg` argument which is a custom error message 1383 * to show when the assertion fails. The message can also be given as the 1384 * second argument to `expect`. 1385 * 1386 * expect(1).to.equal(2, 'nooo why fail??'); 1387 * expect(1, 'nooo why fail??').to.equal(2); 1388 * 1389 * The aliases `.equals` and `eq` can be used interchangeably with `.equal`. 1390 * 1391 * @name equal 1392 * @alias equals 1393 * @alias eq 1394 * @param {Mixed} val 1395 * @param {String} msg _optional_ 1396 * @namespace BDD 1397 * @api public 1398 */ 1399 1400 function assertEqual (val, msg) { 1401 if (msg) flag(this, 'message', msg); 1402 var obj = flag(this, 'object'); 1403 if (flag(this, 'deep')) { 1404 var prevLockSsfi = flag(this, 'lockSsfi'); 1405 flag(this, 'lockSsfi', true); 1406 this.eql(val); 1407 flag(this, 'lockSsfi', prevLockSsfi); 1408 } else { 1409 this.assert( 1410 val === obj 1411 , 'expected #{this} to equal #{exp}' 1412 , 'expected #{this} to not equal #{exp}' 1413 , val 1414 , this._obj 1415 , true 1416 ); 1417 } 1418 } 1419 1420 Assertion.addMethod('equal', assertEqual); 1421 Assertion.addMethod('equals', assertEqual); 1422 Assertion.addMethod('eq', assertEqual); 1423 1424 /** 1425 * ### .eql(obj[, msg]) 1426 * 1427 * Asserts that the target is deeply equal to the given `obj`. See the 1428 * `deep-eql` project page for info on the deep equality algorithm: 1429 * https://github.com/chaijs/deep-eql. 1430 * 1431 * // Target object is deeply (but not strictly) equal to {a: 1} 1432 * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1}); 1433 * 1434 * // Target array is deeply (but not strictly) equal to [1, 2] 1435 * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]); 1436 * 1437 * Add `.not` earlier in the chain to negate `.eql`. However, it's often best 1438 * to assert that the target is deeply equal to its expected value, rather 1439 * than not deeply equal to one of countless unexpected values. 1440 * 1441 * expect({a: 1}).to.eql({a: 1}); // Recommended 1442 * expect({a: 1}).to.not.eql({b: 2}); // Not recommended 1443 * 1444 * `.eql` accepts an optional `msg` argument which is a custom error message 1445 * to show when the assertion fails. The message can also be given as the 1446 * second argument to `expect`. 1447 * 1448 * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??'); 1449 * expect({a: 1}, 'nooo why fail??').to.eql({b: 2}); 1450 * 1451 * The alias `.eqls` can be used interchangeably with `.eql`. 1452 * 1453 * The `.deep.equal` assertion is almost identical to `.eql` but with one 1454 * difference: `.deep.equal` causes deep equality comparisons to also be used 1455 * for any other assertions that follow in the chain. 1456 * 1457 * @name eql 1458 * @alias eqls 1459 * @param {Mixed} obj 1460 * @param {String} msg _optional_ 1461 * @namespace BDD 1462 * @api public 1463 */ 1464 1465 function assertEql(obj, msg) { 1466 if (msg) flag(this, 'message', msg); 1467 this.assert( 1468 _.eql(obj, flag(this, 'object')) 1469 , 'expected #{this} to deeply equal #{exp}' 1470 , 'expected #{this} to not deeply equal #{exp}' 1471 , obj 1472 , this._obj 1473 , true 1474 ); 1475 } 1476 1477 Assertion.addMethod('eql', assertEql); 1478 Assertion.addMethod('eqls', assertEql); 1479 1480 /** 1481 * ### .above(n[, msg]) 1482 * 1483 * Asserts that the target is a number or a date greater than the given number or date `n` respectively. 1484 * However, it's often best to assert that the target is equal to its expected 1485 * value. 1486 * 1487 * expect(2).to.equal(2); // Recommended 1488 * expect(2).to.be.above(1); // Not recommended 1489 * 1490 * Add `.lengthOf` earlier in the chain to assert that the target's `length` 1491 * or `size` is greater than the given number `n`. 1492 * 1493 * expect('foo').to.have.lengthOf(3); // Recommended 1494 * expect('foo').to.have.lengthOf.above(2); // Not recommended 1495 * 1496 * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended 1497 * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended 1498 * 1499 * Add `.not` earlier in the chain to negate `.above`. 1500 * 1501 * expect(2).to.equal(2); // Recommended 1502 * expect(1).to.not.be.above(2); // Not recommended 1503 * 1504 * `.above` accepts an optional `msg` argument which is a custom error message 1505 * to show when the assertion fails. The message can also be given as the 1506 * second argument to `expect`. 1507 * 1508 * expect(1).to.be.above(2, 'nooo why fail??'); 1509 * expect(1, 'nooo why fail??').to.be.above(2); 1510 * 1511 * The aliases `.gt` and `.greaterThan` can be used interchangeably with 1512 * `.above`. 1513 * 1514 * @name above 1515 * @alias gt 1516 * @alias greaterThan 1517 * @param {Number} n 1518 * @param {String} msg _optional_ 1519 * @namespace BDD 1520 * @api public 1521 */ 1522 1523 function assertAbove (n, msg) { 1524 if (msg) flag(this, 'message', msg); 1525 var obj = flag(this, 'object') 1526 , doLength = flag(this, 'doLength') 1527 , flagMsg = flag(this, 'message') 1528 , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') 1529 , ssfi = flag(this, 'ssfi') 1530 , objType = _.type(obj).toLowerCase() 1531 , nType = _.type(n).toLowerCase() 1532 , errorMessage 1533 , shouldThrow = true; 1534 1535 if (doLength && objType !== 'map' && objType !== 'set') { 1536 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); 1537 } 1538 1539 if (!doLength && (objType === 'date' && nType !== 'date')) { 1540 errorMessage = msgPrefix + 'the argument to above must be a date'; 1541 } else if (nType !== 'number' && (doLength || objType === 'number')) { 1542 errorMessage = msgPrefix + 'the argument to above must be a number'; 1543 } else if (!doLength && (objType !== 'date' && objType !== 'number')) { 1544 var printObj = (objType === 'string') ? "'" + obj + "'" : obj; 1545 errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; 1546 } else { 1547 shouldThrow = false; 1548 } 1549 1550 if (shouldThrow) { 1551 throw new AssertionError(errorMessage, undefined, ssfi); 1552 } 1553 1554 if (doLength) { 1555 var descriptor = 'length' 1556 , itemsCount; 1557 if (objType === 'map' || objType === 'set') { 1558 descriptor = 'size'; 1559 itemsCount = obj.size; 1560 } else { 1561 itemsCount = obj.length; 1562 } 1563 this.assert( 1564 itemsCount > n 1565 , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}' 1566 , 'expected #{this} to not have a ' + descriptor + ' above #{exp}' 1567 , n 1568 , itemsCount 1569 ); 1570 } else { 1571 this.assert( 1572 obj > n 1573 , 'expected #{this} to be above #{exp}' 1574 , 'expected #{this} to be at most #{exp}' 1575 , n 1576 ); 1577 } 1578 } 1579 1580 Assertion.addMethod('above', assertAbove); 1581 Assertion.addMethod('gt', assertAbove); 1582 Assertion.addMethod('greaterThan', assertAbove); 1583 1584 /** 1585 * ### .least(n[, msg]) 1586 * 1587 * Asserts that the target is a number or a date greater than or equal to the given 1588 * number or date `n` respectively. However, it's often best to assert that the target is equal to 1589 * its expected value. 1590 * 1591 * expect(2).to.equal(2); // Recommended 1592 * expect(2).to.be.at.least(1); // Not recommended 1593 * expect(2).to.be.at.least(2); // Not recommended 1594 * 1595 * Add `.lengthOf` earlier in the chain to assert that the target's `length` 1596 * or `size` is greater than or equal to the given number `n`. 1597 * 1598 * expect('foo').to.have.lengthOf(3); // Recommended 1599 * expect('foo').to.have.lengthOf.at.least(2); // Not recommended 1600 * 1601 * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended 1602 * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended 1603 * 1604 * Add `.not` earlier in the chain to negate `.least`. 1605 * 1606 * expect(1).to.equal(1); // Recommended 1607 * expect(1).to.not.be.at.least(2); // Not recommended 1608 * 1609 * `.least` accepts an optional `msg` argument which is a custom error message 1610 * to show when the assertion fails. The message can also be given as the 1611 * second argument to `expect`. 1612 * 1613 * expect(1).to.be.at.least(2, 'nooo why fail??'); 1614 * expect(1, 'nooo why fail??').to.be.at.least(2); 1615 * 1616 * The aliases `.gte` and `.greaterThanOrEqual` can be used interchangeably with 1617 * `.least`. 1618 * 1619 * @name least 1620 * @alias gte 1621 * @alias greaterThanOrEqual 1622 * @param {Number} n 1623 * @param {String} msg _optional_ 1624 * @namespace BDD 1625 * @api public 1626 */ 1627 1628 function assertLeast (n, msg) { 1629 if (msg) flag(this, 'message', msg); 1630 var obj = flag(this, 'object') 1631 , doLength = flag(this, 'doLength') 1632 , flagMsg = flag(this, 'message') 1633 , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') 1634 , ssfi = flag(this, 'ssfi') 1635 , objType = _.type(obj).toLowerCase() 1636 , nType = _.type(n).toLowerCase() 1637 , errorMessage 1638 , shouldThrow = true; 1639 1640 if (doLength && objType !== 'map' && objType !== 'set') { 1641 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); 1642 } 1643 1644 if (!doLength && (objType === 'date' && nType !== 'date')) { 1645 errorMessage = msgPrefix + 'the argument to least must be a date'; 1646 } else if (nType !== 'number' && (doLength || objType === 'number')) { 1647 errorMessage = msgPrefix + 'the argument to least must be a number'; 1648 } else if (!doLength && (objType !== 'date' && objType !== 'number')) { 1649 var printObj = (objType === 'string') ? "'" + obj + "'" : obj; 1650 errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; 1651 } else { 1652 shouldThrow = false; 1653 } 1654 1655 if (shouldThrow) { 1656 throw new AssertionError(errorMessage, undefined, ssfi); 1657 } 1658 1659 if (doLength) { 1660 var descriptor = 'length' 1661 , itemsCount; 1662 if (objType === 'map' || objType === 'set') { 1663 descriptor = 'size'; 1664 itemsCount = obj.size; 1665 } else { 1666 itemsCount = obj.length; 1667 } 1668 this.assert( 1669 itemsCount >= n 1670 , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}' 1671 , 'expected #{this} to have a ' + descriptor + ' below #{exp}' 1672 , n 1673 , itemsCount 1674 ); 1675 } else { 1676 this.assert( 1677 obj >= n 1678 , 'expected #{this} to be at least #{exp}' 1679 , 'expected #{this} to be below #{exp}' 1680 , n 1681 ); 1682 } 1683 } 1684 1685 Assertion.addMethod('least', assertLeast); 1686 Assertion.addMethod('gte', assertLeast); 1687 Assertion.addMethod('greaterThanOrEqual', assertLeast); 1688 1689 /** 1690 * ### .below(n[, msg]) 1691 * 1692 * Asserts that the target is a number or a date less than the given number or date `n` respectively. 1693 * However, it's often best to assert that the target is equal to its expected 1694 * value. 1695 * 1696 * expect(1).to.equal(1); // Recommended 1697 * expect(1).to.be.below(2); // Not recommended 1698 * 1699 * Add `.lengthOf` earlier in the chain to assert that the target's `length` 1700 * or `size` is less than the given number `n`. 1701 * 1702 * expect('foo').to.have.lengthOf(3); // Recommended 1703 * expect('foo').to.have.lengthOf.below(4); // Not recommended 1704 * 1705 * expect([1, 2, 3]).to.have.length(3); // Recommended 1706 * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended 1707 * 1708 * Add `.not` earlier in the chain to negate `.below`. 1709 * 1710 * expect(2).to.equal(2); // Recommended 1711 * expect(2).to.not.be.below(1); // Not recommended 1712 * 1713 * `.below` accepts an optional `msg` argument which is a custom error message 1714 * to show when the assertion fails. The message can also be given as the 1715 * second argument to `expect`. 1716 * 1717 * expect(2).to.be.below(1, 'nooo why fail??'); 1718 * expect(2, 'nooo why fail??').to.be.below(1); 1719 * 1720 * The aliases `.lt` and `.lessThan` can be used interchangeably with 1721 * `.below`. 1722 * 1723 * @name below 1724 * @alias lt 1725 * @alias lessThan 1726 * @param {Number} n 1727 * @param {String} msg _optional_ 1728 * @namespace BDD 1729 * @api public 1730 */ 1731 1732 function assertBelow (n, msg) { 1733 if (msg) flag(this, 'message', msg); 1734 var obj = flag(this, 'object') 1735 , doLength = flag(this, 'doLength') 1736 , flagMsg = flag(this, 'message') 1737 , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') 1738 , ssfi = flag(this, 'ssfi') 1739 , objType = _.type(obj).toLowerCase() 1740 , nType = _.type(n).toLowerCase() 1741 , errorMessage 1742 , shouldThrow = true; 1743 1744 if (doLength && objType !== 'map' && objType !== 'set') { 1745 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); 1746 } 1747 1748 if (!doLength && (objType === 'date' && nType !== 'date')) { 1749 errorMessage = msgPrefix + 'the argument to below must be a date'; 1750 } else if (nType !== 'number' && (doLength || objType === 'number')) { 1751 errorMessage = msgPrefix + 'the argument to below must be a number'; 1752 } else if (!doLength && (objType !== 'date' && objType !== 'number')) { 1753 var printObj = (objType === 'string') ? "'" + obj + "'" : obj; 1754 errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; 1755 } else { 1756 shouldThrow = false; 1757 } 1758 1759 if (shouldThrow) { 1760 throw new AssertionError(errorMessage, undefined, ssfi); 1761 } 1762 1763 if (doLength) { 1764 var descriptor = 'length' 1765 , itemsCount; 1766 if (objType === 'map' || objType === 'set') { 1767 descriptor = 'size'; 1768 itemsCount = obj.size; 1769 } else { 1770 itemsCount = obj.length; 1771 } 1772 this.assert( 1773 itemsCount < n 1774 , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}' 1775 , 'expected #{this} to not have a ' + descriptor + ' below #{exp}' 1776 , n 1777 , itemsCount 1778 ); 1779 } else { 1780 this.assert( 1781 obj < n 1782 , 'expected #{this} to be below #{exp}' 1783 , 'expected #{this} to be at least #{exp}' 1784 , n 1785 ); 1786 } 1787 } 1788 1789 Assertion.addMethod('below', assertBelow); 1790 Assertion.addMethod('lt', assertBelow); 1791 Assertion.addMethod('lessThan', assertBelow); 1792 1793 /** 1794 * ### .most(n[, msg]) 1795 * 1796 * Asserts that the target is a number or a date less than or equal to the given number 1797 * or date `n` respectively. However, it's often best to assert that the target is equal to its 1798 * expected value. 1799 * 1800 * expect(1).to.equal(1); // Recommended 1801 * expect(1).to.be.at.most(2); // Not recommended 1802 * expect(1).to.be.at.most(1); // Not recommended 1803 * 1804 * Add `.lengthOf` earlier in the chain to assert that the target's `length` 1805 * or `size` is less than or equal to the given number `n`. 1806 * 1807 * expect('foo').to.have.lengthOf(3); // Recommended 1808 * expect('foo').to.have.lengthOf.at.most(4); // Not recommended 1809 * 1810 * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended 1811 * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended 1812 * 1813 * Add `.not` earlier in the chain to negate `.most`. 1814 * 1815 * expect(2).to.equal(2); // Recommended 1816 * expect(2).to.not.be.at.most(1); // Not recommended 1817 * 1818 * `.most` accepts an optional `msg` argument which is a custom error message 1819 * to show when the assertion fails. The message can also be given as the 1820 * second argument to `expect`. 1821 * 1822 * expect(2).to.be.at.most(1, 'nooo why fail??'); 1823 * expect(2, 'nooo why fail??').to.be.at.most(1); 1824 * 1825 * The aliases `.lte` and `.lessThanOrEqual` can be used interchangeably with 1826 * `.most`. 1827 * 1828 * @name most 1829 * @alias lte 1830 * @alias lessThanOrEqual 1831 * @param {Number} n 1832 * @param {String} msg _optional_ 1833 * @namespace BDD 1834 * @api public 1835 */ 1836 1837 function assertMost (n, msg) { 1838 if (msg) flag(this, 'message', msg); 1839 var obj = flag(this, 'object') 1840 , doLength = flag(this, 'doLength') 1841 , flagMsg = flag(this, 'message') 1842 , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') 1843 , ssfi = flag(this, 'ssfi') 1844 , objType = _.type(obj).toLowerCase() 1845 , nType = _.type(n).toLowerCase() 1846 , errorMessage 1847 , shouldThrow = true; 1848 1849 if (doLength && objType !== 'map' && objType !== 'set') { 1850 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); 1851 } 1852 1853 if (!doLength && (objType === 'date' && nType !== 'date')) { 1854 errorMessage = msgPrefix + 'the argument to most must be a date'; 1855 } else if (nType !== 'number' && (doLength || objType === 'number')) { 1856 errorMessage = msgPrefix + 'the argument to most must be a number'; 1857 } else if (!doLength && (objType !== 'date' && objType !== 'number')) { 1858 var printObj = (objType === 'string') ? "'" + obj + "'" : obj; 1859 errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; 1860 } else { 1861 shouldThrow = false; 1862 } 1863 1864 if (shouldThrow) { 1865 throw new AssertionError(errorMessage, undefined, ssfi); 1866 } 1867 1868 if (doLength) { 1869 var descriptor = 'length' 1870 , itemsCount; 1871 if (objType === 'map' || objType === 'set') { 1872 descriptor = 'size'; 1873 itemsCount = obj.size; 1874 } else { 1875 itemsCount = obj.length; 1876 } 1877 this.assert( 1878 itemsCount <= n 1879 , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}' 1880 , 'expected #{this} to have a ' + descriptor + ' above #{exp}' 1881 , n 1882 , itemsCount 1883 ); 1884 } else { 1885 this.assert( 1886 obj <= n 1887 , 'expected #{this} to be at most #{exp}' 1888 , 'expected #{this} to be above #{exp}' 1889 , n 1890 ); 1891 } 1892 } 1893 1894 Assertion.addMethod('most', assertMost); 1895 Assertion.addMethod('lte', assertMost); 1896 Assertion.addMethod('lessThanOrEqual', assertMost); 1897 1898 /** 1899 * ### .within(start, finish[, msg]) 1900 * 1901 * Asserts that the target is a number or a date greater than or equal to the given 1902 * number or date `start`, and less than or equal to the given number or date `finish` respectively. 1903 * However, it's often best to assert that the target is equal to its expected 1904 * value. 1905 * 1906 * expect(2).to.equal(2); // Recommended 1907 * expect(2).to.be.within(1, 3); // Not recommended 1908 * expect(2).to.be.within(2, 3); // Not recommended 1909 * expect(2).to.be.within(1, 2); // Not recommended 1910 * 1911 * Add `.lengthOf` earlier in the chain to assert that the target's `length` 1912 * or `size` is greater than or equal to the given number `start`, and less 1913 * than or equal to the given number `finish`. 1914 * 1915 * expect('foo').to.have.lengthOf(3); // Recommended 1916 * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended 1917 * 1918 * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended 1919 * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended 1920 * 1921 * Add `.not` earlier in the chain to negate `.within`. 1922 * 1923 * expect(1).to.equal(1); // Recommended 1924 * expect(1).to.not.be.within(2, 4); // Not recommended 1925 * 1926 * `.within` accepts an optional `msg` argument which is a custom error 1927 * message to show when the assertion fails. The message can also be given as 1928 * the second argument to `expect`. 1929 * 1930 * expect(4).to.be.within(1, 3, 'nooo why fail??'); 1931 * expect(4, 'nooo why fail??').to.be.within(1, 3); 1932 * 1933 * @name within 1934 * @param {Number} start lower bound inclusive 1935 * @param {Number} finish upper bound inclusive 1936 * @param {String} msg _optional_ 1937 * @namespace BDD 1938 * @api public 1939 */ 1940 1941 Assertion.addMethod('within', function (start, finish, msg) { 1942 if (msg) flag(this, 'message', msg); 1943 var obj = flag(this, 'object') 1944 , doLength = flag(this, 'doLength') 1945 , flagMsg = flag(this, 'message') 1946 , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') 1947 , ssfi = flag(this, 'ssfi') 1948 , objType = _.type(obj).toLowerCase() 1949 , startType = _.type(start).toLowerCase() 1950 , finishType = _.type(finish).toLowerCase() 1951 , errorMessage 1952 , shouldThrow = true 1953 , range = (startType === 'date' && finishType === 'date') 1954 ? start.toUTCString() + '..' + finish.toUTCString() 1955 : start + '..' + finish; 1956 1957 if (doLength && objType !== 'map' && objType !== 'set') { 1958 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); 1959 } 1960 1961 if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) { 1962 errorMessage = msgPrefix + 'the arguments to within must be dates'; 1963 } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) { 1964 errorMessage = msgPrefix + 'the arguments to within must be numbers'; 1965 } else if (!doLength && (objType !== 'date' && objType !== 'number')) { 1966 var printObj = (objType === 'string') ? "'" + obj + "'" : obj; 1967 errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; 1968 } else { 1969 shouldThrow = false; 1970 } 1971 1972 if (shouldThrow) { 1973 throw new AssertionError(errorMessage, undefined, ssfi); 1974 } 1975 1976 if (doLength) { 1977 var descriptor = 'length' 1978 , itemsCount; 1979 if (objType === 'map' || objType === 'set') { 1980 descriptor = 'size'; 1981 itemsCount = obj.size; 1982 } else { 1983 itemsCount = obj.length; 1984 } 1985 this.assert( 1986 itemsCount >= start && itemsCount <= finish 1987 , 'expected #{this} to have a ' + descriptor + ' within ' + range 1988 , 'expected #{this} to not have a ' + descriptor + ' within ' + range 1989 ); 1990 } else { 1991 this.assert( 1992 obj >= start && obj <= finish 1993 , 'expected #{this} to be within ' + range 1994 , 'expected #{this} to not be within ' + range 1995 ); 1996 } 1997 }); 1998 1999 /** 2000 * ### .instanceof(constructor[, msg]) 2001 * 2002 * Asserts that the target is an instance of the given `constructor`. 2003 * 2004 * function Cat () { } 2005 * 2006 * expect(new Cat()).to.be.an.instanceof(Cat); 2007 * expect([1, 2]).to.be.an.instanceof(Array); 2008 * 2009 * Add `.not` earlier in the chain to negate `.instanceof`. 2010 * 2011 * expect({a: 1}).to.not.be.an.instanceof(Array); 2012 * 2013 * `.instanceof` accepts an optional `msg` argument which is a custom error 2014 * message to show when the assertion fails. The message can also be given as 2015 * the second argument to `expect`. 2016 * 2017 * expect(1).to.be.an.instanceof(Array, 'nooo why fail??'); 2018 * expect(1, 'nooo why fail??').to.be.an.instanceof(Array); 2019 * 2020 * Due to limitations in ES5, `.instanceof` may not always work as expected 2021 * when using a transpiler such as Babel or TypeScript. In particular, it may 2022 * produce unexpected results when subclassing built-in object such as 2023 * `Array`, `Error`, and `Map`. See your transpiler's docs for details: 2024 * 2025 * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) 2026 * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) 2027 * 2028 * The alias `.instanceOf` can be used interchangeably with `.instanceof`. 2029 * 2030 * @name instanceof 2031 * @param {Constructor} constructor 2032 * @param {String} msg _optional_ 2033 * @alias instanceOf 2034 * @namespace BDD 2035 * @api public 2036 */ 2037 2038 function assertInstanceOf (constructor, msg) { 2039 if (msg) flag(this, 'message', msg); 2040 2041 var target = flag(this, 'object') 2042 var ssfi = flag(this, 'ssfi'); 2043 var flagMsg = flag(this, 'message'); 2044 2045 try { 2046 var isInstanceOf = target instanceof constructor; 2047 } catch (err) { 2048 if (err instanceof TypeError) { 2049 flagMsg = flagMsg ? flagMsg + ': ' : ''; 2050 throw new AssertionError( 2051 flagMsg + 'The instanceof assertion needs a constructor but ' 2052 + _.type(constructor) + ' was given.', 2053 undefined, 2054 ssfi 2055 ); 2056 } 2057 throw err; 2058 } 2059 2060 var name = _.getName(constructor); 2061 if (name === null) { 2062 name = 'an unnamed constructor'; 2063 } 2064 2065 this.assert( 2066 isInstanceOf 2067 , 'expected #{this} to be an instance of ' + name 2068 , 'expected #{this} to not be an instance of ' + name 2069 ); 2070 }; 2071 2072 Assertion.addMethod('instanceof', assertInstanceOf); 2073 Assertion.addMethod('instanceOf', assertInstanceOf); 2074 2075 /** 2076 * ### .property(name[, val[, msg]]) 2077 * 2078 * Asserts that the target has a property with the given key `name`. 2079 * 2080 * expect({a: 1}).to.have.property('a'); 2081 * 2082 * When `val` is provided, `.property` also asserts that the property's value 2083 * is equal to the given `val`. 2084 * 2085 * expect({a: 1}).to.have.property('a', 1); 2086 * 2087 * By default, strict (`===`) equality is used. Add `.deep` earlier in the 2088 * chain to use deep equality instead. See the `deep-eql` project page for 2089 * info on the deep equality algorithm: https://github.com/chaijs/deep-eql. 2090 * 2091 * // Target object deeply (but not strictly) has property `x: {a: 1}` 2092 * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); 2093 * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); 2094 * 2095 * The target's enumerable and non-enumerable properties are always included 2096 * in the search. By default, both own and inherited properties are included. 2097 * Add `.own` earlier in the chain to exclude inherited properties from the 2098 * search. 2099 * 2100 * Object.prototype.b = 2; 2101 * 2102 * expect({a: 1}).to.have.own.property('a'); 2103 * expect({a: 1}).to.have.own.property('a', 1); 2104 * expect({a: 1}).to.have.property('b'); 2105 * expect({a: 1}).to.not.have.own.property('b'); 2106 * 2107 * `.deep` and `.own` can be combined. 2108 * 2109 * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1}); 2110 * 2111 * Add `.nested` earlier in the chain to enable dot- and bracket-notation when 2112 * referencing nested properties. 2113 * 2114 * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); 2115 * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y'); 2116 * 2117 * If `.` or `[]` are part of an actual property name, they can be escaped by 2118 * adding two backslashes before them. 2119 * 2120 * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); 2121 * 2122 * `.deep` and `.nested` can be combined. 2123 * 2124 * expect({a: {b: [{c: 3}]}}) 2125 * .to.have.deep.nested.property('a.b[0]', {c: 3}); 2126 * 2127 * `.own` and `.nested` cannot be combined. 2128 * 2129 * Add `.not` earlier in the chain to negate `.property`. 2130 * 2131 * expect({a: 1}).to.not.have.property('b'); 2132 * 2133 * However, it's dangerous to negate `.property` when providing `val`. The 2134 * problem is that it creates uncertain expectations by asserting that the 2135 * target either doesn't have a property with the given key `name`, or that it 2136 * does have a property with the given key `name` but its value isn't equal to 2137 * the given `val`. It's often best to identify the exact output that's 2138 * expected, and then write an assertion that only accepts that exact output. 2139 * 2140 * When the target isn't expected to have a property with the given key 2141 * `name`, it's often best to assert exactly that. 2142 * 2143 * expect({b: 2}).to.not.have.property('a'); // Recommended 2144 * expect({b: 2}).to.not.have.property('a', 1); // Not recommended 2145 * 2146 * When the target is expected to have a property with the given key `name`, 2147 * it's often best to assert that the property has its expected value, rather 2148 * than asserting that it doesn't have one of many unexpected values. 2149 * 2150 * expect({a: 3}).to.have.property('a', 3); // Recommended 2151 * expect({a: 3}).to.not.have.property('a', 1); // Not recommended 2152 * 2153 * `.property` changes the target of any assertions that follow in the chain 2154 * to be the value of the property from the original target object. 2155 * 2156 * expect({a: 1}).to.have.property('a').that.is.a('number'); 2157 * 2158 * `.property` accepts an optional `msg` argument which is a custom error 2159 * message to show when the assertion fails. The message can also be given as 2160 * the second argument to `expect`. When not providing `val`, only use the 2161 * second form. 2162 * 2163 * // Recommended 2164 * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??'); 2165 * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2); 2166 * expect({a: 1}, 'nooo why fail??').to.have.property('b'); 2167 * 2168 * // Not recommended 2169 * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??'); 2170 * 2171 * The above assertion isn't the same thing as not providing `val`. Instead, 2172 * it's asserting that the target object has a `b` property that's equal to 2173 * `undefined`. 2174 * 2175 * The assertions `.ownProperty` and `.haveOwnProperty` can be used 2176 * interchangeably with `.own.property`. 2177 * 2178 * @name property 2179 * @param {String} name 2180 * @param {Mixed} val (optional) 2181 * @param {String} msg _optional_ 2182 * @returns value of property for chaining 2183 * @namespace BDD 2184 * @api public 2185 */ 2186 2187 function assertProperty (name, val, msg) { 2188 if (msg) flag(this, 'message', msg); 2189 2190 var isNested = flag(this, 'nested') 2191 , isOwn = flag(this, 'own') 2192 , flagMsg = flag(this, 'message') 2193 , obj = flag(this, 'object') 2194 , ssfi = flag(this, 'ssfi') 2195 , nameType = typeof name; 2196 2197 flagMsg = flagMsg ? flagMsg + ': ' : ''; 2198 2199 if (isNested) { 2200 if (nameType !== 'string') { 2201 throw new AssertionError( 2202 flagMsg + 'the argument to property must be a string when using nested syntax', 2203 undefined, 2204 ssfi 2205 ); 2206 } 2207 } else { 2208 if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') { 2209 throw new AssertionError( 2210 flagMsg + 'the argument to property must be a string, number, or symbol', 2211 undefined, 2212 ssfi 2213 ); 2214 } 2215 } 2216 2217 if (isNested && isOwn) { 2218 throw new AssertionError( 2219 flagMsg + 'The "nested" and "own" flags cannot be combined.', 2220 undefined, 2221 ssfi 2222 ); 2223 } 2224 2225 if (obj === null || obj === undefined) { 2226 throw new AssertionError( 2227 flagMsg + 'Target cannot be null or undefined.', 2228 undefined, 2229 ssfi 2230 ); 2231 } 2232 2233 var isDeep = flag(this, 'deep') 2234 , negate = flag(this, 'negate') 2235 , pathInfo = isNested ? _.getPathInfo(obj, name) : null 2236 , value = isNested ? pathInfo.value : obj[name]; 2237 2238 var descriptor = ''; 2239 if (isDeep) descriptor += 'deep '; 2240 if (isOwn) descriptor += 'own '; 2241 if (isNested) descriptor += 'nested '; 2242 descriptor += 'property '; 2243 2244 var hasProperty; 2245 if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name); 2246 else if (isNested) hasProperty = pathInfo.exists; 2247 else hasProperty = _.hasProperty(obj, name); 2248 2249 // When performing a negated assertion for both name and val, merely having 2250 // a property with the given name isn't enough to cause the assertion to 2251 // fail. It must both have a property with the given name, and the value of 2252 // that property must equal the given val. Therefore, skip this assertion in 2253 // favor of the next. 2254 if (!negate || arguments.length === 1) { 2255 this.assert( 2256 hasProperty 2257 , 'expected #{this} to have ' + descriptor + _.inspect(name) 2258 , 'expected #{this} to not have ' + descriptor + _.inspect(name)); 2259 } 2260 2261 if (arguments.length > 1) { 2262 this.assert( 2263 hasProperty && (isDeep ? _.eql(val, value) : val === value) 2264 , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' 2265 , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}' 2266 , val 2267 , value 2268 ); 2269 } 2270 2271 flag(this, 'object', value); 2272 } 2273 2274 Assertion.addMethod('property', assertProperty); 2275 2276 function assertOwnProperty (name, value, msg) { 2277 flag(this, 'own', true); 2278 assertProperty.apply(this, arguments); 2279 } 2280 2281 Assertion.addMethod('ownProperty', assertOwnProperty); 2282 Assertion.addMethod('haveOwnProperty', assertOwnProperty); 2283 2284 /** 2285 * ### .ownPropertyDescriptor(name[, descriptor[, msg]]) 2286 * 2287 * Asserts that the target has its own property descriptor with the given key 2288 * `name`. Enumerable and non-enumerable properties are included in the 2289 * search. 2290 * 2291 * expect({a: 1}).to.have.ownPropertyDescriptor('a'); 2292 * 2293 * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that 2294 * the property's descriptor is deeply equal to the given `descriptor`. See 2295 * the `deep-eql` project page for info on the deep equality algorithm: 2296 * https://github.com/chaijs/deep-eql. 2297 * 2298 * expect({a: 1}).to.have.ownPropertyDescriptor('a', { 2299 * configurable: true, 2300 * enumerable: true, 2301 * writable: true, 2302 * value: 1, 2303 * }); 2304 * 2305 * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`. 2306 * 2307 * expect({a: 1}).to.not.have.ownPropertyDescriptor('b'); 2308 * 2309 * However, it's dangerous to negate `.ownPropertyDescriptor` when providing 2310 * a `descriptor`. The problem is that it creates uncertain expectations by 2311 * asserting that the target either doesn't have a property descriptor with 2312 * the given key `name`, or that it does have a property descriptor with the 2313 * given key `name` but it’s not deeply equal to the given `descriptor`. It's 2314 * often best to identify the exact output that's expected, and then write an 2315 * assertion that only accepts that exact output. 2316 * 2317 * When the target isn't expected to have a property descriptor with the given 2318 * key `name`, it's often best to assert exactly that. 2319 * 2320 * // Recommended 2321 * expect({b: 2}).to.not.have.ownPropertyDescriptor('a'); 2322 * 2323 * // Not recommended 2324 * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', { 2325 * configurable: true, 2326 * enumerable: true, 2327 * writable: true, 2328 * value: 1, 2329 * }); 2330 * 2331 * When the target is expected to have a property descriptor with the given 2332 * key `name`, it's often best to assert that the property has its expected 2333 * descriptor, rather than asserting that it doesn't have one of many 2334 * unexpected descriptors. 2335 * 2336 * // Recommended 2337 * expect({a: 3}).to.have.ownPropertyDescriptor('a', { 2338 * configurable: true, 2339 * enumerable: true, 2340 * writable: true, 2341 * value: 3, 2342 * }); 2343 * 2344 * // Not recommended 2345 * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', { 2346 * configurable: true, 2347 * enumerable: true, 2348 * writable: true, 2349 * value: 1, 2350 * }); 2351 * 2352 * `.ownPropertyDescriptor` changes the target of any assertions that follow 2353 * in the chain to be the value of the property descriptor from the original 2354 * target object. 2355 * 2356 * expect({a: 1}).to.have.ownPropertyDescriptor('a') 2357 * .that.has.property('enumerable', true); 2358 * 2359 * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a 2360 * custom error message to show when the assertion fails. The message can also 2361 * be given as the second argument to `expect`. When not providing 2362 * `descriptor`, only use the second form. 2363 * 2364 * // Recommended 2365 * expect({a: 1}).to.have.ownPropertyDescriptor('a', { 2366 * configurable: true, 2367 * enumerable: true, 2368 * writable: true, 2369 * value: 2, 2370 * }, 'nooo why fail??'); 2371 * 2372 * // Recommended 2373 * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', { 2374 * configurable: true, 2375 * enumerable: true, 2376 * writable: true, 2377 * value: 2, 2378 * }); 2379 * 2380 * // Recommended 2381 * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b'); 2382 * 2383 * // Not recommended 2384 * expect({a: 1}) 2385 * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??'); 2386 * 2387 * The above assertion isn't the same thing as not providing `descriptor`. 2388 * Instead, it's asserting that the target object has a `b` property 2389 * descriptor that's deeply equal to `undefined`. 2390 * 2391 * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with 2392 * `.ownPropertyDescriptor`. 2393 * 2394 * @name ownPropertyDescriptor 2395 * @alias haveOwnPropertyDescriptor 2396 * @param {String} name 2397 * @param {Object} descriptor _optional_ 2398 * @param {String} msg _optional_ 2399 * @namespace BDD 2400 * @api public 2401 */ 2402 2403 function assertOwnPropertyDescriptor (name, descriptor, msg) { 2404 if (typeof descriptor === 'string') { 2405 msg = descriptor; 2406 descriptor = null; 2407 } 2408 if (msg) flag(this, 'message', msg); 2409 var obj = flag(this, 'object'); 2410 var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); 2411 if (actualDescriptor && descriptor) { 2412 this.assert( 2413 _.eql(descriptor, actualDescriptor) 2414 , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) 2415 , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) 2416 , descriptor 2417 , actualDescriptor 2418 , true 2419 ); 2420 } else { 2421 this.assert( 2422 actualDescriptor 2423 , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) 2424 , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) 2425 ); 2426 } 2427 flag(this, 'object', actualDescriptor); 2428 } 2429 2430 Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); 2431 Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); 2432 2433 /** 2434 * ### .lengthOf(n[, msg]) 2435 * 2436 * Asserts that the target's `length` or `size` is equal to the given number 2437 * `n`. 2438 * 2439 * expect([1, 2, 3]).to.have.lengthOf(3); 2440 * expect('foo').to.have.lengthOf(3); 2441 * expect(new Set([1, 2, 3])).to.have.lengthOf(3); 2442 * expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3); 2443 * 2444 * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often 2445 * best to assert that the target's `length` property is equal to its expected 2446 * value, rather than not equal to one of many unexpected values. 2447 * 2448 * expect('foo').to.have.lengthOf(3); // Recommended 2449 * expect('foo').to.not.have.lengthOf(4); // Not recommended 2450 * 2451 * `.lengthOf` accepts an optional `msg` argument which is a custom error 2452 * message to show when the assertion fails. The message can also be given as 2453 * the second argument to `expect`. 2454 * 2455 * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??'); 2456 * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2); 2457 * 2458 * `.lengthOf` can also be used as a language chain, causing all `.above`, 2459 * `.below`, `.least`, `.most`, and `.within` assertions that follow in the 2460 * chain to use the target's `length` property as the target. However, it's 2461 * often best to assert that the target's `length` property is equal to its 2462 * expected length, rather than asserting that its `length` property falls 2463 * within some range of values. 2464 * 2465 * // Recommended 2466 * expect([1, 2, 3]).to.have.lengthOf(3); 2467 * 2468 * // Not recommended 2469 * expect([1, 2, 3]).to.have.lengthOf.above(2); 2470 * expect([1, 2, 3]).to.have.lengthOf.below(4); 2471 * expect([1, 2, 3]).to.have.lengthOf.at.least(3); 2472 * expect([1, 2, 3]).to.have.lengthOf.at.most(3); 2473 * expect([1, 2, 3]).to.have.lengthOf.within(2,4); 2474 * 2475 * Due to a compatibility issue, the alias `.length` can't be chained directly 2476 * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used 2477 * interchangeably with `.lengthOf` in every situation. It's recommended to 2478 * always use `.lengthOf` instead of `.length`. 2479 * 2480 * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error 2481 * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected 2482 * 2483 * @name lengthOf 2484 * @alias length 2485 * @param {Number} n 2486 * @param {String} msg _optional_ 2487 * @namespace BDD 2488 * @api public 2489 */ 2490 2491 function assertLengthChain () { 2492 flag(this, 'doLength', true); 2493 } 2494 2495 function assertLength (n, msg) { 2496 if (msg) flag(this, 'message', msg); 2497 var obj = flag(this, 'object') 2498 , objType = _.type(obj).toLowerCase() 2499 , flagMsg = flag(this, 'message') 2500 , ssfi = flag(this, 'ssfi') 2501 , descriptor = 'length' 2502 , itemsCount; 2503 2504 switch (objType) { 2505 case 'map': 2506 case 'set': 2507 descriptor = 'size'; 2508 itemsCount = obj.size; 2509 break; 2510 default: 2511 new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); 2512 itemsCount = obj.length; 2513 } 2514 2515 this.assert( 2516 itemsCount == n 2517 , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}' 2518 , 'expected #{this} to not have a ' + descriptor + ' of #{act}' 2519 , n 2520 , itemsCount 2521 ); 2522 } 2523 2524 Assertion.addChainableMethod('length', assertLength, assertLengthChain); 2525 Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain); 2526 2527 /** 2528 * ### .match(re[, msg]) 2529 * 2530 * Asserts that the target matches the given regular expression `re`. 2531 * 2532 * expect('foobar').to.match(/^foo/); 2533 * 2534 * Add `.not` earlier in the chain to negate `.match`. 2535 * 2536 * expect('foobar').to.not.match(/taco/); 2537 * 2538 * `.match` accepts an optional `msg` argument which is a custom error message 2539 * to show when the assertion fails. The message can also be given as the 2540 * second argument to `expect`. 2541 * 2542 * expect('foobar').to.match(/taco/, 'nooo why fail??'); 2543 * expect('foobar', 'nooo why fail??').to.match(/taco/); 2544 * 2545 * The alias `.matches` can be used interchangeably with `.match`. 2546 * 2547 * @name match 2548 * @alias matches 2549 * @param {RegExp} re 2550 * @param {String} msg _optional_ 2551 * @namespace BDD 2552 * @api public 2553 */ 2554 function assertMatch(re, msg) { 2555 if (msg) flag(this, 'message', msg); 2556 var obj = flag(this, 'object'); 2557 this.assert( 2558 re.exec(obj) 2559 , 'expected #{this} to match ' + re 2560 , 'expected #{this} not to match ' + re 2561 ); 2562 } 2563 2564 Assertion.addMethod('match', assertMatch); 2565 Assertion.addMethod('matches', assertMatch); 2566 2567 /** 2568 * ### .string(str[, msg]) 2569 * 2570 * Asserts that the target string contains the given substring `str`. 2571 * 2572 * expect('foobar').to.have.string('bar'); 2573 * 2574 * Add `.not` earlier in the chain to negate `.string`. 2575 * 2576 * expect('foobar').to.not.have.string('taco'); 2577 * 2578 * `.string` accepts an optional `msg` argument which is a custom error 2579 * message to show when the assertion fails. The message can also be given as 2580 * the second argument to `expect`. 2581 * 2582 * expect('foobar').to.have.string('taco', 'nooo why fail??'); 2583 * expect('foobar', 'nooo why fail??').to.have.string('taco'); 2584 * 2585 * @name string 2586 * @param {String} str 2587 * @param {String} msg _optional_ 2588 * @namespace BDD 2589 * @api public 2590 */ 2591 2592 Assertion.addMethod('string', function (str, msg) { 2593 if (msg) flag(this, 'message', msg); 2594 var obj = flag(this, 'object') 2595 , flagMsg = flag(this, 'message') 2596 , ssfi = flag(this, 'ssfi'); 2597 new Assertion(obj, flagMsg, ssfi, true).is.a('string'); 2598 2599 this.assert( 2600 ~obj.indexOf(str) 2601 , 'expected #{this} to contain ' + _.inspect(str) 2602 , 'expected #{this} to not contain ' + _.inspect(str) 2603 ); 2604 }); 2605 2606 /** 2607 * ### .keys(key1[, key2[, ...]]) 2608 * 2609 * Asserts that the target object, array, map, or set has the given keys. Only 2610 * the target's own inherited properties are included in the search. 2611 * 2612 * When the target is an object or array, keys can be provided as one or more 2613 * string arguments, a single array argument, or a single object argument. In 2614 * the latter case, only the keys in the given object matter; the values are 2615 * ignored. 2616 * 2617 * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); 2618 * expect(['x', 'y']).to.have.all.keys(0, 1); 2619 * 2620 * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']); 2621 * expect(['x', 'y']).to.have.all.keys([0, 1]); 2622 * 2623 * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5 2624 * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5 2625 * 2626 * When the target is a map or set, each key must be provided as a separate 2627 * argument. 2628 * 2629 * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b'); 2630 * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b'); 2631 * 2632 * Because `.keys` does different things based on the target's type, it's 2633 * important to check the target's type before using `.keys`. See the `.a` doc 2634 * for info on testing a target's type. 2635 * 2636 * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b'); 2637 * 2638 * By default, strict (`===`) equality is used to compare keys of maps and 2639 * sets. Add `.deep` earlier in the chain to use deep equality instead. See 2640 * the `deep-eql` project page for info on the deep equality algorithm: 2641 * https://github.com/chaijs/deep-eql. 2642 * 2643 * // Target set deeply (but not strictly) has key `{a: 1}` 2644 * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]); 2645 * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]); 2646 * 2647 * By default, the target must have all of the given keys and no more. Add 2648 * `.any` earlier in the chain to only require that the target have at least 2649 * one of the given keys. Also, add `.not` earlier in the chain to negate 2650 * `.keys`. It's often best to add `.any` when negating `.keys`, and to use 2651 * `.all` when asserting `.keys` without negation. 2652 * 2653 * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts 2654 * exactly what's expected of the output, whereas `.not.all.keys` creates 2655 * uncertain expectations. 2656 * 2657 * // Recommended; asserts that target doesn't have any of the given keys 2658 * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); 2659 * 2660 * // Not recommended; asserts that target doesn't have all of the given 2661 * // keys but may or may not have some of them 2662 * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd'); 2663 * 2664 * When asserting `.keys` without negation, `.all` is preferred because 2665 * `.all.keys` asserts exactly what's expected of the output, whereas 2666 * `.any.keys` creates uncertain expectations. 2667 * 2668 * // Recommended; asserts that target has all the given keys 2669 * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); 2670 * 2671 * // Not recommended; asserts that target has at least one of the given 2672 * // keys but may or may not have more of them 2673 * expect({a: 1, b: 2}).to.have.any.keys('a', 'b'); 2674 * 2675 * Note that `.all` is used by default when neither `.all` nor `.any` appear 2676 * earlier in the chain. However, it's often best to add `.all` anyway because 2677 * it improves readability. 2678 * 2679 * // Both assertions are identical 2680 * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended 2681 * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended 2682 * 2683 * Add `.include` earlier in the chain to require that the target's keys be a 2684 * superset of the expected keys, rather than identical sets. 2685 * 2686 * // Target object's keys are a superset of ['a', 'b'] but not identical 2687 * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); 2688 * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); 2689 * 2690 * However, if `.any` and `.include` are combined, only the `.any` takes 2691 * effect. The `.include` is ignored in this case. 2692 * 2693 * // Both assertions are identical 2694 * expect({a: 1}).to.have.any.keys('a', 'b'); 2695 * expect({a: 1}).to.include.any.keys('a', 'b'); 2696 * 2697 * A custom error message can be given as the second argument to `expect`. 2698 * 2699 * expect({a: 1}, 'nooo why fail??').to.have.key('b'); 2700 * 2701 * The alias `.key` can be used interchangeably with `.keys`. 2702 * 2703 * @name keys 2704 * @alias key 2705 * @param {...String|Array|Object} keys 2706 * @namespace BDD 2707 * @api public 2708 */ 2709 2710 function assertKeys (keys) { 2711 var obj = flag(this, 'object') 2712 , objType = _.type(obj) 2713 , keysType = _.type(keys) 2714 , ssfi = flag(this, 'ssfi') 2715 , isDeep = flag(this, 'deep') 2716 , str 2717 , deepStr = '' 2718 , actual 2719 , ok = true 2720 , flagMsg = flag(this, 'message'); 2721 2722 flagMsg = flagMsg ? flagMsg + ': ' : ''; 2723 var mixedArgsMsg = flagMsg + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments'; 2724 2725 if (objType === 'Map' || objType === 'Set') { 2726 deepStr = isDeep ? 'deeply ' : ''; 2727 actual = []; 2728 2729 // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach. 2730 obj.forEach(function (val, key) { actual.push(key) }); 2731 2732 if (keysType !== 'Array') { 2733 keys = Array.prototype.slice.call(arguments); 2734 } 2735 } else { 2736 actual = _.getOwnEnumerableProperties(obj); 2737 2738 switch (keysType) { 2739 case 'Array': 2740 if (arguments.length > 1) { 2741 throw new AssertionError(mixedArgsMsg, undefined, ssfi); 2742 } 2743 break; 2744 case 'Object': 2745 if (arguments.length > 1) { 2746 throw new AssertionError(mixedArgsMsg, undefined, ssfi); 2747 } 2748 keys = Object.keys(keys); 2749 break; 2750 default: 2751 keys = Array.prototype.slice.call(arguments); 2752 } 2753 2754 // Only stringify non-Symbols because Symbols would become "Symbol()" 2755 keys = keys.map(function (val) { 2756 return typeof val === 'symbol' ? val : String(val); 2757 }); 2758 } 2759 2760 if (!keys.length) { 2761 throw new AssertionError(flagMsg + 'keys required', undefined, ssfi); 2762 } 2763 2764 var len = keys.length 2765 , any = flag(this, 'any') 2766 , all = flag(this, 'all') 2767 , expected = keys; 2768 2769 if (!any && !all) { 2770 all = true; 2771 } 2772 2773 // Has any 2774 if (any) { 2775 ok = expected.some(function(expectedKey) { 2776 return actual.some(function(actualKey) { 2777 if (isDeep) { 2778 return _.eql(expectedKey, actualKey); 2779 } else { 2780 return expectedKey === actualKey; 2781 } 2782 }); 2783 }); 2784 } 2785 2786 // Has all 2787 if (all) { 2788 ok = expected.every(function(expectedKey) { 2789 return actual.some(function(actualKey) { 2790 if (isDeep) { 2791 return _.eql(expectedKey, actualKey); 2792 } else { 2793 return expectedKey === actualKey; 2794 } 2795 }); 2796 }); 2797 2798 if (!flag(this, 'contains')) { 2799 ok = ok && keys.length == actual.length; 2800 } 2801 } 2802 2803 // Key string 2804 if (len > 1) { 2805 keys = keys.map(function(key) { 2806 return _.inspect(key); 2807 }); 2808 var last = keys.pop(); 2809 if (all) { 2810 str = keys.join(', ') + ', and ' + last; 2811 } 2812 if (any) { 2813 str = keys.join(', ') + ', or ' + last; 2814 } 2815 } else { 2816 str = _.inspect(keys[0]); 2817 } 2818 2819 // Form 2820 str = (len > 1 ? 'keys ' : 'key ') + str; 2821 2822 // Have / include 2823 str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; 2824 2825 // Assertion 2826 this.assert( 2827 ok 2828 , 'expected #{this} to ' + deepStr + str 2829 , 'expected #{this} to not ' + deepStr + str 2830 , expected.slice(0).sort(_.compareByInspect) 2831 , actual.sort(_.compareByInspect) 2832 , true 2833 ); 2834 } 2835 2836 Assertion.addMethod('keys', assertKeys); 2837 Assertion.addMethod('key', assertKeys); 2838 2839 /** 2840 * ### .throw([errorLike], [errMsgMatcher], [msg]) 2841 * 2842 * When no arguments are provided, `.throw` invokes the target function and 2843 * asserts that an error is thrown. 2844 * 2845 * var badFn = function () { throw new TypeError('Illegal salmon!'); }; 2846 * 2847 * expect(badFn).to.throw(); 2848 * 2849 * When one argument is provided, and it's an error constructor, `.throw` 2850 * invokes the target function and asserts that an error is thrown that's an 2851 * instance of that error constructor. 2852 * 2853 * var badFn = function () { throw new TypeError('Illegal salmon!'); }; 2854 * 2855 * expect(badFn).to.throw(TypeError); 2856 * 2857 * When one argument is provided, and it's an error instance, `.throw` invokes 2858 * the target function and asserts that an error is thrown that's strictly 2859 * (`===`) equal to that error instance. 2860 * 2861 * var err = new TypeError('Illegal salmon!'); 2862 * var badFn = function () { throw err; }; 2863 * 2864 * expect(badFn).to.throw(err); 2865 * 2866 * When one argument is provided, and it's a string, `.throw` invokes the 2867 * target function and asserts that an error is thrown with a message that 2868 * contains that string. 2869 * 2870 * var badFn = function () { throw new TypeError('Illegal salmon!'); }; 2871 * 2872 * expect(badFn).to.throw('salmon'); 2873 * 2874 * When one argument is provided, and it's a regular expression, `.throw` 2875 * invokes the target function and asserts that an error is thrown with a 2876 * message that matches that regular expression. 2877 * 2878 * var badFn = function () { throw new TypeError('Illegal salmon!'); }; 2879 * 2880 * expect(badFn).to.throw(/salmon/); 2881 * 2882 * When two arguments are provided, and the first is an error instance or 2883 * constructor, and the second is a string or regular expression, `.throw` 2884 * invokes the function and asserts that an error is thrown that fulfills both 2885 * conditions as described above. 2886 * 2887 * var err = new TypeError('Illegal salmon!'); 2888 * var badFn = function () { throw err; }; 2889 * 2890 * expect(badFn).to.throw(TypeError, 'salmon'); 2891 * expect(badFn).to.throw(TypeError, /salmon/); 2892 * expect(badFn).to.throw(err, 'salmon'); 2893 * expect(badFn).to.throw(err, /salmon/); 2894 * 2895 * Add `.not` earlier in the chain to negate `.throw`. 2896 * 2897 * var goodFn = function () {}; 2898 * 2899 * expect(goodFn).to.not.throw(); 2900 * 2901 * However, it's dangerous to negate `.throw` when providing any arguments. 2902 * The problem is that it creates uncertain expectations by asserting that the 2903 * target either doesn't throw an error, or that it throws an error but of a 2904 * different type than the given type, or that it throws an error of the given 2905 * type but with a message that doesn't include the given string. It's often 2906 * best to identify the exact output that's expected, and then write an 2907 * assertion that only accepts that exact output. 2908 * 2909 * When the target isn't expected to throw an error, it's often best to assert 2910 * exactly that. 2911 * 2912 * var goodFn = function () {}; 2913 * 2914 * expect(goodFn).to.not.throw(); // Recommended 2915 * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended 2916 * 2917 * When the target is expected to throw an error, it's often best to assert 2918 * that the error is of its expected type, and has a message that includes an 2919 * expected string, rather than asserting that it doesn't have one of many 2920 * unexpected types, and doesn't have a message that includes some string. 2921 * 2922 * var badFn = function () { throw new TypeError('Illegal salmon!'); }; 2923 * 2924 * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended 2925 * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended 2926 * 2927 * `.throw` changes the target of any assertions that follow in the chain to 2928 * be the error object that's thrown. 2929 * 2930 * var err = new TypeError('Illegal salmon!'); 2931 * err.code = 42; 2932 * var badFn = function () { throw err; }; 2933 * 2934 * expect(badFn).to.throw(TypeError).with.property('code', 42); 2935 * 2936 * `.throw` accepts an optional `msg` argument which is a custom error message 2937 * to show when the assertion fails. The message can also be given as the 2938 * second argument to `expect`. When not providing two arguments, always use 2939 * the second form. 2940 * 2941 * var goodFn = function () {}; 2942 * 2943 * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??'); 2944 * expect(goodFn, 'nooo why fail??').to.throw(); 2945 * 2946 * Due to limitations in ES5, `.throw` may not always work as expected when 2947 * using a transpiler such as Babel or TypeScript. In particular, it may 2948 * produce unexpected results when subclassing the built-in `Error` object and 2949 * then passing the subclassed constructor to `.throw`. See your transpiler's 2950 * docs for details: 2951 * 2952 * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) 2953 * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) 2954 * 2955 * Beware of some common mistakes when using the `throw` assertion. One common 2956 * mistake is to accidentally invoke the function yourself instead of letting 2957 * the `throw` assertion invoke the function for you. For example, when 2958 * testing if a function named `fn` throws, provide `fn` instead of `fn()` as 2959 * the target for the assertion. 2960 * 2961 * expect(fn).to.throw(); // Good! Tests `fn` as desired 2962 * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn` 2963 * 2964 * If you need to assert that your function `fn` throws when passed certain 2965 * arguments, then wrap a call to `fn` inside of another function. 2966 * 2967 * expect(function () { fn(42); }).to.throw(); // Function expression 2968 * expect(() => fn(42)).to.throw(); // ES6 arrow function 2969 * 2970 * Another common mistake is to provide an object method (or any stand-alone 2971 * function that relies on `this`) as the target of the assertion. Doing so is 2972 * problematic because the `this` context will be lost when the function is 2973 * invoked by `.throw`; there's no way for it to know what `this` is supposed 2974 * to be. There are two ways around this problem. One solution is to wrap the 2975 * method or function call inside of another function. Another solution is to 2976 * use `bind`. 2977 * 2978 * expect(function () { cat.meow(); }).to.throw(); // Function expression 2979 * expect(() => cat.meow()).to.throw(); // ES6 arrow function 2980 * expect(cat.meow.bind(cat)).to.throw(); // Bind 2981 * 2982 * Finally, it's worth mentioning that it's a best practice in JavaScript to 2983 * only throw `Error` and derivatives of `Error` such as `ReferenceError`, 2984 * `TypeError`, and user-defined objects that extend `Error`. No other type of 2985 * value will generate a stack trace when initialized. With that said, the 2986 * `throw` assertion does technically support any type of value being thrown, 2987 * not just `Error` and its derivatives. 2988 * 2989 * The aliases `.throws` and `.Throw` can be used interchangeably with 2990 * `.throw`. 2991 * 2992 * @name throw 2993 * @alias throws 2994 * @alias Throw 2995 * @param {Error|ErrorConstructor} errorLike 2996 * @param {String|RegExp} errMsgMatcher error message 2997 * @param {String} msg _optional_ 2998 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types 2999 * @returns error for chaining (null if no error) 3000 * @namespace BDD 3001 * @api public 3002 */ 3003 3004 function assertThrows (errorLike, errMsgMatcher, msg) { 3005 if (msg) flag(this, 'message', msg); 3006 var obj = flag(this, 'object') 3007 , ssfi = flag(this, 'ssfi') 3008 , flagMsg = flag(this, 'message') 3009 , negate = flag(this, 'negate') || false; 3010 new Assertion(obj, flagMsg, ssfi, true).is.a('function'); 3011 3012 if (errorLike instanceof RegExp || typeof errorLike === 'string') { 3013 errMsgMatcher = errorLike; 3014 errorLike = null; 3015 } 3016 3017 var caughtErr; 3018 try { 3019 obj(); 3020 } catch (err) { 3021 caughtErr = err; 3022 } 3023 3024 // If we have the negate flag enabled and at least one valid argument it means we do expect an error 3025 // but we want it to match a given set of criteria 3026 var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined; 3027 3028 // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible 3029 // See Issue #551 and PR #683@GitHub 3030 var everyArgIsDefined = Boolean(errorLike && errMsgMatcher); 3031 var errorLikeFail = false; 3032 var errMsgMatcherFail = false; 3033 3034 // Checking if error was thrown 3035 if (everyArgIsUndefined || !everyArgIsUndefined && !negate) { 3036 // We need this to display results correctly according to their types 3037 var errorLikeString = 'an error'; 3038 if (errorLike instanceof Error) { 3039 errorLikeString = '#{exp}'; 3040 } else if (errorLike) { 3041 errorLikeString = _.checkError.getConstructorName(errorLike); 3042 } 3043 3044 this.assert( 3045 caughtErr 3046 , 'expected #{this} to throw ' + errorLikeString 3047 , 'expected #{this} to not throw an error but #{act} was thrown' 3048 , errorLike && errorLike.toString() 3049 , (caughtErr instanceof Error ? 3050 caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr && 3051 _.checkError.getConstructorName(caughtErr))) 3052 ); 3053 } 3054 3055 if (errorLike && caughtErr) { 3056 // We should compare instances only if `errorLike` is an instance of `Error` 3057 if (errorLike instanceof Error) { 3058 var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike); 3059 3060 if (isCompatibleInstance === negate) { 3061 // These checks were created to ensure we won't fail too soon when we've got both args and a negate 3062 // See Issue #551 and PR #683@GitHub 3063 if (everyArgIsDefined && negate) { 3064 errorLikeFail = true; 3065 } else { 3066 this.assert( 3067 negate 3068 , 'expected #{this} to throw #{exp} but #{act} was thrown' 3069 , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '') 3070 , errorLike.toString() 3071 , caughtErr.toString() 3072 ); 3073 } 3074 } 3075 } 3076 3077 var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike); 3078 if (isCompatibleConstructor === negate) { 3079 if (everyArgIsDefined && negate) { 3080 errorLikeFail = true; 3081 } else { 3082 this.assert( 3083 negate 3084 , 'expected #{this} to throw #{exp} but #{act} was thrown' 3085 , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') 3086 , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) 3087 , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) 3088 ); 3089 } 3090 } 3091 } 3092 3093 if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) { 3094 // Here we check compatible messages 3095 var placeholder = 'including'; 3096 if (errMsgMatcher instanceof RegExp) { 3097 placeholder = 'matching' 3098 } 3099 3100 var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher); 3101 if (isCompatibleMessage === negate) { 3102 if (everyArgIsDefined && negate) { 3103 errMsgMatcherFail = true; 3104 } else { 3105 this.assert( 3106 negate 3107 , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}' 3108 , 'expected #{this} to throw error not ' + placeholder + ' #{exp}' 3109 , errMsgMatcher 3110 , _.checkError.getMessage(caughtErr) 3111 ); 3112 } 3113 } 3114 } 3115 3116 // If both assertions failed and both should've matched we throw an error 3117 if (errorLikeFail && errMsgMatcherFail) { 3118 this.assert( 3119 negate 3120 , 'expected #{this} to throw #{exp} but #{act} was thrown' 3121 , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') 3122 , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) 3123 , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) 3124 ); 3125 } 3126 3127 flag(this, 'object', caughtErr); 3128 }; 3129 3130 Assertion.addMethod('throw', assertThrows); 3131 Assertion.addMethod('throws', assertThrows); 3132 Assertion.addMethod('Throw', assertThrows); 3133 3134 /** 3135 * ### .respondTo(method[, msg]) 3136 * 3137 * When the target is a non-function object, `.respondTo` asserts that the 3138 * target has a method with the given name `method`. The method can be own or 3139 * inherited, and it can be enumerable or non-enumerable. 3140 * 3141 * function Cat () {} 3142 * Cat.prototype.meow = function () {}; 3143 * 3144 * expect(new Cat()).to.respondTo('meow'); 3145 * 3146 * When the target is a function, `.respondTo` asserts that the target's 3147 * `prototype` property has a method with the given name `method`. Again, the 3148 * method can be own or inherited, and it can be enumerable or non-enumerable. 3149 * 3150 * function Cat () {} 3151 * Cat.prototype.meow = function () {}; 3152 * 3153 * expect(Cat).to.respondTo('meow'); 3154 * 3155 * Add `.itself` earlier in the chain to force `.respondTo` to treat the 3156 * target as a non-function object, even if it's a function. Thus, it asserts 3157 * that the target has a method with the given name `method`, rather than 3158 * asserting that the target's `prototype` property has a method with the 3159 * given name `method`. 3160 * 3161 * function Cat () {} 3162 * Cat.prototype.meow = function () {}; 3163 * Cat.hiss = function () {}; 3164 * 3165 * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); 3166 * 3167 * When not adding `.itself`, it's important to check the target's type before 3168 * using `.respondTo`. See the `.a` doc for info on checking a target's type. 3169 * 3170 * function Cat () {} 3171 * Cat.prototype.meow = function () {}; 3172 * 3173 * expect(new Cat()).to.be.an('object').that.respondsTo('meow'); 3174 * 3175 * Add `.not` earlier in the chain to negate `.respondTo`. 3176 * 3177 * function Dog () {} 3178 * Dog.prototype.bark = function () {}; 3179 * 3180 * expect(new Dog()).to.not.respondTo('meow'); 3181 * 3182 * `.respondTo` accepts an optional `msg` argument which is a custom error 3183 * message to show when the assertion fails. The message can also be given as 3184 * the second argument to `expect`. 3185 * 3186 * expect({}).to.respondTo('meow', 'nooo why fail??'); 3187 * expect({}, 'nooo why fail??').to.respondTo('meow'); 3188 * 3189 * The alias `.respondsTo` can be used interchangeably with `.respondTo`. 3190 * 3191 * @name respondTo 3192 * @alias respondsTo 3193 * @param {String} method 3194 * @param {String} msg _optional_ 3195 * @namespace BDD 3196 * @api public 3197 */ 3198 3199 function respondTo (method, msg) { 3200 if (msg) flag(this, 'message', msg); 3201 var obj = flag(this, 'object') 3202 , itself = flag(this, 'itself') 3203 , context = ('function' === typeof obj && !itself) 3204 ? obj.prototype[method] 3205 : obj[method]; 3206 3207 this.assert( 3208 'function' === typeof context 3209 , 'expected #{this} to respond to ' + _.inspect(method) 3210 , 'expected #{this} to not respond to ' + _.inspect(method) 3211 ); 3212 } 3213 3214 Assertion.addMethod('respondTo', respondTo); 3215 Assertion.addMethod('respondsTo', respondTo); 3216 3217 /** 3218 * ### .itself 3219 * 3220 * Forces all `.respondTo` assertions that follow in the chain to behave as if 3221 * the target is a non-function object, even if it's a function. Thus, it 3222 * causes `.respondTo` to assert that the target has a method with the given 3223 * name, rather than asserting that the target's `prototype` property has a 3224 * method with the given name. 3225 * 3226 * function Cat () {} 3227 * Cat.prototype.meow = function () {}; 3228 * Cat.hiss = function () {}; 3229 * 3230 * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); 3231 * 3232 * @name itself 3233 * @namespace BDD 3234 * @api public 3235 */ 3236 3237 Assertion.addProperty('itself', function () { 3238 flag(this, 'itself', true); 3239 }); 3240 3241 /** 3242 * ### .satisfy(matcher[, msg]) 3243 * 3244 * Invokes the given `matcher` function with the target being passed as the 3245 * first argument, and asserts that the value returned is truthy. 3246 * 3247 * expect(1).to.satisfy(function(num) { 3248 * return num > 0; 3249 * }); 3250 * 3251 * Add `.not` earlier in the chain to negate `.satisfy`. 3252 * 3253 * expect(1).to.not.satisfy(function(num) { 3254 * return num > 2; 3255 * }); 3256 * 3257 * `.satisfy` accepts an optional `msg` argument which is a custom error 3258 * message to show when the assertion fails. The message can also be given as 3259 * the second argument to `expect`. 3260 * 3261 * expect(1).to.satisfy(function(num) { 3262 * return num > 2; 3263 * }, 'nooo why fail??'); 3264 * 3265 * expect(1, 'nooo why fail??').to.satisfy(function(num) { 3266 * return num > 2; 3267 * }); 3268 * 3269 * The alias `.satisfies` can be used interchangeably with `.satisfy`. 3270 * 3271 * @name satisfy 3272 * @alias satisfies 3273 * @param {Function} matcher 3274 * @param {String} msg _optional_ 3275 * @namespace BDD 3276 * @api public 3277 */ 3278 3279 function satisfy (matcher, msg) { 3280 if (msg) flag(this, 'message', msg); 3281 var obj = flag(this, 'object'); 3282 var result = matcher(obj); 3283 this.assert( 3284 result 3285 , 'expected #{this} to satisfy ' + _.objDisplay(matcher) 3286 , 'expected #{this} to not satisfy' + _.objDisplay(matcher) 3287 , flag(this, 'negate') ? false : true 3288 , result 3289 ); 3290 } 3291 3292 Assertion.addMethod('satisfy', satisfy); 3293 Assertion.addMethod('satisfies', satisfy); 3294 3295 /** 3296 * ### .closeTo(expected, delta[, msg]) 3297 * 3298 * Asserts that the target is a number that's within a given +/- `delta` range 3299 * of the given number `expected`. However, it's often best to assert that the 3300 * target is equal to its expected value. 3301 * 3302 * // Recommended 3303 * expect(1.5).to.equal(1.5); 3304 * 3305 * // Not recommended 3306 * expect(1.5).to.be.closeTo(1, 0.5); 3307 * expect(1.5).to.be.closeTo(2, 0.5); 3308 * expect(1.5).to.be.closeTo(1, 1); 3309 * 3310 * Add `.not` earlier in the chain to negate `.closeTo`. 3311 * 3312 * expect(1.5).to.equal(1.5); // Recommended 3313 * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended 3314 * 3315 * `.closeTo` accepts an optional `msg` argument which is a custom error 3316 * message to show when the assertion fails. The message can also be given as 3317 * the second argument to `expect`. 3318 * 3319 * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??'); 3320 * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1); 3321 * 3322 * The alias `.approximately` can be used interchangeably with `.closeTo`. 3323 * 3324 * @name closeTo 3325 * @alias approximately 3326 * @param {Number} expected 3327 * @param {Number} delta 3328 * @param {String} msg _optional_ 3329 * @namespace BDD 3330 * @api public 3331 */ 3332 3333 function closeTo(expected, delta, msg) { 3334 if (msg) flag(this, 'message', msg); 3335 var obj = flag(this, 'object') 3336 , flagMsg = flag(this, 'message') 3337 , ssfi = flag(this, 'ssfi'); 3338 3339 new Assertion(obj, flagMsg, ssfi, true).is.a('number'); 3340 if (typeof expected !== 'number' || typeof delta !== 'number') { 3341 flagMsg = flagMsg ? flagMsg + ': ' : ''; 3342 var deltaMessage = delta === undefined ? ", and a delta is required" : ""; 3343 throw new AssertionError( 3344 flagMsg + 'the arguments to closeTo or approximately must be numbers' + deltaMessage, 3345 undefined, 3346 ssfi 3347 ); 3348 } 3349 3350 this.assert( 3351 Math.abs(obj - expected) <= delta 3352 , 'expected #{this} to be close to ' + expected + ' +/- ' + delta 3353 , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta 3354 ); 3355 } 3356 3357 Assertion.addMethod('closeTo', closeTo); 3358 Assertion.addMethod('approximately', closeTo); 3359 3360 // Note: Duplicates are ignored if testing for inclusion instead of sameness. 3361 function isSubsetOf(subset, superset, cmp, contains, ordered) { 3362 if (!contains) { 3363 if (subset.length !== superset.length) return false; 3364 superset = superset.slice(); 3365 } 3366 3367 return subset.every(function(elem, idx) { 3368 if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; 3369 3370 if (!cmp) { 3371 var matchIdx = superset.indexOf(elem); 3372 if (matchIdx === -1) return false; 3373 3374 // Remove match from superset so not counted twice if duplicate in subset. 3375 if (!contains) superset.splice(matchIdx, 1); 3376 return true; 3377 } 3378 3379 return superset.some(function(elem2, matchIdx) { 3380 if (!cmp(elem, elem2)) return false; 3381 3382 // Remove match from superset so not counted twice if duplicate in subset. 3383 if (!contains) superset.splice(matchIdx, 1); 3384 return true; 3385 }); 3386 }); 3387 } 3388 3389 /** 3390 * ### .members(set[, msg]) 3391 * 3392 * Asserts that the target array has the same members as the given array 3393 * `set`. 3394 * 3395 * expect([1, 2, 3]).to.have.members([2, 1, 3]); 3396 * expect([1, 2, 2]).to.have.members([2, 1, 2]); 3397 * 3398 * By default, members are compared using strict (`===`) equality. Add `.deep` 3399 * earlier in the chain to use deep equality instead. See the `deep-eql` 3400 * project page for info on the deep equality algorithm: 3401 * https://github.com/chaijs/deep-eql. 3402 * 3403 * // Target array deeply (but not strictly) has member `{a: 1}` 3404 * expect([{a: 1}]).to.have.deep.members([{a: 1}]); 3405 * expect([{a: 1}]).to.not.have.members([{a: 1}]); 3406 * 3407 * By default, order doesn't matter. Add `.ordered` earlier in the chain to 3408 * require that members appear in the same order. 3409 * 3410 * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]); 3411 * expect([1, 2, 3]).to.have.members([2, 1, 3]) 3412 * .but.not.ordered.members([2, 1, 3]); 3413 * 3414 * By default, both arrays must be the same size. Add `.include` earlier in 3415 * the chain to require that the target's members be a superset of the 3416 * expected members. Note that duplicates are ignored in the subset when 3417 * `.include` is added. 3418 * 3419 * // Target array is a superset of [1, 2] but not identical 3420 * expect([1, 2, 3]).to.include.members([1, 2]); 3421 * expect([1, 2, 3]).to.not.have.members([1, 2]); 3422 * 3423 * // Duplicates in the subset are ignored 3424 * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); 3425 * 3426 * `.deep`, `.ordered`, and `.include` can all be combined. However, if 3427 * `.include` and `.ordered` are combined, the ordering begins at the start of 3428 * both arrays. 3429 * 3430 * expect([{a: 1}, {b: 2}, {c: 3}]) 3431 * .to.include.deep.ordered.members([{a: 1}, {b: 2}]) 3432 * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]); 3433 * 3434 * Add `.not` earlier in the chain to negate `.members`. However, it's 3435 * dangerous to do so. The problem is that it creates uncertain expectations 3436 * by asserting that the target array doesn't have all of the same members as 3437 * the given array `set` but may or may not have some of them. It's often best 3438 * to identify the exact output that's expected, and then write an assertion 3439 * that only accepts that exact output. 3440 * 3441 * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended 3442 * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended 3443 * 3444 * `.members` accepts an optional `msg` argument which is a custom error 3445 * message to show when the assertion fails. The message can also be given as 3446 * the second argument to `expect`. 3447 * 3448 * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??'); 3449 * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]); 3450 * 3451 * @name members 3452 * @param {Array} set 3453 * @param {String} msg _optional_ 3454 * @namespace BDD 3455 * @api public 3456 */ 3457 3458 Assertion.addMethod('members', function (subset, msg) { 3459 if (msg) flag(this, 'message', msg); 3460 var obj = flag(this, 'object') 3461 , flagMsg = flag(this, 'message') 3462 , ssfi = flag(this, 'ssfi'); 3463 3464 new Assertion(obj, flagMsg, ssfi, true).to.be.an('array'); 3465 new Assertion(subset, flagMsg, ssfi, true).to.be.an('array'); 3466 3467 var contains = flag(this, 'contains'); 3468 var ordered = flag(this, 'ordered'); 3469 3470 var subject, failMsg, failNegateMsg; 3471 3472 if (contains) { 3473 subject = ordered ? 'an ordered superset' : 'a superset'; 3474 failMsg = 'expected #{this} to be ' + subject + ' of #{exp}'; 3475 failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}'; 3476 } else { 3477 subject = ordered ? 'ordered members' : 'members'; 3478 failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}'; 3479 failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}'; 3480 } 3481 3482 var cmp = flag(this, 'deep') ? _.eql : undefined; 3483 3484 this.assert( 3485 isSubsetOf(subset, obj, cmp, contains, ordered) 3486 , failMsg 3487 , failNegateMsg 3488 , subset 3489 , obj 3490 , true 3491 ); 3492 }); 3493 3494 /** 3495 * ### .oneOf(list[, msg]) 3496 * 3497 * Asserts that the target is a member of the given array `list`. However, 3498 * it's often best to assert that the target is equal to its expected value. 3499 * 3500 * expect(1).to.equal(1); // Recommended 3501 * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended 3502 * 3503 * Comparisons are performed using strict (`===`) equality. 3504 * 3505 * Add `.not` earlier in the chain to negate `.oneOf`. 3506 * 3507 * expect(1).to.equal(1); // Recommended 3508 * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended 3509 * 3510 * It can also be chained with `.contain` or `.include`, which will work with 3511 * both arrays and strings: 3512 * 3513 * expect('Today is sunny').to.contain.oneOf(['sunny', 'cloudy']) 3514 * expect('Today is rainy').to.not.contain.oneOf(['sunny', 'cloudy']) 3515 * expect([1,2,3]).to.contain.oneOf([3,4,5]) 3516 * expect([1,2,3]).to.not.contain.oneOf([4,5,6]) 3517 * 3518 * `.oneOf` accepts an optional `msg` argument which is a custom error message 3519 * to show when the assertion fails. The message can also be given as the 3520 * second argument to `expect`. 3521 * 3522 * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??'); 3523 * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]); 3524 * 3525 * @name oneOf 3526 * @param {Array<*>} list 3527 * @param {String} msg _optional_ 3528 * @namespace BDD 3529 * @api public 3530 */ 3531 3532 function oneOf (list, msg) { 3533 if (msg) flag(this, 'message', msg); 3534 var expected = flag(this, 'object') 3535 , flagMsg = flag(this, 'message') 3536 , ssfi = flag(this, 'ssfi') 3537 , contains = flag(this, 'contains') 3538 , isDeep = flag(this, 'deep'); 3539 new Assertion(list, flagMsg, ssfi, true).to.be.an('array'); 3540 3541 if (contains) { 3542 this.assert( 3543 list.some(function(possibility) { return expected.indexOf(possibility) > -1 }) 3544 , 'expected #{this} to contain one of #{exp}' 3545 , 'expected #{this} to not contain one of #{exp}' 3546 , list 3547 , expected 3548 ); 3549 } else { 3550 if (isDeep) { 3551 this.assert( 3552 list.some(function(possibility) { return _.eql(expected, possibility) }) 3553 , 'expected #{this} to deeply equal one of #{exp}' 3554 , 'expected #{this} to deeply equal one of #{exp}' 3555 , list 3556 , expected 3557 ); 3558 } else { 3559 this.assert( 3560 list.indexOf(expected) > -1 3561 , 'expected #{this} to be one of #{exp}' 3562 , 'expected #{this} to not be one of #{exp}' 3563 , list 3564 , expected 3565 ); 3566 } 3567 } 3568 } 3569 3570 Assertion.addMethod('oneOf', oneOf); 3571 3572 /** 3573 * ### .change(subject[, prop[, msg]]) 3574 * 3575 * When one argument is provided, `.change` asserts that the given function 3576 * `subject` returns a different value when it's invoked before the target 3577 * function compared to when it's invoked afterward. However, it's often best 3578 * to assert that `subject` is equal to its expected value. 3579 * 3580 * var dots = '' 3581 * , addDot = function () { dots += '.'; } 3582 * , getDots = function () { return dots; }; 3583 * 3584 * // Recommended 3585 * expect(getDots()).to.equal(''); 3586 * addDot(); 3587 * expect(getDots()).to.equal('.'); 3588 * 3589 * // Not recommended 3590 * expect(addDot).to.change(getDots); 3591 * 3592 * When two arguments are provided, `.change` asserts that the value of the 3593 * given object `subject`'s `prop` property is different before invoking the 3594 * target function compared to afterward. 3595 * 3596 * var myObj = {dots: ''} 3597 * , addDot = function () { myObj.dots += '.'; }; 3598 * 3599 * // Recommended 3600 * expect(myObj).to.have.property('dots', ''); 3601 * addDot(); 3602 * expect(myObj).to.have.property('dots', '.'); 3603 * 3604 * // Not recommended 3605 * expect(addDot).to.change(myObj, 'dots'); 3606 * 3607 * Strict (`===`) equality is used to compare before and after values. 3608 * 3609 * Add `.not` earlier in the chain to negate `.change`. 3610 * 3611 * var dots = '' 3612 * , noop = function () {} 3613 * , getDots = function () { return dots; }; 3614 * 3615 * expect(noop).to.not.change(getDots); 3616 * 3617 * var myObj = {dots: ''} 3618 * , noop = function () {}; 3619 * 3620 * expect(noop).to.not.change(myObj, 'dots'); 3621 * 3622 * `.change` accepts an optional `msg` argument which is a custom error 3623 * message to show when the assertion fails. The message can also be given as 3624 * the second argument to `expect`. When not providing two arguments, always 3625 * use the second form. 3626 * 3627 * var myObj = {dots: ''} 3628 * , addDot = function () { myObj.dots += '.'; }; 3629 * 3630 * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??'); 3631 * 3632 * var dots = '' 3633 * , addDot = function () { dots += '.'; } 3634 * , getDots = function () { return dots; }; 3635 * 3636 * expect(addDot, 'nooo why fail??').to.not.change(getDots); 3637 * 3638 * `.change` also causes all `.by` assertions that follow in the chain to 3639 * assert how much a numeric subject was increased or decreased by. However, 3640 * it's dangerous to use `.change.by`. The problem is that it creates 3641 * uncertain expectations by asserting that the subject either increases by 3642 * the given delta, or that it decreases by the given delta. It's often best 3643 * to identify the exact output that's expected, and then write an assertion 3644 * that only accepts that exact output. 3645 * 3646 * var myObj = {val: 1} 3647 * , addTwo = function () { myObj.val += 2; } 3648 * , subtractTwo = function () { myObj.val -= 2; }; 3649 * 3650 * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended 3651 * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended 3652 * 3653 * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended 3654 * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended 3655 * 3656 * The alias `.changes` can be used interchangeably with `.change`. 3657 * 3658 * @name change 3659 * @alias changes 3660 * @param {String} subject 3661 * @param {String} prop name _optional_ 3662 * @param {String} msg _optional_ 3663 * @namespace BDD 3664 * @api public 3665 */ 3666 3667 function assertChanges (subject, prop, msg) { 3668 if (msg) flag(this, 'message', msg); 3669 var fn = flag(this, 'object') 3670 , flagMsg = flag(this, 'message') 3671 , ssfi = flag(this, 'ssfi'); 3672 new Assertion(fn, flagMsg, ssfi, true).is.a('function'); 3673 3674 var initial; 3675 if (!prop) { 3676 new Assertion(subject, flagMsg, ssfi, true).is.a('function'); 3677 initial = subject(); 3678 } else { 3679 new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); 3680 initial = subject[prop]; 3681 } 3682 3683 fn(); 3684 3685 var final = prop === undefined || prop === null ? subject() : subject[prop]; 3686 var msgObj = prop === undefined || prop === null ? initial : '.' + prop; 3687 3688 // This gets flagged because of the .by(delta) assertion 3689 flag(this, 'deltaMsgObj', msgObj); 3690 flag(this, 'initialDeltaValue', initial); 3691 flag(this, 'finalDeltaValue', final); 3692 flag(this, 'deltaBehavior', 'change'); 3693 flag(this, 'realDelta', final !== initial); 3694 3695 this.assert( 3696 initial !== final 3697 , 'expected ' + msgObj + ' to change' 3698 , 'expected ' + msgObj + ' to not change' 3699 ); 3700 } 3701 3702 Assertion.addMethod('change', assertChanges); 3703 Assertion.addMethod('changes', assertChanges); 3704 3705 /** 3706 * ### .increase(subject[, prop[, msg]]) 3707 * 3708 * When one argument is provided, `.increase` asserts that the given function 3709 * `subject` returns a greater number when it's invoked after invoking the 3710 * target function compared to when it's invoked beforehand. `.increase` also 3711 * causes all `.by` assertions that follow in the chain to assert how much 3712 * greater of a number is returned. It's often best to assert that the return 3713 * value increased by the expected amount, rather than asserting it increased 3714 * by any amount. 3715 * 3716 * var val = 1 3717 * , addTwo = function () { val += 2; } 3718 * , getVal = function () { return val; }; 3719 * 3720 * expect(addTwo).to.increase(getVal).by(2); // Recommended 3721 * expect(addTwo).to.increase(getVal); // Not recommended 3722 * 3723 * When two arguments are provided, `.increase` asserts that the value of the 3724 * given object `subject`'s `prop` property is greater after invoking the 3725 * target function compared to beforehand. 3726 * 3727 * var myObj = {val: 1} 3728 * , addTwo = function () { myObj.val += 2; }; 3729 * 3730 * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended 3731 * expect(addTwo).to.increase(myObj, 'val'); // Not recommended 3732 * 3733 * Add `.not` earlier in the chain to negate `.increase`. However, it's 3734 * dangerous to do so. The problem is that it creates uncertain expectations 3735 * by asserting that the subject either decreases, or that it stays the same. 3736 * It's often best to identify the exact output that's expected, and then 3737 * write an assertion that only accepts that exact output. 3738 * 3739 * When the subject is expected to decrease, it's often best to assert that it 3740 * decreased by the expected amount. 3741 * 3742 * var myObj = {val: 1} 3743 * , subtractTwo = function () { myObj.val -= 2; }; 3744 * 3745 * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended 3746 * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended 3747 * 3748 * When the subject is expected to stay the same, it's often best to assert 3749 * exactly that. 3750 * 3751 * var myObj = {val: 1} 3752 * , noop = function () {}; 3753 * 3754 * expect(noop).to.not.change(myObj, 'val'); // Recommended 3755 * expect(noop).to.not.increase(myObj, 'val'); // Not recommended 3756 * 3757 * `.increase` accepts an optional `msg` argument which is a custom error 3758 * message to show when the assertion fails. The message can also be given as 3759 * the second argument to `expect`. When not providing two arguments, always 3760 * use the second form. 3761 * 3762 * var myObj = {val: 1} 3763 * , noop = function () {}; 3764 * 3765 * expect(noop).to.increase(myObj, 'val', 'nooo why fail??'); 3766 * 3767 * var val = 1 3768 * , noop = function () {} 3769 * , getVal = function () { return val; }; 3770 * 3771 * expect(noop, 'nooo why fail??').to.increase(getVal); 3772 * 3773 * The alias `.increases` can be used interchangeably with `.increase`. 3774 * 3775 * @name increase 3776 * @alias increases 3777 * @param {String|Function} subject 3778 * @param {String} prop name _optional_ 3779 * @param {String} msg _optional_ 3780 * @namespace BDD 3781 * @api public 3782 */ 3783 3784 function assertIncreases (subject, prop, msg) { 3785 if (msg) flag(this, 'message', msg); 3786 var fn = flag(this, 'object') 3787 , flagMsg = flag(this, 'message') 3788 , ssfi = flag(this, 'ssfi'); 3789 new Assertion(fn, flagMsg, ssfi, true).is.a('function'); 3790 3791 var initial; 3792 if (!prop) { 3793 new Assertion(subject, flagMsg, ssfi, true).is.a('function'); 3794 initial = subject(); 3795 } else { 3796 new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); 3797 initial = subject[prop]; 3798 } 3799 3800 // Make sure that the target is a number 3801 new Assertion(initial, flagMsg, ssfi, true).is.a('number'); 3802 3803 fn(); 3804 3805 var final = prop === undefined || prop === null ? subject() : subject[prop]; 3806 var msgObj = prop === undefined || prop === null ? initial : '.' + prop; 3807 3808 flag(this, 'deltaMsgObj', msgObj); 3809 flag(this, 'initialDeltaValue', initial); 3810 flag(this, 'finalDeltaValue', final); 3811 flag(this, 'deltaBehavior', 'increase'); 3812 flag(this, 'realDelta', final - initial); 3813 3814 this.assert( 3815 final - initial > 0 3816 , 'expected ' + msgObj + ' to increase' 3817 , 'expected ' + msgObj + ' to not increase' 3818 ); 3819 } 3820 3821 Assertion.addMethod('increase', assertIncreases); 3822 Assertion.addMethod('increases', assertIncreases); 3823 3824 /** 3825 * ### .decrease(subject[, prop[, msg]]) 3826 * 3827 * When one argument is provided, `.decrease` asserts that the given function 3828 * `subject` returns a lesser number when it's invoked after invoking the 3829 * target function compared to when it's invoked beforehand. `.decrease` also 3830 * causes all `.by` assertions that follow in the chain to assert how much 3831 * lesser of a number is returned. It's often best to assert that the return 3832 * value decreased by the expected amount, rather than asserting it decreased 3833 * by any amount. 3834 * 3835 * var val = 1 3836 * , subtractTwo = function () { val -= 2; } 3837 * , getVal = function () { return val; }; 3838 * 3839 * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended 3840 * expect(subtractTwo).to.decrease(getVal); // Not recommended 3841 * 3842 * When two arguments are provided, `.decrease` asserts that the value of the 3843 * given object `subject`'s `prop` property is lesser after invoking the 3844 * target function compared to beforehand. 3845 * 3846 * var myObj = {val: 1} 3847 * , subtractTwo = function () { myObj.val -= 2; }; 3848 * 3849 * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended 3850 * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended 3851 * 3852 * Add `.not` earlier in the chain to negate `.decrease`. However, it's 3853 * dangerous to do so. The problem is that it creates uncertain expectations 3854 * by asserting that the subject either increases, or that it stays the same. 3855 * It's often best to identify the exact output that's expected, and then 3856 * write an assertion that only accepts that exact output. 3857 * 3858 * When the subject is expected to increase, it's often best to assert that it 3859 * increased by the expected amount. 3860 * 3861 * var myObj = {val: 1} 3862 * , addTwo = function () { myObj.val += 2; }; 3863 * 3864 * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended 3865 * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended 3866 * 3867 * When the subject is expected to stay the same, it's often best to assert 3868 * exactly that. 3869 * 3870 * var myObj = {val: 1} 3871 * , noop = function () {}; 3872 * 3873 * expect(noop).to.not.change(myObj, 'val'); // Recommended 3874 * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended 3875 * 3876 * `.decrease` accepts an optional `msg` argument which is a custom error 3877 * message to show when the assertion fails. The message can also be given as 3878 * the second argument to `expect`. When not providing two arguments, always 3879 * use the second form. 3880 * 3881 * var myObj = {val: 1} 3882 * , noop = function () {}; 3883 * 3884 * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??'); 3885 * 3886 * var val = 1 3887 * , noop = function () {} 3888 * , getVal = function () { return val; }; 3889 * 3890 * expect(noop, 'nooo why fail??').to.decrease(getVal); 3891 * 3892 * The alias `.decreases` can be used interchangeably with `.decrease`. 3893 * 3894 * @name decrease 3895 * @alias decreases 3896 * @param {String|Function} subject 3897 * @param {String} prop name _optional_ 3898 * @param {String} msg _optional_ 3899 * @namespace BDD 3900 * @api public 3901 */ 3902 3903 function assertDecreases (subject, prop, msg) { 3904 if (msg) flag(this, 'message', msg); 3905 var fn = flag(this, 'object') 3906 , flagMsg = flag(this, 'message') 3907 , ssfi = flag(this, 'ssfi'); 3908 new Assertion(fn, flagMsg, ssfi, true).is.a('function'); 3909 3910 var initial; 3911 if (!prop) { 3912 new Assertion(subject, flagMsg, ssfi, true).is.a('function'); 3913 initial = subject(); 3914 } else { 3915 new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); 3916 initial = subject[prop]; 3917 } 3918 3919 // Make sure that the target is a number 3920 new Assertion(initial, flagMsg, ssfi, true).is.a('number'); 3921 3922 fn(); 3923 3924 var final = prop === undefined || prop === null ? subject() : subject[prop]; 3925 var msgObj = prop === undefined || prop === null ? initial : '.' + prop; 3926 3927 flag(this, 'deltaMsgObj', msgObj); 3928 flag(this, 'initialDeltaValue', initial); 3929 flag(this, 'finalDeltaValue', final); 3930 flag(this, 'deltaBehavior', 'decrease'); 3931 flag(this, 'realDelta', initial - final); 3932 3933 this.assert( 3934 final - initial < 0 3935 , 'expected ' + msgObj + ' to decrease' 3936 , 'expected ' + msgObj + ' to not decrease' 3937 ); 3938 } 3939 3940 Assertion.addMethod('decrease', assertDecreases); 3941 Assertion.addMethod('decreases', assertDecreases); 3942 3943 /** 3944 * ### .by(delta[, msg]) 3945 * 3946 * When following an `.increase` assertion in the chain, `.by` asserts that 3947 * the subject of the `.increase` assertion increased by the given `delta`. 3948 * 3949 * var myObj = {val: 1} 3950 * , addTwo = function () { myObj.val += 2; }; 3951 * 3952 * expect(addTwo).to.increase(myObj, 'val').by(2); 3953 * 3954 * When following a `.decrease` assertion in the chain, `.by` asserts that the 3955 * subject of the `.decrease` assertion decreased by the given `delta`. 3956 * 3957 * var myObj = {val: 1} 3958 * , subtractTwo = function () { myObj.val -= 2; }; 3959 * 3960 * expect(subtractTwo).to.decrease(myObj, 'val').by(2); 3961 * 3962 * When following a `.change` assertion in the chain, `.by` asserts that the 3963 * subject of the `.change` assertion either increased or decreased by the 3964 * given `delta`. However, it's dangerous to use `.change.by`. The problem is 3965 * that it creates uncertain expectations. It's often best to identify the 3966 * exact output that's expected, and then write an assertion that only accepts 3967 * that exact output. 3968 * 3969 * var myObj = {val: 1} 3970 * , addTwo = function () { myObj.val += 2; } 3971 * , subtractTwo = function () { myObj.val -= 2; }; 3972 * 3973 * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended 3974 * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended 3975 * 3976 * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended 3977 * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended 3978 * 3979 * Add `.not` earlier in the chain to negate `.by`. However, it's often best 3980 * to assert that the subject changed by its expected delta, rather than 3981 * asserting that it didn't change by one of countless unexpected deltas. 3982 * 3983 * var myObj = {val: 1} 3984 * , addTwo = function () { myObj.val += 2; }; 3985 * 3986 * // Recommended 3987 * expect(addTwo).to.increase(myObj, 'val').by(2); 3988 * 3989 * // Not recommended 3990 * expect(addTwo).to.increase(myObj, 'val').but.not.by(3); 3991 * 3992 * `.by` accepts an optional `msg` argument which is a custom error message to 3993 * show when the assertion fails. The message can also be given as the second 3994 * argument to `expect`. 3995 * 3996 * var myObj = {val: 1} 3997 * , addTwo = function () { myObj.val += 2; }; 3998 * 3999 * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??'); 4000 * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3); 4001 * 4002 * @name by 4003 * @param {Number} delta 4004 * @param {String} msg _optional_ 4005 * @namespace BDD 4006 * @api public 4007 */ 4008 4009 function assertDelta(delta, msg) { 4010 if (msg) flag(this, 'message', msg); 4011 4012 var msgObj = flag(this, 'deltaMsgObj'); 4013 var initial = flag(this, 'initialDeltaValue'); 4014 var final = flag(this, 'finalDeltaValue'); 4015 var behavior = flag(this, 'deltaBehavior'); 4016 var realDelta = flag(this, 'realDelta'); 4017 4018 var expression; 4019 if (behavior === 'change') { 4020 expression = Math.abs(final - initial) === Math.abs(delta); 4021 } else { 4022 expression = realDelta === Math.abs(delta); 4023 } 4024 4025 this.assert( 4026 expression 4027 , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta 4028 , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta 4029 ); 4030 } 4031 4032 Assertion.addMethod('by', assertDelta); 4033 4034 /** 4035 * ### .extensible 4036 * 4037 * Asserts that the target is extensible, which means that new properties can 4038 * be added to it. Primitives are never extensible. 4039 * 4040 * expect({a: 1}).to.be.extensible; 4041 * 4042 * Add `.not` earlier in the chain to negate `.extensible`. 4043 * 4044 * var nonExtensibleObject = Object.preventExtensions({}) 4045 * , sealedObject = Object.seal({}) 4046 * , frozenObject = Object.freeze({}); 4047 * 4048 * expect(nonExtensibleObject).to.not.be.extensible; 4049 * expect(sealedObject).to.not.be.extensible; 4050 * expect(frozenObject).to.not.be.extensible; 4051 * expect(1).to.not.be.extensible; 4052 * 4053 * A custom error message can be given as the second argument to `expect`. 4054 * 4055 * expect(1, 'nooo why fail??').to.be.extensible; 4056 * 4057 * @name extensible 4058 * @namespace BDD 4059 * @api public 4060 */ 4061 4062 Assertion.addProperty('extensible', function() { 4063 var obj = flag(this, 'object'); 4064 4065 // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. 4066 // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. 4067 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible 4068 // The following provides ES6 behavior for ES5 environments. 4069 4070 var isExtensible = obj === Object(obj) && Object.isExtensible(obj); 4071 4072 this.assert( 4073 isExtensible 4074 , 'expected #{this} to be extensible' 4075 , 'expected #{this} to not be extensible' 4076 ); 4077 }); 4078 4079 /** 4080 * ### .sealed 4081 * 4082 * Asserts that the target is sealed, which means that new properties can't be 4083 * added to it, and its existing properties can't be reconfigured or deleted. 4084 * However, it's possible that its existing properties can still be reassigned 4085 * to different values. Primitives are always sealed. 4086 * 4087 * var sealedObject = Object.seal({}); 4088 * var frozenObject = Object.freeze({}); 4089 * 4090 * expect(sealedObject).to.be.sealed; 4091 * expect(frozenObject).to.be.sealed; 4092 * expect(1).to.be.sealed; 4093 * 4094 * Add `.not` earlier in the chain to negate `.sealed`. 4095 * 4096 * expect({a: 1}).to.not.be.sealed; 4097 * 4098 * A custom error message can be given as the second argument to `expect`. 4099 * 4100 * expect({a: 1}, 'nooo why fail??').to.be.sealed; 4101 * 4102 * @name sealed 4103 * @namespace BDD 4104 * @api public 4105 */ 4106 4107 Assertion.addProperty('sealed', function() { 4108 var obj = flag(this, 'object'); 4109 4110 // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. 4111 // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. 4112 // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed 4113 // The following provides ES6 behavior for ES5 environments. 4114 4115 var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; 4116 4117 this.assert( 4118 isSealed 4119 , 'expected #{this} to be sealed' 4120 , 'expected #{this} to not be sealed' 4121 ); 4122 }); 4123 4124 /** 4125 * ### .frozen 4126 * 4127 * Asserts that the target is frozen, which means that new properties can't be 4128 * added to it, and its existing properties can't be reassigned to different 4129 * values, reconfigured, or deleted. Primitives are always frozen. 4130 * 4131 * var frozenObject = Object.freeze({}); 4132 * 4133 * expect(frozenObject).to.be.frozen; 4134 * expect(1).to.be.frozen; 4135 * 4136 * Add `.not` earlier in the chain to negate `.frozen`. 4137 * 4138 * expect({a: 1}).to.not.be.frozen; 4139 * 4140 * A custom error message can be given as the second argument to `expect`. 4141 * 4142 * expect({a: 1}, 'nooo why fail??').to.be.frozen; 4143 * 4144 * @name frozen 4145 * @namespace BDD 4146 * @api public 4147 */ 4148 4149 Assertion.addProperty('frozen', function() { 4150 var obj = flag(this, 'object'); 4151 4152 // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. 4153 // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. 4154 // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen 4155 // The following provides ES6 behavior for ES5 environments. 4156 4157 var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; 4158 4159 this.assert( 4160 isFrozen 4161 , 'expected #{this} to be frozen' 4162 , 'expected #{this} to not be frozen' 4163 ); 4164 }); 4165 4166 /** 4167 * ### .finite 4168 * 4169 * Asserts that the target is a number, and isn't `NaN` or positive/negative 4170 * `Infinity`. 4171 * 4172 * expect(1).to.be.finite; 4173 * 4174 * Add `.not` earlier in the chain to negate `.finite`. However, it's 4175 * dangerous to do so. The problem is that it creates uncertain expectations 4176 * by asserting that the subject either isn't a number, or that it's `NaN`, or 4177 * that it's positive `Infinity`, or that it's negative `Infinity`. It's often 4178 * best to identify the exact output that's expected, and then write an 4179 * assertion that only accepts that exact output. 4180 * 4181 * When the target isn't expected to be a number, it's often best to assert 4182 * that it's the expected type, rather than asserting that it isn't one of 4183 * many unexpected types. 4184 * 4185 * expect('foo').to.be.a('string'); // Recommended 4186 * expect('foo').to.not.be.finite; // Not recommended 4187 * 4188 * When the target is expected to be `NaN`, it's often best to assert exactly 4189 * that. 4190 * 4191 * expect(NaN).to.be.NaN; // Recommended 4192 * expect(NaN).to.not.be.finite; // Not recommended 4193 * 4194 * When the target is expected to be positive infinity, it's often best to 4195 * assert exactly that. 4196 * 4197 * expect(Infinity).to.equal(Infinity); // Recommended 4198 * expect(Infinity).to.not.be.finite; // Not recommended 4199 * 4200 * When the target is expected to be negative infinity, it's often best to 4201 * assert exactly that. 4202 * 4203 * expect(-Infinity).to.equal(-Infinity); // Recommended 4204 * expect(-Infinity).to.not.be.finite; // Not recommended 4205 * 4206 * A custom error message can be given as the second argument to `expect`. 4207 * 4208 * expect('foo', 'nooo why fail??').to.be.finite; 4209 * 4210 * @name finite 4211 * @namespace BDD 4212 * @api public 4213 */ 4214 4215 Assertion.addProperty('finite', function(msg) { 4216 var obj = flag(this, 'object'); 4217 4218 this.assert( 4219 typeof obj === 'number' && isFinite(obj) 4220 , 'expected #{this} to be a finite number' 4221 , 'expected #{this} to not be a finite number' 4222 ); 4223 }); 4224 }; 4225 4226 },{}],6:[function(require,module,exports){ 4227 /*! 4228 * chai 4229 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> 4230 * MIT Licensed 4231 */ 4232 4233 module.exports = function (chai, util) { 4234 /*! 4235 * Chai dependencies. 4236 */ 4237 4238 var Assertion = chai.Assertion 4239 , flag = util.flag; 4240 4241 /*! 4242 * Module export. 4243 */ 4244 4245 /** 4246 * ### assert(expression, message) 4247 * 4248 * Write your own test expressions. 4249 * 4250 * assert('foo' !== 'bar', 'foo is not bar'); 4251 * assert(Array.isArray([]), 'empty arrays are arrays'); 4252 * 4253 * @param {Mixed} expression to test for truthiness 4254 * @param {String} message to display on error 4255 * @name assert 4256 * @namespace Assert 4257 * @api public 4258 */ 4259 4260 var assert = chai.assert = function (express, errmsg) { 4261 var test = new Assertion(null, null, chai.assert, true); 4262 test.assert( 4263 express 4264 , errmsg 4265 , '[ negation message unavailable ]' 4266 ); 4267 }; 4268 4269 /** 4270 * ### .fail([message]) 4271 * ### .fail(actual, expected, [message], [operator]) 4272 * 4273 * Throw a failure. Node.js `assert` module-compatible. 4274 * 4275 * assert.fail(); 4276 * assert.fail("custom error message"); 4277 * assert.fail(1, 2); 4278 * assert.fail(1, 2, "custom error message"); 4279 * assert.fail(1, 2, "custom error message", ">"); 4280 * assert.fail(1, 2, undefined, ">"); 4281 * 4282 * @name fail 4283 * @param {Mixed} actual 4284 * @param {Mixed} expected 4285 * @param {String} message 4286 * @param {String} operator 4287 * @namespace Assert 4288 * @api public 4289 */ 4290 4291 assert.fail = function (actual, expected, message, operator) { 4292 if (arguments.length < 2) { 4293 // Comply with Node's fail([message]) interface 4294 4295 message = actual; 4296 actual = undefined; 4297 } 4298 4299 message = message || 'assert.fail()'; 4300 throw new chai.AssertionError(message, { 4301 actual: actual 4302 , expected: expected 4303 , operator: operator 4304 }, assert.fail); 4305 }; 4306 4307 /** 4308 * ### .isOk(object, [message]) 4309 * 4310 * Asserts that `object` is truthy. 4311 * 4312 * assert.isOk('everything', 'everything is ok'); 4313 * assert.isOk(false, 'this will fail'); 4314 * 4315 * @name isOk 4316 * @alias ok 4317 * @param {Mixed} object to test 4318 * @param {String} message 4319 * @namespace Assert 4320 * @api public 4321 */ 4322 4323 assert.isOk = function (val, msg) { 4324 new Assertion(val, msg, assert.isOk, true).is.ok; 4325 }; 4326 4327 /** 4328 * ### .isNotOk(object, [message]) 4329 * 4330 * Asserts that `object` is falsy. 4331 * 4332 * assert.isNotOk('everything', 'this will fail'); 4333 * assert.isNotOk(false, 'this will pass'); 4334 * 4335 * @name isNotOk 4336 * @alias notOk 4337 * @param {Mixed} object to test 4338 * @param {String} message 4339 * @namespace Assert 4340 * @api public 4341 */ 4342 4343 assert.isNotOk = function (val, msg) { 4344 new Assertion(val, msg, assert.isNotOk, true).is.not.ok; 4345 }; 4346 4347 /** 4348 * ### .equal(actual, expected, [message]) 4349 * 4350 * Asserts non-strict equality (`==`) of `actual` and `expected`. 4351 * 4352 * assert.equal(3, '3', '== coerces values to strings'); 4353 * 4354 * @name equal 4355 * @param {Mixed} actual 4356 * @param {Mixed} expected 4357 * @param {String} message 4358 * @namespace Assert 4359 * @api public 4360 */ 4361 4362 assert.equal = function (act, exp, msg) { 4363 var test = new Assertion(act, msg, assert.equal, true); 4364 4365 test.assert( 4366 exp == flag(test, 'object') 4367 , 'expected #{this} to equal #{exp}' 4368 , 'expected #{this} to not equal #{act}' 4369 , exp 4370 , act 4371 , true 4372 ); 4373 }; 4374 4375 /** 4376 * ### .notEqual(actual, expected, [message]) 4377 * 4378 * Asserts non-strict inequality (`!=`) of `actual` and `expected`. 4379 * 4380 * assert.notEqual(3, 4, 'these numbers are not equal'); 4381 * 4382 * @name notEqual 4383 * @param {Mixed} actual 4384 * @param {Mixed} expected 4385 * @param {String} message 4386 * @namespace Assert 4387 * @api public 4388 */ 4389 4390 assert.notEqual = function (act, exp, msg) { 4391 var test = new Assertion(act, msg, assert.notEqual, true); 4392 4393 test.assert( 4394 exp != flag(test, 'object') 4395 , 'expected #{this} to not equal #{exp}' 4396 , 'expected #{this} to equal #{act}' 4397 , exp 4398 , act 4399 , true 4400 ); 4401 }; 4402 4403 /** 4404 * ### .strictEqual(actual, expected, [message]) 4405 * 4406 * Asserts strict equality (`===`) of `actual` and `expected`. 4407 * 4408 * assert.strictEqual(true, true, 'these booleans are strictly equal'); 4409 * 4410 * @name strictEqual 4411 * @param {Mixed} actual 4412 * @param {Mixed} expected 4413 * @param {String} message 4414 * @namespace Assert 4415 * @api public 4416 */ 4417 4418 assert.strictEqual = function (act, exp, msg) { 4419 new Assertion(act, msg, assert.strictEqual, true).to.equal(exp); 4420 }; 4421 4422 /** 4423 * ### .notStrictEqual(actual, expected, [message]) 4424 * 4425 * Asserts strict inequality (`!==`) of `actual` and `expected`. 4426 * 4427 * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); 4428 * 4429 * @name notStrictEqual 4430 * @param {Mixed} actual 4431 * @param {Mixed} expected 4432 * @param {String} message 4433 * @namespace Assert 4434 * @api public 4435 */ 4436 4437 assert.notStrictEqual = function (act, exp, msg) { 4438 new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp); 4439 }; 4440 4441 /** 4442 * ### .deepEqual(actual, expected, [message]) 4443 * 4444 * Asserts that `actual` is deeply equal to `expected`. 4445 * 4446 * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); 4447 * 4448 * @name deepEqual 4449 * @param {Mixed} actual 4450 * @param {Mixed} expected 4451 * @param {String} message 4452 * @alias deepStrictEqual 4453 * @namespace Assert 4454 * @api public 4455 */ 4456 4457 assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) { 4458 new Assertion(act, msg, assert.deepEqual, true).to.eql(exp); 4459 }; 4460 4461 /** 4462 * ### .notDeepEqual(actual, expected, [message]) 4463 * 4464 * Assert that `actual` is not deeply equal to `expected`. 4465 * 4466 * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); 4467 * 4468 * @name notDeepEqual 4469 * @param {Mixed} actual 4470 * @param {Mixed} expected 4471 * @param {String} message 4472 * @namespace Assert 4473 * @api public 4474 */ 4475 4476 assert.notDeepEqual = function (act, exp, msg) { 4477 new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp); 4478 }; 4479 4480 /** 4481 * ### .isAbove(valueToCheck, valueToBeAbove, [message]) 4482 * 4483 * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`. 4484 * 4485 * assert.isAbove(5, 2, '5 is strictly greater than 2'); 4486 * 4487 * @name isAbove 4488 * @param {Mixed} valueToCheck 4489 * @param {Mixed} valueToBeAbove 4490 * @param {String} message 4491 * @namespace Assert 4492 * @api public 4493 */ 4494 4495 assert.isAbove = function (val, abv, msg) { 4496 new Assertion(val, msg, assert.isAbove, true).to.be.above(abv); 4497 }; 4498 4499 /** 4500 * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) 4501 * 4502 * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`. 4503 * 4504 * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); 4505 * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); 4506 * 4507 * @name isAtLeast 4508 * @param {Mixed} valueToCheck 4509 * @param {Mixed} valueToBeAtLeast 4510 * @param {String} message 4511 * @namespace Assert 4512 * @api public 4513 */ 4514 4515 assert.isAtLeast = function (val, atlst, msg) { 4516 new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst); 4517 }; 4518 4519 /** 4520 * ### .isBelow(valueToCheck, valueToBeBelow, [message]) 4521 * 4522 * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`. 4523 * 4524 * assert.isBelow(3, 6, '3 is strictly less than 6'); 4525 * 4526 * @name isBelow 4527 * @param {Mixed} valueToCheck 4528 * @param {Mixed} valueToBeBelow 4529 * @param {String} message 4530 * @namespace Assert 4531 * @api public 4532 */ 4533 4534 assert.isBelow = function (val, blw, msg) { 4535 new Assertion(val, msg, assert.isBelow, true).to.be.below(blw); 4536 }; 4537 4538 /** 4539 * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) 4540 * 4541 * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`. 4542 * 4543 * assert.isAtMost(3, 6, '3 is less than or equal to 6'); 4544 * assert.isAtMost(4, 4, '4 is less than or equal to 4'); 4545 * 4546 * @name isAtMost 4547 * @param {Mixed} valueToCheck 4548 * @param {Mixed} valueToBeAtMost 4549 * @param {String} message 4550 * @namespace Assert 4551 * @api public 4552 */ 4553 4554 assert.isAtMost = function (val, atmst, msg) { 4555 new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst); 4556 }; 4557 4558 /** 4559 * ### .isTrue(value, [message]) 4560 * 4561 * Asserts that `value` is true. 4562 * 4563 * var teaServed = true; 4564 * assert.isTrue(teaServed, 'the tea has been served'); 4565 * 4566 * @name isTrue 4567 * @param {Mixed} value 4568 * @param {String} message 4569 * @namespace Assert 4570 * @api public 4571 */ 4572 4573 assert.isTrue = function (val, msg) { 4574 new Assertion(val, msg, assert.isTrue, true).is['true']; 4575 }; 4576 4577 /** 4578 * ### .isNotTrue(value, [message]) 4579 * 4580 * Asserts that `value` is not true. 4581 * 4582 * var tea = 'tasty chai'; 4583 * assert.isNotTrue(tea, 'great, time for tea!'); 4584 * 4585 * @name isNotTrue 4586 * @param {Mixed} value 4587 * @param {String} message 4588 * @namespace Assert 4589 * @api public 4590 */ 4591 4592 assert.isNotTrue = function (val, msg) { 4593 new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true); 4594 }; 4595 4596 /** 4597 * ### .isFalse(value, [message]) 4598 * 4599 * Asserts that `value` is false. 4600 * 4601 * var teaServed = false; 4602 * assert.isFalse(teaServed, 'no tea yet? hmm...'); 4603 * 4604 * @name isFalse 4605 * @param {Mixed} value 4606 * @param {String} message 4607 * @namespace Assert 4608 * @api public 4609 */ 4610 4611 assert.isFalse = function (val, msg) { 4612 new Assertion(val, msg, assert.isFalse, true).is['false']; 4613 }; 4614 4615 /** 4616 * ### .isNotFalse(value, [message]) 4617 * 4618 * Asserts that `value` is not false. 4619 * 4620 * var tea = 'tasty chai'; 4621 * assert.isNotFalse(tea, 'great, time for tea!'); 4622 * 4623 * @name isNotFalse 4624 * @param {Mixed} value 4625 * @param {String} message 4626 * @namespace Assert 4627 * @api public 4628 */ 4629 4630 assert.isNotFalse = function (val, msg) { 4631 new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false); 4632 }; 4633 4634 /** 4635 * ### .isNull(value, [message]) 4636 * 4637 * Asserts that `value` is null. 4638 * 4639 * assert.isNull(err, 'there was no error'); 4640 * 4641 * @name isNull 4642 * @param {Mixed} value 4643 * @param {String} message 4644 * @namespace Assert 4645 * @api public 4646 */ 4647 4648 assert.isNull = function (val, msg) { 4649 new Assertion(val, msg, assert.isNull, true).to.equal(null); 4650 }; 4651 4652 /** 4653 * ### .isNotNull(value, [message]) 4654 * 4655 * Asserts that `value` is not null. 4656 * 4657 * var tea = 'tasty chai'; 4658 * assert.isNotNull(tea, 'great, time for tea!'); 4659 * 4660 * @name isNotNull 4661 * @param {Mixed} value 4662 * @param {String} message 4663 * @namespace Assert 4664 * @api public 4665 */ 4666 4667 assert.isNotNull = function (val, msg) { 4668 new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null); 4669 }; 4670 4671 /** 4672 * ### .isNaN 4673 * 4674 * Asserts that value is NaN. 4675 * 4676 * assert.isNaN(NaN, 'NaN is NaN'); 4677 * 4678 * @name isNaN 4679 * @param {Mixed} value 4680 * @param {String} message 4681 * @namespace Assert 4682 * @api public 4683 */ 4684 4685 assert.isNaN = function (val, msg) { 4686 new Assertion(val, msg, assert.isNaN, true).to.be.NaN; 4687 }; 4688 4689 /** 4690 * ### .isNotNaN 4691 * 4692 * Asserts that value is not NaN. 4693 * 4694 * assert.isNotNaN(4, '4 is not NaN'); 4695 * 4696 * @name isNotNaN 4697 * @param {Mixed} value 4698 * @param {String} message 4699 * @namespace Assert 4700 * @api public 4701 */ 4702 assert.isNotNaN = function (val, msg) { 4703 new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN; 4704 }; 4705 4706 /** 4707 * ### .exists 4708 * 4709 * Asserts that the target is neither `null` nor `undefined`. 4710 * 4711 * var foo = 'hi'; 4712 * 4713 * assert.exists(foo, 'foo is neither `null` nor `undefined`'); 4714 * 4715 * @name exists 4716 * @param {Mixed} value 4717 * @param {String} message 4718 * @namespace Assert 4719 * @api public 4720 */ 4721 4722 assert.exists = function (val, msg) { 4723 new Assertion(val, msg, assert.exists, true).to.exist; 4724 }; 4725 4726 /** 4727 * ### .notExists 4728 * 4729 * Asserts that the target is either `null` or `undefined`. 4730 * 4731 * var bar = null 4732 * , baz; 4733 * 4734 * assert.notExists(bar); 4735 * assert.notExists(baz, 'baz is either null or undefined'); 4736 * 4737 * @name notExists 4738 * @param {Mixed} value 4739 * @param {String} message 4740 * @namespace Assert 4741 * @api public 4742 */ 4743 4744 assert.notExists = function (val, msg) { 4745 new Assertion(val, msg, assert.notExists, true).to.not.exist; 4746 }; 4747 4748 /** 4749 * ### .isUndefined(value, [message]) 4750 * 4751 * Asserts that `value` is `undefined`. 4752 * 4753 * var tea; 4754 * assert.isUndefined(tea, 'no tea defined'); 4755 * 4756 * @name isUndefined 4757 * @param {Mixed} value 4758 * @param {String} message 4759 * @namespace Assert 4760 * @api public 4761 */ 4762 4763 assert.isUndefined = function (val, msg) { 4764 new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined); 4765 }; 4766 4767 /** 4768 * ### .isDefined(value, [message]) 4769 * 4770 * Asserts that `value` is not `undefined`. 4771 * 4772 * var tea = 'cup of chai'; 4773 * assert.isDefined(tea, 'tea has been defined'); 4774 * 4775 * @name isDefined 4776 * @param {Mixed} value 4777 * @param {String} message 4778 * @namespace Assert 4779 * @api public 4780 */ 4781 4782 assert.isDefined = function (val, msg) { 4783 new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined); 4784 }; 4785 4786 /** 4787 * ### .isFunction(value, [message]) 4788 * 4789 * Asserts that `value` is a function. 4790 * 4791 * function serveTea() { return 'cup of tea'; }; 4792 * assert.isFunction(serveTea, 'great, we can have tea now'); 4793 * 4794 * @name isFunction 4795 * @param {Mixed} value 4796 * @param {String} message 4797 * @namespace Assert 4798 * @api public 4799 */ 4800 4801 assert.isFunction = function (val, msg) { 4802 new Assertion(val, msg, assert.isFunction, true).to.be.a('function'); 4803 }; 4804 4805 /** 4806 * ### .isNotFunction(value, [message]) 4807 * 4808 * Asserts that `value` is _not_ a function. 4809 * 4810 * var serveTea = [ 'heat', 'pour', 'sip' ]; 4811 * assert.isNotFunction(serveTea, 'great, we have listed the steps'); 4812 * 4813 * @name isNotFunction 4814 * @param {Mixed} value 4815 * @param {String} message 4816 * @namespace Assert 4817 * @api public 4818 */ 4819 4820 assert.isNotFunction = function (val, msg) { 4821 new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function'); 4822 }; 4823 4824 /** 4825 * ### .isObject(value, [message]) 4826 * 4827 * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). 4828 * _The assertion does not match subclassed objects._ 4829 * 4830 * var selection = { name: 'Chai', serve: 'with spices' }; 4831 * assert.isObject(selection, 'tea selection is an object'); 4832 * 4833 * @name isObject 4834 * @param {Mixed} value 4835 * @param {String} message 4836 * @namespace Assert 4837 * @api public 4838 */ 4839 4840 assert.isObject = function (val, msg) { 4841 new Assertion(val, msg, assert.isObject, true).to.be.a('object'); 4842 }; 4843 4844 /** 4845 * ### .isNotObject(value, [message]) 4846 * 4847 * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). 4848 * 4849 * var selection = 'chai' 4850 * assert.isNotObject(selection, 'tea selection is not an object'); 4851 * assert.isNotObject(null, 'null is not an object'); 4852 * 4853 * @name isNotObject 4854 * @param {Mixed} value 4855 * @param {String} message 4856 * @namespace Assert 4857 * @api public 4858 */ 4859 4860 assert.isNotObject = function (val, msg) { 4861 new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object'); 4862 }; 4863 4864 /** 4865 * ### .isArray(value, [message]) 4866 * 4867 * Asserts that `value` is an array. 4868 * 4869 * var menu = [ 'green', 'chai', 'oolong' ]; 4870 * assert.isArray(menu, 'what kind of tea do we want?'); 4871 * 4872 * @name isArray 4873 * @param {Mixed} value 4874 * @param {String} message 4875 * @namespace Assert 4876 * @api public 4877 */ 4878 4879 assert.isArray = function (val, msg) { 4880 new Assertion(val, msg, assert.isArray, true).to.be.an('array'); 4881 }; 4882 4883 /** 4884 * ### .isNotArray(value, [message]) 4885 * 4886 * Asserts that `value` is _not_ an array. 4887 * 4888 * var menu = 'green|chai|oolong'; 4889 * assert.isNotArray(menu, 'what kind of tea do we want?'); 4890 * 4891 * @name isNotArray 4892 * @param {Mixed} value 4893 * @param {String} message 4894 * @namespace Assert 4895 * @api public 4896 */ 4897 4898 assert.isNotArray = function (val, msg) { 4899 new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array'); 4900 }; 4901 4902 /** 4903 * ### .isString(value, [message]) 4904 * 4905 * Asserts that `value` is a string. 4906 * 4907 * var teaOrder = 'chai'; 4908 * assert.isString(teaOrder, 'order placed'); 4909 * 4910 * @name isString 4911 * @param {Mixed} value 4912 * @param {String} message 4913 * @namespace Assert 4914 * @api public 4915 */ 4916 4917 assert.isString = function (val, msg) { 4918 new Assertion(val, msg, assert.isString, true).to.be.a('string'); 4919 }; 4920 4921 /** 4922 * ### .isNotString(value, [message]) 4923 * 4924 * Asserts that `value` is _not_ a string. 4925 * 4926 * var teaOrder = 4; 4927 * assert.isNotString(teaOrder, 'order placed'); 4928 * 4929 * @name isNotString 4930 * @param {Mixed} value 4931 * @param {String} message 4932 * @namespace Assert 4933 * @api public 4934 */ 4935 4936 assert.isNotString = function (val, msg) { 4937 new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string'); 4938 }; 4939 4940 /** 4941 * ### .isNumber(value, [message]) 4942 * 4943 * Asserts that `value` is a number. 4944 * 4945 * var cups = 2; 4946 * assert.isNumber(cups, 'how many cups'); 4947 * 4948 * @name isNumber 4949 * @param {Number} value 4950 * @param {String} message 4951 * @namespace Assert 4952 * @api public 4953 */ 4954 4955 assert.isNumber = function (val, msg) { 4956 new Assertion(val, msg, assert.isNumber, true).to.be.a('number'); 4957 }; 4958 4959 /** 4960 * ### .isNotNumber(value, [message]) 4961 * 4962 * Asserts that `value` is _not_ a number. 4963 * 4964 * var cups = '2 cups please'; 4965 * assert.isNotNumber(cups, 'how many cups'); 4966 * 4967 * @name isNotNumber 4968 * @param {Mixed} value 4969 * @param {String} message 4970 * @namespace Assert 4971 * @api public 4972 */ 4973 4974 assert.isNotNumber = function (val, msg) { 4975 new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number'); 4976 }; 4977 4978 /** 4979 * ### .isFinite(value, [message]) 4980 * 4981 * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. 4982 * 4983 * var cups = 2; 4984 * assert.isFinite(cups, 'how many cups'); 4985 * 4986 * assert.isFinite(NaN); // throws 4987 * 4988 * @name isFinite 4989 * @param {Number} value 4990 * @param {String} message 4991 * @namespace Assert 4992 * @api public 4993 */ 4994 4995 assert.isFinite = function (val, msg) { 4996 new Assertion(val, msg, assert.isFinite, true).to.be.finite; 4997 }; 4998 4999 /** 5000 * ### .isBoolean(value, [message]) 5001 * 5002 * Asserts that `value` is a boolean. 5003 * 5004 * var teaReady = true 5005 * , teaServed = false; 5006 * 5007 * assert.isBoolean(teaReady, 'is the tea ready'); 5008 * assert.isBoolean(teaServed, 'has tea been served'); 5009 * 5010 * @name isBoolean 5011 * @param {Mixed} value 5012 * @param {String} message 5013 * @namespace Assert 5014 * @api public 5015 */ 5016 5017 assert.isBoolean = function (val, msg) { 5018 new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean'); 5019 }; 5020 5021 /** 5022 * ### .isNotBoolean(value, [message]) 5023 * 5024 * Asserts that `value` is _not_ a boolean. 5025 * 5026 * var teaReady = 'yep' 5027 * , teaServed = 'nope'; 5028 * 5029 * assert.isNotBoolean(teaReady, 'is the tea ready'); 5030 * assert.isNotBoolean(teaServed, 'has tea been served'); 5031 * 5032 * @name isNotBoolean 5033 * @param {Mixed} value 5034 * @param {String} message 5035 * @namespace Assert 5036 * @api public 5037 */ 5038 5039 assert.isNotBoolean = function (val, msg) { 5040 new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean'); 5041 }; 5042 5043 /** 5044 * ### .typeOf(value, name, [message]) 5045 * 5046 * Asserts that `value`'s type is `name`, as determined by 5047 * `Object.prototype.toString`. 5048 * 5049 * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); 5050 * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); 5051 * assert.typeOf('tea', 'string', 'we have a string'); 5052 * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); 5053 * assert.typeOf(null, 'null', 'we have a null'); 5054 * assert.typeOf(undefined, 'undefined', 'we have an undefined'); 5055 * 5056 * @name typeOf 5057 * @param {Mixed} value 5058 * @param {String} name 5059 * @param {String} message 5060 * @namespace Assert 5061 * @api public 5062 */ 5063 5064 assert.typeOf = function (val, type, msg) { 5065 new Assertion(val, msg, assert.typeOf, true).to.be.a(type); 5066 }; 5067 5068 /** 5069 * ### .notTypeOf(value, name, [message]) 5070 * 5071 * Asserts that `value`'s type is _not_ `name`, as determined by 5072 * `Object.prototype.toString`. 5073 * 5074 * assert.notTypeOf('tea', 'number', 'strings are not numbers'); 5075 * 5076 * @name notTypeOf 5077 * @param {Mixed} value 5078 * @param {String} typeof name 5079 * @param {String} message 5080 * @namespace Assert 5081 * @api public 5082 */ 5083 5084 assert.notTypeOf = function (val, type, msg) { 5085 new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type); 5086 }; 5087 5088 /** 5089 * ### .instanceOf(object, constructor, [message]) 5090 * 5091 * Asserts that `value` is an instance of `constructor`. 5092 * 5093 * var Tea = function (name) { this.name = name; } 5094 * , chai = new Tea('chai'); 5095 * 5096 * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); 5097 * 5098 * @name instanceOf 5099 * @param {Object} object 5100 * @param {Constructor} constructor 5101 * @param {String} message 5102 * @namespace Assert 5103 * @api public 5104 */ 5105 5106 assert.instanceOf = function (val, type, msg) { 5107 new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type); 5108 }; 5109 5110 /** 5111 * ### .notInstanceOf(object, constructor, [message]) 5112 * 5113 * Asserts `value` is not an instance of `constructor`. 5114 * 5115 * var Tea = function (name) { this.name = name; } 5116 * , chai = new String('chai'); 5117 * 5118 * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); 5119 * 5120 * @name notInstanceOf 5121 * @param {Object} object 5122 * @param {Constructor} constructor 5123 * @param {String} message 5124 * @namespace Assert 5125 * @api public 5126 */ 5127 5128 assert.notInstanceOf = function (val, type, msg) { 5129 new Assertion(val, msg, assert.notInstanceOf, true) 5130 .to.not.be.instanceOf(type); 5131 }; 5132 5133 /** 5134 * ### .include(haystack, needle, [message]) 5135 * 5136 * Asserts that `haystack` includes `needle`. Can be used to assert the 5137 * inclusion of a value in an array, a substring in a string, or a subset of 5138 * properties in an object. 5139 * 5140 * assert.include([1,2,3], 2, 'array contains value'); 5141 * assert.include('foobar', 'foo', 'string contains substring'); 5142 * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property'); 5143 * 5144 * Strict equality (===) is used. When asserting the inclusion of a value in 5145 * an array, the array is searched for an element that's strictly equal to the 5146 * given value. When asserting a subset of properties in an object, the object 5147 * is searched for the given property keys, checking that each one is present 5148 * and strictly equal to the given property value. For instance: 5149 * 5150 * var obj1 = {a: 1} 5151 * , obj2 = {b: 2}; 5152 * assert.include([obj1, obj2], obj1); 5153 * assert.include({foo: obj1, bar: obj2}, {foo: obj1}); 5154 * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}); 5155 * 5156 * @name include 5157 * @param {Array|String} haystack 5158 * @param {Mixed} needle 5159 * @param {String} message 5160 * @namespace Assert 5161 * @api public 5162 */ 5163 5164 assert.include = function (exp, inc, msg) { 5165 new Assertion(exp, msg, assert.include, true).include(inc); 5166 }; 5167 5168 /** 5169 * ### .notInclude(haystack, needle, [message]) 5170 * 5171 * Asserts that `haystack` does not include `needle`. Can be used to assert 5172 * the absence of a value in an array, a substring in a string, or a subset of 5173 * properties in an object. 5174 * 5175 * assert.notInclude([1,2,3], 4, "array doesn't contain value"); 5176 * assert.notInclude('foobar', 'baz', "string doesn't contain substring"); 5177 * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property'); 5178 * 5179 * Strict equality (===) is used. When asserting the absence of a value in an 5180 * array, the array is searched to confirm the absence of an element that's 5181 * strictly equal to the given value. When asserting a subset of properties in 5182 * an object, the object is searched to confirm that at least one of the given 5183 * property keys is either not present or not strictly equal to the given 5184 * property value. For instance: 5185 * 5186 * var obj1 = {a: 1} 5187 * , obj2 = {b: 2}; 5188 * assert.notInclude([obj1, obj2], {a: 1}); 5189 * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); 5190 * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}}); 5191 * 5192 * @name notInclude 5193 * @param {Array|String} haystack 5194 * @param {Mixed} needle 5195 * @param {String} message 5196 * @namespace Assert 5197 * @api public 5198 */ 5199 5200 assert.notInclude = function (exp, inc, msg) { 5201 new Assertion(exp, msg, assert.notInclude, true).not.include(inc); 5202 }; 5203 5204 /** 5205 * ### .deepInclude(haystack, needle, [message]) 5206 * 5207 * Asserts that `haystack` includes `needle`. Can be used to assert the 5208 * inclusion of a value in an array or a subset of properties in an object. 5209 * Deep equality is used. 5210 * 5211 * var obj1 = {a: 1} 5212 * , obj2 = {b: 2}; 5213 * assert.deepInclude([obj1, obj2], {a: 1}); 5214 * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); 5215 * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}); 5216 * 5217 * @name deepInclude 5218 * @param {Array|String} haystack 5219 * @param {Mixed} needle 5220 * @param {String} message 5221 * @namespace Assert 5222 * @api public 5223 */ 5224 5225 assert.deepInclude = function (exp, inc, msg) { 5226 new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc); 5227 }; 5228 5229 /** 5230 * ### .notDeepInclude(haystack, needle, [message]) 5231 * 5232 * Asserts that `haystack` does not include `needle`. Can be used to assert 5233 * the absence of a value in an array or a subset of properties in an object. 5234 * Deep equality is used. 5235 * 5236 * var obj1 = {a: 1} 5237 * , obj2 = {b: 2}; 5238 * assert.notDeepInclude([obj1, obj2], {a: 9}); 5239 * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}}); 5240 * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}); 5241 * 5242 * @name notDeepInclude 5243 * @param {Array|String} haystack 5244 * @param {Mixed} needle 5245 * @param {String} message 5246 * @namespace Assert 5247 * @api public 5248 */ 5249 5250 assert.notDeepInclude = function (exp, inc, msg) { 5251 new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc); 5252 }; 5253 5254 /** 5255 * ### .nestedInclude(haystack, needle, [message]) 5256 * 5257 * Asserts that 'haystack' includes 'needle'. 5258 * Can be used to assert the inclusion of a subset of properties in an 5259 * object. 5260 * Enables the use of dot- and bracket-notation for referencing nested 5261 * properties. 5262 * '[]' and '.' in property names can be escaped using double backslashes. 5263 * 5264 * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'}); 5265 * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'}); 5266 * 5267 * @name nestedInclude 5268 * @param {Object} haystack 5269 * @param {Object} needle 5270 * @param {String} message 5271 * @namespace Assert 5272 * @api public 5273 */ 5274 5275 assert.nestedInclude = function (exp, inc, msg) { 5276 new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc); 5277 }; 5278 5279 /** 5280 * ### .notNestedInclude(haystack, needle, [message]) 5281 * 5282 * Asserts that 'haystack' does not include 'needle'. 5283 * Can be used to assert the absence of a subset of properties in an 5284 * object. 5285 * Enables the use of dot- and bracket-notation for referencing nested 5286 * properties. 5287 * '[]' and '.' in property names can be escaped using double backslashes. 5288 * 5289 * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'}); 5290 * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'}); 5291 * 5292 * @name notNestedInclude 5293 * @param {Object} haystack 5294 * @param {Object} needle 5295 * @param {String} message 5296 * @namespace Assert 5297 * @api public 5298 */ 5299 5300 assert.notNestedInclude = function (exp, inc, msg) { 5301 new Assertion(exp, msg, assert.notNestedInclude, true) 5302 .not.nested.include(inc); 5303 }; 5304 5305 /** 5306 * ### .deepNestedInclude(haystack, needle, [message]) 5307 * 5308 * Asserts that 'haystack' includes 'needle'. 5309 * Can be used to assert the inclusion of a subset of properties in an 5310 * object while checking for deep equality. 5311 * Enables the use of dot- and bracket-notation for referencing nested 5312 * properties. 5313 * '[]' and '.' in property names can be escaped using double backslashes. 5314 * 5315 * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); 5316 * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}}); 5317 * 5318 * @name deepNestedInclude 5319 * @param {Object} haystack 5320 * @param {Object} needle 5321 * @param {String} message 5322 * @namespace Assert 5323 * @api public 5324 */ 5325 5326 assert.deepNestedInclude = function(exp, inc, msg) { 5327 new Assertion(exp, msg, assert.deepNestedInclude, true) 5328 .deep.nested.include(inc); 5329 }; 5330 5331 /** 5332 * ### .notDeepNestedInclude(haystack, needle, [message]) 5333 * 5334 * Asserts that 'haystack' does not include 'needle'. 5335 * Can be used to assert the absence of a subset of properties in an 5336 * object while checking for deep equality. 5337 * Enables the use of dot- and bracket-notation for referencing nested 5338 * properties. 5339 * '[]' and '.' in property names can be escaped using double backslashes. 5340 * 5341 * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}}) 5342 * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}}); 5343 * 5344 * @name notDeepNestedInclude 5345 * @param {Object} haystack 5346 * @param {Object} needle 5347 * @param {String} message 5348 * @namespace Assert 5349 * @api public 5350 */ 5351 5352 assert.notDeepNestedInclude = function(exp, inc, msg) { 5353 new Assertion(exp, msg, assert.notDeepNestedInclude, true) 5354 .not.deep.nested.include(inc); 5355 }; 5356 5357 /** 5358 * ### .ownInclude(haystack, needle, [message]) 5359 * 5360 * Asserts that 'haystack' includes 'needle'. 5361 * Can be used to assert the inclusion of a subset of properties in an 5362 * object while ignoring inherited properties. 5363 * 5364 * assert.ownInclude({ a: 1 }, { a: 1 }); 5365 * 5366 * @name ownInclude 5367 * @param {Object} haystack 5368 * @param {Object} needle 5369 * @param {String} message 5370 * @namespace Assert 5371 * @api public 5372 */ 5373 5374 assert.ownInclude = function(exp, inc, msg) { 5375 new Assertion(exp, msg, assert.ownInclude, true).own.include(inc); 5376 }; 5377 5378 /** 5379 * ### .notOwnInclude(haystack, needle, [message]) 5380 * 5381 * Asserts that 'haystack' includes 'needle'. 5382 * Can be used to assert the absence of a subset of properties in an 5383 * object while ignoring inherited properties. 5384 * 5385 * Object.prototype.b = 2; 5386 * 5387 * assert.notOwnInclude({ a: 1 }, { b: 2 }); 5388 * 5389 * @name notOwnInclude 5390 * @param {Object} haystack 5391 * @param {Object} needle 5392 * @param {String} message 5393 * @namespace Assert 5394 * @api public 5395 */ 5396 5397 assert.notOwnInclude = function(exp, inc, msg) { 5398 new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc); 5399 }; 5400 5401 /** 5402 * ### .deepOwnInclude(haystack, needle, [message]) 5403 * 5404 * Asserts that 'haystack' includes 'needle'. 5405 * Can be used to assert the inclusion of a subset of properties in an 5406 * object while ignoring inherited properties and checking for deep equality. 5407 * 5408 * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}}); 5409 * 5410 * @name deepOwnInclude 5411 * @param {Object} haystack 5412 * @param {Object} needle 5413 * @param {String} message 5414 * @namespace Assert 5415 * @api public 5416 */ 5417 5418 assert.deepOwnInclude = function(exp, inc, msg) { 5419 new Assertion(exp, msg, assert.deepOwnInclude, true) 5420 .deep.own.include(inc); 5421 }; 5422 5423 /** 5424 * ### .notDeepOwnInclude(haystack, needle, [message]) 5425 * 5426 * Asserts that 'haystack' includes 'needle'. 5427 * Can be used to assert the absence of a subset of properties in an 5428 * object while ignoring inherited properties and checking for deep equality. 5429 * 5430 * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}}); 5431 * 5432 * @name notDeepOwnInclude 5433 * @param {Object} haystack 5434 * @param {Object} needle 5435 * @param {String} message 5436 * @namespace Assert 5437 * @api public 5438 */ 5439 5440 assert.notDeepOwnInclude = function(exp, inc, msg) { 5441 new Assertion(exp, msg, assert.notDeepOwnInclude, true) 5442 .not.deep.own.include(inc); 5443 }; 5444 5445 /** 5446 * ### .match(value, regexp, [message]) 5447 * 5448 * Asserts that `value` matches the regular expression `regexp`. 5449 * 5450 * assert.match('foobar', /^foo/, 'regexp matches'); 5451 * 5452 * @name match 5453 * @param {Mixed} value 5454 * @param {RegExp} regexp 5455 * @param {String} message 5456 * @namespace Assert 5457 * @api public 5458 */ 5459 5460 assert.match = function (exp, re, msg) { 5461 new Assertion(exp, msg, assert.match, true).to.match(re); 5462 }; 5463 5464 /** 5465 * ### .notMatch(value, regexp, [message]) 5466 * 5467 * Asserts that `value` does not match the regular expression `regexp`. 5468 * 5469 * assert.notMatch('foobar', /^foo/, 'regexp does not match'); 5470 * 5471 * @name notMatch 5472 * @param {Mixed} value 5473 * @param {RegExp} regexp 5474 * @param {String} message 5475 * @namespace Assert 5476 * @api public 5477 */ 5478 5479 assert.notMatch = function (exp, re, msg) { 5480 new Assertion(exp, msg, assert.notMatch, true).to.not.match(re); 5481 }; 5482 5483 /** 5484 * ### .property(object, property, [message]) 5485 * 5486 * Asserts that `object` has a direct or inherited property named by 5487 * `property`. 5488 * 5489 * assert.property({ tea: { green: 'matcha' }}, 'tea'); 5490 * assert.property({ tea: { green: 'matcha' }}, 'toString'); 5491 * 5492 * @name property 5493 * @param {Object} object 5494 * @param {String} property 5495 * @param {String} message 5496 * @namespace Assert 5497 * @api public 5498 */ 5499 5500 assert.property = function (obj, prop, msg) { 5501 new Assertion(obj, msg, assert.property, true).to.have.property(prop); 5502 }; 5503 5504 /** 5505 * ### .notProperty(object, property, [message]) 5506 * 5507 * Asserts that `object` does _not_ have a direct or inherited property named 5508 * by `property`. 5509 * 5510 * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); 5511 * 5512 * @name notProperty 5513 * @param {Object} object 5514 * @param {String} property 5515 * @param {String} message 5516 * @namespace Assert 5517 * @api public 5518 */ 5519 5520 assert.notProperty = function (obj, prop, msg) { 5521 new Assertion(obj, msg, assert.notProperty, true) 5522 .to.not.have.property(prop); 5523 }; 5524 5525 /** 5526 * ### .propertyVal(object, property, value, [message]) 5527 * 5528 * Asserts that `object` has a direct or inherited property named by 5529 * `property` with a value given by `value`. Uses a strict equality check 5530 * (===). 5531 * 5532 * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); 5533 * 5534 * @name propertyVal 5535 * @param {Object} object 5536 * @param {String} property 5537 * @param {Mixed} value 5538 * @param {String} message 5539 * @namespace Assert 5540 * @api public 5541 */ 5542 5543 assert.propertyVal = function (obj, prop, val, msg) { 5544 new Assertion(obj, msg, assert.propertyVal, true) 5545 .to.have.property(prop, val); 5546 }; 5547 5548 /** 5549 * ### .notPropertyVal(object, property, value, [message]) 5550 * 5551 * Asserts that `object` does _not_ have a direct or inherited property named 5552 * by `property` with value given by `value`. Uses a strict equality check 5553 * (===). 5554 * 5555 * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad'); 5556 * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good'); 5557 * 5558 * @name notPropertyVal 5559 * @param {Object} object 5560 * @param {String} property 5561 * @param {Mixed} value 5562 * @param {String} message 5563 * @namespace Assert 5564 * @api public 5565 */ 5566 5567 assert.notPropertyVal = function (obj, prop, val, msg) { 5568 new Assertion(obj, msg, assert.notPropertyVal, true) 5569 .to.not.have.property(prop, val); 5570 }; 5571 5572 /** 5573 * ### .deepPropertyVal(object, property, value, [message]) 5574 * 5575 * Asserts that `object` has a direct or inherited property named by 5576 * `property` with a value given by `value`. Uses a deep equality check. 5577 * 5578 * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); 5579 * 5580 * @name deepPropertyVal 5581 * @param {Object} object 5582 * @param {String} property 5583 * @param {Mixed} value 5584 * @param {String} message 5585 * @namespace Assert 5586 * @api public 5587 */ 5588 5589 assert.deepPropertyVal = function (obj, prop, val, msg) { 5590 new Assertion(obj, msg, assert.deepPropertyVal, true) 5591 .to.have.deep.property(prop, val); 5592 }; 5593 5594 /** 5595 * ### .notDeepPropertyVal(object, property, value, [message]) 5596 * 5597 * Asserts that `object` does _not_ have a direct or inherited property named 5598 * by `property` with value given by `value`. Uses a deep equality check. 5599 * 5600 * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); 5601 * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); 5602 * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); 5603 * 5604 * @name notDeepPropertyVal 5605 * @param {Object} object 5606 * @param {String} property 5607 * @param {Mixed} value 5608 * @param {String} message 5609 * @namespace Assert 5610 * @api public 5611 */ 5612 5613 assert.notDeepPropertyVal = function (obj, prop, val, msg) { 5614 new Assertion(obj, msg, assert.notDeepPropertyVal, true) 5615 .to.not.have.deep.property(prop, val); 5616 }; 5617 5618 /** 5619 * ### .ownProperty(object, property, [message]) 5620 * 5621 * Asserts that `object` has a direct property named by `property`. Inherited 5622 * properties aren't checked. 5623 * 5624 * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea'); 5625 * 5626 * @name ownProperty 5627 * @param {Object} object 5628 * @param {String} property 5629 * @param {String} message 5630 * @api public 5631 */ 5632 5633 assert.ownProperty = function (obj, prop, msg) { 5634 new Assertion(obj, msg, assert.ownProperty, true) 5635 .to.have.own.property(prop); 5636 }; 5637 5638 /** 5639 * ### .notOwnProperty(object, property, [message]) 5640 * 5641 * Asserts that `object` does _not_ have a direct property named by 5642 * `property`. Inherited properties aren't checked. 5643 * 5644 * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee'); 5645 * assert.notOwnProperty({}, 'toString'); 5646 * 5647 * @name notOwnProperty 5648 * @param {Object} object 5649 * @param {String} property 5650 * @param {String} message 5651 * @api public 5652 */ 5653 5654 assert.notOwnProperty = function (obj, prop, msg) { 5655 new Assertion(obj, msg, assert.notOwnProperty, true) 5656 .to.not.have.own.property(prop); 5657 }; 5658 5659 /** 5660 * ### .ownPropertyVal(object, property, value, [message]) 5661 * 5662 * Asserts that `object` has a direct property named by `property` and a value 5663 * equal to the provided `value`. Uses a strict equality check (===). 5664 * Inherited properties aren't checked. 5665 * 5666 * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good'); 5667 * 5668 * @name ownPropertyVal 5669 * @param {Object} object 5670 * @param {String} property 5671 * @param {Mixed} value 5672 * @param {String} message 5673 * @api public 5674 */ 5675 5676 assert.ownPropertyVal = function (obj, prop, value, msg) { 5677 new Assertion(obj, msg, assert.ownPropertyVal, true) 5678 .to.have.own.property(prop, value); 5679 }; 5680 5681 /** 5682 * ### .notOwnPropertyVal(object, property, value, [message]) 5683 * 5684 * Asserts that `object` does _not_ have a direct property named by `property` 5685 * with a value equal to the provided `value`. Uses a strict equality check 5686 * (===). Inherited properties aren't checked. 5687 * 5688 * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse'); 5689 * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString); 5690 * 5691 * @name notOwnPropertyVal 5692 * @param {Object} object 5693 * @param {String} property 5694 * @param {Mixed} value 5695 * @param {String} message 5696 * @api public 5697 */ 5698 5699 assert.notOwnPropertyVal = function (obj, prop, value, msg) { 5700 new Assertion(obj, msg, assert.notOwnPropertyVal, true) 5701 .to.not.have.own.property(prop, value); 5702 }; 5703 5704 /** 5705 * ### .deepOwnPropertyVal(object, property, value, [message]) 5706 * 5707 * Asserts that `object` has a direct property named by `property` and a value 5708 * equal to the provided `value`. Uses a deep equality check. Inherited 5709 * properties aren't checked. 5710 * 5711 * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); 5712 * 5713 * @name deepOwnPropertyVal 5714 * @param {Object} object 5715 * @param {String} property 5716 * @param {Mixed} value 5717 * @param {String} message 5718 * @api public 5719 */ 5720 5721 assert.deepOwnPropertyVal = function (obj, prop, value, msg) { 5722 new Assertion(obj, msg, assert.deepOwnPropertyVal, true) 5723 .to.have.deep.own.property(prop, value); 5724 }; 5725 5726 /** 5727 * ### .notDeepOwnPropertyVal(object, property, value, [message]) 5728 * 5729 * Asserts that `object` does _not_ have a direct property named by `property` 5730 * with a value equal to the provided `value`. Uses a deep equality check. 5731 * Inherited properties aren't checked. 5732 * 5733 * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); 5734 * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); 5735 * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); 5736 * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString); 5737 * 5738 * @name notDeepOwnPropertyVal 5739 * @param {Object} object 5740 * @param {String} property 5741 * @param {Mixed} value 5742 * @param {String} message 5743 * @api public 5744 */ 5745 5746 assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) { 5747 new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true) 5748 .to.not.have.deep.own.property(prop, value); 5749 }; 5750 5751 /** 5752 * ### .nestedProperty(object, property, [message]) 5753 * 5754 * Asserts that `object` has a direct or inherited property named by 5755 * `property`, which can be a string using dot- and bracket-notation for 5756 * nested reference. 5757 * 5758 * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green'); 5759 * 5760 * @name nestedProperty 5761 * @param {Object} object 5762 * @param {String} property 5763 * @param {String} message 5764 * @namespace Assert 5765 * @api public 5766 */ 5767 5768 assert.nestedProperty = function (obj, prop, msg) { 5769 new Assertion(obj, msg, assert.nestedProperty, true) 5770 .to.have.nested.property(prop); 5771 }; 5772 5773 /** 5774 * ### .notNestedProperty(object, property, [message]) 5775 * 5776 * Asserts that `object` does _not_ have a property named by `property`, which 5777 * can be a string using dot- and bracket-notation for nested reference. The 5778 * property cannot exist on the object nor anywhere in its prototype chain. 5779 * 5780 * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); 5781 * 5782 * @name notNestedProperty 5783 * @param {Object} object 5784 * @param {String} property 5785 * @param {String} message 5786 * @namespace Assert 5787 * @api public 5788 */ 5789 5790 assert.notNestedProperty = function (obj, prop, msg) { 5791 new Assertion(obj, msg, assert.notNestedProperty, true) 5792 .to.not.have.nested.property(prop); 5793 }; 5794 5795 /** 5796 * ### .nestedPropertyVal(object, property, value, [message]) 5797 * 5798 * Asserts that `object` has a property named by `property` with value given 5799 * by `value`. `property` can use dot- and bracket-notation for nested 5800 * reference. Uses a strict equality check (===). 5801 * 5802 * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); 5803 * 5804 * @name nestedPropertyVal 5805 * @param {Object} object 5806 * @param {String} property 5807 * @param {Mixed} value 5808 * @param {String} message 5809 * @namespace Assert 5810 * @api public 5811 */ 5812 5813 assert.nestedPropertyVal = function (obj, prop, val, msg) { 5814 new Assertion(obj, msg, assert.nestedPropertyVal, true) 5815 .to.have.nested.property(prop, val); 5816 }; 5817 5818 /** 5819 * ### .notNestedPropertyVal(object, property, value, [message]) 5820 * 5821 * Asserts that `object` does _not_ have a property named by `property` with 5822 * value given by `value`. `property` can use dot- and bracket-notation for 5823 * nested reference. Uses a strict equality check (===). 5824 * 5825 * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); 5826 * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha'); 5827 * 5828 * @name notNestedPropertyVal 5829 * @param {Object} object 5830 * @param {String} property 5831 * @param {Mixed} value 5832 * @param {String} message 5833 * @namespace Assert 5834 * @api public 5835 */ 5836 5837 assert.notNestedPropertyVal = function (obj, prop, val, msg) { 5838 new Assertion(obj, msg, assert.notNestedPropertyVal, true) 5839 .to.not.have.nested.property(prop, val); 5840 }; 5841 5842 /** 5843 * ### .deepNestedPropertyVal(object, property, value, [message]) 5844 * 5845 * Asserts that `object` has a property named by `property` with a value given 5846 * by `value`. `property` can use dot- and bracket-notation for nested 5847 * reference. Uses a deep equality check. 5848 * 5849 * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' }); 5850 * 5851 * @name deepNestedPropertyVal 5852 * @param {Object} object 5853 * @param {String} property 5854 * @param {Mixed} value 5855 * @param {String} message 5856 * @namespace Assert 5857 * @api public 5858 */ 5859 5860 assert.deepNestedPropertyVal = function (obj, prop, val, msg) { 5861 new Assertion(obj, msg, assert.deepNestedPropertyVal, true) 5862 .to.have.deep.nested.property(prop, val); 5863 }; 5864 5865 /** 5866 * ### .notDeepNestedPropertyVal(object, property, value, [message]) 5867 * 5868 * Asserts that `object` does _not_ have a property named by `property` with 5869 * value given by `value`. `property` can use dot- and bracket-notation for 5870 * nested reference. Uses a deep equality check. 5871 * 5872 * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' }); 5873 * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' }); 5874 * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' }); 5875 * 5876 * @name notDeepNestedPropertyVal 5877 * @param {Object} object 5878 * @param {String} property 5879 * @param {Mixed} value 5880 * @param {String} message 5881 * @namespace Assert 5882 * @api public 5883 */ 5884 5885 assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) { 5886 new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true) 5887 .to.not.have.deep.nested.property(prop, val); 5888 } 5889 5890 /** 5891 * ### .lengthOf(object, length, [message]) 5892 * 5893 * Asserts that `object` has a `length` or `size` with the expected value. 5894 * 5895 * assert.lengthOf([1,2,3], 3, 'array has length of 3'); 5896 * assert.lengthOf('foobar', 6, 'string has length of 6'); 5897 * assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3'); 5898 * assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3'); 5899 * 5900 * @name lengthOf 5901 * @param {Mixed} object 5902 * @param {Number} length 5903 * @param {String} message 5904 * @namespace Assert 5905 * @api public 5906 */ 5907 5908 assert.lengthOf = function (exp, len, msg) { 5909 new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len); 5910 }; 5911 5912 /** 5913 * ### .hasAnyKeys(object, [keys], [message]) 5914 * 5915 * Asserts that `object` has at least one of the `keys` provided. 5916 * You can also provide a single object instead of a `keys` array and its keys 5917 * will be used as the expected set of keys. 5918 * 5919 * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); 5920 * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337}); 5921 * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); 5922 * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); 5923 * 5924 * @name hasAnyKeys 5925 * @param {Mixed} object 5926 * @param {Array|Object} keys 5927 * @param {String} message 5928 * @namespace Assert 5929 * @api public 5930 */ 5931 5932 assert.hasAnyKeys = function (obj, keys, msg) { 5933 new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys); 5934 } 5935 5936 /** 5937 * ### .hasAllKeys(object, [keys], [message]) 5938 * 5939 * Asserts that `object` has all and only all of the `keys` provided. 5940 * You can also provide a single object instead of a `keys` array and its keys 5941 * will be used as the expected set of keys. 5942 * 5943 * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); 5944 * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]); 5945 * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); 5946 * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); 5947 * 5948 * @name hasAllKeys 5949 * @param {Mixed} object 5950 * @param {String[]} keys 5951 * @param {String} message 5952 * @namespace Assert 5953 * @api public 5954 */ 5955 5956 assert.hasAllKeys = function (obj, keys, msg) { 5957 new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys); 5958 } 5959 5960 /** 5961 * ### .containsAllKeys(object, [keys], [message]) 5962 * 5963 * Asserts that `object` has all of the `keys` provided but may have more keys not listed. 5964 * You can also provide a single object instead of a `keys` array and its keys 5965 * will be used as the expected set of keys. 5966 * 5967 * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']); 5968 * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); 5969 * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337}); 5970 * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337}); 5971 * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]); 5972 * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); 5973 * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]); 5974 * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); 5975 * 5976 * @name containsAllKeys 5977 * @param {Mixed} object 5978 * @param {String[]} keys 5979 * @param {String} message 5980 * @namespace Assert 5981 * @api public 5982 */ 5983 5984 assert.containsAllKeys = function (obj, keys, msg) { 5985 new Assertion(obj, msg, assert.containsAllKeys, true) 5986 .to.contain.all.keys(keys); 5987 } 5988 5989 /** 5990 * ### .doesNotHaveAnyKeys(object, [keys], [message]) 5991 * 5992 * Asserts that `object` has none of the `keys` provided. 5993 * You can also provide a single object instead of a `keys` array and its keys 5994 * will be used as the expected set of keys. 5995 * 5996 * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); 5997 * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); 5998 * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); 5999 * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); 6000 * 6001 * @name doesNotHaveAnyKeys 6002 * @param {Mixed} object 6003 * @param {String[]} keys 6004 * @param {String} message 6005 * @namespace Assert 6006 * @api public 6007 */ 6008 6009 assert.doesNotHaveAnyKeys = function (obj, keys, msg) { 6010 new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true) 6011 .to.not.have.any.keys(keys); 6012 } 6013 6014 /** 6015 * ### .doesNotHaveAllKeys(object, [keys], [message]) 6016 * 6017 * Asserts that `object` does not have at least one of the `keys` provided. 6018 * You can also provide a single object instead of a `keys` array and its keys 6019 * will be used as the expected set of keys. 6020 * 6021 * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); 6022 * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); 6023 * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); 6024 * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); 6025 * 6026 * @name doesNotHaveAllKeys 6027 * @param {Mixed} object 6028 * @param {String[]} keys 6029 * @param {String} message 6030 * @namespace Assert 6031 * @api public 6032 */ 6033 6034 assert.doesNotHaveAllKeys = function (obj, keys, msg) { 6035 new Assertion(obj, msg, assert.doesNotHaveAllKeys, true) 6036 .to.not.have.all.keys(keys); 6037 } 6038 6039 /** 6040 * ### .hasAnyDeepKeys(object, [keys], [message]) 6041 * 6042 * Asserts that `object` has at least one of the `keys` provided. 6043 * Since Sets and Maps can have objects as keys you can use this assertion to perform 6044 * a deep comparison. 6045 * You can also provide a single object instead of a `keys` array and its keys 6046 * will be used as the expected set of keys. 6047 * 6048 * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); 6049 * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]); 6050 * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); 6051 * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); 6052 * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]); 6053 * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); 6054 * 6055 * @name hasAnyDeepKeys 6056 * @param {Mixed} object 6057 * @param {Array|Object} keys 6058 * @param {String} message 6059 * @namespace Assert 6060 * @api public 6061 */ 6062 6063 assert.hasAnyDeepKeys = function (obj, keys, msg) { 6064 new Assertion(obj, msg, assert.hasAnyDeepKeys, true) 6065 .to.have.any.deep.keys(keys); 6066 } 6067 6068 /** 6069 * ### .hasAllDeepKeys(object, [keys], [message]) 6070 * 6071 * Asserts that `object` has all and only all of the `keys` provided. 6072 * Since Sets and Maps can have objects as keys you can use this assertion to perform 6073 * a deep comparison. 6074 * You can also provide a single object instead of a `keys` array and its keys 6075 * will be used as the expected set of keys. 6076 * 6077 * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'}); 6078 * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); 6079 * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'}); 6080 * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); 6081 * 6082 * @name hasAllDeepKeys 6083 * @param {Mixed} object 6084 * @param {Array|Object} keys 6085 * @param {String} message 6086 * @namespace Assert 6087 * @api public 6088 */ 6089 6090 assert.hasAllDeepKeys = function (obj, keys, msg) { 6091 new Assertion(obj, msg, assert.hasAllDeepKeys, true) 6092 .to.have.all.deep.keys(keys); 6093 } 6094 6095 /** 6096 * ### .containsAllDeepKeys(object, [keys], [message]) 6097 * 6098 * Asserts that `object` contains all of the `keys` provided. 6099 * Since Sets and Maps can have objects as keys you can use this assertion to perform 6100 * a deep comparison. 6101 * You can also provide a single object instead of a `keys` array and its keys 6102 * will be used as the expected set of keys. 6103 * 6104 * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); 6105 * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); 6106 * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); 6107 * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); 6108 * 6109 * @name containsAllDeepKeys 6110 * @param {Mixed} object 6111 * @param {Array|Object} keys 6112 * @param {String} message 6113 * @namespace Assert 6114 * @api public 6115 */ 6116 6117 assert.containsAllDeepKeys = function (obj, keys, msg) { 6118 new Assertion(obj, msg, assert.containsAllDeepKeys, true) 6119 .to.contain.all.deep.keys(keys); 6120 } 6121 6122 /** 6123 * ### .doesNotHaveAnyDeepKeys(object, [keys], [message]) 6124 * 6125 * Asserts that `object` has none of the `keys` provided. 6126 * Since Sets and Maps can have objects as keys you can use this assertion to perform 6127 * a deep comparison. 6128 * You can also provide a single object instead of a `keys` array and its keys 6129 * will be used as the expected set of keys. 6130 * 6131 * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); 6132 * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); 6133 * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); 6134 * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); 6135 * 6136 * @name doesNotHaveAnyDeepKeys 6137 * @param {Mixed} object 6138 * @param {Array|Object} keys 6139 * @param {String} message 6140 * @namespace Assert 6141 * @api public 6142 */ 6143 6144 assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) { 6145 new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true) 6146 .to.not.have.any.deep.keys(keys); 6147 } 6148 6149 /** 6150 * ### .doesNotHaveAllDeepKeys(object, [keys], [message]) 6151 * 6152 * Asserts that `object` does not have at least one of the `keys` provided. 6153 * Since Sets and Maps can have objects as keys you can use this assertion to perform 6154 * a deep comparison. 6155 * You can also provide a single object instead of a `keys` array and its keys 6156 * will be used as the expected set of keys. 6157 * 6158 * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); 6159 * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]); 6160 * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); 6161 * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]); 6162 * 6163 * @name doesNotHaveAllDeepKeys 6164 * @param {Mixed} object 6165 * @param {Array|Object} keys 6166 * @param {String} message 6167 * @namespace Assert 6168 * @api public 6169 */ 6170 6171 assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) { 6172 new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true) 6173 .to.not.have.all.deep.keys(keys); 6174 } 6175 6176 /** 6177 * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message]) 6178 * 6179 * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an 6180 * instance of `errorLike`. 6181 * If `errorLike` is an `Error` instance, asserts that the error thrown is the same 6182 * instance as `errorLike`. 6183 * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a 6184 * message matching `errMsgMatcher`. 6185 * 6186 * assert.throws(fn, 'Error thrown must have this msg'); 6187 * assert.throws(fn, /Error thrown must have a msg that matches this/); 6188 * assert.throws(fn, ReferenceError); 6189 * assert.throws(fn, errorInstance); 6190 * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg'); 6191 * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg'); 6192 * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/); 6193 * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/); 6194 * 6195 * @name throws 6196 * @alias throw 6197 * @alias Throw 6198 * @param {Function} fn 6199 * @param {ErrorConstructor|Error} errorLike 6200 * @param {RegExp|String} errMsgMatcher 6201 * @param {String} message 6202 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types 6203 * @namespace Assert 6204 * @api public 6205 */ 6206 6207 assert.throws = function (fn, errorLike, errMsgMatcher, msg) { 6208 if ('string' === typeof errorLike || errorLike instanceof RegExp) { 6209 errMsgMatcher = errorLike; 6210 errorLike = null; 6211 } 6212 6213 var assertErr = new Assertion(fn, msg, assert.throws, true) 6214 .to.throw(errorLike, errMsgMatcher); 6215 return flag(assertErr, 'object'); 6216 }; 6217 6218 /** 6219 * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message]) 6220 * 6221 * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an 6222 * instance of `errorLike`. 6223 * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same 6224 * instance as `errorLike`. 6225 * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a 6226 * message matching `errMsgMatcher`. 6227 * 6228 * assert.doesNotThrow(fn, 'Any Error thrown must not have this message'); 6229 * assert.doesNotThrow(fn, /Any Error thrown must not match this/); 6230 * assert.doesNotThrow(fn, Error); 6231 * assert.doesNotThrow(fn, errorInstance); 6232 * assert.doesNotThrow(fn, Error, 'Error must not have this message'); 6233 * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message'); 6234 * assert.doesNotThrow(fn, Error, /Error must not match this/); 6235 * assert.doesNotThrow(fn, errorInstance, /Error must not match this/); 6236 * 6237 * @name doesNotThrow 6238 * @param {Function} fn 6239 * @param {ErrorConstructor} errorLike 6240 * @param {RegExp|String} errMsgMatcher 6241 * @param {String} message 6242 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types 6243 * @namespace Assert 6244 * @api public 6245 */ 6246 6247 assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) { 6248 if ('string' === typeof errorLike || errorLike instanceof RegExp) { 6249 errMsgMatcher = errorLike; 6250 errorLike = null; 6251 } 6252 6253 new Assertion(fn, msg, assert.doesNotThrow, true) 6254 .to.not.throw(errorLike, errMsgMatcher); 6255 }; 6256 6257 /** 6258 * ### .operator(val1, operator, val2, [message]) 6259 * 6260 * Compares two values using `operator`. 6261 * 6262 * assert.operator(1, '<', 2, 'everything is ok'); 6263 * assert.operator(1, '>', 2, 'this will fail'); 6264 * 6265 * @name operator 6266 * @param {Mixed} val1 6267 * @param {String} operator 6268 * @param {Mixed} val2 6269 * @param {String} message 6270 * @namespace Assert 6271 * @api public 6272 */ 6273 6274 assert.operator = function (val, operator, val2, msg) { 6275 var ok; 6276 switch(operator) { 6277 case '==': 6278 ok = val == val2; 6279 break; 6280 case '===': 6281 ok = val === val2; 6282 break; 6283 case '>': 6284 ok = val > val2; 6285 break; 6286 case '>=': 6287 ok = val >= val2; 6288 break; 6289 case '<': 6290 ok = val < val2; 6291 break; 6292 case '<=': 6293 ok = val <= val2; 6294 break; 6295 case '!=': 6296 ok = val != val2; 6297 break; 6298 case '!==': 6299 ok = val !== val2; 6300 break; 6301 default: 6302 msg = msg ? msg + ': ' : msg; 6303 throw new chai.AssertionError( 6304 msg + 'Invalid operator "' + operator + '"', 6305 undefined, 6306 assert.operator 6307 ); 6308 } 6309 var test = new Assertion(ok, msg, assert.operator, true); 6310 test.assert( 6311 true === flag(test, 'object') 6312 , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) 6313 , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); 6314 }; 6315 6316 /** 6317 * ### .closeTo(actual, expected, delta, [message]) 6318 * 6319 * Asserts that the target is equal `expected`, to within a +/- `delta` range. 6320 * 6321 * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); 6322 * 6323 * @name closeTo 6324 * @param {Number} actual 6325 * @param {Number} expected 6326 * @param {Number} delta 6327 * @param {String} message 6328 * @namespace Assert 6329 * @api public 6330 */ 6331 6332 assert.closeTo = function (act, exp, delta, msg) { 6333 new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta); 6334 }; 6335 6336 /** 6337 * ### .approximately(actual, expected, delta, [message]) 6338 * 6339 * Asserts that the target is equal `expected`, to within a +/- `delta` range. 6340 * 6341 * assert.approximately(1.5, 1, 0.5, 'numbers are close'); 6342 * 6343 * @name approximately 6344 * @param {Number} actual 6345 * @param {Number} expected 6346 * @param {Number} delta 6347 * @param {String} message 6348 * @namespace Assert 6349 * @api public 6350 */ 6351 6352 assert.approximately = function (act, exp, delta, msg) { 6353 new Assertion(act, msg, assert.approximately, true) 6354 .to.be.approximately(exp, delta); 6355 }; 6356 6357 /** 6358 * ### .sameMembers(set1, set2, [message]) 6359 * 6360 * Asserts that `set1` and `set2` have the same members in any order. Uses a 6361 * strict equality check (===). 6362 * 6363 * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); 6364 * 6365 * @name sameMembers 6366 * @param {Array} set1 6367 * @param {Array} set2 6368 * @param {String} message 6369 * @namespace Assert 6370 * @api public 6371 */ 6372 6373 assert.sameMembers = function (set1, set2, msg) { 6374 new Assertion(set1, msg, assert.sameMembers, true) 6375 .to.have.same.members(set2); 6376 } 6377 6378 /** 6379 * ### .notSameMembers(set1, set2, [message]) 6380 * 6381 * Asserts that `set1` and `set2` don't have the same members in any order. 6382 * Uses a strict equality check (===). 6383 * 6384 * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members'); 6385 * 6386 * @name notSameMembers 6387 * @param {Array} set1 6388 * @param {Array} set2 6389 * @param {String} message 6390 * @namespace Assert 6391 * @api public 6392 */ 6393 6394 assert.notSameMembers = function (set1, set2, msg) { 6395 new Assertion(set1, msg, assert.notSameMembers, true) 6396 .to.not.have.same.members(set2); 6397 } 6398 6399 /** 6400 * ### .sameDeepMembers(set1, set2, [message]) 6401 * 6402 * Asserts that `set1` and `set2` have the same members in any order. Uses a 6403 * deep equality check. 6404 * 6405 * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members'); 6406 * 6407 * @name sameDeepMembers 6408 * @param {Array} set1 6409 * @param {Array} set2 6410 * @param {String} message 6411 * @namespace Assert 6412 * @api public 6413 */ 6414 6415 assert.sameDeepMembers = function (set1, set2, msg) { 6416 new Assertion(set1, msg, assert.sameDeepMembers, true) 6417 .to.have.same.deep.members(set2); 6418 } 6419 6420 /** 6421 * ### .notSameDeepMembers(set1, set2, [message]) 6422 * 6423 * Asserts that `set1` and `set2` don't have the same members in any order. 6424 * Uses a deep equality check. 6425 * 6426 * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members'); 6427 * 6428 * @name notSameDeepMembers 6429 * @param {Array} set1 6430 * @param {Array} set2 6431 * @param {String} message 6432 * @namespace Assert 6433 * @api public 6434 */ 6435 6436 assert.notSameDeepMembers = function (set1, set2, msg) { 6437 new Assertion(set1, msg, assert.notSameDeepMembers, true) 6438 .to.not.have.same.deep.members(set2); 6439 } 6440 6441 /** 6442 * ### .sameOrderedMembers(set1, set2, [message]) 6443 * 6444 * Asserts that `set1` and `set2` have the same members in the same order. 6445 * Uses a strict equality check (===). 6446 * 6447 * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members'); 6448 * 6449 * @name sameOrderedMembers 6450 * @param {Array} set1 6451 * @param {Array} set2 6452 * @param {String} message 6453 * @namespace Assert 6454 * @api public 6455 */ 6456 6457 assert.sameOrderedMembers = function (set1, set2, msg) { 6458 new Assertion(set1, msg, assert.sameOrderedMembers, true) 6459 .to.have.same.ordered.members(set2); 6460 } 6461 6462 /** 6463 * ### .notSameOrderedMembers(set1, set2, [message]) 6464 * 6465 * Asserts that `set1` and `set2` don't have the same members in the same 6466 * order. Uses a strict equality check (===). 6467 * 6468 * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members'); 6469 * 6470 * @name notSameOrderedMembers 6471 * @param {Array} set1 6472 * @param {Array} set2 6473 * @param {String} message 6474 * @namespace Assert 6475 * @api public 6476 */ 6477 6478 assert.notSameOrderedMembers = function (set1, set2, msg) { 6479 new Assertion(set1, msg, assert.notSameOrderedMembers, true) 6480 .to.not.have.same.ordered.members(set2); 6481 } 6482 6483 /** 6484 * ### .sameDeepOrderedMembers(set1, set2, [message]) 6485 * 6486 * Asserts that `set1` and `set2` have the same members in the same order. 6487 * Uses a deep equality check. 6488 * 6489 * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members'); 6490 * 6491 * @name sameDeepOrderedMembers 6492 * @param {Array} set1 6493 * @param {Array} set2 6494 * @param {String} message 6495 * @namespace Assert 6496 * @api public 6497 */ 6498 6499 assert.sameDeepOrderedMembers = function (set1, set2, msg) { 6500 new Assertion(set1, msg, assert.sameDeepOrderedMembers, true) 6501 .to.have.same.deep.ordered.members(set2); 6502 } 6503 6504 /** 6505 * ### .notSameDeepOrderedMembers(set1, set2, [message]) 6506 * 6507 * Asserts that `set1` and `set2` don't have the same members in the same 6508 * order. Uses a deep equality check. 6509 * 6510 * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members'); 6511 * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members'); 6512 * 6513 * @name notSameDeepOrderedMembers 6514 * @param {Array} set1 6515 * @param {Array} set2 6516 * @param {String} message 6517 * @namespace Assert 6518 * @api public 6519 */ 6520 6521 assert.notSameDeepOrderedMembers = function (set1, set2, msg) { 6522 new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true) 6523 .to.not.have.same.deep.ordered.members(set2); 6524 } 6525 6526 /** 6527 * ### .includeMembers(superset, subset, [message]) 6528 * 6529 * Asserts that `subset` is included in `superset` in any order. Uses a 6530 * strict equality check (===). Duplicates are ignored. 6531 * 6532 * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members'); 6533 * 6534 * @name includeMembers 6535 * @param {Array} superset 6536 * @param {Array} subset 6537 * @param {String} message 6538 * @namespace Assert 6539 * @api public 6540 */ 6541 6542 assert.includeMembers = function (superset, subset, msg) { 6543 new Assertion(superset, msg, assert.includeMembers, true) 6544 .to.include.members(subset); 6545 } 6546 6547 /** 6548 * ### .notIncludeMembers(superset, subset, [message]) 6549 * 6550 * Asserts that `subset` isn't included in `superset` in any order. Uses a 6551 * strict equality check (===). Duplicates are ignored. 6552 * 6553 * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members'); 6554 * 6555 * @name notIncludeMembers 6556 * @param {Array} superset 6557 * @param {Array} subset 6558 * @param {String} message 6559 * @namespace Assert 6560 * @api public 6561 */ 6562 6563 assert.notIncludeMembers = function (superset, subset, msg) { 6564 new Assertion(superset, msg, assert.notIncludeMembers, true) 6565 .to.not.include.members(subset); 6566 } 6567 6568 /** 6569 * ### .includeDeepMembers(superset, subset, [message]) 6570 * 6571 * Asserts that `subset` is included in `superset` in any order. Uses a deep 6572 * equality check. Duplicates are ignored. 6573 * 6574 * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members'); 6575 * 6576 * @name includeDeepMembers 6577 * @param {Array} superset 6578 * @param {Array} subset 6579 * @param {String} message 6580 * @namespace Assert 6581 * @api public 6582 */ 6583 6584 assert.includeDeepMembers = function (superset, subset, msg) { 6585 new Assertion(superset, msg, assert.includeDeepMembers, true) 6586 .to.include.deep.members(subset); 6587 } 6588 6589 /** 6590 * ### .notIncludeDeepMembers(superset, subset, [message]) 6591 * 6592 * Asserts that `subset` isn't included in `superset` in any order. Uses a 6593 * deep equality check. Duplicates are ignored. 6594 * 6595 * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members'); 6596 * 6597 * @name notIncludeDeepMembers 6598 * @param {Array} superset 6599 * @param {Array} subset 6600 * @param {String} message 6601 * @namespace Assert 6602 * @api public 6603 */ 6604 6605 assert.notIncludeDeepMembers = function (superset, subset, msg) { 6606 new Assertion(superset, msg, assert.notIncludeDeepMembers, true) 6607 .to.not.include.deep.members(subset); 6608 } 6609 6610 /** 6611 * ### .includeOrderedMembers(superset, subset, [message]) 6612 * 6613 * Asserts that `subset` is included in `superset` in the same order 6614 * beginning with the first element in `superset`. Uses a strict equality 6615 * check (===). 6616 * 6617 * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members'); 6618 * 6619 * @name includeOrderedMembers 6620 * @param {Array} superset 6621 * @param {Array} subset 6622 * @param {String} message 6623 * @namespace Assert 6624 * @api public 6625 */ 6626 6627 assert.includeOrderedMembers = function (superset, subset, msg) { 6628 new Assertion(superset, msg, assert.includeOrderedMembers, true) 6629 .to.include.ordered.members(subset); 6630 } 6631 6632 /** 6633 * ### .notIncludeOrderedMembers(superset, subset, [message]) 6634 * 6635 * Asserts that `subset` isn't included in `superset` in the same order 6636 * beginning with the first element in `superset`. Uses a strict equality 6637 * check (===). 6638 * 6639 * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members'); 6640 * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members'); 6641 * 6642 * @name notIncludeOrderedMembers 6643 * @param {Array} superset 6644 * @param {Array} subset 6645 * @param {String} message 6646 * @namespace Assert 6647 * @api public 6648 */ 6649 6650 assert.notIncludeOrderedMembers = function (superset, subset, msg) { 6651 new Assertion(superset, msg, assert.notIncludeOrderedMembers, true) 6652 .to.not.include.ordered.members(subset); 6653 } 6654 6655 /** 6656 * ### .includeDeepOrderedMembers(superset, subset, [message]) 6657 * 6658 * Asserts that `subset` is included in `superset` in the same order 6659 * beginning with the first element in `superset`. Uses a deep equality 6660 * check. 6661 * 6662 * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members'); 6663 * 6664 * @name includeDeepOrderedMembers 6665 * @param {Array} superset 6666 * @param {Array} subset 6667 * @param {String} message 6668 * @namespace Assert 6669 * @api public 6670 */ 6671 6672 assert.includeDeepOrderedMembers = function (superset, subset, msg) { 6673 new Assertion(superset, msg, assert.includeDeepOrderedMembers, true) 6674 .to.include.deep.ordered.members(subset); 6675 } 6676 6677 /** 6678 * ### .notIncludeDeepOrderedMembers(superset, subset, [message]) 6679 * 6680 * Asserts that `subset` isn't included in `superset` in the same order 6681 * beginning with the first element in `superset`. Uses a deep equality 6682 * check. 6683 * 6684 * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members'); 6685 * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members'); 6686 * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members'); 6687 * 6688 * @name notIncludeDeepOrderedMembers 6689 * @param {Array} superset 6690 * @param {Array} subset 6691 * @param {String} message 6692 * @namespace Assert 6693 * @api public 6694 */ 6695 6696 assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) { 6697 new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true) 6698 .to.not.include.deep.ordered.members(subset); 6699 } 6700 6701 /** 6702 * ### .oneOf(inList, list, [message]) 6703 * 6704 * Asserts that non-object, non-array value `inList` appears in the flat array `list`. 6705 * 6706 * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); 6707 * 6708 * @name oneOf 6709 * @param {*} inList 6710 * @param {Array<*>} list 6711 * @param {String} message 6712 * @namespace Assert 6713 * @api public 6714 */ 6715 6716 assert.oneOf = function (inList, list, msg) { 6717 new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list); 6718 } 6719 6720 /** 6721 * ### .changes(function, object, property, [message]) 6722 * 6723 * Asserts that a function changes the value of a property. 6724 * 6725 * var obj = { val: 10 }; 6726 * var fn = function() { obj.val = 22 }; 6727 * assert.changes(fn, obj, 'val'); 6728 * 6729 * @name changes 6730 * @param {Function} modifier function 6731 * @param {Object} object or getter function 6732 * @param {String} property name _optional_ 6733 * @param {String} message _optional_ 6734 * @namespace Assert 6735 * @api public 6736 */ 6737 6738 assert.changes = function (fn, obj, prop, msg) { 6739 if (arguments.length === 3 && typeof obj === 'function') { 6740 msg = prop; 6741 prop = null; 6742 } 6743 6744 new Assertion(fn, msg, assert.changes, true).to.change(obj, prop); 6745 } 6746 6747 /** 6748 * ### .changesBy(function, object, property, delta, [message]) 6749 * 6750 * Asserts that a function changes the value of a property by an amount (delta). 6751 * 6752 * var obj = { val: 10 }; 6753 * var fn = function() { obj.val += 2 }; 6754 * assert.changesBy(fn, obj, 'val', 2); 6755 * 6756 * @name changesBy 6757 * @param {Function} modifier function 6758 * @param {Object} object or getter function 6759 * @param {String} property name _optional_ 6760 * @param {Number} change amount (delta) 6761 * @param {String} message _optional_ 6762 * @namespace Assert 6763 * @api public 6764 */ 6765 6766 assert.changesBy = function (fn, obj, prop, delta, msg) { 6767 if (arguments.length === 4 && typeof obj === 'function') { 6768 var tmpMsg = delta; 6769 delta = prop; 6770 msg = tmpMsg; 6771 } else if (arguments.length === 3) { 6772 delta = prop; 6773 prop = null; 6774 } 6775 6776 new Assertion(fn, msg, assert.changesBy, true) 6777 .to.change(obj, prop).by(delta); 6778 } 6779 6780 /** 6781 * ### .doesNotChange(function, object, property, [message]) 6782 * 6783 * Asserts that a function does not change the value of a property. 6784 * 6785 * var obj = { val: 10 }; 6786 * var fn = function() { console.log('foo'); }; 6787 * assert.doesNotChange(fn, obj, 'val'); 6788 * 6789 * @name doesNotChange 6790 * @param {Function} modifier function 6791 * @param {Object} object or getter function 6792 * @param {String} property name _optional_ 6793 * @param {String} message _optional_ 6794 * @namespace Assert 6795 * @api public 6796 */ 6797 6798 assert.doesNotChange = function (fn, obj, prop, msg) { 6799 if (arguments.length === 3 && typeof obj === 'function') { 6800 msg = prop; 6801 prop = null; 6802 } 6803 6804 return new Assertion(fn, msg, assert.doesNotChange, true) 6805 .to.not.change(obj, prop); 6806 } 6807 6808 /** 6809 * ### .changesButNotBy(function, object, property, delta, [message]) 6810 * 6811 * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta) 6812 * 6813 * var obj = { val: 10 }; 6814 * var fn = function() { obj.val += 10 }; 6815 * assert.changesButNotBy(fn, obj, 'val', 5); 6816 * 6817 * @name changesButNotBy 6818 * @param {Function} modifier function 6819 * @param {Object} object or getter function 6820 * @param {String} property name _optional_ 6821 * @param {Number} change amount (delta) 6822 * @param {String} message _optional_ 6823 * @namespace Assert 6824 * @api public 6825 */ 6826 6827 assert.changesButNotBy = function (fn, obj, prop, delta, msg) { 6828 if (arguments.length === 4 && typeof obj === 'function') { 6829 var tmpMsg = delta; 6830 delta = prop; 6831 msg = tmpMsg; 6832 } else if (arguments.length === 3) { 6833 delta = prop; 6834 prop = null; 6835 } 6836 6837 new Assertion(fn, msg, assert.changesButNotBy, true) 6838 .to.change(obj, prop).but.not.by(delta); 6839 } 6840 6841 /** 6842 * ### .increases(function, object, property, [message]) 6843 * 6844 * Asserts that a function increases a numeric object property. 6845 * 6846 * var obj = { val: 10 }; 6847 * var fn = function() { obj.val = 13 }; 6848 * assert.increases(fn, obj, 'val'); 6849 * 6850 * @name increases 6851 * @param {Function} modifier function 6852 * @param {Object} object or getter function 6853 * @param {String} property name _optional_ 6854 * @param {String} message _optional_ 6855 * @namespace Assert 6856 * @api public 6857 */ 6858 6859 assert.increases = function (fn, obj, prop, msg) { 6860 if (arguments.length === 3 && typeof obj === 'function') { 6861 msg = prop; 6862 prop = null; 6863 } 6864 6865 return new Assertion(fn, msg, assert.increases, true) 6866 .to.increase(obj, prop); 6867 } 6868 6869 /** 6870 * ### .increasesBy(function, object, property, delta, [message]) 6871 * 6872 * Asserts that a function increases a numeric object property or a function's return value by an amount (delta). 6873 * 6874 * var obj = { val: 10 }; 6875 * var fn = function() { obj.val += 10 }; 6876 * assert.increasesBy(fn, obj, 'val', 10); 6877 * 6878 * @name increasesBy 6879 * @param {Function} modifier function 6880 * @param {Object} object or getter function 6881 * @param {String} property name _optional_ 6882 * @param {Number} change amount (delta) 6883 * @param {String} message _optional_ 6884 * @namespace Assert 6885 * @api public 6886 */ 6887 6888 assert.increasesBy = function (fn, obj, prop, delta, msg) { 6889 if (arguments.length === 4 && typeof obj === 'function') { 6890 var tmpMsg = delta; 6891 delta = prop; 6892 msg = tmpMsg; 6893 } else if (arguments.length === 3) { 6894 delta = prop; 6895 prop = null; 6896 } 6897 6898 new Assertion(fn, msg, assert.increasesBy, true) 6899 .to.increase(obj, prop).by(delta); 6900 } 6901 6902 /** 6903 * ### .doesNotIncrease(function, object, property, [message]) 6904 * 6905 * Asserts that a function does not increase a numeric object property. 6906 * 6907 * var obj = { val: 10 }; 6908 * var fn = function() { obj.val = 8 }; 6909 * assert.doesNotIncrease(fn, obj, 'val'); 6910 * 6911 * @name doesNotIncrease 6912 * @param {Function} modifier function 6913 * @param {Object} object or getter function 6914 * @param {String} property name _optional_ 6915 * @param {String} message _optional_ 6916 * @namespace Assert 6917 * @api public 6918 */ 6919 6920 assert.doesNotIncrease = function (fn, obj, prop, msg) { 6921 if (arguments.length === 3 && typeof obj === 'function') { 6922 msg = prop; 6923 prop = null; 6924 } 6925 6926 return new Assertion(fn, msg, assert.doesNotIncrease, true) 6927 .to.not.increase(obj, prop); 6928 } 6929 6930 /** 6931 * ### .increasesButNotBy(function, object, property, delta, [message]) 6932 * 6933 * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta). 6934 * 6935 * var obj = { val: 10 }; 6936 * var fn = function() { obj.val = 15 }; 6937 * assert.increasesButNotBy(fn, obj, 'val', 10); 6938 * 6939 * @name increasesButNotBy 6940 * @param {Function} modifier function 6941 * @param {Object} object or getter function 6942 * @param {String} property name _optional_ 6943 * @param {Number} change amount (delta) 6944 * @param {String} message _optional_ 6945 * @namespace Assert 6946 * @api public 6947 */ 6948 6949 assert.increasesButNotBy = function (fn, obj, prop, delta, msg) { 6950 if (arguments.length === 4 && typeof obj === 'function') { 6951 var tmpMsg = delta; 6952 delta = prop; 6953 msg = tmpMsg; 6954 } else if (arguments.length === 3) { 6955 delta = prop; 6956 prop = null; 6957 } 6958 6959 new Assertion(fn, msg, assert.increasesButNotBy, true) 6960 .to.increase(obj, prop).but.not.by(delta); 6961 } 6962 6963 /** 6964 * ### .decreases(function, object, property, [message]) 6965 * 6966 * Asserts that a function decreases a numeric object property. 6967 * 6968 * var obj = { val: 10 }; 6969 * var fn = function() { obj.val = 5 }; 6970 * assert.decreases(fn, obj, 'val'); 6971 * 6972 * @name decreases 6973 * @param {Function} modifier function 6974 * @param {Object} object or getter function 6975 * @param {String} property name _optional_ 6976 * @param {String} message _optional_ 6977 * @namespace Assert 6978 * @api public 6979 */ 6980 6981 assert.decreases = function (fn, obj, prop, msg) { 6982 if (arguments.length === 3 && typeof obj === 'function') { 6983 msg = prop; 6984 prop = null; 6985 } 6986 6987 return new Assertion(fn, msg, assert.decreases, true) 6988 .to.decrease(obj, prop); 6989 } 6990 6991 /** 6992 * ### .decreasesBy(function, object, property, delta, [message]) 6993 * 6994 * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta) 6995 * 6996 * var obj = { val: 10 }; 6997 * var fn = function() { obj.val -= 5 }; 6998 * assert.decreasesBy(fn, obj, 'val', 5); 6999 * 7000 * @name decreasesBy 7001 * @param {Function} modifier function 7002 * @param {Object} object or getter function 7003 * @param {String} property name _optional_ 7004 * @param {Number} change amount (delta) 7005 * @param {String} message _optional_ 7006 * @namespace Assert 7007 * @api public 7008 */ 7009 7010 assert.decreasesBy = function (fn, obj, prop, delta, msg) { 7011 if (arguments.length === 4 && typeof obj === 'function') { 7012 var tmpMsg = delta; 7013 delta = prop; 7014 msg = tmpMsg; 7015 } else if (arguments.length === 3) { 7016 delta = prop; 7017 prop = null; 7018 } 7019 7020 new Assertion(fn, msg, assert.decreasesBy, true) 7021 .to.decrease(obj, prop).by(delta); 7022 } 7023 7024 /** 7025 * ### .doesNotDecrease(function, object, property, [message]) 7026 * 7027 * Asserts that a function does not decreases a numeric object property. 7028 * 7029 * var obj = { val: 10 }; 7030 * var fn = function() { obj.val = 15 }; 7031 * assert.doesNotDecrease(fn, obj, 'val'); 7032 * 7033 * @name doesNotDecrease 7034 * @param {Function} modifier function 7035 * @param {Object} object or getter function 7036 * @param {String} property name _optional_ 7037 * @param {String} message _optional_ 7038 * @namespace Assert 7039 * @api public 7040 */ 7041 7042 assert.doesNotDecrease = function (fn, obj, prop, msg) { 7043 if (arguments.length === 3 && typeof obj === 'function') { 7044 msg = prop; 7045 prop = null; 7046 } 7047 7048 return new Assertion(fn, msg, assert.doesNotDecrease, true) 7049 .to.not.decrease(obj, prop); 7050 } 7051 7052 /** 7053 * ### .doesNotDecreaseBy(function, object, property, delta, [message]) 7054 * 7055 * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) 7056 * 7057 * var obj = { val: 10 }; 7058 * var fn = function() { obj.val = 5 }; 7059 * assert.doesNotDecreaseBy(fn, obj, 'val', 1); 7060 * 7061 * @name doesNotDecreaseBy 7062 * @param {Function} modifier function 7063 * @param {Object} object or getter function 7064 * @param {String} property name _optional_ 7065 * @param {Number} change amount (delta) 7066 * @param {String} message _optional_ 7067 * @namespace Assert 7068 * @api public 7069 */ 7070 7071 assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) { 7072 if (arguments.length === 4 && typeof obj === 'function') { 7073 var tmpMsg = delta; 7074 delta = prop; 7075 msg = tmpMsg; 7076 } else if (arguments.length === 3) { 7077 delta = prop; 7078 prop = null; 7079 } 7080 7081 return new Assertion(fn, msg, assert.doesNotDecreaseBy, true) 7082 .to.not.decrease(obj, prop).by(delta); 7083 } 7084 7085 /** 7086 * ### .decreasesButNotBy(function, object, property, delta, [message]) 7087 * 7088 * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) 7089 * 7090 * var obj = { val: 10 }; 7091 * var fn = function() { obj.val = 5 }; 7092 * assert.decreasesButNotBy(fn, obj, 'val', 1); 7093 * 7094 * @name decreasesButNotBy 7095 * @param {Function} modifier function 7096 * @param {Object} object or getter function 7097 * @param {String} property name _optional_ 7098 * @param {Number} change amount (delta) 7099 * @param {String} message _optional_ 7100 * @namespace Assert 7101 * @api public 7102 */ 7103 7104 assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) { 7105 if (arguments.length === 4 && typeof obj === 'function') { 7106 var tmpMsg = delta; 7107 delta = prop; 7108 msg = tmpMsg; 7109 } else if (arguments.length === 3) { 7110 delta = prop; 7111 prop = null; 7112 } 7113 7114 new Assertion(fn, msg, assert.decreasesButNotBy, true) 7115 .to.decrease(obj, prop).but.not.by(delta); 7116 } 7117 7118 /*! 7119 * ### .ifError(object) 7120 * 7121 * Asserts if value is not a false value, and throws if it is a true value. 7122 * This is added to allow for chai to be a drop-in replacement for Node's 7123 * assert class. 7124 * 7125 * var err = new Error('I am a custom error'); 7126 * assert.ifError(err); // Rethrows err! 7127 * 7128 * @name ifError 7129 * @param {Object} object 7130 * @namespace Assert 7131 * @api public 7132 */ 7133 7134 assert.ifError = function (val) { 7135 if (val) { 7136 throw(val); 7137 } 7138 }; 7139 7140 /** 7141 * ### .isExtensible(object) 7142 * 7143 * Asserts that `object` is extensible (can have new properties added to it). 7144 * 7145 * assert.isExtensible({}); 7146 * 7147 * @name isExtensible 7148 * @alias extensible 7149 * @param {Object} object 7150 * @param {String} message _optional_ 7151 * @namespace Assert 7152 * @api public 7153 */ 7154 7155 assert.isExtensible = function (obj, msg) { 7156 new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible; 7157 }; 7158 7159 /** 7160 * ### .isNotExtensible(object) 7161 * 7162 * Asserts that `object` is _not_ extensible. 7163 * 7164 * var nonExtensibleObject = Object.preventExtensions({}); 7165 * var sealedObject = Object.seal({}); 7166 * var frozenObject = Object.freeze({}); 7167 * 7168 * assert.isNotExtensible(nonExtensibleObject); 7169 * assert.isNotExtensible(sealedObject); 7170 * assert.isNotExtensible(frozenObject); 7171 * 7172 * @name isNotExtensible 7173 * @alias notExtensible 7174 * @param {Object} object 7175 * @param {String} message _optional_ 7176 * @namespace Assert 7177 * @api public 7178 */ 7179 7180 assert.isNotExtensible = function (obj, msg) { 7181 new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible; 7182 }; 7183 7184 /** 7185 * ### .isSealed(object) 7186 * 7187 * Asserts that `object` is sealed (cannot have new properties added to it 7188 * and its existing properties cannot be removed). 7189 * 7190 * var sealedObject = Object.seal({}); 7191 * var frozenObject = Object.seal({}); 7192 * 7193 * assert.isSealed(sealedObject); 7194 * assert.isSealed(frozenObject); 7195 * 7196 * @name isSealed 7197 * @alias sealed 7198 * @param {Object} object 7199 * @param {String} message _optional_ 7200 * @namespace Assert 7201 * @api public 7202 */ 7203 7204 assert.isSealed = function (obj, msg) { 7205 new Assertion(obj, msg, assert.isSealed, true).to.be.sealed; 7206 }; 7207 7208 /** 7209 * ### .isNotSealed(object) 7210 * 7211 * Asserts that `object` is _not_ sealed. 7212 * 7213 * assert.isNotSealed({}); 7214 * 7215 * @name isNotSealed 7216 * @alias notSealed 7217 * @param {Object} object 7218 * @param {String} message _optional_ 7219 * @namespace Assert 7220 * @api public 7221 */ 7222 7223 assert.isNotSealed = function (obj, msg) { 7224 new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed; 7225 }; 7226 7227 /** 7228 * ### .isFrozen(object) 7229 * 7230 * Asserts that `object` is frozen (cannot have new properties added to it 7231 * and its existing properties cannot be modified). 7232 * 7233 * var frozenObject = Object.freeze({}); 7234 * assert.frozen(frozenObject); 7235 * 7236 * @name isFrozen 7237 * @alias frozen 7238 * @param {Object} object 7239 * @param {String} message _optional_ 7240 * @namespace Assert 7241 * @api public 7242 */ 7243 7244 assert.isFrozen = function (obj, msg) { 7245 new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen; 7246 }; 7247 7248 /** 7249 * ### .isNotFrozen(object) 7250 * 7251 * Asserts that `object` is _not_ frozen. 7252 * 7253 * assert.isNotFrozen({}); 7254 * 7255 * @name isNotFrozen 7256 * @alias notFrozen 7257 * @param {Object} object 7258 * @param {String} message _optional_ 7259 * @namespace Assert 7260 * @api public 7261 */ 7262 7263 assert.isNotFrozen = function (obj, msg) { 7264 new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen; 7265 }; 7266 7267 /** 7268 * ### .isEmpty(target) 7269 * 7270 * Asserts that the target does not contain any values. 7271 * For arrays and strings, it checks the `length` property. 7272 * For `Map` and `Set` instances, it checks the `size` property. 7273 * For non-function objects, it gets the count of own 7274 * enumerable string keys. 7275 * 7276 * assert.isEmpty([]); 7277 * assert.isEmpty(''); 7278 * assert.isEmpty(new Map); 7279 * assert.isEmpty({}); 7280 * 7281 * @name isEmpty 7282 * @alias empty 7283 * @param {Object|Array|String|Map|Set} target 7284 * @param {String} message _optional_ 7285 * @namespace Assert 7286 * @api public 7287 */ 7288 7289 assert.isEmpty = function(val, msg) { 7290 new Assertion(val, msg, assert.isEmpty, true).to.be.empty; 7291 }; 7292 7293 /** 7294 * ### .isNotEmpty(target) 7295 * 7296 * Asserts that the target contains values. 7297 * For arrays and strings, it checks the `length` property. 7298 * For `Map` and `Set` instances, it checks the `size` property. 7299 * For non-function objects, it gets the count of own 7300 * enumerable string keys. 7301 * 7302 * assert.isNotEmpty([1, 2]); 7303 * assert.isNotEmpty('34'); 7304 * assert.isNotEmpty(new Set([5, 6])); 7305 * assert.isNotEmpty({ key: 7 }); 7306 * 7307 * @name isNotEmpty 7308 * @alias notEmpty 7309 * @param {Object|Array|String|Map|Set} target 7310 * @param {String} message _optional_ 7311 * @namespace Assert 7312 * @api public 7313 */ 7314 7315 assert.isNotEmpty = function(val, msg) { 7316 new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty; 7317 }; 7318 7319 /*! 7320 * Aliases. 7321 */ 7322 7323 (function alias(name, as){ 7324 assert[as] = assert[name]; 7325 return alias; 7326 }) 7327 ('isOk', 'ok') 7328 ('isNotOk', 'notOk') 7329 ('throws', 'throw') 7330 ('throws', 'Throw') 7331 ('isExtensible', 'extensible') 7332 ('isNotExtensible', 'notExtensible') 7333 ('isSealed', 'sealed') 7334 ('isNotSealed', 'notSealed') 7335 ('isFrozen', 'frozen') 7336 ('isNotFrozen', 'notFrozen') 7337 ('isEmpty', 'empty') 7338 ('isNotEmpty', 'notEmpty'); 7339 }; 7340 7341 },{}],7:[function(require,module,exports){ 7342 /*! 7343 * chai 7344 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> 7345 * MIT Licensed 7346 */ 7347 7348 module.exports = function (chai, util) { 7349 chai.expect = function (val, message) { 7350 return new chai.Assertion(val, message); 7351 }; 7352 7353 /** 7354 * ### .fail([message]) 7355 * ### .fail(actual, expected, [message], [operator]) 7356 * 7357 * Throw a failure. 7358 * 7359 * expect.fail(); 7360 * expect.fail("custom error message"); 7361 * expect.fail(1, 2); 7362 * expect.fail(1, 2, "custom error message"); 7363 * expect.fail(1, 2, "custom error message", ">"); 7364 * expect.fail(1, 2, undefined, ">"); 7365 * 7366 * @name fail 7367 * @param {Mixed} actual 7368 * @param {Mixed} expected 7369 * @param {String} message 7370 * @param {String} operator 7371 * @namespace BDD 7372 * @api public 7373 */ 7374 7375 chai.expect.fail = function (actual, expected, message, operator) { 7376 if (arguments.length < 2) { 7377 message = actual; 7378 actual = undefined; 7379 } 7380 7381 message = message || 'expect.fail()'; 7382 throw new chai.AssertionError(message, { 7383 actual: actual 7384 , expected: expected 7385 , operator: operator 7386 }, chai.expect.fail); 7387 }; 7388 }; 7389 7390 },{}],8:[function(require,module,exports){ 7391 /*! 7392 * chai 7393 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> 7394 * MIT Licensed 7395 */ 7396 7397 module.exports = function (chai, util) { 7398 var Assertion = chai.Assertion; 7399 7400 function loadShould () { 7401 // explicitly define this method as function as to have it's name to include as `ssfi` 7402 function shouldGetter() { 7403 if (this instanceof String 7404 || this instanceof Number 7405 || this instanceof Boolean 7406 || typeof Symbol === 'function' && this instanceof Symbol 7407 || typeof BigInt === 'function' && this instanceof BigInt) { 7408 return new Assertion(this.valueOf(), null, shouldGetter); 7409 } 7410 return new Assertion(this, null, shouldGetter); 7411 } 7412 function shouldSetter(value) { 7413 // See https://github.com/chaijs/chai/issues/86: this makes 7414 // `whatever.should = someValue` actually set `someValue`, which is 7415 // especially useful for `global.should = require('chai').should()`. 7416 // 7417 // Note that we have to use [[DefineProperty]] instead of [[Put]] 7418 // since otherwise we would trigger this very setter! 7419 Object.defineProperty(this, 'should', { 7420 value: value, 7421 enumerable: true, 7422 configurable: true, 7423 writable: true 7424 }); 7425 } 7426 // modify Object.prototype to have `should` 7427 Object.defineProperty(Object.prototype, 'should', { 7428 set: shouldSetter 7429 , get: shouldGetter 7430 , configurable: true 7431 }); 7432 7433 var should = {}; 7434 7435 /** 7436 * ### .fail([message]) 7437 * ### .fail(actual, expected, [message], [operator]) 7438 * 7439 * Throw a failure. 7440 * 7441 * should.fail(); 7442 * should.fail("custom error message"); 7443 * should.fail(1, 2); 7444 * should.fail(1, 2, "custom error message"); 7445 * should.fail(1, 2, "custom error message", ">"); 7446 * should.fail(1, 2, undefined, ">"); 7447 * 7448 * 7449 * @name fail 7450 * @param {Mixed} actual 7451 * @param {Mixed} expected 7452 * @param {String} message 7453 * @param {String} operator 7454 * @namespace BDD 7455 * @api public 7456 */ 7457 7458 should.fail = function (actual, expected, message, operator) { 7459 if (arguments.length < 2) { 7460 message = actual; 7461 actual = undefined; 7462 } 7463 7464 message = message || 'should.fail()'; 7465 throw new chai.AssertionError(message, { 7466 actual: actual 7467 , expected: expected 7468 , operator: operator 7469 }, should.fail); 7470 }; 7471 7472 /** 7473 * ### .equal(actual, expected, [message]) 7474 * 7475 * Asserts non-strict equality (`==`) of `actual` and `expected`. 7476 * 7477 * should.equal(3, '3', '== coerces values to strings'); 7478 * 7479 * @name equal 7480 * @param {Mixed} actual 7481 * @param {Mixed} expected 7482 * @param {String} message 7483 * @namespace Should 7484 * @api public 7485 */ 7486 7487 should.equal = function (val1, val2, msg) { 7488 new Assertion(val1, msg).to.equal(val2); 7489 }; 7490 7491 /** 7492 * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) 7493 * 7494 * Asserts that `function` will throw an error that is an instance of 7495 * `constructor`, or alternately that it will throw an error with message 7496 * matching `regexp`. 7497 * 7498 * should.throw(fn, 'function throws a reference error'); 7499 * should.throw(fn, /function throws a reference error/); 7500 * should.throw(fn, ReferenceError); 7501 * should.throw(fn, ReferenceError, 'function throws a reference error'); 7502 * should.throw(fn, ReferenceError, /function throws a reference error/); 7503 * 7504 * @name throw 7505 * @alias Throw 7506 * @param {Function} function 7507 * @param {ErrorConstructor} constructor 7508 * @param {RegExp} regexp 7509 * @param {String} message 7510 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types 7511 * @namespace Should 7512 * @api public 7513 */ 7514 7515 should.Throw = function (fn, errt, errs, msg) { 7516 new Assertion(fn, msg).to.Throw(errt, errs); 7517 }; 7518 7519 /** 7520 * ### .exist 7521 * 7522 * Asserts that the target is neither `null` nor `undefined`. 7523 * 7524 * var foo = 'hi'; 7525 * 7526 * should.exist(foo, 'foo exists'); 7527 * 7528 * @name exist 7529 * @namespace Should 7530 * @api public 7531 */ 7532 7533 should.exist = function (val, msg) { 7534 new Assertion(val, msg).to.exist; 7535 } 7536 7537 // negation 7538 should.not = {} 7539 7540 /** 7541 * ### .not.equal(actual, expected, [message]) 7542 * 7543 * Asserts non-strict inequality (`!=`) of `actual` and `expected`. 7544 * 7545 * should.not.equal(3, 4, 'these numbers are not equal'); 7546 * 7547 * @name not.equal 7548 * @param {Mixed} actual 7549 * @param {Mixed} expected 7550 * @param {String} message 7551 * @namespace Should 7552 * @api public 7553 */ 7554 7555 should.not.equal = function (val1, val2, msg) { 7556 new Assertion(val1, msg).to.not.equal(val2); 7557 }; 7558 7559 /** 7560 * ### .throw(function, [constructor/regexp], [message]) 7561 * 7562 * Asserts that `function` will _not_ throw an error that is an instance of 7563 * `constructor`, or alternately that it will not throw an error with message 7564 * matching `regexp`. 7565 * 7566 * should.not.throw(fn, Error, 'function does not throw'); 7567 * 7568 * @name not.throw 7569 * @alias not.Throw 7570 * @param {Function} function 7571 * @param {ErrorConstructor} constructor 7572 * @param {RegExp} regexp 7573 * @param {String} message 7574 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types 7575 * @namespace Should 7576 * @api public 7577 */ 7578 7579 should.not.Throw = function (fn, errt, errs, msg) { 7580 new Assertion(fn, msg).to.not.Throw(errt, errs); 7581 }; 7582 7583 /** 7584 * ### .not.exist 7585 * 7586 * Asserts that the target is neither `null` nor `undefined`. 7587 * 7588 * var bar = null; 7589 * 7590 * should.not.exist(bar, 'bar does not exist'); 7591 * 7592 * @name not.exist 7593 * @namespace Should 7594 * @api public 7595 */ 7596 7597 should.not.exist = function (val, msg) { 7598 new Assertion(val, msg).to.not.exist; 7599 } 7600 7601 should['throw'] = should['Throw']; 7602 should.not['throw'] = should.not['Throw']; 7603 7604 return should; 7605 }; 7606 7607 chai.should = loadShould; 7608 chai.Should = loadShould; 7609 }; 7610 7611 },{}],9:[function(require,module,exports){ 7612 /*! 7613 * Chai - addChainingMethod utility 7614 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 7615 * MIT Licensed 7616 */ 7617 7618 /*! 7619 * Module dependencies 7620 */ 7621 7622 var addLengthGuard = require('./addLengthGuard'); 7623 var chai = require('../../chai'); 7624 var flag = require('./flag'); 7625 var proxify = require('./proxify'); 7626 var transferFlags = require('./transferFlags'); 7627 7628 /*! 7629 * Module variables 7630 */ 7631 7632 // Check whether `Object.setPrototypeOf` is supported 7633 var canSetPrototype = typeof Object.setPrototypeOf === 'function'; 7634 7635 // Without `Object.setPrototypeOf` support, this module will need to add properties to a function. 7636 // However, some of functions' own props are not configurable and should be skipped. 7637 var testFn = function() {}; 7638 var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) { 7639 var propDesc = Object.getOwnPropertyDescriptor(testFn, name); 7640 7641 // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties, 7642 // but then returns `undefined` as the property descriptor for `callee`. As a 7643 // workaround, we perform an otherwise unnecessary type-check for `propDesc`, 7644 // and then filter it out if it's not an object as it should be. 7645 if (typeof propDesc !== 'object') 7646 return true; 7647 7648 return !propDesc.configurable; 7649 }); 7650 7651 // Cache `Function` properties 7652 var call = Function.prototype.call, 7653 apply = Function.prototype.apply; 7654 7655 /** 7656 * ### .addChainableMethod(ctx, name, method, chainingBehavior) 7657 * 7658 * Adds a method to an object, such that the method can also be chained. 7659 * 7660 * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { 7661 * var obj = utils.flag(this, 'object'); 7662 * new chai.Assertion(obj).to.be.equal(str); 7663 * }); 7664 * 7665 * Can also be accessed directly from `chai.Assertion`. 7666 * 7667 * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); 7668 * 7669 * The result can then be used as both a method assertion, executing both `method` and 7670 * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. 7671 * 7672 * expect(fooStr).to.be.foo('bar'); 7673 * expect(fooStr).to.be.foo.equal('foo'); 7674 * 7675 * @param {Object} ctx object to which the method is added 7676 * @param {String} name of method to add 7677 * @param {Function} method function to be used for `name`, when called 7678 * @param {Function} chainingBehavior function to be called every time the property is accessed 7679 * @namespace Utils 7680 * @name addChainableMethod 7681 * @api public 7682 */ 7683 7684 module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) { 7685 if (typeof chainingBehavior !== 'function') { 7686 chainingBehavior = function () { }; 7687 } 7688 7689 var chainableBehavior = { 7690 method: method 7691 , chainingBehavior: chainingBehavior 7692 }; 7693 7694 // save the methods so we can overwrite them later, if we need to. 7695 if (!ctx.__methods) { 7696 ctx.__methods = {}; 7697 } 7698 ctx.__methods[name] = chainableBehavior; 7699 7700 Object.defineProperty(ctx, name, 7701 { get: function chainableMethodGetter() { 7702 chainableBehavior.chainingBehavior.call(this); 7703 7704 var chainableMethodWrapper = function () { 7705 // Setting the `ssfi` flag to `chainableMethodWrapper` causes this 7706 // function to be the starting point for removing implementation 7707 // frames from the stack trace of a failed assertion. 7708 // 7709 // However, we only want to use this function as the starting point if 7710 // the `lockSsfi` flag isn't set. 7711 // 7712 // If the `lockSsfi` flag is set, then this assertion is being 7713 // invoked from inside of another assertion. In this case, the `ssfi` 7714 // flag has already been set by the outer assertion. 7715 // 7716 // Note that overwriting a chainable method merely replaces the saved 7717 // methods in `ctx.__methods` instead of completely replacing the 7718 // overwritten assertion. Therefore, an overwriting assertion won't 7719 // set the `ssfi` or `lockSsfi` flags. 7720 if (!flag(this, 'lockSsfi')) { 7721 flag(this, 'ssfi', chainableMethodWrapper); 7722 } 7723 7724 var result = chainableBehavior.method.apply(this, arguments); 7725 if (result !== undefined) { 7726 return result; 7727 } 7728 7729 var newAssertion = new chai.Assertion(); 7730 transferFlags(this, newAssertion); 7731 return newAssertion; 7732 }; 7733 7734 addLengthGuard(chainableMethodWrapper, name, true); 7735 7736 // Use `Object.setPrototypeOf` if available 7737 if (canSetPrototype) { 7738 // Inherit all properties from the object by replacing the `Function` prototype 7739 var prototype = Object.create(this); 7740 // Restore the `call` and `apply` methods from `Function` 7741 prototype.call = call; 7742 prototype.apply = apply; 7743 Object.setPrototypeOf(chainableMethodWrapper, prototype); 7744 } 7745 // Otherwise, redefine all properties (slow!) 7746 else { 7747 var asserterNames = Object.getOwnPropertyNames(ctx); 7748 asserterNames.forEach(function (asserterName) { 7749 if (excludeNames.indexOf(asserterName) !== -1) { 7750 return; 7751 } 7752 7753 var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); 7754 Object.defineProperty(chainableMethodWrapper, asserterName, pd); 7755 }); 7756 } 7757 7758 transferFlags(this, chainableMethodWrapper); 7759 return proxify(chainableMethodWrapper); 7760 } 7761 , configurable: true 7762 }); 7763 }; 7764 7765 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":31,"./transferFlags":33}],10:[function(require,module,exports){ 7766 var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); 7767 7768 /*! 7769 * Chai - addLengthGuard utility 7770 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 7771 * MIT Licensed 7772 */ 7773 7774 /** 7775 * ### .addLengthGuard(fn, assertionName, isChainable) 7776 * 7777 * Define `length` as a getter on the given uninvoked method assertion. The 7778 * getter acts as a guard against chaining `length` directly off of an uninvoked 7779 * method assertion, which is a problem because it references `function`'s 7780 * built-in `length` property instead of Chai's `length` assertion. When the 7781 * getter catches the user making this mistake, it throws an error with a 7782 * helpful message. 7783 * 7784 * There are two ways in which this mistake can be made. The first way is by 7785 * chaining the `length` assertion directly off of an uninvoked chainable 7786 * method. In this case, Chai suggests that the user use `lengthOf` instead. The 7787 * second way is by chaining the `length` assertion directly off of an uninvoked 7788 * non-chainable method. Non-chainable methods must be invoked prior to 7789 * chaining. In this case, Chai suggests that the user consult the docs for the 7790 * given assertion. 7791 * 7792 * If the `length` property of functions is unconfigurable, then return `fn` 7793 * without modification. 7794 * 7795 * Note that in ES6, the function's `length` property is configurable, so once 7796 * support for legacy environments is dropped, Chai's `length` property can 7797 * replace the built-in function's `length` property, and this length guard will 7798 * no longer be necessary. In the mean time, maintaining consistency across all 7799 * environments is the priority. 7800 * 7801 * @param {Function} fn 7802 * @param {String} assertionName 7803 * @param {Boolean} isChainable 7804 * @namespace Utils 7805 * @name addLengthGuard 7806 */ 7807 7808 module.exports = function addLengthGuard (fn, assertionName, isChainable) { 7809 if (!fnLengthDesc.configurable) return fn; 7810 7811 Object.defineProperty(fn, 'length', { 7812 get: function () { 7813 if (isChainable) { 7814 throw Error('Invalid Chai property: ' + assertionName + '.length. Due' + 7815 ' to a compatibility issue, "length" cannot directly follow "' + 7816 assertionName + '". Use "' + assertionName + '.lengthOf" instead.'); 7817 } 7818 7819 throw Error('Invalid Chai property: ' + assertionName + '.length. See' + 7820 ' docs for proper usage of "' + assertionName + '".'); 7821 } 7822 }); 7823 7824 return fn; 7825 }; 7826 7827 },{}],11:[function(require,module,exports){ 7828 /*! 7829 * Chai - addMethod utility 7830 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 7831 * MIT Licensed 7832 */ 7833 7834 var addLengthGuard = require('./addLengthGuard'); 7835 var chai = require('../../chai'); 7836 var flag = require('./flag'); 7837 var proxify = require('./proxify'); 7838 var transferFlags = require('./transferFlags'); 7839 7840 /** 7841 * ### .addMethod(ctx, name, method) 7842 * 7843 * Adds a method to the prototype of an object. 7844 * 7845 * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { 7846 * var obj = utils.flag(this, 'object'); 7847 * new chai.Assertion(obj).to.be.equal(str); 7848 * }); 7849 * 7850 * Can also be accessed directly from `chai.Assertion`. 7851 * 7852 * chai.Assertion.addMethod('foo', fn); 7853 * 7854 * Then can be used as any other assertion. 7855 * 7856 * expect(fooStr).to.be.foo('bar'); 7857 * 7858 * @param {Object} ctx object to which the method is added 7859 * @param {String} name of method to add 7860 * @param {Function} method function to be used for name 7861 * @namespace Utils 7862 * @name addMethod 7863 * @api public 7864 */ 7865 7866 module.exports = function addMethod(ctx, name, method) { 7867 var methodWrapper = function () { 7868 // Setting the `ssfi` flag to `methodWrapper` causes this function to be the 7869 // starting point for removing implementation frames from the stack trace of 7870 // a failed assertion. 7871 // 7872 // However, we only want to use this function as the starting point if the 7873 // `lockSsfi` flag isn't set. 7874 // 7875 // If the `lockSsfi` flag is set, then either this assertion has been 7876 // overwritten by another assertion, or this assertion is being invoked from 7877 // inside of another assertion. In the first case, the `ssfi` flag has 7878 // already been set by the overwriting assertion. In the second case, the 7879 // `ssfi` flag has already been set by the outer assertion. 7880 if (!flag(this, 'lockSsfi')) { 7881 flag(this, 'ssfi', methodWrapper); 7882 } 7883 7884 var result = method.apply(this, arguments); 7885 if (result !== undefined) 7886 return result; 7887 7888 var newAssertion = new chai.Assertion(); 7889 transferFlags(this, newAssertion); 7890 return newAssertion; 7891 }; 7892 7893 addLengthGuard(methodWrapper, name, false); 7894 ctx[name] = proxify(methodWrapper, name); 7895 }; 7896 7897 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":31,"./transferFlags":33}],12:[function(require,module,exports){ 7898 /*! 7899 * Chai - addProperty utility 7900 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 7901 * MIT Licensed 7902 */ 7903 7904 var chai = require('../../chai'); 7905 var flag = require('./flag'); 7906 var isProxyEnabled = require('./isProxyEnabled'); 7907 var transferFlags = require('./transferFlags'); 7908 7909 /** 7910 * ### .addProperty(ctx, name, getter) 7911 * 7912 * Adds a property to the prototype of an object. 7913 * 7914 * utils.addProperty(chai.Assertion.prototype, 'foo', function () { 7915 * var obj = utils.flag(this, 'object'); 7916 * new chai.Assertion(obj).to.be.instanceof(Foo); 7917 * }); 7918 * 7919 * Can also be accessed directly from `chai.Assertion`. 7920 * 7921 * chai.Assertion.addProperty('foo', fn); 7922 * 7923 * Then can be used as any other assertion. 7924 * 7925 * expect(myFoo).to.be.foo; 7926 * 7927 * @param {Object} ctx object to which the property is added 7928 * @param {String} name of property to add 7929 * @param {Function} getter function to be used for name 7930 * @namespace Utils 7931 * @name addProperty 7932 * @api public 7933 */ 7934 7935 module.exports = function addProperty(ctx, name, getter) { 7936 getter = getter === undefined ? function () {} : getter; 7937 7938 Object.defineProperty(ctx, name, 7939 { get: function propertyGetter() { 7940 // Setting the `ssfi` flag to `propertyGetter` causes this function to 7941 // be the starting point for removing implementation frames from the 7942 // stack trace of a failed assertion. 7943 // 7944 // However, we only want to use this function as the starting point if 7945 // the `lockSsfi` flag isn't set and proxy protection is disabled. 7946 // 7947 // If the `lockSsfi` flag is set, then either this assertion has been 7948 // overwritten by another assertion, or this assertion is being invoked 7949 // from inside of another assertion. In the first case, the `ssfi` flag 7950 // has already been set by the overwriting assertion. In the second 7951 // case, the `ssfi` flag has already been set by the outer assertion. 7952 // 7953 // If proxy protection is enabled, then the `ssfi` flag has already been 7954 // set by the proxy getter. 7955 if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { 7956 flag(this, 'ssfi', propertyGetter); 7957 } 7958 7959 var result = getter.call(this); 7960 if (result !== undefined) 7961 return result; 7962 7963 var newAssertion = new chai.Assertion(); 7964 transferFlags(this, newAssertion); 7965 return newAssertion; 7966 } 7967 , configurable: true 7968 }); 7969 }; 7970 7971 },{"../../chai":2,"./flag":15,"./isProxyEnabled":26,"./transferFlags":33}],13:[function(require,module,exports){ 7972 /*! 7973 * Chai - compareByInspect utility 7974 * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> 7975 * MIT Licensed 7976 */ 7977 7978 /*! 7979 * Module dependencies 7980 */ 7981 7982 var inspect = require('./inspect'); 7983 7984 /** 7985 * ### .compareByInspect(mixed, mixed) 7986 * 7987 * To be used as a compareFunction with Array.prototype.sort. Compares elements 7988 * using inspect instead of default behavior of using toString so that Symbols 7989 * and objects with irregular/missing toString can still be sorted without a 7990 * TypeError. 7991 * 7992 * @param {Mixed} first element to compare 7993 * @param {Mixed} second element to compare 7994 * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1 7995 * @name compareByInspect 7996 * @namespace Utils 7997 * @api public 7998 */ 7999 8000 module.exports = function compareByInspect(a, b) { 8001 return inspect(a) < inspect(b) ? -1 : 1; 8002 }; 8003 8004 },{"./inspect":24}],14:[function(require,module,exports){ 8005 /*! 8006 * Chai - expectTypes utility 8007 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 8008 * MIT Licensed 8009 */ 8010 8011 /** 8012 * ### .expectTypes(obj, types) 8013 * 8014 * Ensures that the object being tested against is of a valid type. 8015 * 8016 * utils.expectTypes(this, ['array', 'object', 'string']); 8017 * 8018 * @param {Mixed} obj constructed Assertion 8019 * @param {Array} type A list of allowed types for this assertion 8020 * @namespace Utils 8021 * @name expectTypes 8022 * @api public 8023 */ 8024 8025 var AssertionError = require('assertion-error'); 8026 var flag = require('./flag'); 8027 var type = require('type-detect'); 8028 8029 module.exports = function expectTypes(obj, types) { 8030 var flagMsg = flag(obj, 'message'); 8031 var ssfi = flag(obj, 'ssfi'); 8032 8033 flagMsg = flagMsg ? flagMsg + ': ' : ''; 8034 8035 obj = flag(obj, 'object'); 8036 types = types.map(function (t) { return t.toLowerCase(); }); 8037 types.sort(); 8038 8039 // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum' 8040 var str = types.map(function (t, index) { 8041 var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; 8042 var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; 8043 return or + art + ' ' + t; 8044 }).join(', '); 8045 8046 var objType = type(obj).toLowerCase(); 8047 8048 if (!types.some(function (expected) { return objType === expected; })) { 8049 throw new AssertionError( 8050 flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given', 8051 undefined, 8052 ssfi 8053 ); 8054 } 8055 }; 8056 8057 },{"./flag":15,"assertion-error":34,"type-detect":39}],15:[function(require,module,exports){ 8058 /*! 8059 * Chai - flag utility 8060 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 8061 * MIT Licensed 8062 */ 8063 8064 /** 8065 * ### .flag(object, key, [value]) 8066 * 8067 * Get or set a flag value on an object. If a 8068 * value is provided it will be set, else it will 8069 * return the currently set value or `undefined` if 8070 * the value is not set. 8071 * 8072 * utils.flag(this, 'foo', 'bar'); // setter 8073 * utils.flag(this, 'foo'); // getter, returns `bar` 8074 * 8075 * @param {Object} object constructed Assertion 8076 * @param {String} key 8077 * @param {Mixed} value (optional) 8078 * @namespace Utils 8079 * @name flag 8080 * @api private 8081 */ 8082 8083 module.exports = function flag(obj, key, value) { 8084 var flags = obj.__flags || (obj.__flags = Object.create(null)); 8085 if (arguments.length === 3) { 8086 flags[key] = value; 8087 } else { 8088 return flags[key]; 8089 } 8090 }; 8091 8092 },{}],16:[function(require,module,exports){ 8093 /*! 8094 * Chai - getActual utility 8095 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 8096 * MIT Licensed 8097 */ 8098 8099 /** 8100 * ### .getActual(object, [actual]) 8101 * 8102 * Returns the `actual` value for an Assertion. 8103 * 8104 * @param {Object} object (constructed Assertion) 8105 * @param {Arguments} chai.Assertion.prototype.assert arguments 8106 * @namespace Utils 8107 * @name getActual 8108 */ 8109 8110 module.exports = function getActual(obj, args) { 8111 return args.length > 4 ? args[4] : obj._obj; 8112 }; 8113 8114 },{}],17:[function(require,module,exports){ 8115 /*! 8116 * Chai - getEnumerableProperties utility 8117 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 8118 * MIT Licensed 8119 */ 8120 8121 /** 8122 * ### .getEnumerableProperties(object) 8123 * 8124 * This allows the retrieval of enumerable property names of an object, 8125 * inherited or not. 8126 * 8127 * @param {Object} object 8128 * @returns {Array} 8129 * @namespace Utils 8130 * @name getEnumerableProperties 8131 * @api public 8132 */ 8133 8134 module.exports = function getEnumerableProperties(object) { 8135 var result = []; 8136 for (var name in object) { 8137 result.push(name); 8138 } 8139 return result; 8140 }; 8141 8142 },{}],18:[function(require,module,exports){ 8143 /*! 8144 * Chai - message composition utility 8145 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 8146 * MIT Licensed 8147 */ 8148 8149 /*! 8150 * Module dependencies 8151 */ 8152 8153 var flag = require('./flag') 8154 , getActual = require('./getActual') 8155 , objDisplay = require('./objDisplay'); 8156 8157 /** 8158 * ### .getMessage(object, message, negateMessage) 8159 * 8160 * Construct the error message based on flags 8161 * and template tags. Template tags will return 8162 * a stringified inspection of the object referenced. 8163 * 8164 * Message template tags: 8165 * - `#{this}` current asserted object 8166 * - `#{act}` actual value 8167 * - `#{exp}` expected value 8168 * 8169 * @param {Object} object (constructed Assertion) 8170 * @param {Arguments} chai.Assertion.prototype.assert arguments 8171 * @namespace Utils 8172 * @name getMessage 8173 * @api public 8174 */ 8175 8176 module.exports = function getMessage(obj, args) { 8177 var negate = flag(obj, 'negate') 8178 , val = flag(obj, 'object') 8179 , expected = args[3] 8180 , actual = getActual(obj, args) 8181 , msg = negate ? args[2] : args[1] 8182 , flagMsg = flag(obj, 'message'); 8183 8184 if(typeof msg === "function") msg = msg(); 8185 msg = msg || ''; 8186 msg = msg 8187 .replace(/#\{this\}/g, function () { return objDisplay(val); }) 8188 .replace(/#\{act\}/g, function () { return objDisplay(actual); }) 8189 .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); 8190 8191 return flagMsg ? flagMsg + ': ' + msg : msg; 8192 }; 8193 8194 },{"./flag":15,"./getActual":16,"./objDisplay":27}],19:[function(require,module,exports){ 8195 var type = require('type-detect'); 8196 8197 var flag = require('./flag'); 8198 8199 function isObjectType(obj) { 8200 var objectType = type(obj); 8201 var objectTypes = ['Array', 'Object', 'function']; 8202 8203 return objectTypes.indexOf(objectType) !== -1; 8204 } 8205 8206 /** 8207 * ### .getOperator(message) 8208 * 8209 * Extract the operator from error message. 8210 * Operator defined is based on below link 8211 * https://nodejs.org/api/assert.html#assert_assert. 8212 * 8213 * Returns the `operator` or `undefined` value for an Assertion. 8214 * 8215 * @param {Object} object (constructed Assertion) 8216 * @param {Arguments} chai.Assertion.prototype.assert arguments 8217 * @namespace Utils 8218 * @name getOperator 8219 * @api public 8220 */ 8221 8222 module.exports = function getOperator(obj, args) { 8223 var operator = flag(obj, 'operator'); 8224 var negate = flag(obj, 'negate'); 8225 var expected = args[3]; 8226 var msg = negate ? args[2] : args[1]; 8227 8228 if (operator) { 8229 return operator; 8230 } 8231 8232 if (typeof msg === 'function') msg = msg(); 8233 8234 msg = msg || ''; 8235 if (!msg) { 8236 return undefined; 8237 } 8238 8239 if (/\shave\s/.test(msg)) { 8240 return undefined; 8241 } 8242 8243 var isObject = isObjectType(expected); 8244 if (/\snot\s/.test(msg)) { 8245 return isObject ? 'notDeepStrictEqual' : 'notStrictEqual'; 8246 } 8247 8248 return isObject ? 'deepStrictEqual' : 'strictEqual'; 8249 }; 8250 8251 },{"./flag":15,"type-detect":39}],20:[function(require,module,exports){ 8252 /*! 8253 * Chai - getOwnEnumerableProperties utility 8254 * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> 8255 * MIT Licensed 8256 */ 8257 8258 /*! 8259 * Module dependencies 8260 */ 8261 8262 var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); 8263 8264 /** 8265 * ### .getOwnEnumerableProperties(object) 8266 * 8267 * This allows the retrieval of directly-owned enumerable property names and 8268 * symbols of an object. This function is necessary because Object.keys only 8269 * returns enumerable property names, not enumerable property symbols. 8270 * 8271 * @param {Object} object 8272 * @returns {Array} 8273 * @namespace Utils 8274 * @name getOwnEnumerableProperties 8275 * @api public 8276 */ 8277 8278 module.exports = function getOwnEnumerableProperties(obj) { 8279 return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); 8280 }; 8281 8282 },{"./getOwnEnumerablePropertySymbols":21}],21:[function(require,module,exports){ 8283 /*! 8284 * Chai - getOwnEnumerablePropertySymbols utility 8285 * Copyright(c) 2011-2016 Jake Luer <jake@alogicalparadox.com> 8286 * MIT Licensed 8287 */ 8288 8289 /** 8290 * ### .getOwnEnumerablePropertySymbols(object) 8291 * 8292 * This allows the retrieval of directly-owned enumerable property symbols of an 8293 * object. This function is necessary because Object.getOwnPropertySymbols 8294 * returns both enumerable and non-enumerable property symbols. 8295 * 8296 * @param {Object} object 8297 * @returns {Array} 8298 * @namespace Utils 8299 * @name getOwnEnumerablePropertySymbols 8300 * @api public 8301 */ 8302 8303 module.exports = function getOwnEnumerablePropertySymbols(obj) { 8304 if (typeof Object.getOwnPropertySymbols !== 'function') return []; 8305 8306 return Object.getOwnPropertySymbols(obj).filter(function (sym) { 8307 return Object.getOwnPropertyDescriptor(obj, sym).enumerable; 8308 }); 8309 }; 8310 8311 },{}],22:[function(require,module,exports){ 8312 /*! 8313 * Chai - getProperties utility 8314 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 8315 * MIT Licensed 8316 */ 8317 8318 /** 8319 * ### .getProperties(object) 8320 * 8321 * This allows the retrieval of property names of an object, enumerable or not, 8322 * inherited or not. 8323 * 8324 * @param {Object} object 8325 * @returns {Array} 8326 * @namespace Utils 8327 * @name getProperties 8328 * @api public 8329 */ 8330 8331 module.exports = function getProperties(object) { 8332 var result = Object.getOwnPropertyNames(object); 8333 8334 function addProperty(property) { 8335 if (result.indexOf(property) === -1) { 8336 result.push(property); 8337 } 8338 } 8339 8340 var proto = Object.getPrototypeOf(object); 8341 while (proto !== null) { 8342 Object.getOwnPropertyNames(proto).forEach(addProperty); 8343 proto = Object.getPrototypeOf(proto); 8344 } 8345 8346 return result; 8347 }; 8348 8349 },{}],23:[function(require,module,exports){ 8350 /*! 8351 * chai 8352 * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> 8353 * MIT Licensed 8354 */ 8355 8356 /*! 8357 * Dependencies that are used for multiple exports are required here only once 8358 */ 8359 8360 var pathval = require('pathval'); 8361 8362 /*! 8363 * test utility 8364 */ 8365 8366 exports.test = require('./test'); 8367 8368 /*! 8369 * type utility 8370 */ 8371 8372 exports.type = require('type-detect'); 8373 8374 /*! 8375 * expectTypes utility 8376 */ 8377 exports.expectTypes = require('./expectTypes'); 8378 8379 /*! 8380 * message utility 8381 */ 8382 8383 exports.getMessage = require('./getMessage'); 8384 8385 /*! 8386 * actual utility 8387 */ 8388 8389 exports.getActual = require('./getActual'); 8390 8391 /*! 8392 * Inspect util 8393 */ 8394 8395 exports.inspect = require('./inspect'); 8396 8397 /*! 8398 * Object Display util 8399 */ 8400 8401 exports.objDisplay = require('./objDisplay'); 8402 8403 /*! 8404 * Flag utility 8405 */ 8406 8407 exports.flag = require('./flag'); 8408 8409 /*! 8410 * Flag transferring utility 8411 */ 8412 8413 exports.transferFlags = require('./transferFlags'); 8414 8415 /*! 8416 * Deep equal utility 8417 */ 8418 8419 exports.eql = require('deep-eql'); 8420 8421 /*! 8422 * Deep path info 8423 */ 8424 8425 exports.getPathInfo = pathval.getPathInfo; 8426 8427 /*! 8428 * Check if a property exists 8429 */ 8430 8431 exports.hasProperty = pathval.hasProperty; 8432 8433 /*! 8434 * Function name 8435 */ 8436 8437 exports.getName = require('get-func-name'); 8438 8439 /*! 8440 * add Property 8441 */ 8442 8443 exports.addProperty = require('./addProperty'); 8444 8445 /*! 8446 * add Method 8447 */ 8448 8449 exports.addMethod = require('./addMethod'); 8450 8451 /*! 8452 * overwrite Property 8453 */ 8454 8455 exports.overwriteProperty = require('./overwriteProperty'); 8456 8457 /*! 8458 * overwrite Method 8459 */ 8460 8461 exports.overwriteMethod = require('./overwriteMethod'); 8462 8463 /*! 8464 * Add a chainable method 8465 */ 8466 8467 exports.addChainableMethod = require('./addChainableMethod'); 8468 8469 /*! 8470 * Overwrite chainable method 8471 */ 8472 8473 exports.overwriteChainableMethod = require('./overwriteChainableMethod'); 8474 8475 /*! 8476 * Compare by inspect method 8477 */ 8478 8479 exports.compareByInspect = require('./compareByInspect'); 8480 8481 /*! 8482 * Get own enumerable property symbols method 8483 */ 8484 8485 exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); 8486 8487 /*! 8488 * Get own enumerable properties method 8489 */ 8490 8491 exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties'); 8492 8493 /*! 8494 * Checks error against a given set of criteria 8495 */ 8496 8497 exports.checkError = require('check-error'); 8498 8499 /*! 8500 * Proxify util 8501 */ 8502 8503 exports.proxify = require('./proxify'); 8504 8505 /*! 8506 * addLengthGuard util 8507 */ 8508 8509 exports.addLengthGuard = require('./addLengthGuard'); 8510 8511 /*! 8512 * isProxyEnabled helper 8513 */ 8514 8515 exports.isProxyEnabled = require('./isProxyEnabled'); 8516 8517 /*! 8518 * isNaN method 8519 */ 8520 8521 exports.isNaN = require('./isNaN'); 8522 8523 /*! 8524 * getOperator method 8525 */ 8526 8527 exports.getOperator = require('./getOperator'); 8528 },{"./addChainableMethod":9,"./addLengthGuard":10,"./addMethod":11,"./addProperty":12,"./compareByInspect":13,"./expectTypes":14,"./flag":15,"./getActual":16,"./getMessage":18,"./getOperator":19,"./getOwnEnumerableProperties":20,"./getOwnEnumerablePropertySymbols":21,"./inspect":24,"./isNaN":25,"./isProxyEnabled":26,"./objDisplay":27,"./overwriteChainableMethod":28,"./overwriteMethod":29,"./overwriteProperty":30,"./proxify":31,"./test":32,"./transferFlags":33,"check-error":35,"deep-eql":36,"get-func-name":37,"pathval":38,"type-detect":39}],24:[function(require,module,exports){ 8529 // This is (almost) directly from Node.js utils 8530 // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js 8531 8532 var getName = require('get-func-name'); 8533 var getProperties = require('./getProperties'); 8534 var getEnumerableProperties = require('./getEnumerableProperties'); 8535 var config = require('../config'); 8536 8537 module.exports = inspect; 8538 8539 /** 8540 * ### .inspect(obj, [showHidden], [depth], [colors]) 8541 * 8542 * Echoes the value of a value. Tries to print the value out 8543 * in the best way possible given the different types. 8544 * 8545 * @param {Object} obj The object to print out. 8546 * @param {Boolean} showHidden Flag that shows hidden (not enumerable) 8547 * properties of objects. Default is false. 8548 * @param {Number} depth Depth in which to descend in object. Default is 2. 8549 * @param {Boolean} colors Flag to turn on ANSI escape codes to color the 8550 * output. Default is false (no coloring). 8551 * @namespace Utils 8552 * @name inspect 8553 */ 8554 function inspect(obj, showHidden, depth, colors) { 8555 var ctx = { 8556 showHidden: showHidden, 8557 seen: [], 8558 stylize: function (str) { return str; } 8559 }; 8560 return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); 8561 } 8562 8563 // Returns true if object is a DOM element. 8564 var isDOMElement = function (object) { 8565 if (typeof HTMLElement === 'object') { 8566 return object instanceof HTMLElement; 8567 } else { 8568 return object && 8569 typeof object === 'object' && 8570 'nodeType' in object && 8571 object.nodeType === 1 && 8572 typeof object.nodeName === 'string'; 8573 } 8574 }; 8575 8576 function formatValue(ctx, value, recurseTimes) { 8577 // Provide a hook for user-specified inspect functions. 8578 // Check that value is an object with an inspect function on it 8579 if (value && typeof value.inspect === 'function' && 8580 // Filter out the util module, it's inspect function is special 8581 value.inspect !== exports.inspect && 8582 // Also filter out any prototype objects using the circular check. 8583 !(value.constructor && value.constructor.prototype === value)) { 8584 var ret = value.inspect(recurseTimes, ctx); 8585 if (typeof ret !== 'string') { 8586 ret = formatValue(ctx, ret, recurseTimes); 8587 } 8588 return ret; 8589 } 8590 8591 // Primitive types cannot have properties 8592 var primitive = formatPrimitive(ctx, value); 8593 if (primitive) { 8594 return primitive; 8595 } 8596 8597 // If this is a DOM element, try to get the outer HTML. 8598 if (isDOMElement(value)) { 8599 if ('outerHTML' in value) { 8600 return value.outerHTML; 8601 // This value does not have an outerHTML attribute, 8602 // it could still be an XML element 8603 } else { 8604 // Attempt to serialize it 8605 try { 8606 if (document.xmlVersion) { 8607 var xmlSerializer = new XMLSerializer(); 8608 return xmlSerializer.serializeToString(value); 8609 } else { 8610 // Firefox 11- do not support outerHTML 8611 // It does, however, support innerHTML 8612 // Use the following to render the element 8613 var ns = "http://www.w3.org/1999/xhtml"; 8614 var container = document.createElementNS(ns, '_'); 8615 8616 container.appendChild(value.cloneNode(false)); 8617 var html = container.innerHTML 8618 .replace('><', '>' + value.innerHTML + '<'); 8619 container.innerHTML = ''; 8620 return html; 8621 } 8622 } catch (err) { 8623 // This could be a non-native DOM implementation, 8624 // continue with the normal flow: 8625 // printing the element as if it is an object. 8626 } 8627 } 8628 } 8629 8630 // Look up the keys of the object. 8631 var visibleKeys = getEnumerableProperties(value); 8632 var keys = ctx.showHidden ? getProperties(value) : visibleKeys; 8633 8634 var name, nameSuffix; 8635 8636 // Some type of object without properties can be shortcut. 8637 // In IE, errors have a single `stack` property, or if they are vanilla `Error`, 8638 // a `stack` plus `description` property; ignore those for consistency. 8639 if (keys.length === 0 || (isError(value) && ( 8640 (keys.length === 1 && keys[0] === 'stack') || 8641 (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') 8642 ))) { 8643 if (typeof value === 'function') { 8644 name = getName(value); 8645 nameSuffix = name ? ': ' + name : ''; 8646 return ctx.stylize('[Function' + nameSuffix + ']', 'special'); 8647 } 8648 if (isRegExp(value)) { 8649 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); 8650 } 8651 if (isDate(value)) { 8652 return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); 8653 } 8654 if (isError(value)) { 8655 return formatError(value); 8656 } 8657 } 8658 8659 var base = '' 8660 , array = false 8661 , typedArray = false 8662 , braces = ['{', '}']; 8663 8664 if (isTypedArray(value)) { 8665 typedArray = true; 8666 braces = ['[', ']']; 8667 } 8668 8669 // Make Array say that they are Array 8670 if (isArray(value)) { 8671 array = true; 8672 braces = ['[', ']']; 8673 } 8674 8675 // Make functions say that they are functions 8676 if (typeof value === 'function') { 8677 name = getName(value); 8678 nameSuffix = name ? ': ' + name : ''; 8679 base = ' [Function' + nameSuffix + ']'; 8680 } 8681 8682 // Make RegExps say that they are RegExps 8683 if (isRegExp(value)) { 8684 base = ' ' + RegExp.prototype.toString.call(value); 8685 } 8686 8687 // Make dates with properties first say the date 8688 if (isDate(value)) { 8689 base = ' ' + Date.prototype.toUTCString.call(value); 8690 } 8691 8692 // Make error with message first say the error 8693 if (isError(value)) { 8694 return formatError(value); 8695 } 8696 8697 if (keys.length === 0 && (!array || value.length == 0)) { 8698 return braces[0] + base + braces[1]; 8699 } 8700 8701 if (recurseTimes < 0) { 8702 if (isRegExp(value)) { 8703 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); 8704 } else { 8705 return ctx.stylize('[Object]', 'special'); 8706 } 8707 } 8708 8709 ctx.seen.push(value); 8710 8711 var output; 8712 if (array) { 8713 output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); 8714 } else if (typedArray) { 8715 return formatTypedArray(value); 8716 } else { 8717 output = keys.map(function(key) { 8718 return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); 8719 }); 8720 } 8721 8722 ctx.seen.pop(); 8723 8724 return reduceToSingleString(output, base, braces); 8725 } 8726 8727 function formatPrimitive(ctx, value) { 8728 switch (typeof value) { 8729 case 'undefined': 8730 return ctx.stylize('undefined', 'undefined'); 8731 8732 case 'string': 8733 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') 8734 .replace(/'/g, "\\'") 8735 .replace(/\\"/g, '"') + '\''; 8736 return ctx.stylize(simple, 'string'); 8737 8738 case 'number': 8739 if (value === 0 && (1/value) === -Infinity) { 8740 return ctx.stylize('-0', 'number'); 8741 } 8742 return ctx.stylize('' + value, 'number'); 8743 8744 case 'boolean': 8745 return ctx.stylize('' + value, 'boolean'); 8746 8747 case 'symbol': 8748 return ctx.stylize(value.toString(), 'symbol'); 8749 8750 case 'bigint': 8751 return ctx.stylize(value.toString() + 'n', 'bigint'); 8752 } 8753 // For some reason typeof null is "object", so special case here. 8754 if (value === null) { 8755 return ctx.stylize('null', 'null'); 8756 } 8757 } 8758 8759 function formatError(value) { 8760 return '[' + Error.prototype.toString.call(value) + ']'; 8761 } 8762 8763 function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { 8764 var output = []; 8765 for (var i = 0, l = value.length; i < l; ++i) { 8766 if (Object.prototype.hasOwnProperty.call(value, String(i))) { 8767 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, 8768 String(i), true)); 8769 } else { 8770 output.push(''); 8771 } 8772 } 8773 8774 keys.forEach(function(key) { 8775 if (!key.match(/^\d+$/)) { 8776 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, 8777 key, true)); 8778 } 8779 }); 8780 return output; 8781 } 8782 8783 function formatTypedArray(value) { 8784 var str = '[ '; 8785 8786 for (var i = 0; i < value.length; ++i) { 8787 if (str.length >= config.truncateThreshold - 7) { 8788 str += '...'; 8789 break; 8790 } 8791 str += value[i] + ', '; 8792 } 8793 str += ' ]'; 8794 8795 // Removing trailing `, ` if the array was not truncated 8796 if (str.indexOf(', ]') !== -1) { 8797 str = str.replace(', ]', ' ]'); 8798 } 8799 8800 return str; 8801 } 8802 8803 function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { 8804 var name; 8805 var propDescriptor = Object.getOwnPropertyDescriptor(value, key); 8806 var str; 8807 8808 if (propDescriptor) { 8809 if (propDescriptor.get) { 8810 if (propDescriptor.set) { 8811 str = ctx.stylize('[Getter/Setter]', 'special'); 8812 } else { 8813 str = ctx.stylize('[Getter]', 'special'); 8814 } 8815 } else { 8816 if (propDescriptor.set) { 8817 str = ctx.stylize('[Setter]', 'special'); 8818 } 8819 } 8820 } 8821 if (visibleKeys.indexOf(key) < 0) { 8822 name = '[' + key + ']'; 8823 } 8824 if (!str) { 8825 if (ctx.seen.indexOf(value[key]) < 0) { 8826 if (recurseTimes === null) { 8827 str = formatValue(ctx, value[key], null); 8828 } else { 8829 str = formatValue(ctx, value[key], recurseTimes - 1); 8830 } 8831 if (str.indexOf('\n') > -1) { 8832 if (array) { 8833 str = str.split('\n').map(function(line) { 8834 return ' ' + line; 8835 }).join('\n').substr(2); 8836 } else { 8837 str = '\n' + str.split('\n').map(function(line) { 8838 return ' ' + line; 8839 }).join('\n'); 8840 } 8841 } 8842 } else { 8843 str = ctx.stylize('[Circular]', 'special'); 8844 } 8845 } 8846 if (typeof name === 'undefined') { 8847 if (array && key.match(/^\d+$/)) { 8848 return str; 8849 } 8850 name = JSON.stringify('' + key); 8851 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { 8852 name = name.substr(1, name.length - 2); 8853 name = ctx.stylize(name, 'name'); 8854 } else { 8855 name = name.replace(/'/g, "\\'") 8856 .replace(/\\"/g, '"') 8857 .replace(/(^"|"$)/g, "'"); 8858 name = ctx.stylize(name, 'string'); 8859 } 8860 } 8861 8862 return name + ': ' + str; 8863 } 8864 8865 function reduceToSingleString(output, base, braces) { 8866 var length = output.reduce(function(prev, cur) { 8867 return prev + cur.length + 1; 8868 }, 0); 8869 8870 if (length > 60) { 8871 return braces[0] + 8872 (base === '' ? '' : base + '\n ') + 8873 ' ' + 8874 output.join(',\n ') + 8875 ' ' + 8876 braces[1]; 8877 } 8878 8879 return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; 8880 } 8881 8882 function isTypedArray(ar) { 8883 // Unfortunately there's no way to check if an object is a TypedArray 8884 // We have to check if it's one of these types 8885 return (typeof ar === 'object' && /\w+Array]$/.test(objectToString(ar))); 8886 } 8887 8888 function isArray(ar) { 8889 return Array.isArray(ar) || 8890 (typeof ar === 'object' && objectToString(ar) === '[object Array]'); 8891 } 8892 8893 function isRegExp(re) { 8894 return typeof re === 'object' && objectToString(re) === '[object RegExp]'; 8895 } 8896 8897 function isDate(d) { 8898 return typeof d === 'object' && objectToString(d) === '[object Date]'; 8899 } 8900 8901 function isError(e) { 8902 return typeof e === 'object' && objectToString(e) === '[object Error]'; 8903 } 8904 8905 function objectToString(o) { 8906 return Object.prototype.toString.call(o); 8907 } 8908 8909 },{"../config":4,"./getEnumerableProperties":17,"./getProperties":22,"get-func-name":37}],25:[function(require,module,exports){ 8910 /*! 8911 * Chai - isNaN utility 8912 * Copyright(c) 2012-2015 Sakthipriyan Vairamani <thechargingvolcano@gmail.com> 8913 * MIT Licensed 8914 */ 8915 8916 /** 8917 * ### .isNaN(value) 8918 * 8919 * Checks if the given value is NaN or not. 8920 * 8921 * utils.isNaN(NaN); // true 8922 * 8923 * @param {Value} The value which has to be checked if it is NaN 8924 * @name isNaN 8925 * @api private 8926 */ 8927 8928 function isNaN(value) { 8929 // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number 8930 // section's NOTE. 8931 return value !== value; 8932 } 8933 8934 // If ECMAScript 6's Number.isNaN is present, prefer that. 8935 module.exports = Number.isNaN || isNaN; 8936 8937 },{}],26:[function(require,module,exports){ 8938 var config = require('../config'); 8939 8940 /*! 8941 * Chai - isProxyEnabled helper 8942 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 8943 * MIT Licensed 8944 */ 8945 8946 /** 8947 * ### .isProxyEnabled() 8948 * 8949 * Helper function to check if Chai's proxy protection feature is enabled. If 8950 * proxies are unsupported or disabled via the user's Chai config, then return 8951 * false. Otherwise, return true. 8952 * 8953 * @namespace Utils 8954 * @name isProxyEnabled 8955 */ 8956 8957 module.exports = function isProxyEnabled() { 8958 return config.useProxy && 8959 typeof Proxy !== 'undefined' && 8960 typeof Reflect !== 'undefined'; 8961 }; 8962 8963 },{"../config":4}],27:[function(require,module,exports){ 8964 /*! 8965 * Chai - flag utility 8966 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 8967 * MIT Licensed 8968 */ 8969 8970 /*! 8971 * Module dependencies 8972 */ 8973 8974 var inspect = require('./inspect'); 8975 var config = require('../config'); 8976 8977 /** 8978 * ### .objDisplay(object) 8979 * 8980 * Determines if an object or an array matches 8981 * criteria to be inspected in-line for error 8982 * messages or should be truncated. 8983 * 8984 * @param {Mixed} javascript object to inspect 8985 * @name objDisplay 8986 * @namespace Utils 8987 * @api public 8988 */ 8989 8990 module.exports = function objDisplay(obj) { 8991 var str = inspect(obj) 8992 , type = Object.prototype.toString.call(obj); 8993 8994 if (config.truncateThreshold && str.length >= config.truncateThreshold) { 8995 if (type === '[object Function]') { 8996 return !obj.name || obj.name === '' 8997 ? '[Function]' 8998 : '[Function: ' + obj.name + ']'; 8999 } else if (type === '[object Array]') { 9000 return '[ Array(' + obj.length + ') ]'; 9001 } else if (type === '[object Object]') { 9002 var keys = Object.keys(obj) 9003 , kstr = keys.length > 2 9004 ? keys.splice(0, 2).join(', ') + ', ...' 9005 : keys.join(', '); 9006 return '{ Object (' + kstr + ') }'; 9007 } else { 9008 return str; 9009 } 9010 } else { 9011 return str; 9012 } 9013 }; 9014 9015 },{"../config":4,"./inspect":24}],28:[function(require,module,exports){ 9016 /*! 9017 * Chai - overwriteChainableMethod utility 9018 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 9019 * MIT Licensed 9020 */ 9021 9022 var chai = require('../../chai'); 9023 var transferFlags = require('./transferFlags'); 9024 9025 /** 9026 * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior) 9027 * 9028 * Overwrites an already existing chainable method 9029 * and provides access to the previous function or 9030 * property. Must return functions to be used for 9031 * name. 9032 * 9033 * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf', 9034 * function (_super) { 9035 * } 9036 * , function (_super) { 9037 * } 9038 * ); 9039 * 9040 * Can also be accessed directly from `chai.Assertion`. 9041 * 9042 * chai.Assertion.overwriteChainableMethod('foo', fn, fn); 9043 * 9044 * Then can be used as any other assertion. 9045 * 9046 * expect(myFoo).to.have.lengthOf(3); 9047 * expect(myFoo).to.have.lengthOf.above(3); 9048 * 9049 * @param {Object} ctx object whose method / property is to be overwritten 9050 * @param {String} name of method / property to overwrite 9051 * @param {Function} method function that returns a function to be used for name 9052 * @param {Function} chainingBehavior function that returns a function to be used for property 9053 * @namespace Utils 9054 * @name overwriteChainableMethod 9055 * @api public 9056 */ 9057 9058 module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) { 9059 var chainableBehavior = ctx.__methods[name]; 9060 9061 var _chainingBehavior = chainableBehavior.chainingBehavior; 9062 chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() { 9063 var result = chainingBehavior(_chainingBehavior).call(this); 9064 if (result !== undefined) { 9065 return result; 9066 } 9067 9068 var newAssertion = new chai.Assertion(); 9069 transferFlags(this, newAssertion); 9070 return newAssertion; 9071 }; 9072 9073 var _method = chainableBehavior.method; 9074 chainableBehavior.method = function overwritingChainableMethodWrapper() { 9075 var result = method(_method).apply(this, arguments); 9076 if (result !== undefined) { 9077 return result; 9078 } 9079 9080 var newAssertion = new chai.Assertion(); 9081 transferFlags(this, newAssertion); 9082 return newAssertion; 9083 }; 9084 }; 9085 9086 },{"../../chai":2,"./transferFlags":33}],29:[function(require,module,exports){ 9087 /*! 9088 * Chai - overwriteMethod utility 9089 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 9090 * MIT Licensed 9091 */ 9092 9093 var addLengthGuard = require('./addLengthGuard'); 9094 var chai = require('../../chai'); 9095 var flag = require('./flag'); 9096 var proxify = require('./proxify'); 9097 var transferFlags = require('./transferFlags'); 9098 9099 /** 9100 * ### .overwriteMethod(ctx, name, fn) 9101 * 9102 * Overwrites an already existing method and provides 9103 * access to previous function. Must return function 9104 * to be used for name. 9105 * 9106 * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { 9107 * return function (str) { 9108 * var obj = utils.flag(this, 'object'); 9109 * if (obj instanceof Foo) { 9110 * new chai.Assertion(obj.value).to.equal(str); 9111 * } else { 9112 * _super.apply(this, arguments); 9113 * } 9114 * } 9115 * }); 9116 * 9117 * Can also be accessed directly from `chai.Assertion`. 9118 * 9119 * chai.Assertion.overwriteMethod('foo', fn); 9120 * 9121 * Then can be used as any other assertion. 9122 * 9123 * expect(myFoo).to.equal('bar'); 9124 * 9125 * @param {Object} ctx object whose method is to be overwritten 9126 * @param {String} name of method to overwrite 9127 * @param {Function} method function that returns a function to be used for name 9128 * @namespace Utils 9129 * @name overwriteMethod 9130 * @api public 9131 */ 9132 9133 module.exports = function overwriteMethod(ctx, name, method) { 9134 var _method = ctx[name] 9135 , _super = function () { 9136 throw new Error(name + ' is not a function'); 9137 }; 9138 9139 if (_method && 'function' === typeof _method) 9140 _super = _method; 9141 9142 var overwritingMethodWrapper = function () { 9143 // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this 9144 // function to be the starting point for removing implementation frames from 9145 // the stack trace of a failed assertion. 9146 // 9147 // However, we only want to use this function as the starting point if the 9148 // `lockSsfi` flag isn't set. 9149 // 9150 // If the `lockSsfi` flag is set, then either this assertion has been 9151 // overwritten by another assertion, or this assertion is being invoked from 9152 // inside of another assertion. In the first case, the `ssfi` flag has 9153 // already been set by the overwriting assertion. In the second case, the 9154 // `ssfi` flag has already been set by the outer assertion. 9155 if (!flag(this, 'lockSsfi')) { 9156 flag(this, 'ssfi', overwritingMethodWrapper); 9157 } 9158 9159 // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion 9160 // from changing the `ssfi` flag. By this point, the `ssfi` flag is already 9161 // set to the correct starting point for this assertion. 9162 var origLockSsfi = flag(this, 'lockSsfi'); 9163 flag(this, 'lockSsfi', true); 9164 var result = method(_super).apply(this, arguments); 9165 flag(this, 'lockSsfi', origLockSsfi); 9166 9167 if (result !== undefined) { 9168 return result; 9169 } 9170 9171 var newAssertion = new chai.Assertion(); 9172 transferFlags(this, newAssertion); 9173 return newAssertion; 9174 } 9175 9176 addLengthGuard(overwritingMethodWrapper, name, false); 9177 ctx[name] = proxify(overwritingMethodWrapper, name); 9178 }; 9179 9180 },{"../../chai":2,"./addLengthGuard":10,"./flag":15,"./proxify":31,"./transferFlags":33}],30:[function(require,module,exports){ 9181 /*! 9182 * Chai - overwriteProperty utility 9183 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 9184 * MIT Licensed 9185 */ 9186 9187 var chai = require('../../chai'); 9188 var flag = require('./flag'); 9189 var isProxyEnabled = require('./isProxyEnabled'); 9190 var transferFlags = require('./transferFlags'); 9191 9192 /** 9193 * ### .overwriteProperty(ctx, name, fn) 9194 * 9195 * Overwrites an already existing property getter and provides 9196 * access to previous value. Must return function to use as getter. 9197 * 9198 * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { 9199 * return function () { 9200 * var obj = utils.flag(this, 'object'); 9201 * if (obj instanceof Foo) { 9202 * new chai.Assertion(obj.name).to.equal('bar'); 9203 * } else { 9204 * _super.call(this); 9205 * } 9206 * } 9207 * }); 9208 * 9209 * 9210 * Can also be accessed directly from `chai.Assertion`. 9211 * 9212 * chai.Assertion.overwriteProperty('foo', fn); 9213 * 9214 * Then can be used as any other assertion. 9215 * 9216 * expect(myFoo).to.be.ok; 9217 * 9218 * @param {Object} ctx object whose property is to be overwritten 9219 * @param {String} name of property to overwrite 9220 * @param {Function} getter function that returns a getter function to be used for name 9221 * @namespace Utils 9222 * @name overwriteProperty 9223 * @api public 9224 */ 9225 9226 module.exports = function overwriteProperty(ctx, name, getter) { 9227 var _get = Object.getOwnPropertyDescriptor(ctx, name) 9228 , _super = function () {}; 9229 9230 if (_get && 'function' === typeof _get.get) 9231 _super = _get.get 9232 9233 Object.defineProperty(ctx, name, 9234 { get: function overwritingPropertyGetter() { 9235 // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this 9236 // function to be the starting point for removing implementation frames 9237 // from the stack trace of a failed assertion. 9238 // 9239 // However, we only want to use this function as the starting point if 9240 // the `lockSsfi` flag isn't set and proxy protection is disabled. 9241 // 9242 // If the `lockSsfi` flag is set, then either this assertion has been 9243 // overwritten by another assertion, or this assertion is being invoked 9244 // from inside of another assertion. In the first case, the `ssfi` flag 9245 // has already been set by the overwriting assertion. In the second 9246 // case, the `ssfi` flag has already been set by the outer assertion. 9247 // 9248 // If proxy protection is enabled, then the `ssfi` flag has already been 9249 // set by the proxy getter. 9250 if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { 9251 flag(this, 'ssfi', overwritingPropertyGetter); 9252 } 9253 9254 // Setting the `lockSsfi` flag to `true` prevents the overwritten 9255 // assertion from changing the `ssfi` flag. By this point, the `ssfi` 9256 // flag is already set to the correct starting point for this assertion. 9257 var origLockSsfi = flag(this, 'lockSsfi'); 9258 flag(this, 'lockSsfi', true); 9259 var result = getter(_super).call(this); 9260 flag(this, 'lockSsfi', origLockSsfi); 9261 9262 if (result !== undefined) { 9263 return result; 9264 } 9265 9266 var newAssertion = new chai.Assertion(); 9267 transferFlags(this, newAssertion); 9268 return newAssertion; 9269 } 9270 , configurable: true 9271 }); 9272 }; 9273 9274 },{"../../chai":2,"./flag":15,"./isProxyEnabled":26,"./transferFlags":33}],31:[function(require,module,exports){ 9275 var config = require('../config'); 9276 var flag = require('./flag'); 9277 var getProperties = require('./getProperties'); 9278 var isProxyEnabled = require('./isProxyEnabled'); 9279 9280 /*! 9281 * Chai - proxify utility 9282 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 9283 * MIT Licensed 9284 */ 9285 9286 /** 9287 * ### .proxify(object) 9288 * 9289 * Return a proxy of given object that throws an error when a non-existent 9290 * property is read. By default, the root cause is assumed to be a misspelled 9291 * property, and thus an attempt is made to offer a reasonable suggestion from 9292 * the list of existing properties. However, if a nonChainableMethodName is 9293 * provided, then the root cause is instead a failure to invoke a non-chainable 9294 * method prior to reading the non-existent property. 9295 * 9296 * If proxies are unsupported or disabled via the user's Chai config, then 9297 * return object without modification. 9298 * 9299 * @param {Object} obj 9300 * @param {String} nonChainableMethodName 9301 * @namespace Utils 9302 * @name proxify 9303 */ 9304 9305 var builtins = ['__flags', '__methods', '_obj', 'assert']; 9306 9307 module.exports = function proxify(obj, nonChainableMethodName) { 9308 if (!isProxyEnabled()) return obj; 9309 9310 return new Proxy(obj, { 9311 get: function proxyGetter(target, property) { 9312 // This check is here because we should not throw errors on Symbol properties 9313 // such as `Symbol.toStringTag`. 9314 // The values for which an error should be thrown can be configured using 9315 // the `config.proxyExcludedKeys` setting. 9316 if (typeof property === 'string' && 9317 config.proxyExcludedKeys.indexOf(property) === -1 && 9318 !Reflect.has(target, property)) { 9319 // Special message for invalid property access of non-chainable methods. 9320 if (nonChainableMethodName) { 9321 throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' + 9322 property + '. See docs for proper usage of "' + 9323 nonChainableMethodName + '".'); 9324 } 9325 9326 // If the property is reasonably close to an existing Chai property, 9327 // suggest that property to the user. Only suggest properties with a 9328 // distance less than 4. 9329 var suggestion = null; 9330 var suggestionDistance = 4; 9331 getProperties(target).forEach(function(prop) { 9332 if ( 9333 !Object.prototype.hasOwnProperty(prop) && 9334 builtins.indexOf(prop) === -1 9335 ) { 9336 var dist = stringDistanceCapped( 9337 property, 9338 prop, 9339 suggestionDistance 9340 ); 9341 if (dist < suggestionDistance) { 9342 suggestion = prop; 9343 suggestionDistance = dist; 9344 } 9345 } 9346 }); 9347 9348 if (suggestion !== null) { 9349 throw Error('Invalid Chai property: ' + property + 9350 '. Did you mean "' + suggestion + '"?'); 9351 } else { 9352 throw Error('Invalid Chai property: ' + property); 9353 } 9354 } 9355 9356 // Use this proxy getter as the starting point for removing implementation 9357 // frames from the stack trace of a failed assertion. For property 9358 // assertions, this prevents the proxy getter from showing up in the stack 9359 // trace since it's invoked before the property getter. For method and 9360 // chainable method assertions, this flag will end up getting changed to 9361 // the method wrapper, which is good since this frame will no longer be in 9362 // the stack once the method is invoked. Note that Chai builtin assertion 9363 // properties such as `__flags` are skipped since this is only meant to 9364 // capture the starting point of an assertion. This step is also skipped 9365 // if the `lockSsfi` flag is set, thus indicating that this assertion is 9366 // being called from within another assertion. In that case, the `ssfi` 9367 // flag is already set to the outer assertion's starting point. 9368 if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) { 9369 flag(target, 'ssfi', proxyGetter); 9370 } 9371 9372 return Reflect.get(target, property); 9373 } 9374 }); 9375 }; 9376 9377 /** 9378 * # stringDistanceCapped(strA, strB, cap) 9379 * Return the Levenshtein distance between two strings, but no more than cap. 9380 * @param {string} strA 9381 * @param {string} strB 9382 * @param {number} number 9383 * @return {number} min(string distance between strA and strB, cap) 9384 * @api private 9385 */ 9386 9387 function stringDistanceCapped(strA, strB, cap) { 9388 if (Math.abs(strA.length - strB.length) >= cap) { 9389 return cap; 9390 } 9391 9392 var memo = []; 9393 // `memo` is a two-dimensional array containing distances. 9394 // memo[i][j] is the distance between strA.slice(0, i) and 9395 // strB.slice(0, j). 9396 for (var i = 0; i <= strA.length; i++) { 9397 memo[i] = Array(strB.length + 1).fill(0); 9398 memo[i][0] = i; 9399 } 9400 for (var j = 0; j < strB.length; j++) { 9401 memo[0][j] = j; 9402 } 9403 9404 for (var i = 1; i <= strA.length; i++) { 9405 var ch = strA.charCodeAt(i - 1); 9406 for (var j = 1; j <= strB.length; j++) { 9407 if (Math.abs(i - j) >= cap) { 9408 memo[i][j] = cap; 9409 continue; 9410 } 9411 memo[i][j] = Math.min( 9412 memo[i - 1][j] + 1, 9413 memo[i][j - 1] + 1, 9414 memo[i - 1][j - 1] + 9415 (ch === strB.charCodeAt(j - 1) ? 0 : 1) 9416 ); 9417 } 9418 } 9419 9420 return memo[strA.length][strB.length]; 9421 } 9422 9423 },{"../config":4,"./flag":15,"./getProperties":22,"./isProxyEnabled":26}],32:[function(require,module,exports){ 9424 /*! 9425 * Chai - test utility 9426 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 9427 * MIT Licensed 9428 */ 9429 9430 /*! 9431 * Module dependencies 9432 */ 9433 9434 var flag = require('./flag'); 9435 9436 /** 9437 * ### .test(object, expression) 9438 * 9439 * Test and object for expression. 9440 * 9441 * @param {Object} object (constructed Assertion) 9442 * @param {Arguments} chai.Assertion.prototype.assert arguments 9443 * @namespace Utils 9444 * @name test 9445 */ 9446 9447 module.exports = function test(obj, args) { 9448 var negate = flag(obj, 'negate') 9449 , expr = args[0]; 9450 return negate ? !expr : expr; 9451 }; 9452 9453 },{"./flag":15}],33:[function(require,module,exports){ 9454 /*! 9455 * Chai - transferFlags utility 9456 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 9457 * MIT Licensed 9458 */ 9459 9460 /** 9461 * ### .transferFlags(assertion, object, includeAll = true) 9462 * 9463 * Transfer all the flags for `assertion` to `object`. If 9464 * `includeAll` is set to `false`, then the base Chai 9465 * assertion flags (namely `object`, `ssfi`, `lockSsfi`, 9466 * and `message`) will not be transferred. 9467 * 9468 * 9469 * var newAssertion = new Assertion(); 9470 * utils.transferFlags(assertion, newAssertion); 9471 * 9472 * var anotherAssertion = new Assertion(myObj); 9473 * utils.transferFlags(assertion, anotherAssertion, false); 9474 * 9475 * @param {Assertion} assertion the assertion to transfer the flags from 9476 * @param {Object} object the object to transfer the flags to; usually a new assertion 9477 * @param {Boolean} includeAll 9478 * @namespace Utils 9479 * @name transferFlags 9480 * @api private 9481 */ 9482 9483 module.exports = function transferFlags(assertion, object, includeAll) { 9484 var flags = assertion.__flags || (assertion.__flags = Object.create(null)); 9485 9486 if (!object.__flags) { 9487 object.__flags = Object.create(null); 9488 } 9489 9490 includeAll = arguments.length === 3 ? includeAll : true; 9491 9492 for (var flag in flags) { 9493 if (includeAll || 9494 (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) { 9495 object.__flags[flag] = flags[flag]; 9496 } 9497 } 9498 }; 9499 9500 },{}],34:[function(require,module,exports){ 9501 /*! 9502 * assertion-error 9503 * Copyright(c) 2013 Jake Luer <jake@qualiancy.com> 9504 * MIT Licensed 9505 */ 9506 9507 /*! 9508 * Return a function that will copy properties from 9509 * one object to another excluding any originally 9510 * listed. Returned function will create a new `{}`. 9511 * 9512 * @param {String} excluded properties ... 9513 * @return {Function} 9514 */ 9515 9516 function exclude () { 9517 var excludes = [].slice.call(arguments); 9518 9519 function excludeProps (res, obj) { 9520 Object.keys(obj).forEach(function (key) { 9521 if (!~excludes.indexOf(key)) res[key] = obj[key]; 9522 }); 9523 } 9524 9525 return function extendExclude () { 9526 var args = [].slice.call(arguments) 9527 , i = 0 9528 , res = {}; 9529 9530 for (; i < args.length; i++) { 9531 excludeProps(res, args[i]); 9532 } 9533 9534 return res; 9535 }; 9536 }; 9537 9538 /*! 9539 * Primary Exports 9540 */ 9541 9542 module.exports = AssertionError; 9543 9544 /** 9545 * ### AssertionError 9546 * 9547 * An extension of the JavaScript `Error` constructor for 9548 * assertion and validation scenarios. 9549 * 9550 * @param {String} message 9551 * @param {Object} properties to include (optional) 9552 * @param {callee} start stack function (optional) 9553 */ 9554 9555 function AssertionError (message, _props, ssf) { 9556 var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') 9557 , props = extend(_props || {}); 9558 9559 // default values 9560 this.message = message || 'Unspecified AssertionError'; 9561 this.showDiff = false; 9562 9563 // copy from properties 9564 for (var key in props) { 9565 this[key] = props[key]; 9566 } 9567 9568 // capture stack trace 9569 ssf = ssf || AssertionError; 9570 if (Error.captureStackTrace) { 9571 Error.captureStackTrace(this, ssf); 9572 } else { 9573 try { 9574 throw new Error(); 9575 } catch(e) { 9576 this.stack = e.stack; 9577 } 9578 } 9579 } 9580 9581 /*! 9582 * Inherit from Error.prototype 9583 */ 9584 9585 AssertionError.prototype = Object.create(Error.prototype); 9586 9587 /*! 9588 * Statically set name 9589 */ 9590 9591 AssertionError.prototype.name = 'AssertionError'; 9592 9593 /*! 9594 * Ensure correct constructor 9595 */ 9596 9597 AssertionError.prototype.constructor = AssertionError; 9598 9599 /** 9600 * Allow errors to be converted to JSON for static transfer. 9601 * 9602 * @param {Boolean} include stack (default: `true`) 9603 * @return {Object} object that can be `JSON.stringify` 9604 */ 9605 9606 AssertionError.prototype.toJSON = function (stack) { 9607 var extend = exclude('constructor', 'toJSON', 'stack') 9608 , props = extend({ name: this.name }, this); 9609 9610 // include stack if exists and not turned off 9611 if (false !== stack && this.stack) { 9612 props.stack = this.stack; 9613 } 9614 9615 return props; 9616 }; 9617 9618 },{}],35:[function(require,module,exports){ 9619 'use strict'; 9620 9621 /* ! 9622 * Chai - checkError utility 9623 * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com> 9624 * MIT Licensed 9625 */ 9626 9627 /** 9628 * ### .checkError 9629 * 9630 * Checks that an error conforms to a given set of criteria and/or retrieves information about it. 9631 * 9632 * @api public 9633 */ 9634 9635 /** 9636 * ### .compatibleInstance(thrown, errorLike) 9637 * 9638 * Checks if two instances are compatible (strict equal). 9639 * Returns false if errorLike is not an instance of Error, because instances 9640 * can only be compatible if they're both error instances. 9641 * 9642 * @name compatibleInstance 9643 * @param {Error} thrown error 9644 * @param {Error|ErrorConstructor} errorLike object to compare against 9645 * @namespace Utils 9646 * @api public 9647 */ 9648 9649 function compatibleInstance(thrown, errorLike) { 9650 return errorLike instanceof Error && thrown === errorLike; 9651 } 9652 9653 /** 9654 * ### .compatibleConstructor(thrown, errorLike) 9655 * 9656 * Checks if two constructors are compatible. 9657 * This function can receive either an error constructor or 9658 * an error instance as the `errorLike` argument. 9659 * Constructors are compatible if they're the same or if one is 9660 * an instance of another. 9661 * 9662 * @name compatibleConstructor 9663 * @param {Error} thrown error 9664 * @param {Error|ErrorConstructor} errorLike object to compare against 9665 * @namespace Utils 9666 * @api public 9667 */ 9668 9669 function compatibleConstructor(thrown, errorLike) { 9670 if (errorLike instanceof Error) { 9671 // If `errorLike` is an instance of any error we compare their constructors 9672 return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor; 9673 } else if (errorLike.prototype instanceof Error || errorLike === Error) { 9674 // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly 9675 return thrown.constructor === errorLike || thrown instanceof errorLike; 9676 } 9677 9678 return false; 9679 } 9680 9681 /** 9682 * ### .compatibleMessage(thrown, errMatcher) 9683 * 9684 * Checks if an error's message is compatible with a matcher (String or RegExp). 9685 * If the message contains the String or passes the RegExp test, 9686 * it is considered compatible. 9687 * 9688 * @name compatibleMessage 9689 * @param {Error} thrown error 9690 * @param {String|RegExp} errMatcher to look for into the message 9691 * @namespace Utils 9692 * @api public 9693 */ 9694 9695 function compatibleMessage(thrown, errMatcher) { 9696 var comparisonString = typeof thrown === 'string' ? thrown : thrown.message; 9697 if (errMatcher instanceof RegExp) { 9698 return errMatcher.test(comparisonString); 9699 } else if (typeof errMatcher === 'string') { 9700 return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers 9701 } 9702 9703 return false; 9704 } 9705 9706 /** 9707 * ### .getFunctionName(constructorFn) 9708 * 9709 * Returns the name of a function. 9710 * This also includes a polyfill function if `constructorFn.name` is not defined. 9711 * 9712 * @name getFunctionName 9713 * @param {Function} constructorFn 9714 * @namespace Utils 9715 * @api private 9716 */ 9717 9718 var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\(\/]+)/; 9719 function getFunctionName(constructorFn) { 9720 var name = ''; 9721 if (typeof constructorFn.name === 'undefined') { 9722 // Here we run a polyfill if constructorFn.name is not defined 9723 var match = String(constructorFn).match(functionNameMatch); 9724 if (match) { 9725 name = match[1]; 9726 } 9727 } else { 9728 name = constructorFn.name; 9729 } 9730 9731 return name; 9732 } 9733 9734 /** 9735 * ### .getConstructorName(errorLike) 9736 * 9737 * Gets the constructor name for an Error instance or constructor itself. 9738 * 9739 * @name getConstructorName 9740 * @param {Error|ErrorConstructor} errorLike 9741 * @namespace Utils 9742 * @api public 9743 */ 9744 9745 function getConstructorName(errorLike) { 9746 var constructorName = errorLike; 9747 if (errorLike instanceof Error) { 9748 constructorName = getFunctionName(errorLike.constructor); 9749 } else if (typeof errorLike === 'function') { 9750 // If `err` is not an instance of Error it is an error constructor itself or another function. 9751 // If we've got a common function we get its name, otherwise we may need to create a new instance 9752 // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more. 9753 constructorName = getFunctionName(errorLike).trim() || 9754 getFunctionName(new errorLike()); // eslint-disable-line new-cap 9755 } 9756 9757 return constructorName; 9758 } 9759 9760 /** 9761 * ### .getMessage(errorLike) 9762 * 9763 * Gets the error message from an error. 9764 * If `err` is a String itself, we return it. 9765 * If the error has no message, we return an empty string. 9766 * 9767 * @name getMessage 9768 * @param {Error|String} errorLike 9769 * @namespace Utils 9770 * @api public 9771 */ 9772 9773 function getMessage(errorLike) { 9774 var msg = ''; 9775 if (errorLike && errorLike.message) { 9776 msg = errorLike.message; 9777 } else if (typeof errorLike === 'string') { 9778 msg = errorLike; 9779 } 9780 9781 return msg; 9782 } 9783 9784 module.exports = { 9785 compatibleInstance: compatibleInstance, 9786 compatibleConstructor: compatibleConstructor, 9787 compatibleMessage: compatibleMessage, 9788 getMessage: getMessage, 9789 getConstructorName: getConstructorName, 9790 }; 9791 9792 },{}],36:[function(require,module,exports){ 9793 'use strict'; 9794 /* globals Symbol: false, Uint8Array: false, WeakMap: false */ 9795 /*! 9796 * deep-eql 9797 * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com> 9798 * MIT Licensed 9799 */ 9800 9801 var type = require('type-detect'); 9802 function FakeMap() { 9803 this._key = 'chai/deep-eql__' + Math.random() + Date.now(); 9804 } 9805 9806 FakeMap.prototype = { 9807 get: function getMap(key) { 9808 return key[this._key]; 9809 }, 9810 set: function setMap(key, value) { 9811 if (Object.isExtensible(key)) { 9812 Object.defineProperty(key, this._key, { 9813 value: value, 9814 configurable: true, 9815 }); 9816 } 9817 }, 9818 }; 9819 9820 var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap; 9821 /*! 9822 * Check to see if the MemoizeMap has recorded a result of the two operands 9823 * 9824 * @param {Mixed} leftHandOperand 9825 * @param {Mixed} rightHandOperand 9826 * @param {MemoizeMap} memoizeMap 9827 * @returns {Boolean|null} result 9828 */ 9829 function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { 9830 // Technically, WeakMap keys can *only* be objects, not primitives. 9831 if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { 9832 return null; 9833 } 9834 var leftHandMap = memoizeMap.get(leftHandOperand); 9835 if (leftHandMap) { 9836 var result = leftHandMap.get(rightHandOperand); 9837 if (typeof result === 'boolean') { 9838 return result; 9839 } 9840 } 9841 return null; 9842 } 9843 9844 /*! 9845 * Set the result of the equality into the MemoizeMap 9846 * 9847 * @param {Mixed} leftHandOperand 9848 * @param {Mixed} rightHandOperand 9849 * @param {MemoizeMap} memoizeMap 9850 * @param {Boolean} result 9851 */ 9852 function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { 9853 // Technically, WeakMap keys can *only* be objects, not primitives. 9854 if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { 9855 return; 9856 } 9857 var leftHandMap = memoizeMap.get(leftHandOperand); 9858 if (leftHandMap) { 9859 leftHandMap.set(rightHandOperand, result); 9860 } else { 9861 leftHandMap = new MemoizeMap(); 9862 leftHandMap.set(rightHandOperand, result); 9863 memoizeMap.set(leftHandOperand, leftHandMap); 9864 } 9865 } 9866 9867 /*! 9868 * Primary Export 9869 */ 9870 9871 module.exports = deepEqual; 9872 module.exports.MemoizeMap = MemoizeMap; 9873 9874 /** 9875 * Assert deeply nested sameValue equality between two objects of any type. 9876 * 9877 * @param {Mixed} leftHandOperand 9878 * @param {Mixed} rightHandOperand 9879 * @param {Object} [options] (optional) Additional options 9880 * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. 9881 * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of 9882 complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular 9883 references to blow the stack. 9884 * @return {Boolean} equal match 9885 */ 9886 function deepEqual(leftHandOperand, rightHandOperand, options) { 9887 // If we have a comparator, we can't assume anything; so bail to its check first. 9888 if (options && options.comparator) { 9889 return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); 9890 } 9891 9892 var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); 9893 if (simpleResult !== null) { 9894 return simpleResult; 9895 } 9896 9897 // Deeper comparisons are pushed through to a larger function 9898 return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); 9899 } 9900 9901 /** 9902 * Many comparisons can be canceled out early via simple equality or primitive checks. 9903 * @param {Mixed} leftHandOperand 9904 * @param {Mixed} rightHandOperand 9905 * @return {Boolean|null} equal match 9906 */ 9907 function simpleEqual(leftHandOperand, rightHandOperand) { 9908 // Equal references (except for Numbers) can be returned early 9909 if (leftHandOperand === rightHandOperand) { 9910 // Handle +-0 cases 9911 return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; 9912 } 9913 9914 // handle NaN cases 9915 if ( 9916 leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare 9917 rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare 9918 ) { 9919 return true; 9920 } 9921 9922 // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers, 9923 // strings, and undefined, can be compared by reference. 9924 if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { 9925 // Easy out b/c it would have passed the first equality check 9926 return false; 9927 } 9928 return null; 9929 } 9930 9931 /*! 9932 * The main logic of the `deepEqual` function. 9933 * 9934 * @param {Mixed} leftHandOperand 9935 * @param {Mixed} rightHandOperand 9936 * @param {Object} [options] (optional) Additional options 9937 * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. 9938 * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of 9939 complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular 9940 references to blow the stack. 9941 * @return {Boolean} equal match 9942 */ 9943 function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { 9944 options = options || {}; 9945 options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); 9946 var comparator = options && options.comparator; 9947 9948 // Check if a memoized result exists. 9949 var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); 9950 if (memoizeResultLeft !== null) { 9951 return memoizeResultLeft; 9952 } 9953 var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); 9954 if (memoizeResultRight !== null) { 9955 return memoizeResultRight; 9956 } 9957 9958 // If a comparator is present, use it. 9959 if (comparator) { 9960 var comparatorResult = comparator(leftHandOperand, rightHandOperand); 9961 // Comparators may return null, in which case we want to go back to default behavior. 9962 if (comparatorResult === false || comparatorResult === true) { 9963 memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); 9964 return comparatorResult; 9965 } 9966 // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide 9967 // what to do, we need to make sure to return the basic tests first before we move on. 9968 var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); 9969 if (simpleResult !== null) { 9970 // Don't memoize this, it takes longer to set/retrieve than to just compare. 9971 return simpleResult; 9972 } 9973 } 9974 9975 var leftHandType = type(leftHandOperand); 9976 if (leftHandType !== type(rightHandOperand)) { 9977 memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); 9978 return false; 9979 } 9980 9981 // Temporarily set the operands in the memoize object to prevent blowing the stack 9982 memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); 9983 9984 var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); 9985 memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); 9986 return result; 9987 } 9988 9989 function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { 9990 switch (leftHandType) { 9991 case 'String': 9992 case 'Number': 9993 case 'Boolean': 9994 case 'Date': 9995 // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values 9996 return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); 9997 case 'Promise': 9998 case 'Symbol': 9999 case 'function': 10000 case 'WeakMap': 10001 case 'WeakSet': 10002 case 'Error': 10003 return leftHandOperand === rightHandOperand; 10004 case 'Arguments': 10005 case 'Int8Array': 10006 case 'Uint8Array': 10007 case 'Uint8ClampedArray': 10008 case 'Int16Array': 10009 case 'Uint16Array': 10010 case 'Int32Array': 10011 case 'Uint32Array': 10012 case 'Float32Array': 10013 case 'Float64Array': 10014 case 'Array': 10015 return iterableEqual(leftHandOperand, rightHandOperand, options); 10016 case 'RegExp': 10017 return regexpEqual(leftHandOperand, rightHandOperand); 10018 case 'Generator': 10019 return generatorEqual(leftHandOperand, rightHandOperand, options); 10020 case 'DataView': 10021 return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); 10022 case 'ArrayBuffer': 10023 return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); 10024 case 'Set': 10025 return entriesEqual(leftHandOperand, rightHandOperand, options); 10026 case 'Map': 10027 return entriesEqual(leftHandOperand, rightHandOperand, options); 10028 default: 10029 return objectEqual(leftHandOperand, rightHandOperand, options); 10030 } 10031 } 10032 10033 /*! 10034 * Compare two Regular Expressions for equality. 10035 * 10036 * @param {RegExp} leftHandOperand 10037 * @param {RegExp} rightHandOperand 10038 * @return {Boolean} result 10039 */ 10040 10041 function regexpEqual(leftHandOperand, rightHandOperand) { 10042 return leftHandOperand.toString() === rightHandOperand.toString(); 10043 } 10044 10045 /*! 10046 * Compare two Sets/Maps for equality. Faster than other equality functions. 10047 * 10048 * @param {Set} leftHandOperand 10049 * @param {Set} rightHandOperand 10050 * @param {Object} [options] (Optional) 10051 * @return {Boolean} result 10052 */ 10053 10054 function entriesEqual(leftHandOperand, rightHandOperand, options) { 10055 // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach 10056 if (leftHandOperand.size !== rightHandOperand.size) { 10057 return false; 10058 } 10059 if (leftHandOperand.size === 0) { 10060 return true; 10061 } 10062 var leftHandItems = []; 10063 var rightHandItems = []; 10064 leftHandOperand.forEach(function gatherEntries(key, value) { 10065 leftHandItems.push([ key, value ]); 10066 }); 10067 rightHandOperand.forEach(function gatherEntries(key, value) { 10068 rightHandItems.push([ key, value ]); 10069 }); 10070 return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options); 10071 } 10072 10073 /*! 10074 * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. 10075 * 10076 * @param {Iterable} leftHandOperand 10077 * @param {Iterable} rightHandOperand 10078 * @param {Object} [options] (Optional) 10079 * @return {Boolean} result 10080 */ 10081 10082 function iterableEqual(leftHandOperand, rightHandOperand, options) { 10083 var length = leftHandOperand.length; 10084 if (length !== rightHandOperand.length) { 10085 return false; 10086 } 10087 if (length === 0) { 10088 return true; 10089 } 10090 var index = -1; 10091 while (++index < length) { 10092 if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { 10093 return false; 10094 } 10095 } 10096 return true; 10097 } 10098 10099 /*! 10100 * Simple equality for generator objects such as those returned by generator functions. 10101 * 10102 * @param {Iterable} leftHandOperand 10103 * @param {Iterable} rightHandOperand 10104 * @param {Object} [options] (Optional) 10105 * @return {Boolean} result 10106 */ 10107 10108 function generatorEqual(leftHandOperand, rightHandOperand, options) { 10109 return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options); 10110 } 10111 10112 /*! 10113 * Determine if the given object has an @@iterator function. 10114 * 10115 * @param {Object} target 10116 * @return {Boolean} `true` if the object has an @@iterator function. 10117 */ 10118 function hasIteratorFunction(target) { 10119 return typeof Symbol !== 'undefined' && 10120 typeof target === 'object' && 10121 typeof Symbol.iterator !== 'undefined' && 10122 typeof target[Symbol.iterator] === 'function'; 10123 } 10124 10125 /*! 10126 * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. 10127 * This will consume the iterator - which could have side effects depending on the @@iterator implementation. 10128 * 10129 * @param {Object} target 10130 * @returns {Array} an array of entries from the @@iterator function 10131 */ 10132 function getIteratorEntries(target) { 10133 if (hasIteratorFunction(target)) { 10134 try { 10135 return getGeneratorEntries(target[Symbol.iterator]()); 10136 } catch (iteratorError) { 10137 return []; 10138 } 10139 } 10140 return []; 10141 } 10142 10143 /*! 10144 * Gets all entries from a Generator. This will consume the generator - which could have side effects. 10145 * 10146 * @param {Generator} target 10147 * @returns {Array} an array of entries from the Generator. 10148 */ 10149 function getGeneratorEntries(generator) { 10150 var generatorResult = generator.next(); 10151 var accumulator = [ generatorResult.value ]; 10152 while (generatorResult.done === false) { 10153 generatorResult = generator.next(); 10154 accumulator.push(generatorResult.value); 10155 } 10156 return accumulator; 10157 } 10158 10159 /*! 10160 * Gets all own and inherited enumerable keys from a target. 10161 * 10162 * @param {Object} target 10163 * @returns {Array} an array of own and inherited enumerable keys from the target. 10164 */ 10165 function getEnumerableKeys(target) { 10166 var keys = []; 10167 for (var key in target) { 10168 keys.push(key); 10169 } 10170 return keys; 10171 } 10172 10173 /*! 10174 * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of 10175 * each key. If any value of the given key is not equal, the function will return false (early). 10176 * 10177 * @param {Mixed} leftHandOperand 10178 * @param {Mixed} rightHandOperand 10179 * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against 10180 * @param {Object} [options] (Optional) 10181 * @return {Boolean} result 10182 */ 10183 function keysEqual(leftHandOperand, rightHandOperand, keys, options) { 10184 var length = keys.length; 10185 if (length === 0) { 10186 return true; 10187 } 10188 for (var i = 0; i < length; i += 1) { 10189 if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { 10190 return false; 10191 } 10192 } 10193 return true; 10194 } 10195 10196 /*! 10197 * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` 10198 * for each enumerable key in the object. 10199 * 10200 * @param {Mixed} leftHandOperand 10201 * @param {Mixed} rightHandOperand 10202 * @param {Object} [options] (Optional) 10203 * @return {Boolean} result 10204 */ 10205 10206 function objectEqual(leftHandOperand, rightHandOperand, options) { 10207 var leftHandKeys = getEnumerableKeys(leftHandOperand); 10208 var rightHandKeys = getEnumerableKeys(rightHandOperand); 10209 if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { 10210 leftHandKeys.sort(); 10211 rightHandKeys.sort(); 10212 if (iterableEqual(leftHandKeys, rightHandKeys) === false) { 10213 return false; 10214 } 10215 return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); 10216 } 10217 10218 var leftHandEntries = getIteratorEntries(leftHandOperand); 10219 var rightHandEntries = getIteratorEntries(rightHandOperand); 10220 if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { 10221 leftHandEntries.sort(); 10222 rightHandEntries.sort(); 10223 return iterableEqual(leftHandEntries, rightHandEntries, options); 10224 } 10225 10226 if (leftHandKeys.length === 0 && 10227 leftHandEntries.length === 0 && 10228 rightHandKeys.length === 0 && 10229 rightHandEntries.length === 0) { 10230 return true; 10231 } 10232 10233 return false; 10234 } 10235 10236 /*! 10237 * Returns true if the argument is a primitive. 10238 * 10239 * This intentionally returns true for all objects that can be compared by reference, 10240 * including functions and symbols. 10241 * 10242 * @param {Mixed} value 10243 * @return {Boolean} result 10244 */ 10245 function isPrimitive(value) { 10246 return value === null || typeof value !== 'object'; 10247 } 10248 10249 },{"type-detect":39}],37:[function(require,module,exports){ 10250 'use strict'; 10251 10252 /* ! 10253 * Chai - getFuncName utility 10254 * Copyright(c) 2012-2016 Jake Luer <jake@alogicalparadox.com> 10255 * MIT Licensed 10256 */ 10257 10258 /** 10259 * ### .getFuncName(constructorFn) 10260 * 10261 * Returns the name of a function. 10262 * When a non-function instance is passed, returns `null`. 10263 * This also includes a polyfill function if `aFunc.name` is not defined. 10264 * 10265 * @name getFuncName 10266 * @param {Function} funct 10267 * @namespace Utils 10268 * @api public 10269 */ 10270 10271 var toString = Function.prototype.toString; 10272 var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; 10273 function getFuncName(aFunc) { 10274 if (typeof aFunc !== 'function') { 10275 return null; 10276 } 10277 10278 var name = ''; 10279 if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') { 10280 // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined 10281 var match = toString.call(aFunc).match(functionNameMatch); 10282 if (match) { 10283 name = match[1]; 10284 } 10285 } else { 10286 // If we've got a `name` property we just use it 10287 name = aFunc.name; 10288 } 10289 10290 return name; 10291 } 10292 10293 module.exports = getFuncName; 10294 10295 },{}],38:[function(require,module,exports){ 10296 'use strict'; 10297 10298 /* ! 10299 * Chai - pathval utility 10300 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> 10301 * @see https://github.com/logicalparadox/filtr 10302 * MIT Licensed 10303 */ 10304 10305 /** 10306 * ### .hasProperty(object, name) 10307 * 10308 * This allows checking whether an object has own 10309 * or inherited from prototype chain named property. 10310 * 10311 * Basically does the same thing as the `in` 10312 * operator but works properly with null/undefined values 10313 * and other primitives. 10314 * 10315 * var obj = { 10316 * arr: ['a', 'b', 'c'] 10317 * , str: 'Hello' 10318 * } 10319 * 10320 * The following would be the results. 10321 * 10322 * hasProperty(obj, 'str'); // true 10323 * hasProperty(obj, 'constructor'); // true 10324 * hasProperty(obj, 'bar'); // false 10325 * 10326 * hasProperty(obj.str, 'length'); // true 10327 * hasProperty(obj.str, 1); // true 10328 * hasProperty(obj.str, 5); // false 10329 * 10330 * hasProperty(obj.arr, 'length'); // true 10331 * hasProperty(obj.arr, 2); // true 10332 * hasProperty(obj.arr, 3); // false 10333 * 10334 * @param {Object} object 10335 * @param {String|Symbol} name 10336 * @returns {Boolean} whether it exists 10337 * @namespace Utils 10338 * @name hasProperty 10339 * @api public 10340 */ 10341 10342 function hasProperty(obj, name) { 10343 if (typeof obj === 'undefined' || obj === null) { 10344 return false; 10345 } 10346 10347 // The `in` operator does not work with primitives. 10348 return name in Object(obj); 10349 } 10350 10351 /* ! 10352 * ## parsePath(path) 10353 * 10354 * Helper function used to parse string object 10355 * paths. Use in conjunction with `internalGetPathValue`. 10356 * 10357 * var parsed = parsePath('myobject.property.subprop'); 10358 * 10359 * ### Paths: 10360 * 10361 * * Can be infinitely deep and nested. 10362 * * Arrays are also valid using the formal `myobject.document[3].property`. 10363 * * Literal dots and brackets (not delimiter) must be backslash-escaped. 10364 * 10365 * @param {String} path 10366 * @returns {Object} parsed 10367 * @api private 10368 */ 10369 10370 function parsePath(path) { 10371 var str = path.replace(/([^\\])\[/g, '$1.['); 10372 var parts = str.match(/(\\\.|[^.]+?)+/g); 10373 return parts.map(function mapMatches(value) { 10374 if ( 10375 value === 'constructor' || 10376 value === '__proto__' || 10377 value === 'prototype' 10378 ) { 10379 return {}; 10380 } 10381 var regexp = /^\[(\d+)\]$/; 10382 var mArr = regexp.exec(value); 10383 var parsed = null; 10384 if (mArr) { 10385 parsed = { i: parseFloat(mArr[1]) }; 10386 } else { 10387 parsed = { p: value.replace(/\\([.[\]])/g, '$1') }; 10388 } 10389 10390 return parsed; 10391 }); 10392 } 10393 10394 /* ! 10395 * ## internalGetPathValue(obj, parsed[, pathDepth]) 10396 * 10397 * Helper companion function for `.parsePath` that returns 10398 * the value located at the parsed address. 10399 * 10400 * var value = getPathValue(obj, parsed); 10401 * 10402 * @param {Object} object to search against 10403 * @param {Object} parsed definition from `parsePath`. 10404 * @param {Number} depth (nesting level) of the property we want to retrieve 10405 * @returns {Object|Undefined} value 10406 * @api private 10407 */ 10408 10409 function internalGetPathValue(obj, parsed, pathDepth) { 10410 var temporaryValue = obj; 10411 var res = null; 10412 pathDepth = typeof pathDepth === 'undefined' ? parsed.length : pathDepth; 10413 10414 for (var i = 0; i < pathDepth; i++) { 10415 var part = parsed[i]; 10416 if (temporaryValue) { 10417 if (typeof part.p === 'undefined') { 10418 temporaryValue = temporaryValue[part.i]; 10419 } else { 10420 temporaryValue = temporaryValue[part.p]; 10421 } 10422 10423 if (i === pathDepth - 1) { 10424 res = temporaryValue; 10425 } 10426 } 10427 } 10428 10429 return res; 10430 } 10431 10432 /* ! 10433 * ## internalSetPathValue(obj, value, parsed) 10434 * 10435 * Companion function for `parsePath` that sets 10436 * the value located at a parsed address. 10437 * 10438 * internalSetPathValue(obj, 'value', parsed); 10439 * 10440 * @param {Object} object to search and define on 10441 * @param {*} value to use upon set 10442 * @param {Object} parsed definition from `parsePath` 10443 * @api private 10444 */ 10445 10446 function internalSetPathValue(obj, val, parsed) { 10447 var tempObj = obj; 10448 var pathDepth = parsed.length; 10449 var part = null; 10450 // Here we iterate through every part of the path 10451 for (var i = 0; i < pathDepth; i++) { 10452 var propName = null; 10453 var propVal = null; 10454 part = parsed[i]; 10455 10456 // If it's the last part of the path, we set the 'propName' value with the property name 10457 if (i === pathDepth - 1) { 10458 propName = typeof part.p === 'undefined' ? part.i : part.p; 10459 // Now we set the property with the name held by 'propName' on object with the desired val 10460 tempObj[propName] = val; 10461 } else if (typeof part.p !== 'undefined' && tempObj[part.p]) { 10462 tempObj = tempObj[part.p]; 10463 } else if (typeof part.i !== 'undefined' && tempObj[part.i]) { 10464 tempObj = tempObj[part.i]; 10465 } else { 10466 // If the obj doesn't have the property we create one with that name to define it 10467 var next = parsed[i + 1]; 10468 // Here we set the name of the property which will be defined 10469 propName = typeof part.p === 'undefined' ? part.i : part.p; 10470 // Here we decide if this property will be an array or a new object 10471 propVal = typeof next.p === 'undefined' ? [] : {}; 10472 tempObj[propName] = propVal; 10473 tempObj = tempObj[propName]; 10474 } 10475 } 10476 } 10477 10478 /** 10479 * ### .getPathInfo(object, path) 10480 * 10481 * This allows the retrieval of property info in an 10482 * object given a string path. 10483 * 10484 * The path info consists of an object with the 10485 * following properties: 10486 * 10487 * * parent - The parent object of the property referenced by `path` 10488 * * name - The name of the final property, a number if it was an array indexer 10489 * * value - The value of the property, if it exists, otherwise `undefined` 10490 * * exists - Whether the property exists or not 10491 * 10492 * @param {Object} object 10493 * @param {String} path 10494 * @returns {Object} info 10495 * @namespace Utils 10496 * @name getPathInfo 10497 * @api public 10498 */ 10499 10500 function getPathInfo(obj, path) { 10501 var parsed = parsePath(path); 10502 var last = parsed[parsed.length - 1]; 10503 var info = { 10504 parent: 10505 parsed.length > 1 ? 10506 internalGetPathValue(obj, parsed, parsed.length - 1) : 10507 obj, 10508 name: last.p || last.i, 10509 value: internalGetPathValue(obj, parsed), 10510 }; 10511 info.exists = hasProperty(info.parent, info.name); 10512 10513 return info; 10514 } 10515 10516 /** 10517 * ### .getPathValue(object, path) 10518 * 10519 * This allows the retrieval of values in an 10520 * object given a string path. 10521 * 10522 * var obj = { 10523 * prop1: { 10524 * arr: ['a', 'b', 'c'] 10525 * , str: 'Hello' 10526 * } 10527 * , prop2: { 10528 * arr: [ { nested: 'Universe' } ] 10529 * , str: 'Hello again!' 10530 * } 10531 * } 10532 * 10533 * The following would be the results. 10534 * 10535 * getPathValue(obj, 'prop1.str'); // Hello 10536 * getPathValue(obj, 'prop1.att[2]'); // b 10537 * getPathValue(obj, 'prop2.arr[0].nested'); // Universe 10538 * 10539 * @param {Object} object 10540 * @param {String} path 10541 * @returns {Object} value or `undefined` 10542 * @namespace Utils 10543 * @name getPathValue 10544 * @api public 10545 */ 10546 10547 function getPathValue(obj, path) { 10548 var info = getPathInfo(obj, path); 10549 return info.value; 10550 } 10551 10552 /** 10553 * ### .setPathValue(object, path, value) 10554 * 10555 * Define the value in an object at a given string path. 10556 * 10557 * ```js 10558 * var obj = { 10559 * prop1: { 10560 * arr: ['a', 'b', 'c'] 10561 * , str: 'Hello' 10562 * } 10563 * , prop2: { 10564 * arr: [ { nested: 'Universe' } ] 10565 * , str: 'Hello again!' 10566 * } 10567 * }; 10568 * ``` 10569 * 10570 * The following would be acceptable. 10571 * 10572 * ```js 10573 * var properties = require('tea-properties'); 10574 * properties.set(obj, 'prop1.str', 'Hello Universe!'); 10575 * properties.set(obj, 'prop1.arr[2]', 'B'); 10576 * properties.set(obj, 'prop2.arr[0].nested.value', { hello: 'universe' }); 10577 * ``` 10578 * 10579 * @param {Object} object 10580 * @param {String} path 10581 * @param {Mixed} value 10582 * @api private 10583 */ 10584 10585 function setPathValue(obj, path, val) { 10586 var parsed = parsePath(path); 10587 internalSetPathValue(obj, val, parsed); 10588 return obj; 10589 } 10590 10591 module.exports = { 10592 hasProperty: hasProperty, 10593 getPathInfo: getPathInfo, 10594 getPathValue: getPathValue, 10595 setPathValue: setPathValue, 10596 }; 10597 10598 },{}],39:[function(require,module,exports){ 10599 (function (global, factory) { 10600 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 10601 typeof define === 'function' && define.amd ? define(factory) : 10602 (global.typeDetect = factory()); 10603 }(this, (function () { 'use strict'; 10604 10605 /* ! 10606 * type-detect 10607 * Copyright(c) 2013 jake luer <jake@alogicalparadox.com> 10608 * MIT Licensed 10609 */ 10610 var promiseExists = typeof Promise === 'function'; 10611 10612 /* eslint-disable no-undef */ 10613 var globalObject = typeof self === 'object' ? self : global; // eslint-disable-line id-blacklist 10614 10615 var symbolExists = typeof Symbol !== 'undefined'; 10616 var mapExists = typeof Map !== 'undefined'; 10617 var setExists = typeof Set !== 'undefined'; 10618 var weakMapExists = typeof WeakMap !== 'undefined'; 10619 var weakSetExists = typeof WeakSet !== 'undefined'; 10620 var dataViewExists = typeof DataView !== 'undefined'; 10621 var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== 'undefined'; 10622 var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== 'undefined'; 10623 var setEntriesExists = setExists && typeof Set.prototype.entries === 'function'; 10624 var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function'; 10625 var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf(new Set().entries()); 10626 var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf(new Map().entries()); 10627 var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function'; 10628 var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]()); 10629 var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === 'function'; 10630 var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]()); 10631 var toStringLeftSliceLength = 8; 10632 var toStringRightSliceLength = -1; 10633 /** 10634 * ### typeOf (obj) 10635 * 10636 * Uses `Object.prototype.toString` to determine the type of an object, 10637 * normalising behaviour across engine versions & well optimised. 10638 * 10639 * @param {Mixed} object 10640 * @return {String} object type 10641 * @api public 10642 */ 10643 function typeDetect(obj) { 10644 /* ! Speed optimisation 10645 * Pre: 10646 * string literal x 3,039,035 ops/sec ±1.62% (78 runs sampled) 10647 * boolean literal x 1,424,138 ops/sec ±4.54% (75 runs sampled) 10648 * number literal x 1,653,153 ops/sec ±1.91% (82 runs sampled) 10649 * undefined x 9,978,660 ops/sec ±1.92% (75 runs sampled) 10650 * function x 2,556,769 ops/sec ±1.73% (77 runs sampled) 10651 * Post: 10652 * string literal x 38,564,796 ops/sec ±1.15% (79 runs sampled) 10653 * boolean literal x 31,148,940 ops/sec ±1.10% (79 runs sampled) 10654 * number literal x 32,679,330 ops/sec ±1.90% (78 runs sampled) 10655 * undefined x 32,363,368 ops/sec ±1.07% (82 runs sampled) 10656 * function x 31,296,870 ops/sec ±0.96% (83 runs sampled) 10657 */ 10658 var typeofObj = typeof obj; 10659 if (typeofObj !== 'object') { 10660 return typeofObj; 10661 } 10662 10663 /* ! Speed optimisation 10664 * Pre: 10665 * null x 28,645,765 ops/sec ±1.17% (82 runs sampled) 10666 * Post: 10667 * null x 36,428,962 ops/sec ±1.37% (84 runs sampled) 10668 */ 10669 if (obj === null) { 10670 return 'null'; 10671 } 10672 10673 /* ! Spec Conformance 10674 * Test: `Object.prototype.toString.call(window)`` 10675 * - Node === "[object global]" 10676 * - Chrome === "[object global]" 10677 * - Firefox === "[object Window]" 10678 * - PhantomJS === "[object Window]" 10679 * - Safari === "[object Window]" 10680 * - IE 11 === "[object Window]" 10681 * - IE Edge === "[object Window]" 10682 * Test: `Object.prototype.toString.call(this)`` 10683 * - Chrome Worker === "[object global]" 10684 * - Firefox Worker === "[object DedicatedWorkerGlobalScope]" 10685 * - Safari Worker === "[object DedicatedWorkerGlobalScope]" 10686 * - IE 11 Worker === "[object WorkerGlobalScope]" 10687 * - IE Edge Worker === "[object WorkerGlobalScope]" 10688 */ 10689 if (obj === globalObject) { 10690 return 'global'; 10691 } 10692 10693 /* ! Speed optimisation 10694 * Pre: 10695 * array literal x 2,888,352 ops/sec ±0.67% (82 runs sampled) 10696 * Post: 10697 * array literal x 22,479,650 ops/sec ±0.96% (81 runs sampled) 10698 */ 10699 if ( 10700 Array.isArray(obj) && 10701 (symbolToStringTagExists === false || !(Symbol.toStringTag in obj)) 10702 ) { 10703 return 'Array'; 10704 } 10705 10706 // Not caching existence of `window` and related properties due to potential 10707 // for `window` to be unset before tests in quasi-browser environments. 10708 if (typeof window === 'object' && window !== null) { 10709 /* ! Spec Conformance 10710 * (https://html.spec.whatwg.org/multipage/browsers.html#location) 10711 * WhatWG HTML$7.7.3 - The `Location` interface 10712 * Test: `Object.prototype.toString.call(window.location)`` 10713 * - IE <=11 === "[object Object]" 10714 * - IE Edge <=13 === "[object Object]" 10715 */ 10716 if (typeof window.location === 'object' && obj === window.location) { 10717 return 'Location'; 10718 } 10719 10720 /* ! Spec Conformance 10721 * (https://html.spec.whatwg.org/#document) 10722 * WhatWG HTML$3.1.1 - The `Document` object 10723 * Note: Most browsers currently adher to the W3C DOM Level 2 spec 10724 * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268) 10725 * which suggests that browsers should use HTMLTableCellElement for 10726 * both TD and TH elements. WhatWG separates these. 10727 * WhatWG HTML states: 10728 * > For historical reasons, Window objects must also have a 10729 * > writable, configurable, non-enumerable property named 10730 * > HTMLDocument whose value is the Document interface object. 10731 * Test: `Object.prototype.toString.call(document)`` 10732 * - Chrome === "[object HTMLDocument]" 10733 * - Firefox === "[object HTMLDocument]" 10734 * - Safari === "[object HTMLDocument]" 10735 * - IE <=10 === "[object Document]" 10736 * - IE 11 === "[object HTMLDocument]" 10737 * - IE Edge <=13 === "[object HTMLDocument]" 10738 */ 10739 if (typeof window.document === 'object' && obj === window.document) { 10740 return 'Document'; 10741 } 10742 10743 if (typeof window.navigator === 'object') { 10744 /* ! Spec Conformance 10745 * (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray) 10746 * WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray 10747 * Test: `Object.prototype.toString.call(navigator.mimeTypes)`` 10748 * - IE <=10 === "[object MSMimeTypesCollection]" 10749 */ 10750 if (typeof window.navigator.mimeTypes === 'object' && 10751 obj === window.navigator.mimeTypes) { 10752 return 'MimeTypeArray'; 10753 } 10754 10755 /* ! Spec Conformance 10756 * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) 10757 * WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray 10758 * Test: `Object.prototype.toString.call(navigator.plugins)`` 10759 * - IE <=10 === "[object MSPluginsCollection]" 10760 */ 10761 if (typeof window.navigator.plugins === 'object' && 10762 obj === window.navigator.plugins) { 10763 return 'PluginArray'; 10764 } 10765 } 10766 10767 if ((typeof window.HTMLElement === 'function' || 10768 typeof window.HTMLElement === 'object') && 10769 obj instanceof window.HTMLElement) { 10770 /* ! Spec Conformance 10771 * (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray) 10772 * WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement` 10773 * Test: `Object.prototype.toString.call(document.createElement('blockquote'))`` 10774 * - IE <=10 === "[object HTMLBlockElement]" 10775 */ 10776 if (obj.tagName === 'BLOCKQUOTE') { 10777 return 'HTMLQuoteElement'; 10778 } 10779 10780 /* ! Spec Conformance 10781 * (https://html.spec.whatwg.org/#htmltabledatacellelement) 10782 * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement` 10783 * Note: Most browsers currently adher to the W3C DOM Level 2 spec 10784 * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) 10785 * which suggests that browsers should use HTMLTableCellElement for 10786 * both TD and TH elements. WhatWG separates these. 10787 * Test: Object.prototype.toString.call(document.createElement('td')) 10788 * - Chrome === "[object HTMLTableCellElement]" 10789 * - Firefox === "[object HTMLTableCellElement]" 10790 * - Safari === "[object HTMLTableCellElement]" 10791 */ 10792 if (obj.tagName === 'TD') { 10793 return 'HTMLTableDataCellElement'; 10794 } 10795 10796 /* ! Spec Conformance 10797 * (https://html.spec.whatwg.org/#htmltableheadercellelement) 10798 * WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement` 10799 * Note: Most browsers currently adher to the W3C DOM Level 2 spec 10800 * (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075) 10801 * which suggests that browsers should use HTMLTableCellElement for 10802 * both TD and TH elements. WhatWG separates these. 10803 * Test: Object.prototype.toString.call(document.createElement('th')) 10804 * - Chrome === "[object HTMLTableCellElement]" 10805 * - Firefox === "[object HTMLTableCellElement]" 10806 * - Safari === "[object HTMLTableCellElement]" 10807 */ 10808 if (obj.tagName === 'TH') { 10809 return 'HTMLTableHeaderCellElement'; 10810 } 10811 } 10812 } 10813 10814 /* ! Speed optimisation 10815 * Pre: 10816 * Float64Array x 625,644 ops/sec ±1.58% (80 runs sampled) 10817 * Float32Array x 1,279,852 ops/sec ±2.91% (77 runs sampled) 10818 * Uint32Array x 1,178,185 ops/sec ±1.95% (83 runs sampled) 10819 * Uint16Array x 1,008,380 ops/sec ±2.25% (80 runs sampled) 10820 * Uint8Array x 1,128,040 ops/sec ±2.11% (81 runs sampled) 10821 * Int32Array x 1,170,119 ops/sec ±2.88% (80 runs sampled) 10822 * Int16Array x 1,176,348 ops/sec ±5.79% (86 runs sampled) 10823 * Int8Array x 1,058,707 ops/sec ±4.94% (77 runs sampled) 10824 * Uint8ClampedArray x 1,110,633 ops/sec ±4.20% (80 runs sampled) 10825 * Post: 10826 * Float64Array x 7,105,671 ops/sec ±13.47% (64 runs sampled) 10827 * Float32Array x 5,887,912 ops/sec ±1.46% (82 runs sampled) 10828 * Uint32Array x 6,491,661 ops/sec ±1.76% (79 runs sampled) 10829 * Uint16Array x 6,559,795 ops/sec ±1.67% (82 runs sampled) 10830 * Uint8Array x 6,463,966 ops/sec ±1.43% (85 runs sampled) 10831 * Int32Array x 5,641,841 ops/sec ±3.49% (81 runs sampled) 10832 * Int16Array x 6,583,511 ops/sec ±1.98% (80 runs sampled) 10833 * Int8Array x 6,606,078 ops/sec ±1.74% (81 runs sampled) 10834 * Uint8ClampedArray x 6,602,224 ops/sec ±1.77% (83 runs sampled) 10835 */ 10836 var stringTag = (symbolToStringTagExists && obj[Symbol.toStringTag]); 10837 if (typeof stringTag === 'string') { 10838 return stringTag; 10839 } 10840 10841 var objPrototype = Object.getPrototypeOf(obj); 10842 /* ! Speed optimisation 10843 * Pre: 10844 * regex literal x 1,772,385 ops/sec ±1.85% (77 runs sampled) 10845 * regex constructor x 2,143,634 ops/sec ±2.46% (78 runs sampled) 10846 * Post: 10847 * regex literal x 3,928,009 ops/sec ±0.65% (78 runs sampled) 10848 * regex constructor x 3,931,108 ops/sec ±0.58% (84 runs sampled) 10849 */ 10850 if (objPrototype === RegExp.prototype) { 10851 return 'RegExp'; 10852 } 10853 10854 /* ! Speed optimisation 10855 * Pre: 10856 * date x 2,130,074 ops/sec ±4.42% (68 runs sampled) 10857 * Post: 10858 * date x 3,953,779 ops/sec ±1.35% (77 runs sampled) 10859 */ 10860 if (objPrototype === Date.prototype) { 10861 return 'Date'; 10862 } 10863 10864 /* ! Spec Conformance 10865 * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-promise.prototype-@@tostringtag) 10866 * ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise": 10867 * Test: `Object.prototype.toString.call(Promise.resolve())`` 10868 * - Chrome <=47 === "[object Object]" 10869 * - Edge <=20 === "[object Object]" 10870 * - Firefox 29-Latest === "[object Promise]" 10871 * - Safari 7.1-Latest === "[object Promise]" 10872 */ 10873 if (promiseExists && objPrototype === Promise.prototype) { 10874 return 'Promise'; 10875 } 10876 10877 /* ! Speed optimisation 10878 * Pre: 10879 * set x 2,222,186 ops/sec ±1.31% (82 runs sampled) 10880 * Post: 10881 * set x 4,545,879 ops/sec ±1.13% (83 runs sampled) 10882 */ 10883 if (setExists && objPrototype === Set.prototype) { 10884 return 'Set'; 10885 } 10886 10887 /* ! Speed optimisation 10888 * Pre: 10889 * map x 2,396,842 ops/sec ±1.59% (81 runs sampled) 10890 * Post: 10891 * map x 4,183,945 ops/sec ±6.59% (82 runs sampled) 10892 */ 10893 if (mapExists && objPrototype === Map.prototype) { 10894 return 'Map'; 10895 } 10896 10897 /* ! Speed optimisation 10898 * Pre: 10899 * weakset x 1,323,220 ops/sec ±2.17% (76 runs sampled) 10900 * Post: 10901 * weakset x 4,237,510 ops/sec ±2.01% (77 runs sampled) 10902 */ 10903 if (weakSetExists && objPrototype === WeakSet.prototype) { 10904 return 'WeakSet'; 10905 } 10906 10907 /* ! Speed optimisation 10908 * Pre: 10909 * weakmap x 1,500,260 ops/sec ±2.02% (78 runs sampled) 10910 * Post: 10911 * weakmap x 3,881,384 ops/sec ±1.45% (82 runs sampled) 10912 */ 10913 if (weakMapExists && objPrototype === WeakMap.prototype) { 10914 return 'WeakMap'; 10915 } 10916 10917 /* ! Spec Conformance 10918 * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag) 10919 * ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView": 10920 * Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))`` 10921 * - Edge <=13 === "[object Object]" 10922 */ 10923 if (dataViewExists && objPrototype === DataView.prototype) { 10924 return 'DataView'; 10925 } 10926 10927 /* ! Spec Conformance 10928 * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag) 10929 * ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator": 10930 * Test: `Object.prototype.toString.call(new Map().entries())`` 10931 * - Edge <=13 === "[object Object]" 10932 */ 10933 if (mapExists && objPrototype === mapIteratorPrototype) { 10934 return 'Map Iterator'; 10935 } 10936 10937 /* ! Spec Conformance 10938 * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag) 10939 * ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator": 10940 * Test: `Object.prototype.toString.call(new Set().entries())`` 10941 * - Edge <=13 === "[object Object]" 10942 */ 10943 if (setExists && objPrototype === setIteratorPrototype) { 10944 return 'Set Iterator'; 10945 } 10946 10947 /* ! Spec Conformance 10948 * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag) 10949 * ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator": 10950 * Test: `Object.prototype.toString.call([][Symbol.iterator]())`` 10951 * - Edge <=13 === "[object Object]" 10952 */ 10953 if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) { 10954 return 'Array Iterator'; 10955 } 10956 10957 /* ! Spec Conformance 10958 * (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag) 10959 * ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator": 10960 * Test: `Object.prototype.toString.call(''[Symbol.iterator]())`` 10961 * - Edge <=13 === "[object Object]" 10962 */ 10963 if (stringIteratorExists && objPrototype === stringIteratorPrototype) { 10964 return 'String Iterator'; 10965 } 10966 10967 /* ! Speed optimisation 10968 * Pre: 10969 * object from null x 2,424,320 ops/sec ±1.67% (76 runs sampled) 10970 * Post: 10971 * object from null x 5,838,000 ops/sec ±0.99% (84 runs sampled) 10972 */ 10973 if (objPrototype === null) { 10974 return 'Object'; 10975 } 10976 10977 return Object 10978 .prototype 10979 .toString 10980 .call(obj) 10981 .slice(toStringLeftSliceLength, toStringRightSliceLength); 10982 } 10983 10984 return typeDetect; 10985 10986 }))); 10987 10988 },{}]},{},[1])(1) 10989 });