OLD | NEW |
(Empty) | |
| 1 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.e
xports=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 e(t,n,r){function s(o,u){i
f(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o
,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.c
ode="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function
(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}v
ar i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);retu
rn s})({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 , exports = module.exports = {}; |
| 13 |
| 14 /*! |
| 15 * Chai version |
| 16 */ |
| 17 |
| 18 exports.version = '3.4.1'; |
| 19 |
| 20 /*! |
| 21 * Assertion Error |
| 22 */ |
| 23 |
| 24 exports.AssertionError = require('assertion-error'); |
| 25 |
| 26 /*! |
| 27 * Utils for plugins (not exported) |
| 28 */ |
| 29 |
| 30 var util = require('./chai/utils'); |
| 31 |
| 32 /** |
| 33 * # .use(function) |
| 34 * |
| 35 * Provides a way to extend the internals of Chai |
| 36 * |
| 37 * @param {Function} |
| 38 * @returns {this} for chaining |
| 39 * @api public |
| 40 */ |
| 41 |
| 42 exports.use = function (fn) { |
| 43 if (!~used.indexOf(fn)) { |
| 44 fn(this, util); |
| 45 used.push(fn); |
| 46 } |
| 47 |
| 48 return this; |
| 49 }; |
| 50 |
| 51 /*! |
| 52 * Utility Functions |
| 53 */ |
| 54 |
| 55 exports.util = util; |
| 56 |
| 57 /*! |
| 58 * Configuration |
| 59 */ |
| 60 |
| 61 var config = require('./chai/config'); |
| 62 exports.config = config; |
| 63 |
| 64 /*! |
| 65 * Primary `Assertion` prototype |
| 66 */ |
| 67 |
| 68 var assertion = require('./chai/assertion'); |
| 69 exports.use(assertion); |
| 70 |
| 71 /*! |
| 72 * Core Assertions |
| 73 */ |
| 74 |
| 75 var core = require('./chai/core/assertions'); |
| 76 exports.use(core); |
| 77 |
| 78 /*! |
| 79 * Expect interface |
| 80 */ |
| 81 |
| 82 var expect = require('./chai/interface/expect'); |
| 83 exports.use(expect); |
| 84 |
| 85 /*! |
| 86 * Should interface |
| 87 */ |
| 88 |
| 89 var should = require('./chai/interface/should'); |
| 90 exports.use(should); |
| 91 |
| 92 /*! |
| 93 * Assert interface |
| 94 */ |
| 95 |
| 96 var assert = require('./chai/interface/assert'); |
| 97 exports.use(assert); |
| 98 |
| 99 },{"./chai/assertion":3,"./chai/config":4,"./chai/core/assertions":5,"./chai/int
erface/assert":6,"./chai/interface/expect":7,"./chai/interface/should":8,"./chai
/utils":22,"assertion-error":30}],3:[function(require,module,exports){ |
| 100 /*! |
| 101 * chai |
| 102 * http://chaijs.com |
| 103 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> |
| 104 * MIT Licensed |
| 105 */ |
| 106 |
| 107 var config = require('./config'); |
| 108 |
| 109 module.exports = function (_chai, util) { |
| 110 /*! |
| 111 * Module dependencies. |
| 112 */ |
| 113 |
| 114 var AssertionError = _chai.AssertionError |
| 115 , flag = util.flag; |
| 116 |
| 117 /*! |
| 118 * Module export. |
| 119 */ |
| 120 |
| 121 _chai.Assertion = Assertion; |
| 122 |
| 123 /*! |
| 124 * Assertion Constructor |
| 125 * |
| 126 * Creates object for chaining. |
| 127 * |
| 128 * @api private |
| 129 */ |
| 130 |
| 131 function Assertion (obj, msg, stack) { |
| 132 flag(this, 'ssfi', stack || arguments.callee); |
| 133 flag(this, 'object', obj); |
| 134 flag(this, 'message', msg); |
| 135 } |
| 136 |
| 137 Object.defineProperty(Assertion, 'includeStack', { |
| 138 get: function() { |
| 139 console.warn('Assertion.includeStack is deprecated, use chai.config.includ
eStack instead.'); |
| 140 return config.includeStack; |
| 141 }, |
| 142 set: function(value) { |
| 143 console.warn('Assertion.includeStack is deprecated, use chai.config.includ
eStack instead.'); |
| 144 config.includeStack = value; |
| 145 } |
| 146 }); |
| 147 |
| 148 Object.defineProperty(Assertion, 'showDiff', { |
| 149 get: function() { |
| 150 console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff i
nstead.'); |
| 151 return config.showDiff; |
| 152 }, |
| 153 set: function(value) { |
| 154 console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff i
nstead.'); |
| 155 config.showDiff = value; |
| 156 } |
| 157 }); |
| 158 |
| 159 Assertion.addProperty = function (name, fn) { |
| 160 util.addProperty(this.prototype, name, fn); |
| 161 }; |
| 162 |
| 163 Assertion.addMethod = function (name, fn) { |
| 164 util.addMethod(this.prototype, name, fn); |
| 165 }; |
| 166 |
| 167 Assertion.addChainableMethod = function (name, fn, chainingBehavior) { |
| 168 util.addChainableMethod(this.prototype, name, fn, chainingBehavior); |
| 169 }; |
| 170 |
| 171 Assertion.overwriteProperty = function (name, fn) { |
| 172 util.overwriteProperty(this.prototype, name, fn); |
| 173 }; |
| 174 |
| 175 Assertion.overwriteMethod = function (name, fn) { |
| 176 util.overwriteMethod(this.prototype, name, fn); |
| 177 }; |
| 178 |
| 179 Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { |
| 180 util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); |
| 181 }; |
| 182 |
| 183 /** |
| 184 * ### .assert(expression, message, negateMessage, expected, actual, showDiff) |
| 185 * |
| 186 * Executes an expression and check expectations. Throws AssertionError for re
porting if test doesn't pass. |
| 187 * |
| 188 * @name assert |
| 189 * @param {Philosophical} expression to be tested |
| 190 * @param {String|Function} message or function that returns message to displa
y if expression fails |
| 191 * @param {String|Function} negatedMessage or function that returns negatedMes
sage to display if negated expression fails |
| 192 * @param {Mixed} expected value (remember to check for negation) |
| 193 * @param {Mixed} actual (optional) will default to `this.obj` |
| 194 * @param {Boolean} showDiff (optional) when set to `true`, assert will displa
y a diff in addition to the message if expression fails |
| 195 * @api private |
| 196 */ |
| 197 |
| 198 Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual
, showDiff) { |
| 199 var ok = util.test(this, arguments); |
| 200 if (true !== showDiff) showDiff = false; |
| 201 if (true !== config.showDiff) showDiff = false; |
| 202 |
| 203 if (!ok) { |
| 204 var msg = util.getMessage(this, arguments) |
| 205 , actual = util.getActual(this, arguments); |
| 206 throw new AssertionError(msg, { |
| 207 actual: actual |
| 208 , expected: expected |
| 209 , showDiff: showDiff |
| 210 }, (config.includeStack) ? this.assert : flag(this, 'ssfi')); |
| 211 } |
| 212 }; |
| 213 |
| 214 /*! |
| 215 * ### ._obj |
| 216 * |
| 217 * Quick reference to stored `actual` value for plugin developers. |
| 218 * |
| 219 * @api private |
| 220 */ |
| 221 |
| 222 Object.defineProperty(Assertion.prototype, '_obj', |
| 223 { get: function () { |
| 224 return flag(this, 'object'); |
| 225 } |
| 226 , set: function (val) { |
| 227 flag(this, 'object', val); |
| 228 } |
| 229 }); |
| 230 }; |
| 231 |
| 232 },{"./config":4}],4:[function(require,module,exports){ |
| 233 module.exports = { |
| 234 |
| 235 /** |
| 236 * ### config.includeStack |
| 237 * |
| 238 * User configurable property, influences whether stack trace |
| 239 * is included in Assertion error message. Default of false |
| 240 * suppresses stack trace in the error message. |
| 241 * |
| 242 * chai.config.includeStack = true; // enable stack on error |
| 243 * |
| 244 * @param {Boolean} |
| 245 * @api public |
| 246 */ |
| 247 |
| 248 includeStack: false, |
| 249 |
| 250 /** |
| 251 * ### config.showDiff |
| 252 * |
| 253 * User configurable property, influences whether or not |
| 254 * the `showDiff` flag should be included in the thrown |
| 255 * AssertionErrors. `false` will always be `false`; `true` |
| 256 * will be true when the assertion has requested a diff |
| 257 * be shown. |
| 258 * |
| 259 * @param {Boolean} |
| 260 * @api public |
| 261 */ |
| 262 |
| 263 showDiff: true, |
| 264 |
| 265 /** |
| 266 * ### config.truncateThreshold |
| 267 * |
| 268 * User configurable property, sets length threshold for actual and |
| 269 * expected values in assertion errors. If this threshold is exceeded, for |
| 270 * example for large data structures, the value is replaced with something |
| 271 * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. |
| 272 * |
| 273 * Set it to zero if you want to disable truncating altogether. |
| 274 * |
| 275 * This is especially userful when doing assertions on arrays: having this |
| 276 * set to a reasonable large value makes the failure messages readily |
| 277 * inspectable. |
| 278 * |
| 279 * chai.config.truncateThreshold = 0; // disable truncating |
| 280 * |
| 281 * @param {Number} |
| 282 * @api public |
| 283 */ |
| 284 |
| 285 truncateThreshold: 40 |
| 286 |
| 287 }; |
| 288 |
| 289 },{}],5:[function(require,module,exports){ |
| 290 /*! |
| 291 * chai |
| 292 * http://chaijs.com |
| 293 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> |
| 294 * MIT Licensed |
| 295 */ |
| 296 |
| 297 module.exports = function (chai, _) { |
| 298 var Assertion = chai.Assertion |
| 299 , toString = Object.prototype.toString |
| 300 , flag = _.flag; |
| 301 |
| 302 /** |
| 303 * ### Language Chains |
| 304 * |
| 305 * The following are provided as chainable getters to |
| 306 * improve the readability of your assertions. They |
| 307 * do not provide testing capabilities unless they |
| 308 * have been overwritten by a plugin. |
| 309 * |
| 310 * **Chains** |
| 311 * |
| 312 * - to |
| 313 * - be |
| 314 * - been |
| 315 * - is |
| 316 * - that |
| 317 * - which |
| 318 * - and |
| 319 * - has |
| 320 * - have |
| 321 * - with |
| 322 * - at |
| 323 * - of |
| 324 * - same |
| 325 * |
| 326 * @name language chains |
| 327 * @api public |
| 328 */ |
| 329 |
| 330 [ 'to', 'be', 'been' |
| 331 , 'is', 'and', 'has', 'have' |
| 332 , 'with', 'that', 'which', 'at' |
| 333 , 'of', 'same' ].forEach(function (chain) { |
| 334 Assertion.addProperty(chain, function () { |
| 335 return this; |
| 336 }); |
| 337 }); |
| 338 |
| 339 /** |
| 340 * ### .not |
| 341 * |
| 342 * Negates any of assertions following in the chain. |
| 343 * |
| 344 * expect(foo).to.not.equal('bar'); |
| 345 * expect(goodFn).to.not.throw(Error); |
| 346 * expect({ foo: 'baz' }).to.have.property('foo') |
| 347 * .and.not.equal('bar'); |
| 348 * |
| 349 * @name not |
| 350 * @api public |
| 351 */ |
| 352 |
| 353 Assertion.addProperty('not', function () { |
| 354 flag(this, 'negate', true); |
| 355 }); |
| 356 |
| 357 /** |
| 358 * ### .deep |
| 359 * |
| 360 * Sets the `deep` flag, later used by the `equal` and |
| 361 * `property` assertions. |
| 362 * |
| 363 * expect(foo).to.deep.equal({ bar: 'baz' }); |
| 364 * expect({ foo: { bar: { baz: 'quux' } } }) |
| 365 * .to.have.deep.property('foo.bar.baz', 'quux'); |
| 366 * |
| 367 * `.deep.property` special characters can be escaped |
| 368 * by adding two slashes before the `.` or `[]`. |
| 369 * |
| 370 * var deepCss = { '.link': { '[target]': 42 }}; |
| 371 * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42); |
| 372 * |
| 373 * @name deep |
| 374 * @api public |
| 375 */ |
| 376 |
| 377 Assertion.addProperty('deep', function () { |
| 378 flag(this, 'deep', true); |
| 379 }); |
| 380 |
| 381 /** |
| 382 * ### .any |
| 383 * |
| 384 * Sets the `any` flag, (opposite of the `all` flag) |
| 385 * later used in the `keys` assertion. |
| 386 * |
| 387 * expect(foo).to.have.any.keys('bar', 'baz'); |
| 388 * |
| 389 * @name any |
| 390 * @api public |
| 391 */ |
| 392 |
| 393 Assertion.addProperty('any', function () { |
| 394 flag(this, 'any', true); |
| 395 flag(this, 'all', false) |
| 396 }); |
| 397 |
| 398 |
| 399 /** |
| 400 * ### .all |
| 401 * |
| 402 * Sets the `all` flag (opposite of the `any` flag) |
| 403 * later used by the `keys` assertion. |
| 404 * |
| 405 * expect(foo).to.have.all.keys('bar', 'baz'); |
| 406 * |
| 407 * @name all |
| 408 * @api public |
| 409 */ |
| 410 |
| 411 Assertion.addProperty('all', function () { |
| 412 flag(this, 'all', true); |
| 413 flag(this, 'any', false); |
| 414 }); |
| 415 |
| 416 /** |
| 417 * ### .a(type) |
| 418 * |
| 419 * The `a` and `an` assertions are aliases that can be |
| 420 * used either as language chains or to assert a value's |
| 421 * type. |
| 422 * |
| 423 * // typeof |
| 424 * expect('test').to.be.a('string'); |
| 425 * expect({ foo: 'bar' }).to.be.an('object'); |
| 426 * expect(null).to.be.a('null'); |
| 427 * expect(undefined).to.be.an('undefined'); |
| 428 * expect(new Error).to.be.an('error'); |
| 429 * expect(new Promise).to.be.a('promise'); |
| 430 * expect(new Float32Array()).to.be.a('float32array'); |
| 431 * expect(Symbol()).to.be.a('symbol'); |
| 432 * |
| 433 * // es6 overrides |
| 434 * expect({[Symbol.toStringTag]:()=>'foo'}).to.be.a('foo'); |
| 435 * |
| 436 * // language chain |
| 437 * expect(foo).to.be.an.instanceof(Foo); |
| 438 * |
| 439 * @name a |
| 440 * @alias an |
| 441 * @param {String} type |
| 442 * @param {String} message _optional_ |
| 443 * @api public |
| 444 */ |
| 445 |
| 446 function an (type, msg) { |
| 447 if (msg) flag(this, 'message', msg); |
| 448 type = type.toLowerCase(); |
| 449 var obj = flag(this, 'object') |
| 450 , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' :
'a '; |
| 451 |
| 452 this.assert( |
| 453 type === _.type(obj) |
| 454 , 'expected #{this} to be ' + article + type |
| 455 , 'expected #{this} not to be ' + article + type |
| 456 ); |
| 457 } |
| 458 |
| 459 Assertion.addChainableMethod('an', an); |
| 460 Assertion.addChainableMethod('a', an); |
| 461 |
| 462 /** |
| 463 * ### .include(value) |
| 464 * |
| 465 * The `include` and `contain` assertions can be used as either property |
| 466 * based language chains or as methods to assert the inclusion of an object |
| 467 * in an array or a substring in a string. When used as language chains, |
| 468 * they toggle the `contains` flag for the `keys` assertion. |
| 469 * |
| 470 * expect([1,2,3]).to.include(2); |
| 471 * expect('foobar').to.contain('foo'); |
| 472 * expect({ foo: 'bar', hello: 'universe' }).to.include.keys('foo'); |
| 473 * |
| 474 * @name include |
| 475 * @alias contain |
| 476 * @alias includes |
| 477 * @alias contains |
| 478 * @param {Object|String|Number} obj |
| 479 * @param {String} message _optional_ |
| 480 * @api public |
| 481 */ |
| 482 |
| 483 function includeChainingBehavior () { |
| 484 flag(this, 'contains', true); |
| 485 } |
| 486 |
| 487 function include (val, msg) { |
| 488 _.expectTypes(this, ['array', 'object', 'string']); |
| 489 |
| 490 if (msg) flag(this, 'message', msg); |
| 491 var obj = flag(this, 'object'); |
| 492 var expected = false; |
| 493 |
| 494 if (_.type(obj) === 'array' && _.type(val) === 'object') { |
| 495 for (var i in obj) { |
| 496 if (_.eql(obj[i], val)) { |
| 497 expected = true; |
| 498 break; |
| 499 } |
| 500 } |
| 501 } else if (_.type(val) === 'object') { |
| 502 if (!flag(this, 'negate')) { |
| 503 for (var k in val) new Assertion(obj).property(k, val[k]); |
| 504 return; |
| 505 } |
| 506 var subset = {}; |
| 507 for (var k in val) subset[k] = obj[k]; |
| 508 expected = _.eql(subset, val); |
| 509 } else { |
| 510 expected = (obj != undefined) && ~obj.indexOf(val); |
| 511 } |
| 512 this.assert( |
| 513 expected |
| 514 , 'expected #{this} to include ' + _.inspect(val) |
| 515 , 'expected #{this} to not include ' + _.inspect(val)); |
| 516 } |
| 517 |
| 518 Assertion.addChainableMethod('include', include, includeChainingBehavior); |
| 519 Assertion.addChainableMethod('contain', include, includeChainingBehavior); |
| 520 Assertion.addChainableMethod('contains', include, includeChainingBehavior); |
| 521 Assertion.addChainableMethod('includes', include, includeChainingBehavior); |
| 522 |
| 523 /** |
| 524 * ### .ok |
| 525 * |
| 526 * Asserts that the target is truthy. |
| 527 * |
| 528 * expect('everything').to.be.ok; |
| 529 * expect(1).to.be.ok; |
| 530 * expect(false).to.not.be.ok; |
| 531 * expect(undefined).to.not.be.ok; |
| 532 * expect(null).to.not.be.ok; |
| 533 * |
| 534 * @name ok |
| 535 * @api public |
| 536 */ |
| 537 |
| 538 Assertion.addProperty('ok', function () { |
| 539 this.assert( |
| 540 flag(this, 'object') |
| 541 , 'expected #{this} to be truthy' |
| 542 , 'expected #{this} to be falsy'); |
| 543 }); |
| 544 |
| 545 /** |
| 546 * ### .true |
| 547 * |
| 548 * Asserts that the target is `true`. |
| 549 * |
| 550 * expect(true).to.be.true; |
| 551 * expect(1).to.not.be.true; |
| 552 * |
| 553 * @name true |
| 554 * @api public |
| 555 */ |
| 556 |
| 557 Assertion.addProperty('true', function () { |
| 558 this.assert( |
| 559 true === flag(this, 'object') |
| 560 , 'expected #{this} to be true' |
| 561 , 'expected #{this} to be false' |
| 562 , this.negate ? false : true |
| 563 ); |
| 564 }); |
| 565 |
| 566 /** |
| 567 * ### .false |
| 568 * |
| 569 * Asserts that the target is `false`. |
| 570 * |
| 571 * expect(false).to.be.false; |
| 572 * expect(0).to.not.be.false; |
| 573 * |
| 574 * @name false |
| 575 * @api public |
| 576 */ |
| 577 |
| 578 Assertion.addProperty('false', function () { |
| 579 this.assert( |
| 580 false === flag(this, 'object') |
| 581 , 'expected #{this} to be false' |
| 582 , 'expected #{this} to be true' |
| 583 , this.negate ? true : false |
| 584 ); |
| 585 }); |
| 586 |
| 587 /** |
| 588 * ### .null |
| 589 * |
| 590 * Asserts that the target is `null`. |
| 591 * |
| 592 * expect(null).to.be.null; |
| 593 * expect(undefined).to.not.be.null; |
| 594 * |
| 595 * @name null |
| 596 * @api public |
| 597 */ |
| 598 |
| 599 Assertion.addProperty('null', function () { |
| 600 this.assert( |
| 601 null === flag(this, 'object') |
| 602 , 'expected #{this} to be null' |
| 603 , 'expected #{this} not to be null' |
| 604 ); |
| 605 }); |
| 606 |
| 607 /** |
| 608 * ### .undefined |
| 609 * |
| 610 * Asserts that the target is `undefined`. |
| 611 * |
| 612 * expect(undefined).to.be.undefined; |
| 613 * expect(null).to.not.be.undefined; |
| 614 * |
| 615 * @name undefined |
| 616 * @api public |
| 617 */ |
| 618 |
| 619 Assertion.addProperty('undefined', function () { |
| 620 this.assert( |
| 621 undefined === flag(this, 'object') |
| 622 , 'expected #{this} to be undefined' |
| 623 , 'expected #{this} not to be undefined' |
| 624 ); |
| 625 }); |
| 626 |
| 627 /** |
| 628 * ### .NaN |
| 629 * Asserts that the target is `NaN`. |
| 630 * |
| 631 * expect('foo').to.be.NaN; |
| 632 * expect(4).not.to.be.NaN; |
| 633 * |
| 634 * @name NaN |
| 635 * @api public |
| 636 */ |
| 637 |
| 638 Assertion.addProperty('NaN', function () { |
| 639 this.assert( |
| 640 isNaN(flag(this, 'object')) |
| 641 , 'expected #{this} to be NaN' |
| 642 , 'expected #{this} not to be NaN' |
| 643 ); |
| 644 }); |
| 645 |
| 646 /** |
| 647 * ### .exist |
| 648 * |
| 649 * Asserts that the target is neither `null` nor `undefined`. |
| 650 * |
| 651 * var foo = 'hi' |
| 652 * , bar = null |
| 653 * , baz; |
| 654 * |
| 655 * expect(foo).to.exist; |
| 656 * expect(bar).to.not.exist; |
| 657 * expect(baz).to.not.exist; |
| 658 * |
| 659 * @name exist |
| 660 * @api public |
| 661 */ |
| 662 |
| 663 Assertion.addProperty('exist', function () { |
| 664 this.assert( |
| 665 null != flag(this, 'object') |
| 666 , 'expected #{this} to exist' |
| 667 , 'expected #{this} to not exist' |
| 668 ); |
| 669 }); |
| 670 |
| 671 |
| 672 /** |
| 673 * ### .empty |
| 674 * |
| 675 * Asserts that the target's length is `0`. For arrays and strings, it checks |
| 676 * the `length` property. For objects, it gets the count of |
| 677 * enumerable keys. |
| 678 * |
| 679 * expect([]).to.be.empty; |
| 680 * expect('').to.be.empty; |
| 681 * expect({}).to.be.empty; |
| 682 * |
| 683 * @name empty |
| 684 * @api public |
| 685 */ |
| 686 |
| 687 Assertion.addProperty('empty', function () { |
| 688 var obj = flag(this, 'object') |
| 689 , expected = obj; |
| 690 |
| 691 if (Array.isArray(obj) || 'string' === typeof object) { |
| 692 expected = obj.length; |
| 693 } else if (typeof obj === 'object') { |
| 694 expected = Object.keys(obj).length; |
| 695 } |
| 696 |
| 697 this.assert( |
| 698 !expected |
| 699 , 'expected #{this} to be empty' |
| 700 , 'expected #{this} not to be empty' |
| 701 ); |
| 702 }); |
| 703 |
| 704 /** |
| 705 * ### .arguments |
| 706 * |
| 707 * Asserts that the target is an arguments object. |
| 708 * |
| 709 * function test () { |
| 710 * expect(arguments).to.be.arguments; |
| 711 * } |
| 712 * |
| 713 * @name arguments |
| 714 * @alias Arguments |
| 715 * @api public |
| 716 */ |
| 717 |
| 718 function checkArguments () { |
| 719 var obj = flag(this, 'object') |
| 720 , type = Object.prototype.toString.call(obj); |
| 721 this.assert( |
| 722 '[object Arguments]' === type |
| 723 , 'expected #{this} to be arguments but got ' + type |
| 724 , 'expected #{this} to not be arguments' |
| 725 ); |
| 726 } |
| 727 |
| 728 Assertion.addProperty('arguments', checkArguments); |
| 729 Assertion.addProperty('Arguments', checkArguments); |
| 730 |
| 731 /** |
| 732 * ### .equal(value) |
| 733 * |
| 734 * Asserts that the target is strictly equal (`===`) to `value`. |
| 735 * Alternately, if the `deep` flag is set, asserts that |
| 736 * the target is deeply equal to `value`. |
| 737 * |
| 738 * expect('hello').to.equal('hello'); |
| 739 * expect(42).to.equal(42); |
| 740 * expect(1).to.not.equal(true); |
| 741 * expect({ foo: 'bar' }).to.not.equal({ foo: 'bar' }); |
| 742 * expect({ foo: 'bar' }).to.deep.equal({ foo: 'bar' }); |
| 743 * |
| 744 * @name equal |
| 745 * @alias equals |
| 746 * @alias eq |
| 747 * @alias deep.equal |
| 748 * @param {Mixed} value |
| 749 * @param {String} message _optional_ |
| 750 * @api public |
| 751 */ |
| 752 |
| 753 function assertEqual (val, msg) { |
| 754 if (msg) flag(this, 'message', msg); |
| 755 var obj = flag(this, 'object'); |
| 756 if (flag(this, 'deep')) { |
| 757 return this.eql(val); |
| 758 } else { |
| 759 this.assert( |
| 760 val === obj |
| 761 , 'expected #{this} to equal #{exp}' |
| 762 , 'expected #{this} to not equal #{exp}' |
| 763 , val |
| 764 , this._obj |
| 765 , true |
| 766 ); |
| 767 } |
| 768 } |
| 769 |
| 770 Assertion.addMethod('equal', assertEqual); |
| 771 Assertion.addMethod('equals', assertEqual); |
| 772 Assertion.addMethod('eq', assertEqual); |
| 773 |
| 774 /** |
| 775 * ### .eql(value) |
| 776 * |
| 777 * Asserts that the target is deeply equal to `value`. |
| 778 * |
| 779 * expect({ foo: 'bar' }).to.eql({ foo: 'bar' }); |
| 780 * expect([ 1, 2, 3 ]).to.eql([ 1, 2, 3 ]); |
| 781 * |
| 782 * @name eql |
| 783 * @alias eqls |
| 784 * @param {Mixed} value |
| 785 * @param {String} message _optional_ |
| 786 * @api public |
| 787 */ |
| 788 |
| 789 function assertEql(obj, msg) { |
| 790 if (msg) flag(this, 'message', msg); |
| 791 this.assert( |
| 792 _.eql(obj, flag(this, 'object')) |
| 793 , 'expected #{this} to deeply equal #{exp}' |
| 794 , 'expected #{this} to not deeply equal #{exp}' |
| 795 , obj |
| 796 , this._obj |
| 797 , true |
| 798 ); |
| 799 } |
| 800 |
| 801 Assertion.addMethod('eql', assertEql); |
| 802 Assertion.addMethod('eqls', assertEql); |
| 803 |
| 804 /** |
| 805 * ### .above(value) |
| 806 * |
| 807 * Asserts that the target is greater than `value`. |
| 808 * |
| 809 * expect(10).to.be.above(5); |
| 810 * |
| 811 * Can also be used in conjunction with `length` to |
| 812 * assert a minimum length. The benefit being a |
| 813 * more informative error message than if the length |
| 814 * was supplied directly. |
| 815 * |
| 816 * expect('foo').to.have.length.above(2); |
| 817 * expect([ 1, 2, 3 ]).to.have.length.above(2); |
| 818 * |
| 819 * @name above |
| 820 * @alias gt |
| 821 * @alias greaterThan |
| 822 * @param {Number} value |
| 823 * @param {String} message _optional_ |
| 824 * @api public |
| 825 */ |
| 826 |
| 827 function assertAbove (n, msg) { |
| 828 if (msg) flag(this, 'message', msg); |
| 829 var obj = flag(this, 'object'); |
| 830 if (flag(this, 'doLength')) { |
| 831 new Assertion(obj, msg).to.have.property('length'); |
| 832 var len = obj.length; |
| 833 this.assert( |
| 834 len > n |
| 835 , 'expected #{this} to have a length above #{exp} but got #{act}' |
| 836 , 'expected #{this} to not have a length above #{exp}' |
| 837 , n |
| 838 , len |
| 839 ); |
| 840 } else { |
| 841 this.assert( |
| 842 obj > n |
| 843 , 'expected #{this} to be above ' + n |
| 844 , 'expected #{this} to be at most ' + n |
| 845 ); |
| 846 } |
| 847 } |
| 848 |
| 849 Assertion.addMethod('above', assertAbove); |
| 850 Assertion.addMethod('gt', assertAbove); |
| 851 Assertion.addMethod('greaterThan', assertAbove); |
| 852 |
| 853 /** |
| 854 * ### .least(value) |
| 855 * |
| 856 * Asserts that the target is greater than or equal to `value`. |
| 857 * |
| 858 * expect(10).to.be.at.least(10); |
| 859 * |
| 860 * Can also be used in conjunction with `length` to |
| 861 * assert a minimum length. The benefit being a |
| 862 * more informative error message than if the length |
| 863 * was supplied directly. |
| 864 * |
| 865 * expect('foo').to.have.length.of.at.least(2); |
| 866 * expect([ 1, 2, 3 ]).to.have.length.of.at.least(3); |
| 867 * |
| 868 * @name least |
| 869 * @alias gte |
| 870 * @param {Number} value |
| 871 * @param {String} message _optional_ |
| 872 * @api public |
| 873 */ |
| 874 |
| 875 function assertLeast (n, msg) { |
| 876 if (msg) flag(this, 'message', msg); |
| 877 var obj = flag(this, 'object'); |
| 878 if (flag(this, 'doLength')) { |
| 879 new Assertion(obj, msg).to.have.property('length'); |
| 880 var len = obj.length; |
| 881 this.assert( |
| 882 len >= n |
| 883 , 'expected #{this} to have a length at least #{exp} but got #{act}' |
| 884 , 'expected #{this} to have a length below #{exp}' |
| 885 , n |
| 886 , len |
| 887 ); |
| 888 } else { |
| 889 this.assert( |
| 890 obj >= n |
| 891 , 'expected #{this} to be at least ' + n |
| 892 , 'expected #{this} to be below ' + n |
| 893 ); |
| 894 } |
| 895 } |
| 896 |
| 897 Assertion.addMethod('least', assertLeast); |
| 898 Assertion.addMethod('gte', assertLeast); |
| 899 |
| 900 /** |
| 901 * ### .below(value) |
| 902 * |
| 903 * Asserts that the target is less than `value`. |
| 904 * |
| 905 * expect(5).to.be.below(10); |
| 906 * |
| 907 * Can also be used in conjunction with `length` to |
| 908 * assert a maximum length. The benefit being a |
| 909 * more informative error message than if the length |
| 910 * was supplied directly. |
| 911 * |
| 912 * expect('foo').to.have.length.below(4); |
| 913 * expect([ 1, 2, 3 ]).to.have.length.below(4); |
| 914 * |
| 915 * @name below |
| 916 * @alias lt |
| 917 * @alias lessThan |
| 918 * @param {Number} value |
| 919 * @param {String} message _optional_ |
| 920 * @api public |
| 921 */ |
| 922 |
| 923 function assertBelow (n, msg) { |
| 924 if (msg) flag(this, 'message', msg); |
| 925 var obj = flag(this, 'object'); |
| 926 if (flag(this, 'doLength')) { |
| 927 new Assertion(obj, msg).to.have.property('length'); |
| 928 var len = obj.length; |
| 929 this.assert( |
| 930 len < n |
| 931 , 'expected #{this} to have a length below #{exp} but got #{act}' |
| 932 , 'expected #{this} to not have a length below #{exp}' |
| 933 , n |
| 934 , len |
| 935 ); |
| 936 } else { |
| 937 this.assert( |
| 938 obj < n |
| 939 , 'expected #{this} to be below ' + n |
| 940 , 'expected #{this} to be at least ' + n |
| 941 ); |
| 942 } |
| 943 } |
| 944 |
| 945 Assertion.addMethod('below', assertBelow); |
| 946 Assertion.addMethod('lt', assertBelow); |
| 947 Assertion.addMethod('lessThan', assertBelow); |
| 948 |
| 949 /** |
| 950 * ### .most(value) |
| 951 * |
| 952 * Asserts that the target is less than or equal to `value`. |
| 953 * |
| 954 * expect(5).to.be.at.most(5); |
| 955 * |
| 956 * Can also be used in conjunction with `length` to |
| 957 * assert a maximum length. The benefit being a |
| 958 * more informative error message than if the length |
| 959 * was supplied directly. |
| 960 * |
| 961 * expect('foo').to.have.length.of.at.most(4); |
| 962 * expect([ 1, 2, 3 ]).to.have.length.of.at.most(3); |
| 963 * |
| 964 * @name most |
| 965 * @alias lte |
| 966 * @param {Number} value |
| 967 * @param {String} message _optional_ |
| 968 * @api public |
| 969 */ |
| 970 |
| 971 function assertMost (n, msg) { |
| 972 if (msg) flag(this, 'message', msg); |
| 973 var obj = flag(this, 'object'); |
| 974 if (flag(this, 'doLength')) { |
| 975 new Assertion(obj, msg).to.have.property('length'); |
| 976 var len = obj.length; |
| 977 this.assert( |
| 978 len <= n |
| 979 , 'expected #{this} to have a length at most #{exp} but got #{act}' |
| 980 , 'expected #{this} to have a length above #{exp}' |
| 981 , n |
| 982 , len |
| 983 ); |
| 984 } else { |
| 985 this.assert( |
| 986 obj <= n |
| 987 , 'expected #{this} to be at most ' + n |
| 988 , 'expected #{this} to be above ' + n |
| 989 ); |
| 990 } |
| 991 } |
| 992 |
| 993 Assertion.addMethod('most', assertMost); |
| 994 Assertion.addMethod('lte', assertMost); |
| 995 |
| 996 /** |
| 997 * ### .within(start, finish) |
| 998 * |
| 999 * Asserts that the target is within a range. |
| 1000 * |
| 1001 * expect(7).to.be.within(5,10); |
| 1002 * |
| 1003 * Can also be used in conjunction with `length` to |
| 1004 * assert a length range. The benefit being a |
| 1005 * more informative error message than if the length |
| 1006 * was supplied directly. |
| 1007 * |
| 1008 * expect('foo').to.have.length.within(2,4); |
| 1009 * expect([ 1, 2, 3 ]).to.have.length.within(2,4); |
| 1010 * |
| 1011 * @name within |
| 1012 * @param {Number} start lowerbound inclusive |
| 1013 * @param {Number} finish upperbound inclusive |
| 1014 * @param {String} message _optional_ |
| 1015 * @api public |
| 1016 */ |
| 1017 |
| 1018 Assertion.addMethod('within', function (start, finish, msg) { |
| 1019 if (msg) flag(this, 'message', msg); |
| 1020 var obj = flag(this, 'object') |
| 1021 , range = start + '..' + finish; |
| 1022 if (flag(this, 'doLength')) { |
| 1023 new Assertion(obj, msg).to.have.property('length'); |
| 1024 var len = obj.length; |
| 1025 this.assert( |
| 1026 len >= start && len <= finish |
| 1027 , 'expected #{this} to have a length within ' + range |
| 1028 , 'expected #{this} to not have a length within ' + range |
| 1029 ); |
| 1030 } else { |
| 1031 this.assert( |
| 1032 obj >= start && obj <= finish |
| 1033 , 'expected #{this} to be within ' + range |
| 1034 , 'expected #{this} to not be within ' + range |
| 1035 ); |
| 1036 } |
| 1037 }); |
| 1038 |
| 1039 /** |
| 1040 * ### .instanceof(constructor) |
| 1041 * |
| 1042 * Asserts that the target is an instance of `constructor`. |
| 1043 * |
| 1044 * var Tea = function (name) { this.name = name; } |
| 1045 * , Chai = new Tea('chai'); |
| 1046 * |
| 1047 * expect(Chai).to.be.an.instanceof(Tea); |
| 1048 * expect([ 1, 2, 3 ]).to.be.instanceof(Array); |
| 1049 * |
| 1050 * @name instanceof |
| 1051 * @param {Constructor} constructor |
| 1052 * @param {String} message _optional_ |
| 1053 * @alias instanceOf |
| 1054 * @api public |
| 1055 */ |
| 1056 |
| 1057 function assertInstanceOf (constructor, msg) { |
| 1058 if (msg) flag(this, 'message', msg); |
| 1059 var name = _.getName(constructor); |
| 1060 this.assert( |
| 1061 flag(this, 'object') instanceof constructor |
| 1062 , 'expected #{this} to be an instance of ' + name |
| 1063 , 'expected #{this} to not be an instance of ' + name |
| 1064 ); |
| 1065 }; |
| 1066 |
| 1067 Assertion.addMethod('instanceof', assertInstanceOf); |
| 1068 Assertion.addMethod('instanceOf', assertInstanceOf); |
| 1069 |
| 1070 /** |
| 1071 * ### .property(name, [value]) |
| 1072 * |
| 1073 * Asserts that the target has a property `name`, optionally asserting that |
| 1074 * the value of that property is strictly equal to `value`. |
| 1075 * If the `deep` flag is set, you can use dot- and bracket-notation for deep |
| 1076 * references into objects and arrays. |
| 1077 * |
| 1078 * // simple referencing |
| 1079 * var obj = { foo: 'bar' }; |
| 1080 * expect(obj).to.have.property('foo'); |
| 1081 * expect(obj).to.have.property('foo', 'bar'); |
| 1082 * |
| 1083 * // deep referencing |
| 1084 * var deepObj = { |
| 1085 * green: { tea: 'matcha' } |
| 1086 * , teas: [ 'chai', 'matcha', { tea: 'konacha' } ] |
| 1087 * }; |
| 1088 * |
| 1089 * expect(deepObj).to.have.deep.property('green.tea', 'matcha'); |
| 1090 * expect(deepObj).to.have.deep.property('teas[1]', 'matcha'); |
| 1091 * expect(deepObj).to.have.deep.property('teas[2].tea', 'konacha'); |
| 1092 * |
| 1093 * You can also use an array as the starting point of a `deep.property` |
| 1094 * assertion, or traverse nested arrays. |
| 1095 * |
| 1096 * var arr = [ |
| 1097 * [ 'chai', 'matcha', 'konacha' ] |
| 1098 * , [ { tea: 'chai' } |
| 1099 * , { tea: 'matcha' } |
| 1100 * , { tea: 'konacha' } ] |
| 1101 * ]; |
| 1102 * |
| 1103 * expect(arr).to.have.deep.property('[0][1]', 'matcha'); |
| 1104 * expect(arr).to.have.deep.property('[1][2].tea', 'konacha'); |
| 1105 * |
| 1106 * Furthermore, `property` changes the subject of the assertion |
| 1107 * to be the value of that property from the original object. This |
| 1108 * permits for further chainable assertions on that property. |
| 1109 * |
| 1110 * expect(obj).to.have.property('foo') |
| 1111 * .that.is.a('string'); |
| 1112 * expect(deepObj).to.have.property('green') |
| 1113 * .that.is.an('object') |
| 1114 * .that.deep.equals({ tea: 'matcha' }); |
| 1115 * expect(deepObj).to.have.property('teas') |
| 1116 * .that.is.an('array') |
| 1117 * .with.deep.property('[2]') |
| 1118 * .that.deep.equals({ tea: 'konacha' }); |
| 1119 * |
| 1120 * Note that dots and bracket in `name` must be backslash-escaped when |
| 1121 * the `deep` flag is set, while they must NOT be escaped when the `deep` |
| 1122 * flag is not set. |
| 1123 * |
| 1124 * // simple referencing |
| 1125 * var css = { '.link[target]': 42 }; |
| 1126 * expect(css).to.have.property('.link[target]', 42); |
| 1127 * |
| 1128 * // deep referencing |
| 1129 * var deepCss = { '.link': { '[target]': 42 }}; |
| 1130 * expect(deepCss).to.have.deep.property('\\.link.\\[target\\]', 42); |
| 1131 * |
| 1132 * @name property |
| 1133 * @alias deep.property |
| 1134 * @param {String} name |
| 1135 * @param {Mixed} value (optional) |
| 1136 * @param {String} message _optional_ |
| 1137 * @returns value of property for chaining |
| 1138 * @api public |
| 1139 */ |
| 1140 |
| 1141 Assertion.addMethod('property', function (name, val, msg) { |
| 1142 if (msg) flag(this, 'message', msg); |
| 1143 |
| 1144 var isDeep = !!flag(this, 'deep') |
| 1145 , descriptor = isDeep ? 'deep property ' : 'property ' |
| 1146 , negate = flag(this, 'negate') |
| 1147 , obj = flag(this, 'object') |
| 1148 , pathInfo = isDeep ? _.getPathInfo(name, obj) : null |
| 1149 , hasProperty = isDeep |
| 1150 ? pathInfo.exists |
| 1151 : _.hasProperty(name, obj) |
| 1152 , value = isDeep |
| 1153 ? pathInfo.value |
| 1154 : obj[name]; |
| 1155 |
| 1156 if (negate && arguments.length > 1) { |
| 1157 if (undefined === value) { |
| 1158 msg = (msg != null) ? msg + ': ' : ''; |
| 1159 throw new Error(msg + _.inspect(obj) + ' has no ' + descriptor + _.inspe
ct(name)); |
| 1160 } |
| 1161 } else { |
| 1162 this.assert( |
| 1163 hasProperty |
| 1164 , 'expected #{this} to have a ' + descriptor + _.inspect(name) |
| 1165 , 'expected #{this} to not have ' + descriptor + _.inspect(name)); |
| 1166 } |
| 1167 |
| 1168 if (arguments.length > 1) { |
| 1169 this.assert( |
| 1170 val === value |
| 1171 , 'expected #{this} to have a ' + descriptor + _.inspect(name) + ' of #{
exp}, but got #{act}' |
| 1172 , 'expected #{this} to not have a ' + descriptor + _.inspect(name) + ' o
f #{act}' |
| 1173 , val |
| 1174 , value |
| 1175 ); |
| 1176 } |
| 1177 |
| 1178 flag(this, 'object', value); |
| 1179 }); |
| 1180 |
| 1181 |
| 1182 /** |
| 1183 * ### .ownProperty(name) |
| 1184 * |
| 1185 * Asserts that the target has an own property `name`. |
| 1186 * |
| 1187 * expect('test').to.have.ownProperty('length'); |
| 1188 * |
| 1189 * @name ownProperty |
| 1190 * @alias haveOwnProperty |
| 1191 * @param {String} name |
| 1192 * @param {String} message _optional_ |
| 1193 * @api public |
| 1194 */ |
| 1195 |
| 1196 function assertOwnProperty (name, msg) { |
| 1197 if (msg) flag(this, 'message', msg); |
| 1198 var obj = flag(this, 'object'); |
| 1199 this.assert( |
| 1200 obj.hasOwnProperty(name) |
| 1201 , 'expected #{this} to have own property ' + _.inspect(name) |
| 1202 , 'expected #{this} to not have own property ' + _.inspect(name) |
| 1203 ); |
| 1204 } |
| 1205 |
| 1206 Assertion.addMethod('ownProperty', assertOwnProperty); |
| 1207 Assertion.addMethod('haveOwnProperty', assertOwnProperty); |
| 1208 |
| 1209 /** |
| 1210 * ### .ownPropertyDescriptor(name[, descriptor[, message]]) |
| 1211 * |
| 1212 * Asserts that the target has an own property descriptor `name`, that optiona
lly matches `descriptor`. |
| 1213 * |
| 1214 * expect('test').to.have.ownPropertyDescriptor('length'); |
| 1215 * expect('test').to.have.ownPropertyDescriptor('length', { enumerable: fa
lse, configurable: false, writable: false, value: 4 }); |
| 1216 * expect('test').not.to.have.ownPropertyDescriptor('length', { enumerable
: false, configurable: false, writable: false, value: 3 }); |
| 1217 * expect('test').ownPropertyDescriptor('length').to.have.property('enumer
able', false); |
| 1218 * expect('test').ownPropertyDescriptor('length').to.have.keys('value'); |
| 1219 * |
| 1220 * @name ownPropertyDescriptor |
| 1221 * @alias haveOwnPropertyDescriptor |
| 1222 * @param {String} name |
| 1223 * @param {Object} descriptor _optional_ |
| 1224 * @param {String} message _optional_ |
| 1225 * @api public |
| 1226 */ |
| 1227 |
| 1228 function assertOwnPropertyDescriptor (name, descriptor, msg) { |
| 1229 if (typeof descriptor === 'string') { |
| 1230 msg = descriptor; |
| 1231 descriptor = null; |
| 1232 } |
| 1233 if (msg) flag(this, 'message', msg); |
| 1234 var obj = flag(this, 'object'); |
| 1235 var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); |
| 1236 if (actualDescriptor && descriptor) { |
| 1237 this.assert( |
| 1238 _.eql(descriptor, actualDescriptor) |
| 1239 , 'expected the own property descriptor for ' + _.inspect(name) + ' on #
{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescripto
r) |
| 1240 , 'expected the own property descriptor for ' + _.inspect(name) + ' on #
{this} to not match ' + _.inspect(descriptor) |
| 1241 , descriptor |
| 1242 , actualDescriptor |
| 1243 , true |
| 1244 ); |
| 1245 } else { |
| 1246 this.assert( |
| 1247 actualDescriptor |
| 1248 , 'expected #{this} to have an own property descriptor for ' + _.inspect
(name) |
| 1249 , 'expected #{this} to not have an own property descriptor for ' + _.ins
pect(name) |
| 1250 ); |
| 1251 } |
| 1252 flag(this, 'object', actualDescriptor); |
| 1253 } |
| 1254 |
| 1255 Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); |
| 1256 Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); |
| 1257 |
| 1258 /** |
| 1259 * ### .length |
| 1260 * |
| 1261 * Sets the `doLength` flag later used as a chain precursor to a value |
| 1262 * comparison for the `length` property. |
| 1263 * |
| 1264 * expect('foo').to.have.length.above(2); |
| 1265 * expect([ 1, 2, 3 ]).to.have.length.above(2); |
| 1266 * expect('foo').to.have.length.below(4); |
| 1267 * expect([ 1, 2, 3 ]).to.have.length.below(4); |
| 1268 * expect('foo').to.have.length.within(2,4); |
| 1269 * expect([ 1, 2, 3 ]).to.have.length.within(2,4); |
| 1270 * |
| 1271 * *Deprecation notice:* Using `length` as an assertion will be deprecated |
| 1272 * in version 2.4.0 and removed in 3.0.0. Code using the old style of |
| 1273 * asserting for `length` property value using `length(value)` should be |
| 1274 * switched to use `lengthOf(value)` instead. |
| 1275 * |
| 1276 * @name length |
| 1277 * @api public |
| 1278 */ |
| 1279 |
| 1280 /** |
| 1281 * ### .lengthOf(value[, message]) |
| 1282 * |
| 1283 * Asserts that the target's `length` property has |
| 1284 * the expected value. |
| 1285 * |
| 1286 * expect([ 1, 2, 3]).to.have.lengthOf(3); |
| 1287 * expect('foobar').to.have.lengthOf(6); |
| 1288 * |
| 1289 * @name lengthOf |
| 1290 * @param {Number} length |
| 1291 * @param {String} message _optional_ |
| 1292 * @api public |
| 1293 */ |
| 1294 |
| 1295 function assertLengthChain () { |
| 1296 flag(this, 'doLength', true); |
| 1297 } |
| 1298 |
| 1299 function assertLength (n, msg) { |
| 1300 if (msg) flag(this, 'message', msg); |
| 1301 var obj = flag(this, 'object'); |
| 1302 new Assertion(obj, msg).to.have.property('length'); |
| 1303 var len = obj.length; |
| 1304 |
| 1305 this.assert( |
| 1306 len == n |
| 1307 , 'expected #{this} to have a length of #{exp} but got #{act}' |
| 1308 , 'expected #{this} to not have a length of #{act}' |
| 1309 , n |
| 1310 , len |
| 1311 ); |
| 1312 } |
| 1313 |
| 1314 Assertion.addChainableMethod('length', assertLength, assertLengthChain); |
| 1315 Assertion.addMethod('lengthOf', assertLength); |
| 1316 |
| 1317 /** |
| 1318 * ### .match(regexp) |
| 1319 * |
| 1320 * Asserts that the target matches a regular expression. |
| 1321 * |
| 1322 * expect('foobar').to.match(/^foo/); |
| 1323 * |
| 1324 * @name match |
| 1325 * @alias matches |
| 1326 * @param {RegExp} RegularExpression |
| 1327 * @param {String} message _optional_ |
| 1328 * @api public |
| 1329 */ |
| 1330 function assertMatch(re, msg) { |
| 1331 if (msg) flag(this, 'message', msg); |
| 1332 var obj = flag(this, 'object'); |
| 1333 this.assert( |
| 1334 re.exec(obj) |
| 1335 , 'expected #{this} to match ' + re |
| 1336 , 'expected #{this} not to match ' + re |
| 1337 ); |
| 1338 } |
| 1339 |
| 1340 Assertion.addMethod('match', assertMatch); |
| 1341 Assertion.addMethod('matches', assertMatch); |
| 1342 |
| 1343 /** |
| 1344 * ### .string(string) |
| 1345 * |
| 1346 * Asserts that the string target contains another string. |
| 1347 * |
| 1348 * expect('foobar').to.have.string('bar'); |
| 1349 * |
| 1350 * @name string |
| 1351 * @param {String} string |
| 1352 * @param {String} message _optional_ |
| 1353 * @api public |
| 1354 */ |
| 1355 |
| 1356 Assertion.addMethod('string', function (str, msg) { |
| 1357 if (msg) flag(this, 'message', msg); |
| 1358 var obj = flag(this, 'object'); |
| 1359 new Assertion(obj, msg).is.a('string'); |
| 1360 |
| 1361 this.assert( |
| 1362 ~obj.indexOf(str) |
| 1363 , 'expected #{this} to contain ' + _.inspect(str) |
| 1364 , 'expected #{this} to not contain ' + _.inspect(str) |
| 1365 ); |
| 1366 }); |
| 1367 |
| 1368 |
| 1369 /** |
| 1370 * ### .keys(key1, [key2], [...]) |
| 1371 * |
| 1372 * Asserts that the target contains any or all of the passed-in keys. |
| 1373 * Use in combination with `any`, `all`, `contains`, or `have` will affect |
| 1374 * what will pass. |
| 1375 * |
| 1376 * When used in conjunction with `any`, at least one key that is passed |
| 1377 * in must exist in the target object. This is regardless whether or not |
| 1378 * the `have` or `contain` qualifiers are used. Note, either `any` or `all` |
| 1379 * should be used in the assertion. If neither are used, the assertion is |
| 1380 * defaulted to `all`. |
| 1381 * |
| 1382 * When both `all` and `contain` are used, the target object must have at |
| 1383 * least all of the passed-in keys but may have more keys not listed. |
| 1384 * |
| 1385 * When both `all` and `have` are used, the target object must both contain |
| 1386 * all of the passed-in keys AND the number of keys in the target object must |
| 1387 * match the number of keys passed in (in other words, a target object must |
| 1388 * have all and only all of the passed-in keys). |
| 1389 * |
| 1390 * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo', 'baz'); |
| 1391 * expect({ foo: 1, bar: 2 }).to.have.any.keys('foo'); |
| 1392 * expect({ foo: 1, bar: 2 }).to.contain.any.keys('bar', 'baz'); |
| 1393 * expect({ foo: 1, bar: 2 }).to.contain.any.keys(['foo']); |
| 1394 * expect({ foo: 1, bar: 2 }).to.contain.any.keys({'foo': 6}); |
| 1395 * expect({ foo: 1, bar: 2 }).to.have.all.keys(['bar', 'foo']); |
| 1396 * expect({ foo: 1, bar: 2 }).to.have.all.keys({'bar': 6, 'foo': 7}); |
| 1397 * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys(['bar', 'foo']); |
| 1398 * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.all.keys({'bar': 6}); |
| 1399 * |
| 1400 * |
| 1401 * @name keys |
| 1402 * @alias key |
| 1403 * @param {...String|Array|Object} keys |
| 1404 * @api public |
| 1405 */ |
| 1406 |
| 1407 function assertKeys (keys) { |
| 1408 var obj = flag(this, 'object') |
| 1409 , str |
| 1410 , ok = true |
| 1411 , mixedArgsMsg = 'keys must be given single argument of Array|Object|Strin
g, or multiple String arguments'; |
| 1412 |
| 1413 switch (_.type(keys)) { |
| 1414 case "array": |
| 1415 if (arguments.length > 1) throw (new Error(mixedArgsMsg)); |
| 1416 break; |
| 1417 case "object": |
| 1418 if (arguments.length > 1) throw (new Error(mixedArgsMsg)); |
| 1419 keys = Object.keys(keys); |
| 1420 break; |
| 1421 default: |
| 1422 keys = Array.prototype.slice.call(arguments); |
| 1423 } |
| 1424 |
| 1425 if (!keys.length) throw new Error('keys required'); |
| 1426 |
| 1427 var actual = Object.keys(obj) |
| 1428 , expected = keys |
| 1429 , len = keys.length |
| 1430 , any = flag(this, 'any') |
| 1431 , all = flag(this, 'all'); |
| 1432 |
| 1433 if (!any && !all) { |
| 1434 all = true; |
| 1435 } |
| 1436 |
| 1437 // Has any |
| 1438 if (any) { |
| 1439 var intersection = expected.filter(function(key) { |
| 1440 return ~actual.indexOf(key); |
| 1441 }); |
| 1442 ok = intersection.length > 0; |
| 1443 } |
| 1444 |
| 1445 // Has all |
| 1446 if (all) { |
| 1447 ok = keys.every(function(key){ |
| 1448 return ~actual.indexOf(key); |
| 1449 }); |
| 1450 if (!flag(this, 'negate') && !flag(this, 'contains')) { |
| 1451 ok = ok && keys.length == actual.length; |
| 1452 } |
| 1453 } |
| 1454 |
| 1455 // Key string |
| 1456 if (len > 1) { |
| 1457 keys = keys.map(function(key){ |
| 1458 return _.inspect(key); |
| 1459 }); |
| 1460 var last = keys.pop(); |
| 1461 if (all) { |
| 1462 str = keys.join(', ') + ', and ' + last; |
| 1463 } |
| 1464 if (any) { |
| 1465 str = keys.join(', ') + ', or ' + last; |
| 1466 } |
| 1467 } else { |
| 1468 str = _.inspect(keys[0]); |
| 1469 } |
| 1470 |
| 1471 // Form |
| 1472 str = (len > 1 ? 'keys ' : 'key ') + str; |
| 1473 |
| 1474 // Have / include |
| 1475 str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; |
| 1476 |
| 1477 // Assertion |
| 1478 this.assert( |
| 1479 ok |
| 1480 , 'expected #{this} to ' + str |
| 1481 , 'expected #{this} to not ' + str |
| 1482 , expected.slice(0).sort() |
| 1483 , actual.sort() |
| 1484 , true |
| 1485 ); |
| 1486 } |
| 1487 |
| 1488 Assertion.addMethod('keys', assertKeys); |
| 1489 Assertion.addMethod('key', assertKeys); |
| 1490 |
| 1491 /** |
| 1492 * ### .throw(constructor) |
| 1493 * |
| 1494 * Asserts that the function target will throw a specific error, or specific t
ype of error |
| 1495 * (as determined using `instanceof`), optionally with a RegExp or string incl
usion test |
| 1496 * for the error's message. |
| 1497 * |
| 1498 * var err = new ReferenceError('This is a bad function.'); |
| 1499 * var fn = function () { throw err; } |
| 1500 * expect(fn).to.throw(ReferenceError); |
| 1501 * expect(fn).to.throw(Error); |
| 1502 * expect(fn).to.throw(/bad function/); |
| 1503 * expect(fn).to.not.throw('good function'); |
| 1504 * expect(fn).to.throw(ReferenceError, /bad function/); |
| 1505 * expect(fn).to.throw(err); |
| 1506 * |
| 1507 * Please note that when a throw expectation is negated, it will check each |
| 1508 * parameter independently, starting with error constructor type. The appropri
ate way |
| 1509 * to check for the existence of a type of error but for a message that does n
ot match |
| 1510 * is to use `and`. |
| 1511 * |
| 1512 * expect(fn).to.throw(ReferenceError) |
| 1513 * .and.not.throw(/good function/); |
| 1514 * |
| 1515 * @name throw |
| 1516 * @alias throws |
| 1517 * @alias Throw |
| 1518 * @param {ErrorConstructor} constructor |
| 1519 * @param {String|RegExp} expected error message |
| 1520 * @param {String} message _optional_ |
| 1521 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/E
rror#Error_types |
| 1522 * @returns error for chaining (null if no error) |
| 1523 * @api public |
| 1524 */ |
| 1525 |
| 1526 function assertThrows (constructor, errMsg, msg) { |
| 1527 if (msg) flag(this, 'message', msg); |
| 1528 var obj = flag(this, 'object'); |
| 1529 new Assertion(obj, msg).is.a('function'); |
| 1530 |
| 1531 var thrown = false |
| 1532 , desiredError = null |
| 1533 , name = null |
| 1534 , thrownError = null; |
| 1535 |
| 1536 if (arguments.length === 0) { |
| 1537 errMsg = null; |
| 1538 constructor = null; |
| 1539 } else if (constructor && (constructor instanceof RegExp || 'string' === typ
eof constructor)) { |
| 1540 errMsg = constructor; |
| 1541 constructor = null; |
| 1542 } else if (constructor && constructor instanceof Error) { |
| 1543 desiredError = constructor; |
| 1544 constructor = null; |
| 1545 errMsg = null; |
| 1546 } else if (typeof constructor === 'function') { |
| 1547 name = constructor.prototype.name; |
| 1548 if (!name || (name === 'Error' && constructor !== Error)) { |
| 1549 name = constructor.name || (new constructor()).name; |
| 1550 } |
| 1551 } else { |
| 1552 constructor = null; |
| 1553 } |
| 1554 |
| 1555 try { |
| 1556 obj(); |
| 1557 } catch (err) { |
| 1558 // first, check desired error |
| 1559 if (desiredError) { |
| 1560 this.assert( |
| 1561 err === desiredError |
| 1562 , 'expected #{this} to throw #{exp} but #{act} was thrown' |
| 1563 , 'expected #{this} to not throw #{exp}' |
| 1564 , (desiredError instanceof Error ? desiredError.toString() : desiredEr
ror) |
| 1565 , (err instanceof Error ? err.toString() : err) |
| 1566 ); |
| 1567 |
| 1568 flag(this, 'object', err); |
| 1569 return this; |
| 1570 } |
| 1571 |
| 1572 // next, check constructor |
| 1573 if (constructor) { |
| 1574 this.assert( |
| 1575 err instanceof constructor |
| 1576 , 'expected #{this} to throw #{exp} but #{act} was thrown' |
| 1577 , 'expected #{this} to not throw #{exp} but #{act} was thrown' |
| 1578 , name |
| 1579 , (err instanceof Error ? err.toString() : err) |
| 1580 ); |
| 1581 |
| 1582 if (!errMsg) { |
| 1583 flag(this, 'object', err); |
| 1584 return this; |
| 1585 } |
| 1586 } |
| 1587 |
| 1588 // next, check message |
| 1589 var message = 'error' === _.type(err) && "message" in err |
| 1590 ? err.message |
| 1591 : '' + err; |
| 1592 |
| 1593 if ((message != null) && errMsg && errMsg instanceof RegExp) { |
| 1594 this.assert( |
| 1595 errMsg.exec(message) |
| 1596 , 'expected #{this} to throw error matching #{exp} but got #{act}' |
| 1597 , 'expected #{this} to throw error not matching #{exp}' |
| 1598 , errMsg |
| 1599 , message |
| 1600 ); |
| 1601 |
| 1602 flag(this, 'object', err); |
| 1603 return this; |
| 1604 } else if ((message != null) && errMsg && 'string' === typeof errMsg) { |
| 1605 this.assert( |
| 1606 ~message.indexOf(errMsg) |
| 1607 , 'expected #{this} to throw error including #{exp} but got #{act}' |
| 1608 , 'expected #{this} to throw error not including #{act}' |
| 1609 , errMsg |
| 1610 , message |
| 1611 ); |
| 1612 |
| 1613 flag(this, 'object', err); |
| 1614 return this; |
| 1615 } else { |
| 1616 thrown = true; |
| 1617 thrownError = err; |
| 1618 } |
| 1619 } |
| 1620 |
| 1621 var actuallyGot = '' |
| 1622 , expectedThrown = name !== null |
| 1623 ? name |
| 1624 : desiredError |
| 1625 ? '#{exp}' //_.inspect(desiredError) |
| 1626 : 'an error'; |
| 1627 |
| 1628 if (thrown) { |
| 1629 actuallyGot = ' but #{act} was thrown' |
| 1630 } |
| 1631 |
| 1632 this.assert( |
| 1633 thrown === true |
| 1634 , 'expected #{this} to throw ' + expectedThrown + actuallyGot |
| 1635 , 'expected #{this} to not throw ' + expectedThrown + actuallyGot |
| 1636 , (desiredError instanceof Error ? desiredError.toString() : desiredError) |
| 1637 , (thrownError instanceof Error ? thrownError.toString() : thrownError) |
| 1638 ); |
| 1639 |
| 1640 flag(this, 'object', thrownError); |
| 1641 }; |
| 1642 |
| 1643 Assertion.addMethod('throw', assertThrows); |
| 1644 Assertion.addMethod('throws', assertThrows); |
| 1645 Assertion.addMethod('Throw', assertThrows); |
| 1646 |
| 1647 /** |
| 1648 * ### .respondTo(method) |
| 1649 * |
| 1650 * Asserts that the object or class target will respond to a method. |
| 1651 * |
| 1652 * Klass.prototype.bar = function(){}; |
| 1653 * expect(Klass).to.respondTo('bar'); |
| 1654 * expect(obj).to.respondTo('bar'); |
| 1655 * |
| 1656 * To check if a constructor will respond to a static function, |
| 1657 * set the `itself` flag. |
| 1658 * |
| 1659 * Klass.baz = function(){}; |
| 1660 * expect(Klass).itself.to.respondTo('baz'); |
| 1661 * |
| 1662 * @name respondTo |
| 1663 * @alias respondsTo |
| 1664 * @param {String} method |
| 1665 * @param {String} message _optional_ |
| 1666 * @api public |
| 1667 */ |
| 1668 |
| 1669 function respondTo (method, msg) { |
| 1670 if (msg) flag(this, 'message', msg); |
| 1671 var obj = flag(this, 'object') |
| 1672 , itself = flag(this, 'itself') |
| 1673 , context = ('function' === _.type(obj) && !itself) |
| 1674 ? obj.prototype[method] |
| 1675 : obj[method]; |
| 1676 |
| 1677 this.assert( |
| 1678 'function' === typeof context |
| 1679 , 'expected #{this} to respond to ' + _.inspect(method) |
| 1680 , 'expected #{this} to not respond to ' + _.inspect(method) |
| 1681 ); |
| 1682 } |
| 1683 |
| 1684 Assertion.addMethod('respondTo', respondTo); |
| 1685 Assertion.addMethod('respondsTo', respondTo); |
| 1686 |
| 1687 /** |
| 1688 * ### .itself |
| 1689 * |
| 1690 * Sets the `itself` flag, later used by the `respondTo` assertion. |
| 1691 * |
| 1692 * function Foo() {} |
| 1693 * Foo.bar = function() {} |
| 1694 * Foo.prototype.baz = function() {} |
| 1695 * |
| 1696 * expect(Foo).itself.to.respondTo('bar'); |
| 1697 * expect(Foo).itself.not.to.respondTo('baz'); |
| 1698 * |
| 1699 * @name itself |
| 1700 * @api public |
| 1701 */ |
| 1702 |
| 1703 Assertion.addProperty('itself', function () { |
| 1704 flag(this, 'itself', true); |
| 1705 }); |
| 1706 |
| 1707 /** |
| 1708 * ### .satisfy(method) |
| 1709 * |
| 1710 * Asserts that the target passes a given truth test. |
| 1711 * |
| 1712 * expect(1).to.satisfy(function(num) { return num > 0; }); |
| 1713 * |
| 1714 * @name satisfy |
| 1715 * @alias satisfies |
| 1716 * @param {Function} matcher |
| 1717 * @param {String} message _optional_ |
| 1718 * @api public |
| 1719 */ |
| 1720 |
| 1721 function satisfy (matcher, msg) { |
| 1722 if (msg) flag(this, 'message', msg); |
| 1723 var obj = flag(this, 'object'); |
| 1724 var result = matcher(obj); |
| 1725 this.assert( |
| 1726 result |
| 1727 , 'expected #{this} to satisfy ' + _.objDisplay(matcher) |
| 1728 , 'expected #{this} to not satisfy' + _.objDisplay(matcher) |
| 1729 , this.negate ? false : true |
| 1730 , result |
| 1731 ); |
| 1732 } |
| 1733 |
| 1734 Assertion.addMethod('satisfy', satisfy); |
| 1735 Assertion.addMethod('satisfies', satisfy); |
| 1736 |
| 1737 /** |
| 1738 * ### .closeTo(expected, delta) |
| 1739 * |
| 1740 * Asserts that the target is equal `expected`, to within a +/- `delta` range. |
| 1741 * |
| 1742 * expect(1.5).to.be.closeTo(1, 0.5); |
| 1743 * |
| 1744 * @name closeTo |
| 1745 * @alias approximately |
| 1746 * @param {Number} expected |
| 1747 * @param {Number} delta |
| 1748 * @param {String} message _optional_ |
| 1749 * @api public |
| 1750 */ |
| 1751 |
| 1752 function closeTo(expected, delta, msg) { |
| 1753 if (msg) flag(this, 'message', msg); |
| 1754 var obj = flag(this, 'object'); |
| 1755 |
| 1756 new Assertion(obj, msg).is.a('number'); |
| 1757 if (_.type(expected) !== 'number' || _.type(delta) !== 'number') { |
| 1758 throw new Error('the arguments to closeTo or approximately must be numbers
'); |
| 1759 } |
| 1760 |
| 1761 this.assert( |
| 1762 Math.abs(obj - expected) <= delta |
| 1763 , 'expected #{this} to be close to ' + expected + ' +/- ' + delta |
| 1764 , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta |
| 1765 ); |
| 1766 } |
| 1767 |
| 1768 Assertion.addMethod('closeTo', closeTo); |
| 1769 Assertion.addMethod('approximately', closeTo); |
| 1770 |
| 1771 function isSubsetOf(subset, superset, cmp) { |
| 1772 return subset.every(function(elem) { |
| 1773 if (!cmp) return superset.indexOf(elem) !== -1; |
| 1774 |
| 1775 return superset.some(function(elem2) { |
| 1776 return cmp(elem, elem2); |
| 1777 }); |
| 1778 }) |
| 1779 } |
| 1780 |
| 1781 /** |
| 1782 * ### .members(set) |
| 1783 * |
| 1784 * Asserts that the target is a superset of `set`, |
| 1785 * or that the target and `set` have the same strictly-equal (===) members. |
| 1786 * Alternately, if the `deep` flag is set, set members are compared for deep |
| 1787 * equality. |
| 1788 * |
| 1789 * expect([1, 2, 3]).to.include.members([3, 2]); |
| 1790 * expect([1, 2, 3]).to.not.include.members([3, 2, 8]); |
| 1791 * |
| 1792 * expect([4, 2]).to.have.members([2, 4]); |
| 1793 * expect([5, 2]).to.not.have.members([5, 2, 1]); |
| 1794 * |
| 1795 * expect([{ id: 1 }]).to.deep.include.members([{ id: 1 }]); |
| 1796 * |
| 1797 * @name members |
| 1798 * @param {Array} set |
| 1799 * @param {String} message _optional_ |
| 1800 * @api public |
| 1801 */ |
| 1802 |
| 1803 Assertion.addMethod('members', function (subset, msg) { |
| 1804 if (msg) flag(this, 'message', msg); |
| 1805 var obj = flag(this, 'object'); |
| 1806 |
| 1807 new Assertion(obj).to.be.an('array'); |
| 1808 new Assertion(subset).to.be.an('array'); |
| 1809 |
| 1810 var cmp = flag(this, 'deep') ? _.eql : undefined; |
| 1811 |
| 1812 if (flag(this, 'contains')) { |
| 1813 return this.assert( |
| 1814 isSubsetOf(subset, obj, cmp) |
| 1815 , 'expected #{this} to be a superset of #{act}' |
| 1816 , 'expected #{this} to not be a superset of #{act}' |
| 1817 , obj |
| 1818 , subset |
| 1819 ); |
| 1820 } |
| 1821 |
| 1822 this.assert( |
| 1823 isSubsetOf(obj, subset, cmp) && isSubsetOf(subset, obj, cmp) |
| 1824 , 'expected #{this} to have the same members as #{act}' |
| 1825 , 'expected #{this} to not have the same members as #{act}' |
| 1826 , obj |
| 1827 , subset |
| 1828 ); |
| 1829 }); |
| 1830 |
| 1831 /** |
| 1832 * ### .oneOf(list) |
| 1833 * |
| 1834 * Assert that a value appears somewhere in the top level of array `list`. |
| 1835 * |
| 1836 * expect('a').to.be.oneOf(['a', 'b', 'c']); |
| 1837 * expect(9).to.not.be.oneOf(['z']); |
| 1838 * expect([3]).to.not.be.oneOf([1, 2, [3]]); |
| 1839 * |
| 1840 * var three = [3]; |
| 1841 * // for object-types, contents are not compared |
| 1842 * expect(three).to.not.be.oneOf([1, 2, [3]]); |
| 1843 * // comparing references works |
| 1844 * expect(three).to.be.oneOf([1, 2, three]); |
| 1845 * |
| 1846 * @name oneOf |
| 1847 * @param {Array<*>} list |
| 1848 * @param {String} message _optional_ |
| 1849 * @api public |
| 1850 */ |
| 1851 |
| 1852 function oneOf (list, msg) { |
| 1853 if (msg) flag(this, 'message', msg); |
| 1854 var expected = flag(this, 'object'); |
| 1855 new Assertion(list).to.be.an('array'); |
| 1856 |
| 1857 this.assert( |
| 1858 list.indexOf(expected) > -1 |
| 1859 , 'expected #{this} to be one of #{exp}' |
| 1860 , 'expected #{this} to not be one of #{exp}' |
| 1861 , list |
| 1862 , expected |
| 1863 ); |
| 1864 } |
| 1865 |
| 1866 Assertion.addMethod('oneOf', oneOf); |
| 1867 |
| 1868 |
| 1869 /** |
| 1870 * ### .change(function) |
| 1871 * |
| 1872 * Asserts that a function changes an object property |
| 1873 * |
| 1874 * var obj = { val: 10 }; |
| 1875 * var fn = function() { obj.val += 3 }; |
| 1876 * var noChangeFn = function() { return 'foo' + 'bar'; } |
| 1877 * expect(fn).to.change(obj, 'val'); |
| 1878 * expect(noChangFn).to.not.change(obj, 'val') |
| 1879 * |
| 1880 * @name change |
| 1881 * @alias changes |
| 1882 * @alias Change |
| 1883 * @param {String} object |
| 1884 * @param {String} property name |
| 1885 * @param {String} message _optional_ |
| 1886 * @api public |
| 1887 */ |
| 1888 |
| 1889 function assertChanges (object, prop, msg) { |
| 1890 if (msg) flag(this, 'message', msg); |
| 1891 var fn = flag(this, 'object'); |
| 1892 new Assertion(object, msg).to.have.property(prop); |
| 1893 new Assertion(fn).is.a('function'); |
| 1894 |
| 1895 var initial = object[prop]; |
| 1896 fn(); |
| 1897 |
| 1898 this.assert( |
| 1899 initial !== object[prop] |
| 1900 , 'expected .' + prop + ' to change' |
| 1901 , 'expected .' + prop + ' to not change' |
| 1902 ); |
| 1903 } |
| 1904 |
| 1905 Assertion.addChainableMethod('change', assertChanges); |
| 1906 Assertion.addChainableMethod('changes', assertChanges); |
| 1907 |
| 1908 /** |
| 1909 * ### .increase(function) |
| 1910 * |
| 1911 * Asserts that a function increases an object property |
| 1912 * |
| 1913 * var obj = { val: 10 }; |
| 1914 * var fn = function() { obj.val = 15 }; |
| 1915 * expect(fn).to.increase(obj, 'val'); |
| 1916 * |
| 1917 * @name increase |
| 1918 * @alias increases |
| 1919 * @alias Increase |
| 1920 * @param {String} object |
| 1921 * @param {String} property name |
| 1922 * @param {String} message _optional_ |
| 1923 * @api public |
| 1924 */ |
| 1925 |
| 1926 function assertIncreases (object, prop, msg) { |
| 1927 if (msg) flag(this, 'message', msg); |
| 1928 var fn = flag(this, 'object'); |
| 1929 new Assertion(object, msg).to.have.property(prop); |
| 1930 new Assertion(fn).is.a('function'); |
| 1931 |
| 1932 var initial = object[prop]; |
| 1933 fn(); |
| 1934 |
| 1935 this.assert( |
| 1936 object[prop] - initial > 0 |
| 1937 , 'expected .' + prop + ' to increase' |
| 1938 , 'expected .' + prop + ' to not increase' |
| 1939 ); |
| 1940 } |
| 1941 |
| 1942 Assertion.addChainableMethod('increase', assertIncreases); |
| 1943 Assertion.addChainableMethod('increases', assertIncreases); |
| 1944 |
| 1945 /** |
| 1946 * ### .decrease(function) |
| 1947 * |
| 1948 * Asserts that a function decreases an object property |
| 1949 * |
| 1950 * var obj = { val: 10 }; |
| 1951 * var fn = function() { obj.val = 5 }; |
| 1952 * expect(fn).to.decrease(obj, 'val'); |
| 1953 * |
| 1954 * @name decrease |
| 1955 * @alias decreases |
| 1956 * @alias Decrease |
| 1957 * @param {String} object |
| 1958 * @param {String} property name |
| 1959 * @param {String} message _optional_ |
| 1960 * @api public |
| 1961 */ |
| 1962 |
| 1963 function assertDecreases (object, prop, msg) { |
| 1964 if (msg) flag(this, 'message', msg); |
| 1965 var fn = flag(this, 'object'); |
| 1966 new Assertion(object, msg).to.have.property(prop); |
| 1967 new Assertion(fn).is.a('function'); |
| 1968 |
| 1969 var initial = object[prop]; |
| 1970 fn(); |
| 1971 |
| 1972 this.assert( |
| 1973 object[prop] - initial < 0 |
| 1974 , 'expected .' + prop + ' to decrease' |
| 1975 , 'expected .' + prop + ' to not decrease' |
| 1976 ); |
| 1977 } |
| 1978 |
| 1979 Assertion.addChainableMethod('decrease', assertDecreases); |
| 1980 Assertion.addChainableMethod('decreases', assertDecreases); |
| 1981 |
| 1982 /** |
| 1983 * ### .extensible |
| 1984 * |
| 1985 * Asserts that the target is extensible (can have new properties added to |
| 1986 * it). |
| 1987 * |
| 1988 * var nonExtensibleObject = Object.preventExtensions({}); |
| 1989 * var sealedObject = Object.seal({}); |
| 1990 * var frozenObject = Object.freeze({}); |
| 1991 * |
| 1992 * expect({}).to.be.extensible; |
| 1993 * expect(nonExtensibleObject).to.not.be.extensible; |
| 1994 * expect(sealedObject).to.not.be.extensible; |
| 1995 * expect(frozenObject).to.not.be.extensible; |
| 1996 * |
| 1997 * @name extensible |
| 1998 * @api public |
| 1999 */ |
| 2000 |
| 2001 Assertion.addProperty('extensible', function() { |
| 2002 var obj = flag(this, 'object'); |
| 2003 |
| 2004 // In ES5, if the argument to this method is not an object (a primitive), th
en it will cause a TypeError. |
| 2005 // In ES6, a non-object argument will be treated as if it was a non-extensib
le ordinary object, simply return false. |
| 2006 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_
Objects/Object/isExtensible |
| 2007 // The following provides ES6 behavior when a TypeError is thrown under ES5. |
| 2008 |
| 2009 var isExtensible; |
| 2010 |
| 2011 try { |
| 2012 isExtensible = Object.isExtensible(obj); |
| 2013 } catch (err) { |
| 2014 if (err instanceof TypeError) isExtensible = false; |
| 2015 else throw err; |
| 2016 } |
| 2017 |
| 2018 this.assert( |
| 2019 isExtensible |
| 2020 , 'expected #{this} to be extensible' |
| 2021 , 'expected #{this} to not be extensible' |
| 2022 ); |
| 2023 }); |
| 2024 |
| 2025 /** |
| 2026 * ### .sealed |
| 2027 * |
| 2028 * Asserts that the target is sealed (cannot have new properties added to it |
| 2029 * and its existing properties cannot be removed). |
| 2030 * |
| 2031 * var sealedObject = Object.seal({}); |
| 2032 * var frozenObject = Object.freeze({}); |
| 2033 * |
| 2034 * expect(sealedObject).to.be.sealed; |
| 2035 * expect(frozenObject).to.be.sealed; |
| 2036 * expect({}).to.not.be.sealed; |
| 2037 * |
| 2038 * @name sealed |
| 2039 * @api public |
| 2040 */ |
| 2041 |
| 2042 Assertion.addProperty('sealed', function() { |
| 2043 var obj = flag(this, 'object'); |
| 2044 |
| 2045 // In ES5, if the argument to this method is not an object (a primitive), th
en it will cause a TypeError. |
| 2046 // In ES6, a non-object argument will be treated as if it was a sealed ordin
ary object, simply return true. |
| 2047 // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Glo
bal_Objects/Object/isSealed |
| 2048 // The following provides ES6 behavior when a TypeError is thrown under ES5. |
| 2049 |
| 2050 var isSealed; |
| 2051 |
| 2052 try { |
| 2053 isSealed = Object.isSealed(obj); |
| 2054 } catch (err) { |
| 2055 if (err instanceof TypeError) isSealed = true; |
| 2056 else throw err; |
| 2057 } |
| 2058 |
| 2059 this.assert( |
| 2060 isSealed |
| 2061 , 'expected #{this} to be sealed' |
| 2062 , 'expected #{this} to not be sealed' |
| 2063 ); |
| 2064 }); |
| 2065 |
| 2066 /** |
| 2067 * ### .frozen |
| 2068 * |
| 2069 * Asserts that the target is frozen (cannot have new properties added to it |
| 2070 * and its existing properties cannot be modified). |
| 2071 * |
| 2072 * var frozenObject = Object.freeze({}); |
| 2073 * |
| 2074 * expect(frozenObject).to.be.frozen; |
| 2075 * expect({}).to.not.be.frozen; |
| 2076 * |
| 2077 * @name frozen |
| 2078 * @api public |
| 2079 */ |
| 2080 |
| 2081 Assertion.addProperty('frozen', function() { |
| 2082 var obj = flag(this, 'object'); |
| 2083 |
| 2084 // In ES5, if the argument to this method is not an object (a primitive), th
en it will cause a TypeError. |
| 2085 // In ES6, a non-object argument will be treated as if it was a frozen ordin
ary object, simply return true. |
| 2086 // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Glo
bal_Objects/Object/isFrozen |
| 2087 // The following provides ES6 behavior when a TypeError is thrown under ES5. |
| 2088 |
| 2089 var isFrozen; |
| 2090 |
| 2091 try { |
| 2092 isFrozen = Object.isFrozen(obj); |
| 2093 } catch (err) { |
| 2094 if (err instanceof TypeError) isFrozen = true; |
| 2095 else throw err; |
| 2096 } |
| 2097 |
| 2098 this.assert( |
| 2099 isFrozen |
| 2100 , 'expected #{this} to be frozen' |
| 2101 , 'expected #{this} to not be frozen' |
| 2102 ); |
| 2103 }); |
| 2104 }; |
| 2105 |
| 2106 },{}],6:[function(require,module,exports){ |
| 2107 /*! |
| 2108 * chai |
| 2109 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> |
| 2110 * MIT Licensed |
| 2111 */ |
| 2112 |
| 2113 |
| 2114 module.exports = function (chai, util) { |
| 2115 |
| 2116 /*! |
| 2117 * Chai dependencies. |
| 2118 */ |
| 2119 |
| 2120 var Assertion = chai.Assertion |
| 2121 , flag = util.flag; |
| 2122 |
| 2123 /*! |
| 2124 * Module export. |
| 2125 */ |
| 2126 |
| 2127 /** |
| 2128 * ### assert(expression, message) |
| 2129 * |
| 2130 * Write your own test expressions. |
| 2131 * |
| 2132 * assert('foo' !== 'bar', 'foo is not bar'); |
| 2133 * assert(Array.isArray([]), 'empty arrays are arrays'); |
| 2134 * |
| 2135 * @param {Mixed} expression to test for truthiness |
| 2136 * @param {String} message to display on error |
| 2137 * @name assert |
| 2138 * @api public |
| 2139 */ |
| 2140 |
| 2141 var assert = chai.assert = function (express, errmsg) { |
| 2142 var test = new Assertion(null, null, chai.assert); |
| 2143 test.assert( |
| 2144 express |
| 2145 , errmsg |
| 2146 , '[ negation message unavailable ]' |
| 2147 ); |
| 2148 }; |
| 2149 |
| 2150 /** |
| 2151 * ### .fail(actual, expected, [message], [operator]) |
| 2152 * |
| 2153 * Throw a failure. Node.js `assert` module-compatible. |
| 2154 * |
| 2155 * @name fail |
| 2156 * @param {Mixed} actual |
| 2157 * @param {Mixed} expected |
| 2158 * @param {String} message |
| 2159 * @param {String} operator |
| 2160 * @api public |
| 2161 */ |
| 2162 |
| 2163 assert.fail = function (actual, expected, message, operator) { |
| 2164 message = message || 'assert.fail()'; |
| 2165 throw new chai.AssertionError(message, { |
| 2166 actual: actual |
| 2167 , expected: expected |
| 2168 , operator: operator |
| 2169 }, assert.fail); |
| 2170 }; |
| 2171 |
| 2172 /** |
| 2173 * ### .isOk(object, [message]) |
| 2174 * |
| 2175 * Asserts that `object` is truthy. |
| 2176 * |
| 2177 * assert.isOk('everything', 'everything is ok'); |
| 2178 * assert.isOk(false, 'this will fail'); |
| 2179 * |
| 2180 * @name isOk |
| 2181 * @alias ok |
| 2182 * @param {Mixed} object to test |
| 2183 * @param {String} message |
| 2184 * @api public |
| 2185 */ |
| 2186 |
| 2187 assert.isOk = function (val, msg) { |
| 2188 new Assertion(val, msg).is.ok; |
| 2189 }; |
| 2190 |
| 2191 /** |
| 2192 * ### .isNotOk(object, [message]) |
| 2193 * |
| 2194 * Asserts that `object` is falsy. |
| 2195 * |
| 2196 * assert.isNotOk('everything', 'this will fail'); |
| 2197 * assert.isNotOk(false, 'this will pass'); |
| 2198 * |
| 2199 * @name isNotOk |
| 2200 * @alias notOk |
| 2201 * @param {Mixed} object to test |
| 2202 * @param {String} message |
| 2203 * @api public |
| 2204 */ |
| 2205 |
| 2206 assert.isNotOk = function (val, msg) { |
| 2207 new Assertion(val, msg).is.not.ok; |
| 2208 }; |
| 2209 |
| 2210 /** |
| 2211 * ### .equal(actual, expected, [message]) |
| 2212 * |
| 2213 * Asserts non-strict equality (`==`) of `actual` and `expected`. |
| 2214 * |
| 2215 * assert.equal(3, '3', '== coerces values to strings'); |
| 2216 * |
| 2217 * @name equal |
| 2218 * @param {Mixed} actual |
| 2219 * @param {Mixed} expected |
| 2220 * @param {String} message |
| 2221 * @api public |
| 2222 */ |
| 2223 |
| 2224 assert.equal = function (act, exp, msg) { |
| 2225 var test = new Assertion(act, msg, assert.equal); |
| 2226 |
| 2227 test.assert( |
| 2228 exp == flag(test, 'object') |
| 2229 , 'expected #{this} to equal #{exp}' |
| 2230 , 'expected #{this} to not equal #{act}' |
| 2231 , exp |
| 2232 , act |
| 2233 ); |
| 2234 }; |
| 2235 |
| 2236 /** |
| 2237 * ### .notEqual(actual, expected, [message]) |
| 2238 * |
| 2239 * Asserts non-strict inequality (`!=`) of `actual` and `expected`. |
| 2240 * |
| 2241 * assert.notEqual(3, 4, 'these numbers are not equal'); |
| 2242 * |
| 2243 * @name notEqual |
| 2244 * @param {Mixed} actual |
| 2245 * @param {Mixed} expected |
| 2246 * @param {String} message |
| 2247 * @api public |
| 2248 */ |
| 2249 |
| 2250 assert.notEqual = function (act, exp, msg) { |
| 2251 var test = new Assertion(act, msg, assert.notEqual); |
| 2252 |
| 2253 test.assert( |
| 2254 exp != flag(test, 'object') |
| 2255 , 'expected #{this} to not equal #{exp}' |
| 2256 , 'expected #{this} to equal #{act}' |
| 2257 , exp |
| 2258 , act |
| 2259 ); |
| 2260 }; |
| 2261 |
| 2262 /** |
| 2263 * ### .strictEqual(actual, expected, [message]) |
| 2264 * |
| 2265 * Asserts strict equality (`===`) of `actual` and `expected`. |
| 2266 * |
| 2267 * assert.strictEqual(true, true, 'these booleans are strictly equal'); |
| 2268 * |
| 2269 * @name strictEqual |
| 2270 * @param {Mixed} actual |
| 2271 * @param {Mixed} expected |
| 2272 * @param {String} message |
| 2273 * @api public |
| 2274 */ |
| 2275 |
| 2276 assert.strictEqual = function (act, exp, msg) { |
| 2277 new Assertion(act, msg).to.equal(exp); |
| 2278 }; |
| 2279 |
| 2280 /** |
| 2281 * ### .notStrictEqual(actual, expected, [message]) |
| 2282 * |
| 2283 * Asserts strict inequality (`!==`) of `actual` and `expected`. |
| 2284 * |
| 2285 * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); |
| 2286 * |
| 2287 * @name notStrictEqual |
| 2288 * @param {Mixed} actual |
| 2289 * @param {Mixed} expected |
| 2290 * @param {String} message |
| 2291 * @api public |
| 2292 */ |
| 2293 |
| 2294 assert.notStrictEqual = function (act, exp, msg) { |
| 2295 new Assertion(act, msg).to.not.equal(exp); |
| 2296 }; |
| 2297 |
| 2298 /** |
| 2299 * ### .deepEqual(actual, expected, [message]) |
| 2300 * |
| 2301 * Asserts that `actual` is deeply equal to `expected`. |
| 2302 * |
| 2303 * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); |
| 2304 * |
| 2305 * @name deepEqual |
| 2306 * @param {Mixed} actual |
| 2307 * @param {Mixed} expected |
| 2308 * @param {String} message |
| 2309 * @api public |
| 2310 */ |
| 2311 |
| 2312 assert.deepEqual = function (act, exp, msg) { |
| 2313 new Assertion(act, msg).to.eql(exp); |
| 2314 }; |
| 2315 |
| 2316 /** |
| 2317 * ### .notDeepEqual(actual, expected, [message]) |
| 2318 * |
| 2319 * Assert that `actual` is not deeply equal to `expected`. |
| 2320 * |
| 2321 * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); |
| 2322 * |
| 2323 * @name notDeepEqual |
| 2324 * @param {Mixed} actual |
| 2325 * @param {Mixed} expected |
| 2326 * @param {String} message |
| 2327 * @api public |
| 2328 */ |
| 2329 |
| 2330 assert.notDeepEqual = function (act, exp, msg) { |
| 2331 new Assertion(act, msg).to.not.eql(exp); |
| 2332 }; |
| 2333 |
| 2334 /** |
| 2335 * ### .isAbove(valueToCheck, valueToBeAbove, [message]) |
| 2336 * |
| 2337 * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove` |
| 2338 * |
| 2339 * assert.isAbove(5, 2, '5 is strictly greater than 2'); |
| 2340 * |
| 2341 * @name isAbove |
| 2342 * @param {Mixed} valueToCheck |
| 2343 * @param {Mixed} valueToBeAbove |
| 2344 * @param {String} message |
| 2345 * @api public |
| 2346 */ |
| 2347 |
| 2348 assert.isAbove = function (val, abv, msg) { |
| 2349 new Assertion(val, msg).to.be.above(abv); |
| 2350 }; |
| 2351 |
| 2352 /** |
| 2353 * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) |
| 2354 * |
| 2355 * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast` |
| 2356 * |
| 2357 * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); |
| 2358 * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); |
| 2359 * |
| 2360 * @name isAtLeast |
| 2361 * @param {Mixed} valueToCheck |
| 2362 * @param {Mixed} valueToBeAtLeast |
| 2363 * @param {String} message |
| 2364 * @api public |
| 2365 */ |
| 2366 |
| 2367 assert.isAtLeast = function (val, atlst, msg) { |
| 2368 new Assertion(val, msg).to.be.least(atlst); |
| 2369 }; |
| 2370 |
| 2371 /** |
| 2372 * ### .isBelow(valueToCheck, valueToBeBelow, [message]) |
| 2373 * |
| 2374 * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow` |
| 2375 * |
| 2376 * assert.isBelow(3, 6, '3 is strictly less than 6'); |
| 2377 * |
| 2378 * @name isBelow |
| 2379 * @param {Mixed} valueToCheck |
| 2380 * @param {Mixed} valueToBeBelow |
| 2381 * @param {String} message |
| 2382 * @api public |
| 2383 */ |
| 2384 |
| 2385 assert.isBelow = function (val, blw, msg) { |
| 2386 new Assertion(val, msg).to.be.below(blw); |
| 2387 }; |
| 2388 |
| 2389 /** |
| 2390 * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) |
| 2391 * |
| 2392 * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost` |
| 2393 * |
| 2394 * assert.isAtMost(3, 6, '3 is less than or equal to 6'); |
| 2395 * assert.isAtMost(4, 4, '4 is less than or equal to 4'); |
| 2396 * |
| 2397 * @name isAtMost |
| 2398 * @param {Mixed} valueToCheck |
| 2399 * @param {Mixed} valueToBeAtMost |
| 2400 * @param {String} message |
| 2401 * @api public |
| 2402 */ |
| 2403 |
| 2404 assert.isAtMost = function (val, atmst, msg) { |
| 2405 new Assertion(val, msg).to.be.most(atmst); |
| 2406 }; |
| 2407 |
| 2408 /** |
| 2409 * ### .isTrue(value, [message]) |
| 2410 * |
| 2411 * Asserts that `value` is true. |
| 2412 * |
| 2413 * var teaServed = true; |
| 2414 * assert.isTrue(teaServed, 'the tea has been served'); |
| 2415 * |
| 2416 * @name isTrue |
| 2417 * @param {Mixed} value |
| 2418 * @param {String} message |
| 2419 * @api public |
| 2420 */ |
| 2421 |
| 2422 assert.isTrue = function (val, msg) { |
| 2423 new Assertion(val, msg).is['true']; |
| 2424 }; |
| 2425 |
| 2426 /** |
| 2427 * ### .isNotTrue(value, [message]) |
| 2428 * |
| 2429 * Asserts that `value` is not true. |
| 2430 * |
| 2431 * var tea = 'tasty chai'; |
| 2432 * assert.isNotTrue(tea, 'great, time for tea!'); |
| 2433 * |
| 2434 * @name isNotTrue |
| 2435 * @param {Mixed} value |
| 2436 * @param {String} message |
| 2437 * @api public |
| 2438 */ |
| 2439 |
| 2440 assert.isNotTrue = function (val, msg) { |
| 2441 new Assertion(val, msg).to.not.equal(true); |
| 2442 }; |
| 2443 |
| 2444 /** |
| 2445 * ### .isFalse(value, [message]) |
| 2446 * |
| 2447 * Asserts that `value` is false. |
| 2448 * |
| 2449 * var teaServed = false; |
| 2450 * assert.isFalse(teaServed, 'no tea yet? hmm...'); |
| 2451 * |
| 2452 * @name isFalse |
| 2453 * @param {Mixed} value |
| 2454 * @param {String} message |
| 2455 * @api public |
| 2456 */ |
| 2457 |
| 2458 assert.isFalse = function (val, msg) { |
| 2459 new Assertion(val, msg).is['false']; |
| 2460 }; |
| 2461 |
| 2462 /** |
| 2463 * ### .isNotFalse(value, [message]) |
| 2464 * |
| 2465 * Asserts that `value` is not false. |
| 2466 * |
| 2467 * var tea = 'tasty chai'; |
| 2468 * assert.isNotFalse(tea, 'great, time for tea!'); |
| 2469 * |
| 2470 * @name isNotFalse |
| 2471 * @param {Mixed} value |
| 2472 * @param {String} message |
| 2473 * @api public |
| 2474 */ |
| 2475 |
| 2476 assert.isNotFalse = function (val, msg) { |
| 2477 new Assertion(val, msg).to.not.equal(false); |
| 2478 }; |
| 2479 |
| 2480 /** |
| 2481 * ### .isNull(value, [message]) |
| 2482 * |
| 2483 * Asserts that `value` is null. |
| 2484 * |
| 2485 * assert.isNull(err, 'there was no error'); |
| 2486 * |
| 2487 * @name isNull |
| 2488 * @param {Mixed} value |
| 2489 * @param {String} message |
| 2490 * @api public |
| 2491 */ |
| 2492 |
| 2493 assert.isNull = function (val, msg) { |
| 2494 new Assertion(val, msg).to.equal(null); |
| 2495 }; |
| 2496 |
| 2497 /** |
| 2498 * ### .isNotNull(value, [message]) |
| 2499 * |
| 2500 * Asserts that `value` is not null. |
| 2501 * |
| 2502 * var tea = 'tasty chai'; |
| 2503 * assert.isNotNull(tea, 'great, time for tea!'); |
| 2504 * |
| 2505 * @name isNotNull |
| 2506 * @param {Mixed} value |
| 2507 * @param {String} message |
| 2508 * @api public |
| 2509 */ |
| 2510 |
| 2511 assert.isNotNull = function (val, msg) { |
| 2512 new Assertion(val, msg).to.not.equal(null); |
| 2513 }; |
| 2514 |
| 2515 /** |
| 2516 * ### .isNaN |
| 2517 * Asserts that value is NaN |
| 2518 * |
| 2519 * assert.isNaN('foo', 'foo is NaN'); |
| 2520 * |
| 2521 * @name isNaN |
| 2522 * @param {Mixed} value |
| 2523 * @param {String} message |
| 2524 * @api public |
| 2525 */ |
| 2526 |
| 2527 assert.isNaN = function (val, msg) { |
| 2528 new Assertion(val, msg).to.be.NaN; |
| 2529 }; |
| 2530 |
| 2531 /** |
| 2532 * ### .isNotNaN |
| 2533 * Asserts that value is not NaN |
| 2534 * |
| 2535 * assert.isNotNaN(4, '4 is not NaN'); |
| 2536 * |
| 2537 * @name isNotNaN |
| 2538 * @param {Mixed} value |
| 2539 * @param {String} message |
| 2540 * @api public |
| 2541 */ |
| 2542 assert.isNotNaN = function (val, msg) { |
| 2543 new Assertion(val, msg).not.to.be.NaN; |
| 2544 }; |
| 2545 |
| 2546 /** |
| 2547 * ### .isUndefined(value, [message]) |
| 2548 * |
| 2549 * Asserts that `value` is `undefined`. |
| 2550 * |
| 2551 * var tea; |
| 2552 * assert.isUndefined(tea, 'no tea defined'); |
| 2553 * |
| 2554 * @name isUndefined |
| 2555 * @param {Mixed} value |
| 2556 * @param {String} message |
| 2557 * @api public |
| 2558 */ |
| 2559 |
| 2560 assert.isUndefined = function (val, msg) { |
| 2561 new Assertion(val, msg).to.equal(undefined); |
| 2562 }; |
| 2563 |
| 2564 /** |
| 2565 * ### .isDefined(value, [message]) |
| 2566 * |
| 2567 * Asserts that `value` is not `undefined`. |
| 2568 * |
| 2569 * var tea = 'cup of chai'; |
| 2570 * assert.isDefined(tea, 'tea has been defined'); |
| 2571 * |
| 2572 * @name isDefined |
| 2573 * @param {Mixed} value |
| 2574 * @param {String} message |
| 2575 * @api public |
| 2576 */ |
| 2577 |
| 2578 assert.isDefined = function (val, msg) { |
| 2579 new Assertion(val, msg).to.not.equal(undefined); |
| 2580 }; |
| 2581 |
| 2582 /** |
| 2583 * ### .isFunction(value, [message]) |
| 2584 * |
| 2585 * Asserts that `value` is a function. |
| 2586 * |
| 2587 * function serveTea() { return 'cup of tea'; }; |
| 2588 * assert.isFunction(serveTea, 'great, we can have tea now'); |
| 2589 * |
| 2590 * @name isFunction |
| 2591 * @param {Mixed} value |
| 2592 * @param {String} message |
| 2593 * @api public |
| 2594 */ |
| 2595 |
| 2596 assert.isFunction = function (val, msg) { |
| 2597 new Assertion(val, msg).to.be.a('function'); |
| 2598 }; |
| 2599 |
| 2600 /** |
| 2601 * ### .isNotFunction(value, [message]) |
| 2602 * |
| 2603 * Asserts that `value` is _not_ a function. |
| 2604 * |
| 2605 * var serveTea = [ 'heat', 'pour', 'sip' ]; |
| 2606 * assert.isNotFunction(serveTea, 'great, we have listed the steps'); |
| 2607 * |
| 2608 * @name isNotFunction |
| 2609 * @param {Mixed} value |
| 2610 * @param {String} message |
| 2611 * @api public |
| 2612 */ |
| 2613 |
| 2614 assert.isNotFunction = function (val, msg) { |
| 2615 new Assertion(val, msg).to.not.be.a('function'); |
| 2616 }; |
| 2617 |
| 2618 /** |
| 2619 * ### .isObject(value, [message]) |
| 2620 * |
| 2621 * Asserts that `value` is an object (as revealed by |
| 2622 * `Object.prototype.toString`). |
| 2623 * |
| 2624 * var selection = { name: 'Chai', serve: 'with spices' }; |
| 2625 * assert.isObject(selection, 'tea selection is an object'); |
| 2626 * |
| 2627 * @name isObject |
| 2628 * @param {Mixed} value |
| 2629 * @param {String} message |
| 2630 * @api public |
| 2631 */ |
| 2632 |
| 2633 assert.isObject = function (val, msg) { |
| 2634 new Assertion(val, msg).to.be.a('object'); |
| 2635 }; |
| 2636 |
| 2637 /** |
| 2638 * ### .isNotObject(value, [message]) |
| 2639 * |
| 2640 * Asserts that `value` is _not_ an object. |
| 2641 * |
| 2642 * var selection = 'chai' |
| 2643 * assert.isNotObject(selection, 'tea selection is not an object'); |
| 2644 * assert.isNotObject(null, 'null is not an object'); |
| 2645 * |
| 2646 * @name isNotObject |
| 2647 * @param {Mixed} value |
| 2648 * @param {String} message |
| 2649 * @api public |
| 2650 */ |
| 2651 |
| 2652 assert.isNotObject = function (val, msg) { |
| 2653 new Assertion(val, msg).to.not.be.a('object'); |
| 2654 }; |
| 2655 |
| 2656 /** |
| 2657 * ### .isArray(value, [message]) |
| 2658 * |
| 2659 * Asserts that `value` is an array. |
| 2660 * |
| 2661 * var menu = [ 'green', 'chai', 'oolong' ]; |
| 2662 * assert.isArray(menu, 'what kind of tea do we want?'); |
| 2663 * |
| 2664 * @name isArray |
| 2665 * @param {Mixed} value |
| 2666 * @param {String} message |
| 2667 * @api public |
| 2668 */ |
| 2669 |
| 2670 assert.isArray = function (val, msg) { |
| 2671 new Assertion(val, msg).to.be.an('array'); |
| 2672 }; |
| 2673 |
| 2674 /** |
| 2675 * ### .isNotArray(value, [message]) |
| 2676 * |
| 2677 * Asserts that `value` is _not_ an array. |
| 2678 * |
| 2679 * var menu = 'green|chai|oolong'; |
| 2680 * assert.isNotArray(menu, 'what kind of tea do we want?'); |
| 2681 * |
| 2682 * @name isNotArray |
| 2683 * @param {Mixed} value |
| 2684 * @param {String} message |
| 2685 * @api public |
| 2686 */ |
| 2687 |
| 2688 assert.isNotArray = function (val, msg) { |
| 2689 new Assertion(val, msg).to.not.be.an('array'); |
| 2690 }; |
| 2691 |
| 2692 /** |
| 2693 * ### .isString(value, [message]) |
| 2694 * |
| 2695 * Asserts that `value` is a string. |
| 2696 * |
| 2697 * var teaOrder = 'chai'; |
| 2698 * assert.isString(teaOrder, 'order placed'); |
| 2699 * |
| 2700 * @name isString |
| 2701 * @param {Mixed} value |
| 2702 * @param {String} message |
| 2703 * @api public |
| 2704 */ |
| 2705 |
| 2706 assert.isString = function (val, msg) { |
| 2707 new Assertion(val, msg).to.be.a('string'); |
| 2708 }; |
| 2709 |
| 2710 /** |
| 2711 * ### .isNotString(value, [message]) |
| 2712 * |
| 2713 * Asserts that `value` is _not_ a string. |
| 2714 * |
| 2715 * var teaOrder = 4; |
| 2716 * assert.isNotString(teaOrder, 'order placed'); |
| 2717 * |
| 2718 * @name isNotString |
| 2719 * @param {Mixed} value |
| 2720 * @param {String} message |
| 2721 * @api public |
| 2722 */ |
| 2723 |
| 2724 assert.isNotString = function (val, msg) { |
| 2725 new Assertion(val, msg).to.not.be.a('string'); |
| 2726 }; |
| 2727 |
| 2728 /** |
| 2729 * ### .isNumber(value, [message]) |
| 2730 * |
| 2731 * Asserts that `value` is a number. |
| 2732 * |
| 2733 * var cups = 2; |
| 2734 * assert.isNumber(cups, 'how many cups'); |
| 2735 * |
| 2736 * @name isNumber |
| 2737 * @param {Number} value |
| 2738 * @param {String} message |
| 2739 * @api public |
| 2740 */ |
| 2741 |
| 2742 assert.isNumber = function (val, msg) { |
| 2743 new Assertion(val, msg).to.be.a('number'); |
| 2744 }; |
| 2745 |
| 2746 /** |
| 2747 * ### .isNotNumber(value, [message]) |
| 2748 * |
| 2749 * Asserts that `value` is _not_ a number. |
| 2750 * |
| 2751 * var cups = '2 cups please'; |
| 2752 * assert.isNotNumber(cups, 'how many cups'); |
| 2753 * |
| 2754 * @name isNotNumber |
| 2755 * @param {Mixed} value |
| 2756 * @param {String} message |
| 2757 * @api public |
| 2758 */ |
| 2759 |
| 2760 assert.isNotNumber = function (val, msg) { |
| 2761 new Assertion(val, msg).to.not.be.a('number'); |
| 2762 }; |
| 2763 |
| 2764 /** |
| 2765 * ### .isBoolean(value, [message]) |
| 2766 * |
| 2767 * Asserts that `value` is a boolean. |
| 2768 * |
| 2769 * var teaReady = true |
| 2770 * , teaServed = false; |
| 2771 * |
| 2772 * assert.isBoolean(teaReady, 'is the tea ready'); |
| 2773 * assert.isBoolean(teaServed, 'has tea been served'); |
| 2774 * |
| 2775 * @name isBoolean |
| 2776 * @param {Mixed} value |
| 2777 * @param {String} message |
| 2778 * @api public |
| 2779 */ |
| 2780 |
| 2781 assert.isBoolean = function (val, msg) { |
| 2782 new Assertion(val, msg).to.be.a('boolean'); |
| 2783 }; |
| 2784 |
| 2785 /** |
| 2786 * ### .isNotBoolean(value, [message]) |
| 2787 * |
| 2788 * Asserts that `value` is _not_ a boolean. |
| 2789 * |
| 2790 * var teaReady = 'yep' |
| 2791 * , teaServed = 'nope'; |
| 2792 * |
| 2793 * assert.isNotBoolean(teaReady, 'is the tea ready'); |
| 2794 * assert.isNotBoolean(teaServed, 'has tea been served'); |
| 2795 * |
| 2796 * @name isNotBoolean |
| 2797 * @param {Mixed} value |
| 2798 * @param {String} message |
| 2799 * @api public |
| 2800 */ |
| 2801 |
| 2802 assert.isNotBoolean = function (val, msg) { |
| 2803 new Assertion(val, msg).to.not.be.a('boolean'); |
| 2804 }; |
| 2805 |
| 2806 /** |
| 2807 * ### .typeOf(value, name, [message]) |
| 2808 * |
| 2809 * Asserts that `value`'s type is `name`, as determined by |
| 2810 * `Object.prototype.toString`. |
| 2811 * |
| 2812 * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); |
| 2813 * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); |
| 2814 * assert.typeOf('tea', 'string', 'we have a string'); |
| 2815 * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); |
| 2816 * assert.typeOf(null, 'null', 'we have a null'); |
| 2817 * assert.typeOf(undefined, 'undefined', 'we have an undefined'); |
| 2818 * |
| 2819 * @name typeOf |
| 2820 * @param {Mixed} value |
| 2821 * @param {String} name |
| 2822 * @param {String} message |
| 2823 * @api public |
| 2824 */ |
| 2825 |
| 2826 assert.typeOf = function (val, type, msg) { |
| 2827 new Assertion(val, msg).to.be.a(type); |
| 2828 }; |
| 2829 |
| 2830 /** |
| 2831 * ### .notTypeOf(value, name, [message]) |
| 2832 * |
| 2833 * Asserts that `value`'s type is _not_ `name`, as determined by |
| 2834 * `Object.prototype.toString`. |
| 2835 * |
| 2836 * assert.notTypeOf('tea', 'number', 'strings are not numbers'); |
| 2837 * |
| 2838 * @name notTypeOf |
| 2839 * @param {Mixed} value |
| 2840 * @param {String} typeof name |
| 2841 * @param {String} message |
| 2842 * @api public |
| 2843 */ |
| 2844 |
| 2845 assert.notTypeOf = function (val, type, msg) { |
| 2846 new Assertion(val, msg).to.not.be.a(type); |
| 2847 }; |
| 2848 |
| 2849 /** |
| 2850 * ### .instanceOf(object, constructor, [message]) |
| 2851 * |
| 2852 * Asserts that `value` is an instance of `constructor`. |
| 2853 * |
| 2854 * var Tea = function (name) { this.name = name; } |
| 2855 * , chai = new Tea('chai'); |
| 2856 * |
| 2857 * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); |
| 2858 * |
| 2859 * @name instanceOf |
| 2860 * @param {Object} object |
| 2861 * @param {Constructor} constructor |
| 2862 * @param {String} message |
| 2863 * @api public |
| 2864 */ |
| 2865 |
| 2866 assert.instanceOf = function (val, type, msg) { |
| 2867 new Assertion(val, msg).to.be.instanceOf(type); |
| 2868 }; |
| 2869 |
| 2870 /** |
| 2871 * ### .notInstanceOf(object, constructor, [message]) |
| 2872 * |
| 2873 * Asserts `value` is not an instance of `constructor`. |
| 2874 * |
| 2875 * var Tea = function (name) { this.name = name; } |
| 2876 * , chai = new String('chai'); |
| 2877 * |
| 2878 * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); |
| 2879 * |
| 2880 * @name notInstanceOf |
| 2881 * @param {Object} object |
| 2882 * @param {Constructor} constructor |
| 2883 * @param {String} message |
| 2884 * @api public |
| 2885 */ |
| 2886 |
| 2887 assert.notInstanceOf = function (val, type, msg) { |
| 2888 new Assertion(val, msg).to.not.be.instanceOf(type); |
| 2889 }; |
| 2890 |
| 2891 /** |
| 2892 * ### .include(haystack, needle, [message]) |
| 2893 * |
| 2894 * Asserts that `haystack` includes `needle`. Works |
| 2895 * for strings and arrays. |
| 2896 * |
| 2897 * assert.include('foobar', 'bar', 'foobar contains string "bar"'); |
| 2898 * assert.include([ 1, 2, 3 ], 3, 'array contains value'); |
| 2899 * |
| 2900 * @name include |
| 2901 * @param {Array|String} haystack |
| 2902 * @param {Mixed} needle |
| 2903 * @param {String} message |
| 2904 * @api public |
| 2905 */ |
| 2906 |
| 2907 assert.include = function (exp, inc, msg) { |
| 2908 new Assertion(exp, msg, assert.include).include(inc); |
| 2909 }; |
| 2910 |
| 2911 /** |
| 2912 * ### .notInclude(haystack, needle, [message]) |
| 2913 * |
| 2914 * Asserts that `haystack` does not include `needle`. Works |
| 2915 * for strings and arrays. |
| 2916 * |
| 2917 * assert.notInclude('foobar', 'baz', 'string not include substring'); |
| 2918 * assert.notInclude([ 1, 2, 3 ], 4, 'array not include contain value'); |
| 2919 * |
| 2920 * @name notInclude |
| 2921 * @param {Array|String} haystack |
| 2922 * @param {Mixed} needle |
| 2923 * @param {String} message |
| 2924 * @api public |
| 2925 */ |
| 2926 |
| 2927 assert.notInclude = function (exp, inc, msg) { |
| 2928 new Assertion(exp, msg, assert.notInclude).not.include(inc); |
| 2929 }; |
| 2930 |
| 2931 /** |
| 2932 * ### .match(value, regexp, [message]) |
| 2933 * |
| 2934 * Asserts that `value` matches the regular expression `regexp`. |
| 2935 * |
| 2936 * assert.match('foobar', /^foo/, 'regexp matches'); |
| 2937 * |
| 2938 * @name match |
| 2939 * @param {Mixed} value |
| 2940 * @param {RegExp} regexp |
| 2941 * @param {String} message |
| 2942 * @api public |
| 2943 */ |
| 2944 |
| 2945 assert.match = function (exp, re, msg) { |
| 2946 new Assertion(exp, msg).to.match(re); |
| 2947 }; |
| 2948 |
| 2949 /** |
| 2950 * ### .notMatch(value, regexp, [message]) |
| 2951 * |
| 2952 * Asserts that `value` does not match the regular expression `regexp`. |
| 2953 * |
| 2954 * assert.notMatch('foobar', /^foo/, 'regexp does not match'); |
| 2955 * |
| 2956 * @name notMatch |
| 2957 * @param {Mixed} value |
| 2958 * @param {RegExp} regexp |
| 2959 * @param {String} message |
| 2960 * @api public |
| 2961 */ |
| 2962 |
| 2963 assert.notMatch = function (exp, re, msg) { |
| 2964 new Assertion(exp, msg).to.not.match(re); |
| 2965 }; |
| 2966 |
| 2967 /** |
| 2968 * ### .property(object, property, [message]) |
| 2969 * |
| 2970 * Asserts that `object` has a property named by `property`. |
| 2971 * |
| 2972 * assert.property({ tea: { green: 'matcha' }}, 'tea'); |
| 2973 * |
| 2974 * @name property |
| 2975 * @param {Object} object |
| 2976 * @param {String} property |
| 2977 * @param {String} message |
| 2978 * @api public |
| 2979 */ |
| 2980 |
| 2981 assert.property = function (obj, prop, msg) { |
| 2982 new Assertion(obj, msg).to.have.property(prop); |
| 2983 }; |
| 2984 |
| 2985 /** |
| 2986 * ### .notProperty(object, property, [message]) |
| 2987 * |
| 2988 * Asserts that `object` does _not_ have a property named by `property`. |
| 2989 * |
| 2990 * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); |
| 2991 * |
| 2992 * @name notProperty |
| 2993 * @param {Object} object |
| 2994 * @param {String} property |
| 2995 * @param {String} message |
| 2996 * @api public |
| 2997 */ |
| 2998 |
| 2999 assert.notProperty = function (obj, prop, msg) { |
| 3000 new Assertion(obj, msg).to.not.have.property(prop); |
| 3001 }; |
| 3002 |
| 3003 /** |
| 3004 * ### .deepProperty(object, property, [message]) |
| 3005 * |
| 3006 * Asserts that `object` has a property named by `property`, which can be a |
| 3007 * string using dot- and bracket-notation for deep reference. |
| 3008 * |
| 3009 * assert.deepProperty({ tea: { green: 'matcha' }}, 'tea.green'); |
| 3010 * |
| 3011 * @name deepProperty |
| 3012 * @param {Object} object |
| 3013 * @param {String} property |
| 3014 * @param {String} message |
| 3015 * @api public |
| 3016 */ |
| 3017 |
| 3018 assert.deepProperty = function (obj, prop, msg) { |
| 3019 new Assertion(obj, msg).to.have.deep.property(prop); |
| 3020 }; |
| 3021 |
| 3022 /** |
| 3023 * ### .notDeepProperty(object, property, [message]) |
| 3024 * |
| 3025 * Asserts that `object` does _not_ have a property named by `property`, which |
| 3026 * can be a string using dot- and bracket-notation for deep reference. |
| 3027 * |
| 3028 * assert.notDeepProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); |
| 3029 * |
| 3030 * @name notDeepProperty |
| 3031 * @param {Object} object |
| 3032 * @param {String} property |
| 3033 * @param {String} message |
| 3034 * @api public |
| 3035 */ |
| 3036 |
| 3037 assert.notDeepProperty = function (obj, prop, msg) { |
| 3038 new Assertion(obj, msg).to.not.have.deep.property(prop); |
| 3039 }; |
| 3040 |
| 3041 /** |
| 3042 * ### .propertyVal(object, property, value, [message]) |
| 3043 * |
| 3044 * Asserts that `object` has a property named by `property` with value given |
| 3045 * by `value`. |
| 3046 * |
| 3047 * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); |
| 3048 * |
| 3049 * @name propertyVal |
| 3050 * @param {Object} object |
| 3051 * @param {String} property |
| 3052 * @param {Mixed} value |
| 3053 * @param {String} message |
| 3054 * @api public |
| 3055 */ |
| 3056 |
| 3057 assert.propertyVal = function (obj, prop, val, msg) { |
| 3058 new Assertion(obj, msg).to.have.property(prop, val); |
| 3059 }; |
| 3060 |
| 3061 /** |
| 3062 * ### .propertyNotVal(object, property, value, [message]) |
| 3063 * |
| 3064 * Asserts that `object` has a property named by `property`, but with a value |
| 3065 * different from that given by `value`. |
| 3066 * |
| 3067 * assert.propertyNotVal({ tea: 'is good' }, 'tea', 'is bad'); |
| 3068 * |
| 3069 * @name propertyNotVal |
| 3070 * @param {Object} object |
| 3071 * @param {String} property |
| 3072 * @param {Mixed} value |
| 3073 * @param {String} message |
| 3074 * @api public |
| 3075 */ |
| 3076 |
| 3077 assert.propertyNotVal = function (obj, prop, val, msg) { |
| 3078 new Assertion(obj, msg).to.not.have.property(prop, val); |
| 3079 }; |
| 3080 |
| 3081 /** |
| 3082 * ### .deepPropertyVal(object, property, value, [message]) |
| 3083 * |
| 3084 * Asserts that `object` has a property named by `property` with value given |
| 3085 * by `value`. `property` can use dot- and bracket-notation for deep |
| 3086 * reference. |
| 3087 * |
| 3088 * assert.deepPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'match
a'); |
| 3089 * |
| 3090 * @name deepPropertyVal |
| 3091 * @param {Object} object |
| 3092 * @param {String} property |
| 3093 * @param {Mixed} value |
| 3094 * @param {String} message |
| 3095 * @api public |
| 3096 */ |
| 3097 |
| 3098 assert.deepPropertyVal = function (obj, prop, val, msg) { |
| 3099 new Assertion(obj, msg).to.have.deep.property(prop, val); |
| 3100 }; |
| 3101 |
| 3102 /** |
| 3103 * ### .deepPropertyNotVal(object, property, value, [message]) |
| 3104 * |
| 3105 * Asserts that `object` has a property named by `property`, but with a value |
| 3106 * different from that given by `value`. `property` can use dot- and |
| 3107 * bracket-notation for deep reference. |
| 3108 * |
| 3109 * assert.deepPropertyNotVal({ tea: { green: 'matcha' }}, 'tea.green', 'ko
nacha'); |
| 3110 * |
| 3111 * @name deepPropertyNotVal |
| 3112 * @param {Object} object |
| 3113 * @param {String} property |
| 3114 * @param {Mixed} value |
| 3115 * @param {String} message |
| 3116 * @api public |
| 3117 */ |
| 3118 |
| 3119 assert.deepPropertyNotVal = function (obj, prop, val, msg) { |
| 3120 new Assertion(obj, msg).to.not.have.deep.property(prop, val); |
| 3121 }; |
| 3122 |
| 3123 /** |
| 3124 * ### .lengthOf(object, length, [message]) |
| 3125 * |
| 3126 * Asserts that `object` has a `length` property with the expected value. |
| 3127 * |
| 3128 * assert.lengthOf([1,2,3], 3, 'array has length of 3'); |
| 3129 * assert.lengthOf('foobar', 6, 'string has length of 6'); |
| 3130 * |
| 3131 * @name lengthOf |
| 3132 * @param {Mixed} object |
| 3133 * @param {Number} length |
| 3134 * @param {String} message |
| 3135 * @api public |
| 3136 */ |
| 3137 |
| 3138 assert.lengthOf = function (exp, len, msg) { |
| 3139 new Assertion(exp, msg).to.have.length(len); |
| 3140 }; |
| 3141 |
| 3142 /** |
| 3143 * ### .throws(function, [constructor/string/regexp], [string/regexp], [messag
e]) |
| 3144 * |
| 3145 * Asserts that `function` will throw an error that is an instance of |
| 3146 * `constructor`, or alternately that it will throw an error with message |
| 3147 * matching `regexp`. |
| 3148 * |
| 3149 * assert.throws(fn, 'function throws a reference error'); |
| 3150 * assert.throws(fn, /function throws a reference error/); |
| 3151 * assert.throws(fn, ReferenceError); |
| 3152 * assert.throws(fn, ReferenceError, 'function throws a reference error'); |
| 3153 * assert.throws(fn, ReferenceError, /function throws a reference error/); |
| 3154 * |
| 3155 * @name throws |
| 3156 * @alias throw |
| 3157 * @alias Throw |
| 3158 * @param {Function} function |
| 3159 * @param {ErrorConstructor} constructor |
| 3160 * @param {RegExp} regexp |
| 3161 * @param {String} message |
| 3162 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/E
rror#Error_types |
| 3163 * @api public |
| 3164 */ |
| 3165 |
| 3166 assert.throws = function (fn, errt, errs, msg) { |
| 3167 if ('string' === typeof errt || errt instanceof RegExp) { |
| 3168 errs = errt; |
| 3169 errt = null; |
| 3170 } |
| 3171 |
| 3172 var assertErr = new Assertion(fn, msg).to.throw(errt, errs); |
| 3173 return flag(assertErr, 'object'); |
| 3174 }; |
| 3175 |
| 3176 /** |
| 3177 * ### .doesNotThrow(function, [constructor/regexp], [message]) |
| 3178 * |
| 3179 * Asserts that `function` will _not_ throw an error that is an instance of |
| 3180 * `constructor`, or alternately that it will not throw an error with message |
| 3181 * matching `regexp`. |
| 3182 * |
| 3183 * assert.doesNotThrow(fn, Error, 'function does not throw'); |
| 3184 * |
| 3185 * @name doesNotThrow |
| 3186 * @param {Function} function |
| 3187 * @param {ErrorConstructor} constructor |
| 3188 * @param {RegExp} regexp |
| 3189 * @param {String} message |
| 3190 * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/E
rror#Error_types |
| 3191 * @api public |
| 3192 */ |
| 3193 |
| 3194 assert.doesNotThrow = function (fn, type, msg) { |
| 3195 if ('string' === typeof type) { |
| 3196 msg = type; |
| 3197 type = null; |
| 3198 } |
| 3199 |
| 3200 new Assertion(fn, msg).to.not.Throw(type); |
| 3201 }; |
| 3202 |
| 3203 /** |
| 3204 * ### .operator(val1, operator, val2, [message]) |
| 3205 * |
| 3206 * Compares two values using `operator`. |
| 3207 * |
| 3208 * assert.operator(1, '<', 2, 'everything is ok'); |
| 3209 * assert.operator(1, '>', 2, 'this will fail'); |
| 3210 * |
| 3211 * @name operator |
| 3212 * @param {Mixed} val1 |
| 3213 * @param {String} operator |
| 3214 * @param {Mixed} val2 |
| 3215 * @param {String} message |
| 3216 * @api public |
| 3217 */ |
| 3218 |
| 3219 assert.operator = function (val, operator, val2, msg) { |
| 3220 var ok; |
| 3221 switch(operator) { |
| 3222 case '==': |
| 3223 ok = val == val2; |
| 3224 break; |
| 3225 case '===': |
| 3226 ok = val === val2; |
| 3227 break; |
| 3228 case '>': |
| 3229 ok = val > val2; |
| 3230 break; |
| 3231 case '>=': |
| 3232 ok = val >= val2; |
| 3233 break; |
| 3234 case '<': |
| 3235 ok = val < val2; |
| 3236 break; |
| 3237 case '<=': |
| 3238 ok = val <= val2; |
| 3239 break; |
| 3240 case '!=': |
| 3241 ok = val != val2; |
| 3242 break; |
| 3243 case '!==': |
| 3244 ok = val !== val2; |
| 3245 break; |
| 3246 default: |
| 3247 throw new Error('Invalid operator "' + operator + '"'); |
| 3248 } |
| 3249 var test = new Assertion(ok, msg); |
| 3250 test.assert( |
| 3251 true === flag(test, 'object') |
| 3252 , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.insp
ect(val2) |
| 3253 , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.
inspect(val2) ); |
| 3254 }; |
| 3255 |
| 3256 /** |
| 3257 * ### .closeTo(actual, expected, delta, [message]) |
| 3258 * |
| 3259 * Asserts that the target is equal `expected`, to within a +/- `delta` range. |
| 3260 * |
| 3261 * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); |
| 3262 * |
| 3263 * @name closeTo |
| 3264 * @param {Number} actual |
| 3265 * @param {Number} expected |
| 3266 * @param {Number} delta |
| 3267 * @param {String} message |
| 3268 * @api public |
| 3269 */ |
| 3270 |
| 3271 assert.closeTo = function (act, exp, delta, msg) { |
| 3272 new Assertion(act, msg).to.be.closeTo(exp, delta); |
| 3273 }; |
| 3274 |
| 3275 /** |
| 3276 * ### .approximately(actual, expected, delta, [message]) |
| 3277 * |
| 3278 * Asserts that the target is equal `expected`, to within a +/- `delta` range. |
| 3279 * |
| 3280 * assert.approximately(1.5, 1, 0.5, 'numbers are close'); |
| 3281 * |
| 3282 * @name approximately |
| 3283 * @param {Number} actual |
| 3284 * @param {Number} expected |
| 3285 * @param {Number} delta |
| 3286 * @param {String} message |
| 3287 * @api public |
| 3288 */ |
| 3289 |
| 3290 assert.approximately = function (act, exp, delta, msg) { |
| 3291 new Assertion(act, msg).to.be.approximately(exp, delta); |
| 3292 }; |
| 3293 |
| 3294 /** |
| 3295 * ### .sameMembers(set1, set2, [message]) |
| 3296 * |
| 3297 * Asserts that `set1` and `set2` have the same members. |
| 3298 * Order is not taken into account. |
| 3299 * |
| 3300 * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); |
| 3301 * |
| 3302 * @name sameMembers |
| 3303 * @param {Array} set1 |
| 3304 * @param {Array} set2 |
| 3305 * @param {String} message |
| 3306 * @api public |
| 3307 */ |
| 3308 |
| 3309 assert.sameMembers = function (set1, set2, msg) { |
| 3310 new Assertion(set1, msg).to.have.same.members(set2); |
| 3311 } |
| 3312 |
| 3313 /** |
| 3314 * ### .sameDeepMembers(set1, set2, [message]) |
| 3315 * |
| 3316 * Asserts that `set1` and `set2` have the same members - using a deep equalit
y checking. |
| 3317 * Order is not taken into account. |
| 3318 * |
| 3319 * assert.sameDeepMembers([ {b: 3}, {a: 2}, {c: 5} ], [ {c: 5}, {b: 3}, {a
: 2} ], 'same deep members'); |
| 3320 * |
| 3321 * @name sameDeepMembers |
| 3322 * @param {Array} set1 |
| 3323 * @param {Array} set2 |
| 3324 * @param {String} message |
| 3325 * @api public |
| 3326 */ |
| 3327 |
| 3328 assert.sameDeepMembers = function (set1, set2, msg) { |
| 3329 new Assertion(set1, msg).to.have.same.deep.members(set2); |
| 3330 } |
| 3331 |
| 3332 /** |
| 3333 * ### .includeMembers(superset, subset, [message]) |
| 3334 * |
| 3335 * Asserts that `subset` is included in `superset`. |
| 3336 * Order is not taken into account. |
| 3337 * |
| 3338 * assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members'); |
| 3339 * |
| 3340 * @name includeMembers |
| 3341 * @param {Array} superset |
| 3342 * @param {Array} subset |
| 3343 * @param {String} message |
| 3344 * @api public |
| 3345 */ |
| 3346 |
| 3347 assert.includeMembers = function (superset, subset, msg) { |
| 3348 new Assertion(superset, msg).to.include.members(subset); |
| 3349 } |
| 3350 |
| 3351 /** |
| 3352 * ### .oneOf(inList, list, [message]) |
| 3353 * |
| 3354 * Asserts that non-object, non-array value `inList` appears in the flat array
`list`. |
| 3355 * |
| 3356 * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); |
| 3357 * |
| 3358 * @name oneOf |
| 3359 * @param {*} inList |
| 3360 * @param {Array<*>} list |
| 3361 * @param {String} message |
| 3362 * @api public |
| 3363 */ |
| 3364 |
| 3365 assert.oneOf = function (inList, list, msg) { |
| 3366 new Assertion(inList, msg).to.be.oneOf(list); |
| 3367 } |
| 3368 |
| 3369 /** |
| 3370 * ### .changes(function, object, property) |
| 3371 * |
| 3372 * Asserts that a function changes the value of a property |
| 3373 * |
| 3374 * var obj = { val: 10 }; |
| 3375 * var fn = function() { obj.val = 22 }; |
| 3376 * assert.changes(fn, obj, 'val'); |
| 3377 * |
| 3378 * @name changes |
| 3379 * @param {Function} modifier function |
| 3380 * @param {Object} object |
| 3381 * @param {String} property name |
| 3382 * @param {String} message _optional_ |
| 3383 * @api public |
| 3384 */ |
| 3385 |
| 3386 assert.changes = function (fn, obj, prop) { |
| 3387 new Assertion(fn).to.change(obj, prop); |
| 3388 } |
| 3389 |
| 3390 /** |
| 3391 * ### .doesNotChange(function, object, property) |
| 3392 * |
| 3393 * Asserts that a function does not changes the value of a property |
| 3394 * |
| 3395 * var obj = { val: 10 }; |
| 3396 * var fn = function() { console.log('foo'); }; |
| 3397 * assert.doesNotChange(fn, obj, 'val'); |
| 3398 * |
| 3399 * @name doesNotChange |
| 3400 * @param {Function} modifier function |
| 3401 * @param {Object} object |
| 3402 * @param {String} property name |
| 3403 * @param {String} message _optional_ |
| 3404 * @api public |
| 3405 */ |
| 3406 |
| 3407 assert.doesNotChange = function (fn, obj, prop) { |
| 3408 new Assertion(fn).to.not.change(obj, prop); |
| 3409 } |
| 3410 |
| 3411 /** |
| 3412 * ### .increases(function, object, property) |
| 3413 * |
| 3414 * Asserts that a function increases an object property |
| 3415 * |
| 3416 * var obj = { val: 10 }; |
| 3417 * var fn = function() { obj.val = 13 }; |
| 3418 * assert.increases(fn, obj, 'val'); |
| 3419 * |
| 3420 * @name increases |
| 3421 * @param {Function} modifier function |
| 3422 * @param {Object} object |
| 3423 * @param {String} property name |
| 3424 * @param {String} message _optional_ |
| 3425 * @api public |
| 3426 */ |
| 3427 |
| 3428 assert.increases = function (fn, obj, prop) { |
| 3429 new Assertion(fn).to.increase(obj, prop); |
| 3430 } |
| 3431 |
| 3432 /** |
| 3433 * ### .doesNotIncrease(function, object, property) |
| 3434 * |
| 3435 * Asserts that a function does not increase object property |
| 3436 * |
| 3437 * var obj = { val: 10 }; |
| 3438 * var fn = function() { obj.val = 8 }; |
| 3439 * assert.doesNotIncrease(fn, obj, 'val'); |
| 3440 * |
| 3441 * @name doesNotIncrease |
| 3442 * @param {Function} modifier function |
| 3443 * @param {Object} object |
| 3444 * @param {String} property name |
| 3445 * @param {String} message _optional_ |
| 3446 * @api public |
| 3447 */ |
| 3448 |
| 3449 assert.doesNotIncrease = function (fn, obj, prop) { |
| 3450 new Assertion(fn).to.not.increase(obj, prop); |
| 3451 } |
| 3452 |
| 3453 /** |
| 3454 * ### .decreases(function, object, property) |
| 3455 * |
| 3456 * Asserts that a function decreases an object property |
| 3457 * |
| 3458 * var obj = { val: 10 }; |
| 3459 * var fn = function() { obj.val = 5 }; |
| 3460 * assert.decreases(fn, obj, 'val'); |
| 3461 * |
| 3462 * @name decreases |
| 3463 * @param {Function} modifier function |
| 3464 * @param {Object} object |
| 3465 * @param {String} property name |
| 3466 * @param {String} message _optional_ |
| 3467 * @api public |
| 3468 */ |
| 3469 |
| 3470 assert.decreases = function (fn, obj, prop) { |
| 3471 new Assertion(fn).to.decrease(obj, prop); |
| 3472 } |
| 3473 |
| 3474 /** |
| 3475 * ### .doesNotDecrease(function, object, property) |
| 3476 * |
| 3477 * Asserts that a function does not decreases an object property |
| 3478 * |
| 3479 * var obj = { val: 10 }; |
| 3480 * var fn = function() { obj.val = 15 }; |
| 3481 * assert.doesNotDecrease(fn, obj, 'val'); |
| 3482 * |
| 3483 * @name doesNotDecrease |
| 3484 * @param {Function} modifier function |
| 3485 * @param {Object} object |
| 3486 * @param {String} property name |
| 3487 * @param {String} message _optional_ |
| 3488 * @api public |
| 3489 */ |
| 3490 |
| 3491 assert.doesNotDecrease = function (fn, obj, prop) { |
| 3492 new Assertion(fn).to.not.decrease(obj, prop); |
| 3493 } |
| 3494 |
| 3495 /*! |
| 3496 * ### .ifError(object) |
| 3497 * |
| 3498 * Asserts if value is not a false value, and throws if it is a true value. |
| 3499 * This is added to allow for chai to be a drop-in replacement for Node's |
| 3500 * assert class. |
| 3501 * |
| 3502 * var err = new Error('I am a custom error'); |
| 3503 * assert.ifError(err); // Rethrows err! |
| 3504 * |
| 3505 * @name ifError |
| 3506 * @param {Object} object |
| 3507 * @api public |
| 3508 */ |
| 3509 |
| 3510 assert.ifError = function (val) { |
| 3511 if (val) { |
| 3512 throw(val); |
| 3513 } |
| 3514 }; |
| 3515 |
| 3516 /** |
| 3517 * ### .isExtensible(object) |
| 3518 * |
| 3519 * Asserts that `object` is extensible (can have new properties added to it). |
| 3520 * |
| 3521 * assert.isExtensible({}); |
| 3522 * |
| 3523 * @name isExtensible |
| 3524 * @alias extensible |
| 3525 * @param {Object} object |
| 3526 * @param {String} message _optional_ |
| 3527 * @api public |
| 3528 */ |
| 3529 |
| 3530 assert.isExtensible = function (obj, msg) { |
| 3531 new Assertion(obj, msg).to.be.extensible; |
| 3532 }; |
| 3533 |
| 3534 /** |
| 3535 * ### .isNotExtensible(object) |
| 3536 * |
| 3537 * Asserts that `object` is _not_ extensible. |
| 3538 * |
| 3539 * var nonExtensibleObject = Object.preventExtensions({}); |
| 3540 * var sealedObject = Object.seal({}); |
| 3541 * var frozenObject = Object.freese({}); |
| 3542 * |
| 3543 * assert.isNotExtensible(nonExtensibleObject); |
| 3544 * assert.isNotExtensible(sealedObject); |
| 3545 * assert.isNotExtensible(frozenObject); |
| 3546 * |
| 3547 * @name isNotExtensible |
| 3548 * @alias notExtensible |
| 3549 * @param {Object} object |
| 3550 * @param {String} message _optional_ |
| 3551 * @api public |
| 3552 */ |
| 3553 |
| 3554 assert.isNotExtensible = function (obj, msg) { |
| 3555 new Assertion(obj, msg).to.not.be.extensible; |
| 3556 }; |
| 3557 |
| 3558 /** |
| 3559 * ### .isSealed(object) |
| 3560 * |
| 3561 * Asserts that `object` is sealed (cannot have new properties added to it |
| 3562 * and its existing properties cannot be removed). |
| 3563 * |
| 3564 * var sealedObject = Object.seal({}); |
| 3565 * var frozenObject = Object.seal({}); |
| 3566 * |
| 3567 * assert.isSealed(sealedObject); |
| 3568 * assert.isSealed(frozenObject); |
| 3569 * |
| 3570 * @name isSealed |
| 3571 * @alias sealed |
| 3572 * @param {Object} object |
| 3573 * @param {String} message _optional_ |
| 3574 * @api public |
| 3575 */ |
| 3576 |
| 3577 assert.isSealed = function (obj, msg) { |
| 3578 new Assertion(obj, msg).to.be.sealed; |
| 3579 }; |
| 3580 |
| 3581 /** |
| 3582 * ### .isNotSealed(object) |
| 3583 * |
| 3584 * Asserts that `object` is _not_ sealed. |
| 3585 * |
| 3586 * assert.isNotSealed({}); |
| 3587 * |
| 3588 * @name isNotSealed |
| 3589 * @alias notSealed |
| 3590 * @param {Object} object |
| 3591 * @param {String} message _optional_ |
| 3592 * @api public |
| 3593 */ |
| 3594 |
| 3595 assert.isNotSealed = function (obj, msg) { |
| 3596 new Assertion(obj, msg).to.not.be.sealed; |
| 3597 }; |
| 3598 |
| 3599 /** |
| 3600 * ### .isFrozen(object) |
| 3601 * |
| 3602 * Asserts that `object` is frozen (cannot have new properties added to it |
| 3603 * and its existing properties cannot be modified). |
| 3604 * |
| 3605 * var frozenObject = Object.freeze({}); |
| 3606 * assert.frozen(frozenObject); |
| 3607 * |
| 3608 * @name isFrozen |
| 3609 * @alias frozen |
| 3610 * @param {Object} object |
| 3611 * @param {String} message _optional_ |
| 3612 * @api public |
| 3613 */ |
| 3614 |
| 3615 assert.isFrozen = function (obj, msg) { |
| 3616 new Assertion(obj, msg).to.be.frozen; |
| 3617 }; |
| 3618 |
| 3619 /** |
| 3620 * ### .isNotFrozen(object) |
| 3621 * |
| 3622 * Asserts that `object` is _not_ frozen. |
| 3623 * |
| 3624 * assert.isNotFrozen({}); |
| 3625 * |
| 3626 * @name isNotFrozen |
| 3627 * @alias notFrozen |
| 3628 * @param {Object} object |
| 3629 * @param {String} message _optional_ |
| 3630 * @api public |
| 3631 */ |
| 3632 |
| 3633 assert.isNotFrozen = function (obj, msg) { |
| 3634 new Assertion(obj, msg).to.not.be.frozen; |
| 3635 }; |
| 3636 |
| 3637 /*! |
| 3638 * Aliases. |
| 3639 */ |
| 3640 |
| 3641 (function alias(name, as){ |
| 3642 assert[as] = assert[name]; |
| 3643 return alias; |
| 3644 }) |
| 3645 ('isOk', 'ok') |
| 3646 ('isNotOk', 'notOk') |
| 3647 ('throws', 'throw') |
| 3648 ('throws', 'Throw') |
| 3649 ('isExtensible', 'extensible') |
| 3650 ('isNotExtensible', 'notExtensible') |
| 3651 ('isSealed', 'sealed') |
| 3652 ('isNotSealed', 'notSealed') |
| 3653 ('isFrozen', 'frozen') |
| 3654 ('isNotFrozen', 'notFrozen'); |
| 3655 }; |
| 3656 |
| 3657 },{}],7:[function(require,module,exports){ |
| 3658 /*! |
| 3659 * chai |
| 3660 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> |
| 3661 * MIT Licensed |
| 3662 */ |
| 3663 |
| 3664 module.exports = function (chai, util) { |
| 3665 chai.expect = function (val, message) { |
| 3666 return new chai.Assertion(val, message); |
| 3667 }; |
| 3668 |
| 3669 /** |
| 3670 * ### .fail(actual, expected, [message], [operator]) |
| 3671 * |
| 3672 * Throw a failure. |
| 3673 * |
| 3674 * @name fail |
| 3675 * @param {Mixed} actual |
| 3676 * @param {Mixed} expected |
| 3677 * @param {String} message |
| 3678 * @param {String} operator |
| 3679 * @api public |
| 3680 */ |
| 3681 |
| 3682 chai.expect.fail = function (actual, expected, message, operator) { |
| 3683 message = message || 'expect.fail()'; |
| 3684 throw new chai.AssertionError(message, { |
| 3685 actual: actual |
| 3686 , expected: expected |
| 3687 , operator: operator |
| 3688 }, chai.expect.fail); |
| 3689 }; |
| 3690 }; |
| 3691 |
| 3692 },{}],8:[function(require,module,exports){ |
| 3693 /*! |
| 3694 * chai |
| 3695 * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> |
| 3696 * MIT Licensed |
| 3697 */ |
| 3698 |
| 3699 module.exports = function (chai, util) { |
| 3700 var Assertion = chai.Assertion; |
| 3701 |
| 3702 function loadShould () { |
| 3703 // explicitly define this method as function as to have it's name to include
as `ssfi` |
| 3704 function shouldGetter() { |
| 3705 if (this instanceof String || this instanceof Number || this instanceof Bo
olean ) { |
| 3706 return new Assertion(this.valueOf(), null, shouldGetter); |
| 3707 } |
| 3708 return new Assertion(this, null, shouldGetter); |
| 3709 } |
| 3710 function shouldSetter(value) { |
| 3711 // See https://github.com/chaijs/chai/issues/86: this makes |
| 3712 // `whatever.should = someValue` actually set `someValue`, which is |
| 3713 // especially useful for `global.should = require('chai').should()`. |
| 3714 // |
| 3715 // Note that we have to use [[DefineProperty]] instead of [[Put]] |
| 3716 // since otherwise we would trigger this very setter! |
| 3717 Object.defineProperty(this, 'should', { |
| 3718 value: value, |
| 3719 enumerable: true, |
| 3720 configurable: true, |
| 3721 writable: true |
| 3722 }); |
| 3723 } |
| 3724 // modify Object.prototype to have `should` |
| 3725 Object.defineProperty(Object.prototype, 'should', { |
| 3726 set: shouldSetter |
| 3727 , get: shouldGetter |
| 3728 , configurable: true |
| 3729 }); |
| 3730 |
| 3731 var should = {}; |
| 3732 |
| 3733 /** |
| 3734 * ### .fail(actual, expected, [message], [operator]) |
| 3735 * |
| 3736 * Throw a failure. |
| 3737 * |
| 3738 * @name fail |
| 3739 * @param {Mixed} actual |
| 3740 * @param {Mixed} expected |
| 3741 * @param {String} message |
| 3742 * @param {String} operator |
| 3743 * @api public |
| 3744 */ |
| 3745 |
| 3746 should.fail = function (actual, expected, message, operator) { |
| 3747 message = message || 'should.fail()'; |
| 3748 throw new chai.AssertionError(message, { |
| 3749 actual: actual |
| 3750 , expected: expected |
| 3751 , operator: operator |
| 3752 }, should.fail); |
| 3753 }; |
| 3754 |
| 3755 should.equal = function (val1, val2, msg) { |
| 3756 new Assertion(val1, msg).to.equal(val2); |
| 3757 }; |
| 3758 |
| 3759 should.Throw = function (fn, errt, errs, msg) { |
| 3760 new Assertion(fn, msg).to.Throw(errt, errs); |
| 3761 }; |
| 3762 |
| 3763 should.exist = function (val, msg) { |
| 3764 new Assertion(val, msg).to.exist; |
| 3765 } |
| 3766 |
| 3767 // negation |
| 3768 should.not = {} |
| 3769 |
| 3770 should.not.equal = function (val1, val2, msg) { |
| 3771 new Assertion(val1, msg).to.not.equal(val2); |
| 3772 }; |
| 3773 |
| 3774 should.not.Throw = function (fn, errt, errs, msg) { |
| 3775 new Assertion(fn, msg).to.not.Throw(errt, errs); |
| 3776 }; |
| 3777 |
| 3778 should.not.exist = function (val, msg) { |
| 3779 new Assertion(val, msg).to.not.exist; |
| 3780 } |
| 3781 |
| 3782 should['throw'] = should['Throw']; |
| 3783 should.not['throw'] = should.not['Throw']; |
| 3784 |
| 3785 return should; |
| 3786 }; |
| 3787 |
| 3788 chai.should = loadShould; |
| 3789 chai.Should = loadShould; |
| 3790 }; |
| 3791 |
| 3792 },{}],9:[function(require,module,exports){ |
| 3793 /*! |
| 3794 * Chai - addChainingMethod utility |
| 3795 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 3796 * MIT Licensed |
| 3797 */ |
| 3798 |
| 3799 /*! |
| 3800 * Module dependencies |
| 3801 */ |
| 3802 |
| 3803 var transferFlags = require('./transferFlags'); |
| 3804 var flag = require('./flag'); |
| 3805 var config = require('../config'); |
| 3806 |
| 3807 /*! |
| 3808 * Module variables |
| 3809 */ |
| 3810 |
| 3811 // Check whether `__proto__` is supported |
| 3812 var hasProtoSupport = '__proto__' in Object; |
| 3813 |
| 3814 // Without `__proto__` support, this module will need to add properties to a fun
ction. |
| 3815 // However, some Function.prototype methods cannot be overwritten, |
| 3816 // and there seems no easy cross-platform way to detect them (@see chaijs/chai/i
ssues/69). |
| 3817 var excludeNames = /^(?:length|name|arguments|caller)$/; |
| 3818 |
| 3819 // Cache `Function` properties |
| 3820 var call = Function.prototype.call, |
| 3821 apply = Function.prototype.apply; |
| 3822 |
| 3823 /** |
| 3824 * ### addChainableMethod (ctx, name, method, chainingBehavior) |
| 3825 * |
| 3826 * Adds a method to an object, such that the method can also be chained. |
| 3827 * |
| 3828 * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str)
{ |
| 3829 * var obj = utils.flag(this, 'object'); |
| 3830 * new chai.Assertion(obj).to.be.equal(str); |
| 3831 * }); |
| 3832 * |
| 3833 * Can also be accessed directly from `chai.Assertion`. |
| 3834 * |
| 3835 * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); |
| 3836 * |
| 3837 * The result can then be used as both a method assertion, executing both `metho
d` and |
| 3838 * `chainingBehavior`, or as a language chain, which only executes `chainingBeha
vior`. |
| 3839 * |
| 3840 * expect(fooStr).to.be.foo('bar'); |
| 3841 * expect(fooStr).to.be.foo.equal('foo'); |
| 3842 * |
| 3843 * @param {Object} ctx object to which the method is added |
| 3844 * @param {String} name of method to add |
| 3845 * @param {Function} method function to be used for `name`, when called |
| 3846 * @param {Function} chainingBehavior function to be called every time the prope
rty is accessed |
| 3847 * @name addChainableMethod |
| 3848 * @api public |
| 3849 */ |
| 3850 |
| 3851 module.exports = function (ctx, name, method, chainingBehavior) { |
| 3852 if (typeof chainingBehavior !== 'function') { |
| 3853 chainingBehavior = function () { }; |
| 3854 } |
| 3855 |
| 3856 var chainableBehavior = { |
| 3857 method: method |
| 3858 , chainingBehavior: chainingBehavior |
| 3859 }; |
| 3860 |
| 3861 // save the methods so we can overwrite them later, if we need to. |
| 3862 if (!ctx.__methods) { |
| 3863 ctx.__methods = {}; |
| 3864 } |
| 3865 ctx.__methods[name] = chainableBehavior; |
| 3866 |
| 3867 Object.defineProperty(ctx, name, |
| 3868 { get: function () { |
| 3869 chainableBehavior.chainingBehavior.call(this); |
| 3870 |
| 3871 var assert = function assert() { |
| 3872 var old_ssfi = flag(this, 'ssfi'); |
| 3873 if (old_ssfi && config.includeStack === false) |
| 3874 flag(this, 'ssfi', assert); |
| 3875 var result = chainableBehavior.method.apply(this, arguments); |
| 3876 return result === undefined ? this : result; |
| 3877 }; |
| 3878 |
| 3879 // Use `__proto__` if available |
| 3880 if (hasProtoSupport) { |
| 3881 // Inherit all properties from the object by replacing the `Function`
prototype |
| 3882 var prototype = assert.__proto__ = Object.create(this); |
| 3883 // Restore the `call` and `apply` methods from `Function` |
| 3884 prototype.call = call; |
| 3885 prototype.apply = apply; |
| 3886 } |
| 3887 // Otherwise, redefine all properties (slow!) |
| 3888 else { |
| 3889 var asserterNames = Object.getOwnPropertyNames(ctx); |
| 3890 asserterNames.forEach(function (asserterName) { |
| 3891 if (!excludeNames.test(asserterName)) { |
| 3892 var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); |
| 3893 Object.defineProperty(assert, asserterName, pd); |
| 3894 } |
| 3895 }); |
| 3896 } |
| 3897 |
| 3898 transferFlags(this, assert); |
| 3899 return assert; |
| 3900 } |
| 3901 , configurable: true |
| 3902 }); |
| 3903 }; |
| 3904 |
| 3905 },{"../config":4,"./flag":13,"./transferFlags":29}],10:[function(require,module,
exports){ |
| 3906 /*! |
| 3907 * Chai - addMethod utility |
| 3908 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 3909 * MIT Licensed |
| 3910 */ |
| 3911 |
| 3912 var config = require('../config'); |
| 3913 |
| 3914 /** |
| 3915 * ### .addMethod (ctx, name, method) |
| 3916 * |
| 3917 * Adds a method to the prototype of an object. |
| 3918 * |
| 3919 * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { |
| 3920 * var obj = utils.flag(this, 'object'); |
| 3921 * new chai.Assertion(obj).to.be.equal(str); |
| 3922 * }); |
| 3923 * |
| 3924 * Can also be accessed directly from `chai.Assertion`. |
| 3925 * |
| 3926 * chai.Assertion.addMethod('foo', fn); |
| 3927 * |
| 3928 * Then can be used as any other assertion. |
| 3929 * |
| 3930 * expect(fooStr).to.be.foo('bar'); |
| 3931 * |
| 3932 * @param {Object} ctx object to which the method is added |
| 3933 * @param {String} name of method to add |
| 3934 * @param {Function} method function to be used for name |
| 3935 * @name addMethod |
| 3936 * @api public |
| 3937 */ |
| 3938 var flag = require('./flag'); |
| 3939 |
| 3940 module.exports = function (ctx, name, method) { |
| 3941 ctx[name] = function () { |
| 3942 var old_ssfi = flag(this, 'ssfi'); |
| 3943 if (old_ssfi && config.includeStack === false) |
| 3944 flag(this, 'ssfi', ctx[name]); |
| 3945 var result = method.apply(this, arguments); |
| 3946 return result === undefined ? this : result; |
| 3947 }; |
| 3948 }; |
| 3949 |
| 3950 },{"../config":4,"./flag":13}],11:[function(require,module,exports){ |
| 3951 /*! |
| 3952 * Chai - addProperty utility |
| 3953 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 3954 * MIT Licensed |
| 3955 */ |
| 3956 |
| 3957 var config = require('../config'); |
| 3958 var flag = require('./flag'); |
| 3959 |
| 3960 /** |
| 3961 * ### addProperty (ctx, name, getter) |
| 3962 * |
| 3963 * Adds a property to the prototype of an object. |
| 3964 * |
| 3965 * utils.addProperty(chai.Assertion.prototype, 'foo', function () { |
| 3966 * var obj = utils.flag(this, 'object'); |
| 3967 * new chai.Assertion(obj).to.be.instanceof(Foo); |
| 3968 * }); |
| 3969 * |
| 3970 * Can also be accessed directly from `chai.Assertion`. |
| 3971 * |
| 3972 * chai.Assertion.addProperty('foo', fn); |
| 3973 * |
| 3974 * Then can be used as any other assertion. |
| 3975 * |
| 3976 * expect(myFoo).to.be.foo; |
| 3977 * |
| 3978 * @param {Object} ctx object to which the property is added |
| 3979 * @param {String} name of property to add |
| 3980 * @param {Function} getter function to be used for name |
| 3981 * @name addProperty |
| 3982 * @api public |
| 3983 */ |
| 3984 |
| 3985 module.exports = function (ctx, name, getter) { |
| 3986 Object.defineProperty(ctx, name, |
| 3987 { get: function addProperty() { |
| 3988 var old_ssfi = flag(this, 'ssfi'); |
| 3989 if (old_ssfi && config.includeStack === false) |
| 3990 flag(this, 'ssfi', addProperty); |
| 3991 |
| 3992 var result = getter.call(this); |
| 3993 return result === undefined ? this : result; |
| 3994 } |
| 3995 , configurable: true |
| 3996 }); |
| 3997 }; |
| 3998 |
| 3999 },{"../config":4,"./flag":13}],12:[function(require,module,exports){ |
| 4000 /*! |
| 4001 * Chai - expectTypes utility |
| 4002 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4003 * MIT Licensed |
| 4004 */ |
| 4005 |
| 4006 /** |
| 4007 * ### expectTypes(obj, types) |
| 4008 * |
| 4009 * Ensures that the object being tested against is of a valid type. |
| 4010 * |
| 4011 * utils.expectTypes(this, ['array', 'object', 'string']); |
| 4012 * |
| 4013 * @param {Mixed} obj constructed Assertion |
| 4014 * @param {Array} type A list of allowed types for this assertion |
| 4015 * @name expectTypes |
| 4016 * @api public |
| 4017 */ |
| 4018 |
| 4019 var AssertionError = require('assertion-error'); |
| 4020 var flag = require('./flag'); |
| 4021 var type = require('type-detect'); |
| 4022 |
| 4023 module.exports = function (obj, types) { |
| 4024 var obj = flag(obj, 'object'); |
| 4025 types = types.map(function (t) { return t.toLowerCase(); }); |
| 4026 types.sort(); |
| 4027 |
| 4028 // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum' |
| 4029 var str = types.map(function (t, index) { |
| 4030 var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; |
| 4031 var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; |
| 4032 return or + art + ' ' + t; |
| 4033 }).join(', '); |
| 4034 |
| 4035 if (!types.some(function (expected) { return type(obj) === expected; })) { |
| 4036 throw new AssertionError( |
| 4037 'object tested must be ' + str + ', but ' + type(obj) + ' given' |
| 4038 ); |
| 4039 } |
| 4040 }; |
| 4041 |
| 4042 },{"./flag":13,"assertion-error":30,"type-detect":35}],13:[function(require,modu
le,exports){ |
| 4043 /*! |
| 4044 * Chai - flag utility |
| 4045 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4046 * MIT Licensed |
| 4047 */ |
| 4048 |
| 4049 /** |
| 4050 * ### flag(object, key, [value]) |
| 4051 * |
| 4052 * Get or set a flag value on an object. If a |
| 4053 * value is provided it will be set, else it will |
| 4054 * return the currently set value or `undefined` if |
| 4055 * the value is not set. |
| 4056 * |
| 4057 * utils.flag(this, 'foo', 'bar'); // setter |
| 4058 * utils.flag(this, 'foo'); // getter, returns `bar` |
| 4059 * |
| 4060 * @param {Object} object constructed Assertion |
| 4061 * @param {String} key |
| 4062 * @param {Mixed} value (optional) |
| 4063 * @name flag |
| 4064 * @api private |
| 4065 */ |
| 4066 |
| 4067 module.exports = function (obj, key, value) { |
| 4068 var flags = obj.__flags || (obj.__flags = Object.create(null)); |
| 4069 if (arguments.length === 3) { |
| 4070 flags[key] = value; |
| 4071 } else { |
| 4072 return flags[key]; |
| 4073 } |
| 4074 }; |
| 4075 |
| 4076 },{}],14:[function(require,module,exports){ |
| 4077 /*! |
| 4078 * Chai - getActual utility |
| 4079 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4080 * MIT Licensed |
| 4081 */ |
| 4082 |
| 4083 /** |
| 4084 * # getActual(object, [actual]) |
| 4085 * |
| 4086 * Returns the `actual` value for an Assertion |
| 4087 * |
| 4088 * @param {Object} object (constructed Assertion) |
| 4089 * @param {Arguments} chai.Assertion.prototype.assert arguments |
| 4090 */ |
| 4091 |
| 4092 module.exports = function (obj, args) { |
| 4093 return args.length > 4 ? args[4] : obj._obj; |
| 4094 }; |
| 4095 |
| 4096 },{}],15:[function(require,module,exports){ |
| 4097 /*! |
| 4098 * Chai - getEnumerableProperties utility |
| 4099 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4100 * MIT Licensed |
| 4101 */ |
| 4102 |
| 4103 /** |
| 4104 * ### .getEnumerableProperties(object) |
| 4105 * |
| 4106 * This allows the retrieval of enumerable property names of an object, |
| 4107 * inherited or not. |
| 4108 * |
| 4109 * @param {Object} object |
| 4110 * @returns {Array} |
| 4111 * @name getEnumerableProperties |
| 4112 * @api public |
| 4113 */ |
| 4114 |
| 4115 module.exports = function getEnumerableProperties(object) { |
| 4116 var result = []; |
| 4117 for (var name in object) { |
| 4118 result.push(name); |
| 4119 } |
| 4120 return result; |
| 4121 }; |
| 4122 |
| 4123 },{}],16:[function(require,module,exports){ |
| 4124 /*! |
| 4125 * Chai - message composition utility |
| 4126 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4127 * MIT Licensed |
| 4128 */ |
| 4129 |
| 4130 /*! |
| 4131 * Module dependancies |
| 4132 */ |
| 4133 |
| 4134 var flag = require('./flag') |
| 4135 , getActual = require('./getActual') |
| 4136 , inspect = require('./inspect') |
| 4137 , objDisplay = require('./objDisplay'); |
| 4138 |
| 4139 /** |
| 4140 * ### .getMessage(object, message, negateMessage) |
| 4141 * |
| 4142 * Construct the error message based on flags |
| 4143 * and template tags. Template tags will return |
| 4144 * a stringified inspection of the object referenced. |
| 4145 * |
| 4146 * Message template tags: |
| 4147 * - `#{this}` current asserted object |
| 4148 * - `#{act}` actual value |
| 4149 * - `#{exp}` expected value |
| 4150 * |
| 4151 * @param {Object} object (constructed Assertion) |
| 4152 * @param {Arguments} chai.Assertion.prototype.assert arguments |
| 4153 * @name getMessage |
| 4154 * @api public |
| 4155 */ |
| 4156 |
| 4157 module.exports = function (obj, args) { |
| 4158 var negate = flag(obj, 'negate') |
| 4159 , val = flag(obj, 'object') |
| 4160 , expected = args[3] |
| 4161 , actual = getActual(obj, args) |
| 4162 , msg = negate ? args[2] : args[1] |
| 4163 , flagMsg = flag(obj, 'message'); |
| 4164 |
| 4165 if(typeof msg === "function") msg = msg(); |
| 4166 msg = msg || ''; |
| 4167 msg = msg |
| 4168 .replace(/#{this}/g, objDisplay(val)) |
| 4169 .replace(/#{act}/g, objDisplay(actual)) |
| 4170 .replace(/#{exp}/g, objDisplay(expected)); |
| 4171 |
| 4172 return flagMsg ? flagMsg + ': ' + msg : msg; |
| 4173 }; |
| 4174 |
| 4175 },{"./flag":13,"./getActual":14,"./inspect":23,"./objDisplay":24}],17:[function(
require,module,exports){ |
| 4176 /*! |
| 4177 * Chai - getName utility |
| 4178 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4179 * MIT Licensed |
| 4180 */ |
| 4181 |
| 4182 /** |
| 4183 * # getName(func) |
| 4184 * |
| 4185 * Gets the name of a function, in a cross-browser way. |
| 4186 * |
| 4187 * @param {Function} a function (usually a constructor) |
| 4188 */ |
| 4189 |
| 4190 module.exports = function (func) { |
| 4191 if (func.name) return func.name; |
| 4192 |
| 4193 var match = /^\s?function ([^(]*)\(/.exec(func); |
| 4194 return match && match[1] ? match[1] : ""; |
| 4195 }; |
| 4196 |
| 4197 },{}],18:[function(require,module,exports){ |
| 4198 /*! |
| 4199 * Chai - getPathInfo utility |
| 4200 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4201 * MIT Licensed |
| 4202 */ |
| 4203 |
| 4204 var hasProperty = require('./hasProperty'); |
| 4205 |
| 4206 /** |
| 4207 * ### .getPathInfo(path, object) |
| 4208 * |
| 4209 * This allows the retrieval of property info in an |
| 4210 * object given a string path. |
| 4211 * |
| 4212 * The path info consists of an object with the |
| 4213 * following properties: |
| 4214 * |
| 4215 * * parent - The parent object of the property referenced by `path` |
| 4216 * * name - The name of the final property, a number if it was an array indexer |
| 4217 * * value - The value of the property, if it exists, otherwise `undefined` |
| 4218 * * exists - Whether the property exists or not |
| 4219 * |
| 4220 * @param {String} path |
| 4221 * @param {Object} object |
| 4222 * @returns {Object} info |
| 4223 * @name getPathInfo |
| 4224 * @api public |
| 4225 */ |
| 4226 |
| 4227 module.exports = function getPathInfo(path, obj) { |
| 4228 var parsed = parsePath(path), |
| 4229 last = parsed[parsed.length - 1]; |
| 4230 |
| 4231 var info = { |
| 4232 parent: parsed.length > 1 ? _getPathValue(parsed, obj, parsed.length - 1) :
obj, |
| 4233 name: last.p || last.i, |
| 4234 value: _getPathValue(parsed, obj) |
| 4235 }; |
| 4236 info.exists = hasProperty(info.name, info.parent); |
| 4237 |
| 4238 return info; |
| 4239 }; |
| 4240 |
| 4241 |
| 4242 /*! |
| 4243 * ## parsePath(path) |
| 4244 * |
| 4245 * Helper function used to parse string object |
| 4246 * paths. Use in conjunction with `_getPathValue`. |
| 4247 * |
| 4248 * var parsed = parsePath('myobject.property.subprop'); |
| 4249 * |
| 4250 * ### Paths: |
| 4251 * |
| 4252 * * Can be as near infinitely deep and nested |
| 4253 * * Arrays are also valid using the formal `myobject.document[3].property`. |
| 4254 * * Literal dots and brackets (not delimiter) must be backslash-escaped. |
| 4255 * |
| 4256 * @param {String} path |
| 4257 * @returns {Object} parsed |
| 4258 * @api private |
| 4259 */ |
| 4260 |
| 4261 function parsePath (path) { |
| 4262 var str = path.replace(/([^\\])\[/g, '$1.[') |
| 4263 , parts = str.match(/(\\\.|[^.]+?)+/g); |
| 4264 return parts.map(function (value) { |
| 4265 var re = /^\[(\d+)\]$/ |
| 4266 , mArr = re.exec(value); |
| 4267 if (mArr) return { i: parseFloat(mArr[1]) }; |
| 4268 else return { p: value.replace(/\\([.\[\]])/g, '$1') }; |
| 4269 }); |
| 4270 } |
| 4271 |
| 4272 |
| 4273 /*! |
| 4274 * ## _getPathValue(parsed, obj) |
| 4275 * |
| 4276 * Helper companion function for `.parsePath` that returns |
| 4277 * the value located at the parsed address. |
| 4278 * |
| 4279 * var value = getPathValue(parsed, obj); |
| 4280 * |
| 4281 * @param {Object} parsed definition from `parsePath`. |
| 4282 * @param {Object} object to search against |
| 4283 * @param {Number} object to search against |
| 4284 * @returns {Object|Undefined} value |
| 4285 * @api private |
| 4286 */ |
| 4287 |
| 4288 function _getPathValue (parsed, obj, index) { |
| 4289 var tmp = obj |
| 4290 , res; |
| 4291 |
| 4292 index = (index === undefined ? parsed.length : index); |
| 4293 |
| 4294 for (var i = 0, l = index; i < l; i++) { |
| 4295 var part = parsed[i]; |
| 4296 if (tmp) { |
| 4297 if ('undefined' !== typeof part.p) |
| 4298 tmp = tmp[part.p]; |
| 4299 else if ('undefined' !== typeof part.i) |
| 4300 tmp = tmp[part.i]; |
| 4301 if (i == (l - 1)) res = tmp; |
| 4302 } else { |
| 4303 res = undefined; |
| 4304 } |
| 4305 } |
| 4306 return res; |
| 4307 } |
| 4308 |
| 4309 },{"./hasProperty":21}],19:[function(require,module,exports){ |
| 4310 /*! |
| 4311 * Chai - getPathValue utility |
| 4312 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4313 * @see https://github.com/logicalparadox/filtr |
| 4314 * MIT Licensed |
| 4315 */ |
| 4316 |
| 4317 var getPathInfo = require('./getPathInfo'); |
| 4318 |
| 4319 /** |
| 4320 * ### .getPathValue(path, object) |
| 4321 * |
| 4322 * This allows the retrieval of values in an |
| 4323 * object given a string path. |
| 4324 * |
| 4325 * var obj = { |
| 4326 * prop1: { |
| 4327 * arr: ['a', 'b', 'c'] |
| 4328 * , str: 'Hello' |
| 4329 * } |
| 4330 * , prop2: { |
| 4331 * arr: [ { nested: 'Universe' } ] |
| 4332 * , str: 'Hello again!' |
| 4333 * } |
| 4334 * } |
| 4335 * |
| 4336 * The following would be the results. |
| 4337 * |
| 4338 * getPathValue('prop1.str', obj); // Hello |
| 4339 * getPathValue('prop1.att[2]', obj); // b |
| 4340 * getPathValue('prop2.arr[0].nested', obj); // Universe |
| 4341 * |
| 4342 * @param {String} path |
| 4343 * @param {Object} object |
| 4344 * @returns {Object} value or `undefined` |
| 4345 * @name getPathValue |
| 4346 * @api public |
| 4347 */ |
| 4348 module.exports = function(path, obj) { |
| 4349 var info = getPathInfo(path, obj); |
| 4350 return info.value; |
| 4351 }; |
| 4352 |
| 4353 },{"./getPathInfo":18}],20:[function(require,module,exports){ |
| 4354 /*! |
| 4355 * Chai - getProperties utility |
| 4356 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4357 * MIT Licensed |
| 4358 */ |
| 4359 |
| 4360 /** |
| 4361 * ### .getProperties(object) |
| 4362 * |
| 4363 * This allows the retrieval of property names of an object, enumerable or not, |
| 4364 * inherited or not. |
| 4365 * |
| 4366 * @param {Object} object |
| 4367 * @returns {Array} |
| 4368 * @name getProperties |
| 4369 * @api public |
| 4370 */ |
| 4371 |
| 4372 module.exports = function getProperties(object) { |
| 4373 var result = Object.getOwnPropertyNames(object); |
| 4374 |
| 4375 function addProperty(property) { |
| 4376 if (result.indexOf(property) === -1) { |
| 4377 result.push(property); |
| 4378 } |
| 4379 } |
| 4380 |
| 4381 var proto = Object.getPrototypeOf(object); |
| 4382 while (proto !== null) { |
| 4383 Object.getOwnPropertyNames(proto).forEach(addProperty); |
| 4384 proto = Object.getPrototypeOf(proto); |
| 4385 } |
| 4386 |
| 4387 return result; |
| 4388 }; |
| 4389 |
| 4390 },{}],21:[function(require,module,exports){ |
| 4391 /*! |
| 4392 * Chai - hasProperty utility |
| 4393 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4394 * MIT Licensed |
| 4395 */ |
| 4396 |
| 4397 var type = require('type-detect'); |
| 4398 |
| 4399 /** |
| 4400 * ### .hasProperty(object, name) |
| 4401 * |
| 4402 * This allows checking whether an object has |
| 4403 * named property or numeric array index. |
| 4404 * |
| 4405 * Basically does the same thing as the `in` |
| 4406 * operator but works properly with natives |
| 4407 * and null/undefined values. |
| 4408 * |
| 4409 * var obj = { |
| 4410 * arr: ['a', 'b', 'c'] |
| 4411 * , str: 'Hello' |
| 4412 * } |
| 4413 * |
| 4414 * The following would be the results. |
| 4415 * |
| 4416 * hasProperty('str', obj); // true |
| 4417 * hasProperty('constructor', obj); // true |
| 4418 * hasProperty('bar', obj); // false |
| 4419 * |
| 4420 * hasProperty('length', obj.str); // true |
| 4421 * hasProperty(1, obj.str); // true |
| 4422 * hasProperty(5, obj.str); // false |
| 4423 * |
| 4424 * hasProperty('length', obj.arr); // true |
| 4425 * hasProperty(2, obj.arr); // true |
| 4426 * hasProperty(3, obj.arr); // false |
| 4427 * |
| 4428 * @param {Objuect} object |
| 4429 * @param {String|Number} name |
| 4430 * @returns {Boolean} whether it exists |
| 4431 * @name getPathInfo |
| 4432 * @api public |
| 4433 */ |
| 4434 |
| 4435 var literals = { |
| 4436 'number': Number |
| 4437 , 'string': String |
| 4438 }; |
| 4439 |
| 4440 module.exports = function hasProperty(name, obj) { |
| 4441 var ot = type(obj); |
| 4442 |
| 4443 // Bad Object, obviously no props at all |
| 4444 if(ot === 'null' || ot === 'undefined') |
| 4445 return false; |
| 4446 |
| 4447 // The `in` operator does not work with certain literals |
| 4448 // box these before the check |
| 4449 if(literals[ot] && typeof obj !== 'object') |
| 4450 obj = new literals[ot](obj); |
| 4451 |
| 4452 return name in obj; |
| 4453 }; |
| 4454 |
| 4455 },{"type-detect":35}],22:[function(require,module,exports){ |
| 4456 /*! |
| 4457 * chai |
| 4458 * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> |
| 4459 * MIT Licensed |
| 4460 */ |
| 4461 |
| 4462 /*! |
| 4463 * Main exports |
| 4464 */ |
| 4465 |
| 4466 var exports = module.exports = {}; |
| 4467 |
| 4468 /*! |
| 4469 * test utility |
| 4470 */ |
| 4471 |
| 4472 exports.test = require('./test'); |
| 4473 |
| 4474 /*! |
| 4475 * type utility |
| 4476 */ |
| 4477 |
| 4478 exports.type = require('type-detect'); |
| 4479 |
| 4480 /*! |
| 4481 * expectTypes utility |
| 4482 */ |
| 4483 exports.expectTypes = require('./expectTypes'); |
| 4484 |
| 4485 /*! |
| 4486 * message utility |
| 4487 */ |
| 4488 |
| 4489 exports.getMessage = require('./getMessage'); |
| 4490 |
| 4491 /*! |
| 4492 * actual utility |
| 4493 */ |
| 4494 |
| 4495 exports.getActual = require('./getActual'); |
| 4496 |
| 4497 /*! |
| 4498 * Inspect util |
| 4499 */ |
| 4500 |
| 4501 exports.inspect = require('./inspect'); |
| 4502 |
| 4503 /*! |
| 4504 * Object Display util |
| 4505 */ |
| 4506 |
| 4507 exports.objDisplay = require('./objDisplay'); |
| 4508 |
| 4509 /*! |
| 4510 * Flag utility |
| 4511 */ |
| 4512 |
| 4513 exports.flag = require('./flag'); |
| 4514 |
| 4515 /*! |
| 4516 * Flag transferring utility |
| 4517 */ |
| 4518 |
| 4519 exports.transferFlags = require('./transferFlags'); |
| 4520 |
| 4521 /*! |
| 4522 * Deep equal utility |
| 4523 */ |
| 4524 |
| 4525 exports.eql = require('deep-eql'); |
| 4526 |
| 4527 /*! |
| 4528 * Deep path value |
| 4529 */ |
| 4530 |
| 4531 exports.getPathValue = require('./getPathValue'); |
| 4532 |
| 4533 /*! |
| 4534 * Deep path info |
| 4535 */ |
| 4536 |
| 4537 exports.getPathInfo = require('./getPathInfo'); |
| 4538 |
| 4539 /*! |
| 4540 * Check if a property exists |
| 4541 */ |
| 4542 |
| 4543 exports.hasProperty = require('./hasProperty'); |
| 4544 |
| 4545 /*! |
| 4546 * Function name |
| 4547 */ |
| 4548 |
| 4549 exports.getName = require('./getName'); |
| 4550 |
| 4551 /*! |
| 4552 * add Property |
| 4553 */ |
| 4554 |
| 4555 exports.addProperty = require('./addProperty'); |
| 4556 |
| 4557 /*! |
| 4558 * add Method |
| 4559 */ |
| 4560 |
| 4561 exports.addMethod = require('./addMethod'); |
| 4562 |
| 4563 /*! |
| 4564 * overwrite Property |
| 4565 */ |
| 4566 |
| 4567 exports.overwriteProperty = require('./overwriteProperty'); |
| 4568 |
| 4569 /*! |
| 4570 * overwrite Method |
| 4571 */ |
| 4572 |
| 4573 exports.overwriteMethod = require('./overwriteMethod'); |
| 4574 |
| 4575 /*! |
| 4576 * Add a chainable method |
| 4577 */ |
| 4578 |
| 4579 exports.addChainableMethod = require('./addChainableMethod'); |
| 4580 |
| 4581 /*! |
| 4582 * Overwrite chainable method |
| 4583 */ |
| 4584 |
| 4585 exports.overwriteChainableMethod = require('./overwriteChainableMethod'); |
| 4586 |
| 4587 },{"./addChainableMethod":9,"./addMethod":10,"./addProperty":11,"./expectTypes":
12,"./flag":13,"./getActual":14,"./getMessage":16,"./getName":17,"./getPathInfo"
:18,"./getPathValue":19,"./hasProperty":21,"./inspect":23,"./objDisplay":24,"./o
verwriteChainableMethod":25,"./overwriteMethod":26,"./overwriteProperty":27,"./t
est":28,"./transferFlags":29,"deep-eql":31,"type-detect":35}],23:[function(requi
re,module,exports){ |
| 4588 // This is (almost) directly from Node.js utils |
| 4589 // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/
lib/util.js |
| 4590 |
| 4591 var getName = require('./getName'); |
| 4592 var getProperties = require('./getProperties'); |
| 4593 var getEnumerableProperties = require('./getEnumerableProperties'); |
| 4594 |
| 4595 module.exports = inspect; |
| 4596 |
| 4597 /** |
| 4598 * Echos the value of a value. Trys to print the value out |
| 4599 * in the best way possible given the different types. |
| 4600 * |
| 4601 * @param {Object} obj The object to print out. |
| 4602 * @param {Boolean} showHidden Flag that shows hidden (not enumerable) |
| 4603 * properties of objects. |
| 4604 * @param {Number} depth Depth in which to descend in object. Default is 2. |
| 4605 * @param {Boolean} colors Flag to turn on ANSI escape codes to color the |
| 4606 * output. Default is false (no coloring). |
| 4607 */ |
| 4608 function inspect(obj, showHidden, depth, colors) { |
| 4609 var ctx = { |
| 4610 showHidden: showHidden, |
| 4611 seen: [], |
| 4612 stylize: function (str) { return str; } |
| 4613 }; |
| 4614 return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); |
| 4615 } |
| 4616 |
| 4617 // Returns true if object is a DOM element. |
| 4618 var isDOMElement = function (object) { |
| 4619 if (typeof HTMLElement === 'object') { |
| 4620 return object instanceof HTMLElement; |
| 4621 } else { |
| 4622 return object && |
| 4623 typeof object === 'object' && |
| 4624 object.nodeType === 1 && |
| 4625 typeof object.nodeName === 'string'; |
| 4626 } |
| 4627 }; |
| 4628 |
| 4629 function formatValue(ctx, value, recurseTimes) { |
| 4630 // Provide a hook for user-specified inspect functions. |
| 4631 // Check that value is an object with an inspect function on it |
| 4632 if (value && typeof value.inspect === 'function' && |
| 4633 // Filter out the util module, it's inspect function is special |
| 4634 value.inspect !== exports.inspect && |
| 4635 // Also filter out any prototype objects using the circular check. |
| 4636 !(value.constructor && value.constructor.prototype === value)) { |
| 4637 var ret = value.inspect(recurseTimes); |
| 4638 if (typeof ret !== 'string') { |
| 4639 ret = formatValue(ctx, ret, recurseTimes); |
| 4640 } |
| 4641 return ret; |
| 4642 } |
| 4643 |
| 4644 // Primitive types cannot have properties |
| 4645 var primitive = formatPrimitive(ctx, value); |
| 4646 if (primitive) { |
| 4647 return primitive; |
| 4648 } |
| 4649 |
| 4650 // If this is a DOM element, try to get the outer HTML. |
| 4651 if (isDOMElement(value)) { |
| 4652 if ('outerHTML' in value) { |
| 4653 return value.outerHTML; |
| 4654 // This value does not have an outerHTML attribute, |
| 4655 // it could still be an XML element |
| 4656 } else { |
| 4657 // Attempt to serialize it |
| 4658 try { |
| 4659 if (document.xmlVersion) { |
| 4660 var xmlSerializer = new XMLSerializer(); |
| 4661 return xmlSerializer.serializeToString(value); |
| 4662 } else { |
| 4663 // Firefox 11- do not support outerHTML |
| 4664 // It does, however, support innerHTML |
| 4665 // Use the following to render the element |
| 4666 var ns = "http://www.w3.org/1999/xhtml"; |
| 4667 var container = document.createElementNS(ns, '_'); |
| 4668 |
| 4669 container.appendChild(value.cloneNode(false)); |
| 4670 html = container.innerHTML |
| 4671 .replace('><', '>' + value.innerHTML + '<'); |
| 4672 container.innerHTML = ''; |
| 4673 return html; |
| 4674 } |
| 4675 } catch (err) { |
| 4676 // This could be a non-native DOM implementation, |
| 4677 // continue with the normal flow: |
| 4678 // printing the element as if it is an object. |
| 4679 } |
| 4680 } |
| 4681 } |
| 4682 |
| 4683 // Look up the keys of the object. |
| 4684 var visibleKeys = getEnumerableProperties(value); |
| 4685 var keys = ctx.showHidden ? getProperties(value) : visibleKeys; |
| 4686 |
| 4687 // Some type of object without properties can be shortcutted. |
| 4688 // In IE, errors have a single `stack` property, or if they are vanilla `Error
`, |
| 4689 // a `stack` plus `description` property; ignore those for consistency. |
| 4690 if (keys.length === 0 || (isError(value) && ( |
| 4691 (keys.length === 1 && keys[0] === 'stack') || |
| 4692 (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') |
| 4693 ))) { |
| 4694 if (typeof value === 'function') { |
| 4695 var name = getName(value); |
| 4696 var nameSuffix = name ? ': ' + name : ''; |
| 4697 return ctx.stylize('[Function' + nameSuffix + ']', 'special'); |
| 4698 } |
| 4699 if (isRegExp(value)) { |
| 4700 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
| 4701 } |
| 4702 if (isDate(value)) { |
| 4703 return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); |
| 4704 } |
| 4705 if (isError(value)) { |
| 4706 return formatError(value); |
| 4707 } |
| 4708 } |
| 4709 |
| 4710 var base = '', array = false, braces = ['{', '}']; |
| 4711 |
| 4712 // Make Array say that they are Array |
| 4713 if (isArray(value)) { |
| 4714 array = true; |
| 4715 braces = ['[', ']']; |
| 4716 } |
| 4717 |
| 4718 // Make functions say that they are functions |
| 4719 if (typeof value === 'function') { |
| 4720 var name = getName(value); |
| 4721 var nameSuffix = name ? ': ' + name : ''; |
| 4722 base = ' [Function' + nameSuffix + ']'; |
| 4723 } |
| 4724 |
| 4725 // Make RegExps say that they are RegExps |
| 4726 if (isRegExp(value)) { |
| 4727 base = ' ' + RegExp.prototype.toString.call(value); |
| 4728 } |
| 4729 |
| 4730 // Make dates with properties first say the date |
| 4731 if (isDate(value)) { |
| 4732 base = ' ' + Date.prototype.toUTCString.call(value); |
| 4733 } |
| 4734 |
| 4735 // Make error with message first say the error |
| 4736 if (isError(value)) { |
| 4737 return formatError(value); |
| 4738 } |
| 4739 |
| 4740 if (keys.length === 0 && (!array || value.length == 0)) { |
| 4741 return braces[0] + base + braces[1]; |
| 4742 } |
| 4743 |
| 4744 if (recurseTimes < 0) { |
| 4745 if (isRegExp(value)) { |
| 4746 return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
| 4747 } else { |
| 4748 return ctx.stylize('[Object]', 'special'); |
| 4749 } |
| 4750 } |
| 4751 |
| 4752 ctx.seen.push(value); |
| 4753 |
| 4754 var output; |
| 4755 if (array) { |
| 4756 output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); |
| 4757 } else { |
| 4758 output = keys.map(function(key) { |
| 4759 return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); |
| 4760 }); |
| 4761 } |
| 4762 |
| 4763 ctx.seen.pop(); |
| 4764 |
| 4765 return reduceToSingleString(output, base, braces); |
| 4766 } |
| 4767 |
| 4768 |
| 4769 function formatPrimitive(ctx, value) { |
| 4770 switch (typeof value) { |
| 4771 case 'undefined': |
| 4772 return ctx.stylize('undefined', 'undefined'); |
| 4773 |
| 4774 case 'string': |
| 4775 var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') |
| 4776 .replace(/'/g, "\\'") |
| 4777 .replace(/\\"/g, '"') + '\''; |
| 4778 return ctx.stylize(simple, 'string'); |
| 4779 |
| 4780 case 'number': |
| 4781 if (value === 0 && (1/value) === -Infinity) { |
| 4782 return ctx.stylize('-0', 'number'); |
| 4783 } |
| 4784 return ctx.stylize('' + value, 'number'); |
| 4785 |
| 4786 case 'boolean': |
| 4787 return ctx.stylize('' + value, 'boolean'); |
| 4788 } |
| 4789 // For some reason typeof null is "object", so special case here. |
| 4790 if (value === null) { |
| 4791 return ctx.stylize('null', 'null'); |
| 4792 } |
| 4793 } |
| 4794 |
| 4795 |
| 4796 function formatError(value) { |
| 4797 return '[' + Error.prototype.toString.call(value) + ']'; |
| 4798 } |
| 4799 |
| 4800 |
| 4801 function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { |
| 4802 var output = []; |
| 4803 for (var i = 0, l = value.length; i < l; ++i) { |
| 4804 if (Object.prototype.hasOwnProperty.call(value, String(i))) { |
| 4805 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
| 4806 String(i), true)); |
| 4807 } else { |
| 4808 output.push(''); |
| 4809 } |
| 4810 } |
| 4811 keys.forEach(function(key) { |
| 4812 if (!key.match(/^\d+$/)) { |
| 4813 output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
| 4814 key, true)); |
| 4815 } |
| 4816 }); |
| 4817 return output; |
| 4818 } |
| 4819 |
| 4820 |
| 4821 function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { |
| 4822 var name, str; |
| 4823 if (value.__lookupGetter__) { |
| 4824 if (value.__lookupGetter__(key)) { |
| 4825 if (value.__lookupSetter__(key)) { |
| 4826 str = ctx.stylize('[Getter/Setter]', 'special'); |
| 4827 } else { |
| 4828 str = ctx.stylize('[Getter]', 'special'); |
| 4829 } |
| 4830 } else { |
| 4831 if (value.__lookupSetter__(key)) { |
| 4832 str = ctx.stylize('[Setter]', 'special'); |
| 4833 } |
| 4834 } |
| 4835 } |
| 4836 if (visibleKeys.indexOf(key) < 0) { |
| 4837 name = '[' + key + ']'; |
| 4838 } |
| 4839 if (!str) { |
| 4840 if (ctx.seen.indexOf(value[key]) < 0) { |
| 4841 if (recurseTimes === null) { |
| 4842 str = formatValue(ctx, value[key], null); |
| 4843 } else { |
| 4844 str = formatValue(ctx, value[key], recurseTimes - 1); |
| 4845 } |
| 4846 if (str.indexOf('\n') > -1) { |
| 4847 if (array) { |
| 4848 str = str.split('\n').map(function(line) { |
| 4849 return ' ' + line; |
| 4850 }).join('\n').substr(2); |
| 4851 } else { |
| 4852 str = '\n' + str.split('\n').map(function(line) { |
| 4853 return ' ' + line; |
| 4854 }).join('\n'); |
| 4855 } |
| 4856 } |
| 4857 } else { |
| 4858 str = ctx.stylize('[Circular]', 'special'); |
| 4859 } |
| 4860 } |
| 4861 if (typeof name === 'undefined') { |
| 4862 if (array && key.match(/^\d+$/)) { |
| 4863 return str; |
| 4864 } |
| 4865 name = JSON.stringify('' + key); |
| 4866 if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { |
| 4867 name = name.substr(1, name.length - 2); |
| 4868 name = ctx.stylize(name, 'name'); |
| 4869 } else { |
| 4870 name = name.replace(/'/g, "\\'") |
| 4871 .replace(/\\"/g, '"') |
| 4872 .replace(/(^"|"$)/g, "'"); |
| 4873 name = ctx.stylize(name, 'string'); |
| 4874 } |
| 4875 } |
| 4876 |
| 4877 return name + ': ' + str; |
| 4878 } |
| 4879 |
| 4880 |
| 4881 function reduceToSingleString(output, base, braces) { |
| 4882 var numLinesEst = 0; |
| 4883 var length = output.reduce(function(prev, cur) { |
| 4884 numLinesEst++; |
| 4885 if (cur.indexOf('\n') >= 0) numLinesEst++; |
| 4886 return prev + cur.length + 1; |
| 4887 }, 0); |
| 4888 |
| 4889 if (length > 60) { |
| 4890 return braces[0] + |
| 4891 (base === '' ? '' : base + '\n ') + |
| 4892 ' ' + |
| 4893 output.join(',\n ') + |
| 4894 ' ' + |
| 4895 braces[1]; |
| 4896 } |
| 4897 |
| 4898 return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; |
| 4899 } |
| 4900 |
| 4901 function isArray(ar) { |
| 4902 return Array.isArray(ar) || |
| 4903 (typeof ar === 'object' && objectToString(ar) === '[object Array]'); |
| 4904 } |
| 4905 |
| 4906 function isRegExp(re) { |
| 4907 return typeof re === 'object' && objectToString(re) === '[object RegExp]'; |
| 4908 } |
| 4909 |
| 4910 function isDate(d) { |
| 4911 return typeof d === 'object' && objectToString(d) === '[object Date]'; |
| 4912 } |
| 4913 |
| 4914 function isError(e) { |
| 4915 return typeof e === 'object' && objectToString(e) === '[object Error]'; |
| 4916 } |
| 4917 |
| 4918 function objectToString(o) { |
| 4919 return Object.prototype.toString.call(o); |
| 4920 } |
| 4921 |
| 4922 },{"./getEnumerableProperties":15,"./getName":17,"./getProperties":20}],24:[func
tion(require,module,exports){ |
| 4923 /*! |
| 4924 * Chai - flag utility |
| 4925 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4926 * MIT Licensed |
| 4927 */ |
| 4928 |
| 4929 /*! |
| 4930 * Module dependancies |
| 4931 */ |
| 4932 |
| 4933 var inspect = require('./inspect'); |
| 4934 var config = require('../config'); |
| 4935 |
| 4936 /** |
| 4937 * ### .objDisplay (object) |
| 4938 * |
| 4939 * Determines if an object or an array matches |
| 4940 * criteria to be inspected in-line for error |
| 4941 * messages or should be truncated. |
| 4942 * |
| 4943 * @param {Mixed} javascript object to inspect |
| 4944 * @name objDisplay |
| 4945 * @api public |
| 4946 */ |
| 4947 |
| 4948 module.exports = function (obj) { |
| 4949 var str = inspect(obj) |
| 4950 , type = Object.prototype.toString.call(obj); |
| 4951 |
| 4952 if (config.truncateThreshold && str.length >= config.truncateThreshold) { |
| 4953 if (type === '[object Function]') { |
| 4954 return !obj.name || obj.name === '' |
| 4955 ? '[Function]' |
| 4956 : '[Function: ' + obj.name + ']'; |
| 4957 } else if (type === '[object Array]') { |
| 4958 return '[ Array(' + obj.length + ') ]'; |
| 4959 } else if (type === '[object Object]') { |
| 4960 var keys = Object.keys(obj) |
| 4961 , kstr = keys.length > 2 |
| 4962 ? keys.splice(0, 2).join(', ') + ', ...' |
| 4963 : keys.join(', '); |
| 4964 return '{ Object (' + kstr + ') }'; |
| 4965 } else { |
| 4966 return str; |
| 4967 } |
| 4968 } else { |
| 4969 return str; |
| 4970 } |
| 4971 }; |
| 4972 |
| 4973 },{"../config":4,"./inspect":23}],25:[function(require,module,exports){ |
| 4974 /*! |
| 4975 * Chai - overwriteChainableMethod utility |
| 4976 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 4977 * MIT Licensed |
| 4978 */ |
| 4979 |
| 4980 /** |
| 4981 * ### overwriteChainableMethod (ctx, name, method, chainingBehavior) |
| 4982 * |
| 4983 * Overwites an already existing chainable method |
| 4984 * and provides access to the previous function or |
| 4985 * property. Must return functions to be used for |
| 4986 * name. |
| 4987 * |
| 4988 * utils.overwriteChainableMethod(chai.Assertion.prototype, 'length', |
| 4989 * function (_super) { |
| 4990 * } |
| 4991 * , function (_super) { |
| 4992 * } |
| 4993 * ); |
| 4994 * |
| 4995 * Can also be accessed directly from `chai.Assertion`. |
| 4996 * |
| 4997 * chai.Assertion.overwriteChainableMethod('foo', fn, fn); |
| 4998 * |
| 4999 * Then can be used as any other assertion. |
| 5000 * |
| 5001 * expect(myFoo).to.have.length(3); |
| 5002 * expect(myFoo).to.have.length.above(3); |
| 5003 * |
| 5004 * @param {Object} ctx object whose method / property is to be overwritten |
| 5005 * @param {String} name of method / property to overwrite |
| 5006 * @param {Function} method function that returns a function to be used for name |
| 5007 * @param {Function} chainingBehavior function that returns a function to be use
d for property |
| 5008 * @name overwriteChainableMethod |
| 5009 * @api public |
| 5010 */ |
| 5011 |
| 5012 module.exports = function (ctx, name, method, chainingBehavior) { |
| 5013 var chainableBehavior = ctx.__methods[name]; |
| 5014 |
| 5015 var _chainingBehavior = chainableBehavior.chainingBehavior; |
| 5016 chainableBehavior.chainingBehavior = function () { |
| 5017 var result = chainingBehavior(_chainingBehavior).call(this); |
| 5018 return result === undefined ? this : result; |
| 5019 }; |
| 5020 |
| 5021 var _method = chainableBehavior.method; |
| 5022 chainableBehavior.method = function () { |
| 5023 var result = method(_method).apply(this, arguments); |
| 5024 return result === undefined ? this : result; |
| 5025 }; |
| 5026 }; |
| 5027 |
| 5028 },{}],26:[function(require,module,exports){ |
| 5029 /*! |
| 5030 * Chai - overwriteMethod utility |
| 5031 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 5032 * MIT Licensed |
| 5033 */ |
| 5034 |
| 5035 /** |
| 5036 * ### overwriteMethod (ctx, name, fn) |
| 5037 * |
| 5038 * Overwites an already existing method and provides |
| 5039 * access to previous function. Must return function |
| 5040 * to be used for name. |
| 5041 * |
| 5042 * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super
) { |
| 5043 * return function (str) { |
| 5044 * var obj = utils.flag(this, 'object'); |
| 5045 * if (obj instanceof Foo) { |
| 5046 * new chai.Assertion(obj.value).to.equal(str); |
| 5047 * } else { |
| 5048 * _super.apply(this, arguments); |
| 5049 * } |
| 5050 * } |
| 5051 * }); |
| 5052 * |
| 5053 * Can also be accessed directly from `chai.Assertion`. |
| 5054 * |
| 5055 * chai.Assertion.overwriteMethod('foo', fn); |
| 5056 * |
| 5057 * Then can be used as any other assertion. |
| 5058 * |
| 5059 * expect(myFoo).to.equal('bar'); |
| 5060 * |
| 5061 * @param {Object} ctx object whose method is to be overwritten |
| 5062 * @param {String} name of method to overwrite |
| 5063 * @param {Function} method function that returns a function to be used for name |
| 5064 * @name overwriteMethod |
| 5065 * @api public |
| 5066 */ |
| 5067 |
| 5068 module.exports = function (ctx, name, method) { |
| 5069 var _method = ctx[name] |
| 5070 , _super = function () { return this; }; |
| 5071 |
| 5072 if (_method && 'function' === typeof _method) |
| 5073 _super = _method; |
| 5074 |
| 5075 ctx[name] = function () { |
| 5076 var result = method(_super).apply(this, arguments); |
| 5077 return result === undefined ? this : result; |
| 5078 } |
| 5079 }; |
| 5080 |
| 5081 },{}],27:[function(require,module,exports){ |
| 5082 /*! |
| 5083 * Chai - overwriteProperty utility |
| 5084 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 5085 * MIT Licensed |
| 5086 */ |
| 5087 |
| 5088 /** |
| 5089 * ### overwriteProperty (ctx, name, fn) |
| 5090 * |
| 5091 * Overwites an already existing property getter and provides |
| 5092 * access to previous value. Must return function to use as getter. |
| 5093 * |
| 5094 * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super)
{ |
| 5095 * return function () { |
| 5096 * var obj = utils.flag(this, 'object'); |
| 5097 * if (obj instanceof Foo) { |
| 5098 * new chai.Assertion(obj.name).to.equal('bar'); |
| 5099 * } else { |
| 5100 * _super.call(this); |
| 5101 * } |
| 5102 * } |
| 5103 * }); |
| 5104 * |
| 5105 * |
| 5106 * Can also be accessed directly from `chai.Assertion`. |
| 5107 * |
| 5108 * chai.Assertion.overwriteProperty('foo', fn); |
| 5109 * |
| 5110 * Then can be used as any other assertion. |
| 5111 * |
| 5112 * expect(myFoo).to.be.ok; |
| 5113 * |
| 5114 * @param {Object} ctx object whose property is to be overwritten |
| 5115 * @param {String} name of property to overwrite |
| 5116 * @param {Function} getter function that returns a getter function to be used f
or name |
| 5117 * @name overwriteProperty |
| 5118 * @api public |
| 5119 */ |
| 5120 |
| 5121 module.exports = function (ctx, name, getter) { |
| 5122 var _get = Object.getOwnPropertyDescriptor(ctx, name) |
| 5123 , _super = function () {}; |
| 5124 |
| 5125 if (_get && 'function' === typeof _get.get) |
| 5126 _super = _get.get |
| 5127 |
| 5128 Object.defineProperty(ctx, name, |
| 5129 { get: function () { |
| 5130 var result = getter(_super).call(this); |
| 5131 return result === undefined ? this : result; |
| 5132 } |
| 5133 , configurable: true |
| 5134 }); |
| 5135 }; |
| 5136 |
| 5137 },{}],28:[function(require,module,exports){ |
| 5138 /*! |
| 5139 * Chai - test utility |
| 5140 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 5141 * MIT Licensed |
| 5142 */ |
| 5143 |
| 5144 /*! |
| 5145 * Module dependancies |
| 5146 */ |
| 5147 |
| 5148 var flag = require('./flag'); |
| 5149 |
| 5150 /** |
| 5151 * # test(object, expression) |
| 5152 * |
| 5153 * Test and object for expression. |
| 5154 * |
| 5155 * @param {Object} object (constructed Assertion) |
| 5156 * @param {Arguments} chai.Assertion.prototype.assert arguments |
| 5157 */ |
| 5158 |
| 5159 module.exports = function (obj, args) { |
| 5160 var negate = flag(obj, 'negate') |
| 5161 , expr = args[0]; |
| 5162 return negate ? !expr : expr; |
| 5163 }; |
| 5164 |
| 5165 },{"./flag":13}],29:[function(require,module,exports){ |
| 5166 /*! |
| 5167 * Chai - transferFlags utility |
| 5168 * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> |
| 5169 * MIT Licensed |
| 5170 */ |
| 5171 |
| 5172 /** |
| 5173 * ### transferFlags(assertion, object, includeAll = true) |
| 5174 * |
| 5175 * Transfer all the flags for `assertion` to `object`. If |
| 5176 * `includeAll` is set to `false`, then the base Chai |
| 5177 * assertion flags (namely `object`, `ssfi`, and `message`) |
| 5178 * will not be transferred. |
| 5179 * |
| 5180 * |
| 5181 * var newAssertion = new Assertion(); |
| 5182 * utils.transferFlags(assertion, newAssertion); |
| 5183 * |
| 5184 * var anotherAsseriton = new Assertion(myObj); |
| 5185 * utils.transferFlags(assertion, anotherAssertion, false); |
| 5186 * |
| 5187 * @param {Assertion} assertion the assertion to transfer the flags from |
| 5188 * @param {Object} object the object to transfer the flags to; usually a new ass
ertion |
| 5189 * @param {Boolean} includeAll |
| 5190 * @name transferFlags |
| 5191 * @api private |
| 5192 */ |
| 5193 |
| 5194 module.exports = function (assertion, object, includeAll) { |
| 5195 var flags = assertion.__flags || (assertion.__flags = Object.create(null)); |
| 5196 |
| 5197 if (!object.__flags) { |
| 5198 object.__flags = Object.create(null); |
| 5199 } |
| 5200 |
| 5201 includeAll = arguments.length === 3 ? includeAll : true; |
| 5202 |
| 5203 for (var flag in flags) { |
| 5204 if (includeAll || |
| 5205 (flag !== 'object' && flag !== 'ssfi' && flag != 'message')) { |
| 5206 object.__flags[flag] = flags[flag]; |
| 5207 } |
| 5208 } |
| 5209 }; |
| 5210 |
| 5211 },{}],30:[function(require,module,exports){ |
| 5212 /*! |
| 5213 * assertion-error |
| 5214 * Copyright(c) 2013 Jake Luer <jake@qualiancy.com> |
| 5215 * MIT Licensed |
| 5216 */ |
| 5217 |
| 5218 /*! |
| 5219 * Return a function that will copy properties from |
| 5220 * one object to another excluding any originally |
| 5221 * listed. Returned function will create a new `{}`. |
| 5222 * |
| 5223 * @param {String} excluded properties ... |
| 5224 * @return {Function} |
| 5225 */ |
| 5226 |
| 5227 function exclude () { |
| 5228 var excludes = [].slice.call(arguments); |
| 5229 |
| 5230 function excludeProps (res, obj) { |
| 5231 Object.keys(obj).forEach(function (key) { |
| 5232 if (!~excludes.indexOf(key)) res[key] = obj[key]; |
| 5233 }); |
| 5234 } |
| 5235 |
| 5236 return function extendExclude () { |
| 5237 var args = [].slice.call(arguments) |
| 5238 , i = 0 |
| 5239 , res = {}; |
| 5240 |
| 5241 for (; i < args.length; i++) { |
| 5242 excludeProps(res, args[i]); |
| 5243 } |
| 5244 |
| 5245 return res; |
| 5246 }; |
| 5247 }; |
| 5248 |
| 5249 /*! |
| 5250 * Primary Exports |
| 5251 */ |
| 5252 |
| 5253 module.exports = AssertionError; |
| 5254 |
| 5255 /** |
| 5256 * ### AssertionError |
| 5257 * |
| 5258 * An extension of the JavaScript `Error` constructor for |
| 5259 * assertion and validation scenarios. |
| 5260 * |
| 5261 * @param {String} message |
| 5262 * @param {Object} properties to include (optional) |
| 5263 * @param {callee} start stack function (optional) |
| 5264 */ |
| 5265 |
| 5266 function AssertionError (message, _props, ssf) { |
| 5267 var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') |
| 5268 , props = extend(_props || {}); |
| 5269 |
| 5270 // default values |
| 5271 this.message = message || 'Unspecified AssertionError'; |
| 5272 this.showDiff = false; |
| 5273 |
| 5274 // copy from properties |
| 5275 for (var key in props) { |
| 5276 this[key] = props[key]; |
| 5277 } |
| 5278 |
| 5279 // capture stack trace |
| 5280 ssf = ssf || arguments.callee; |
| 5281 if (ssf && Error.captureStackTrace) { |
| 5282 Error.captureStackTrace(this, ssf); |
| 5283 } else { |
| 5284 this.stack = new Error().stack; |
| 5285 } |
| 5286 } |
| 5287 |
| 5288 /*! |
| 5289 * Inherit from Error.prototype |
| 5290 */ |
| 5291 |
| 5292 AssertionError.prototype = Object.create(Error.prototype); |
| 5293 |
| 5294 /*! |
| 5295 * Statically set name |
| 5296 */ |
| 5297 |
| 5298 AssertionError.prototype.name = 'AssertionError'; |
| 5299 |
| 5300 /*! |
| 5301 * Ensure correct constructor |
| 5302 */ |
| 5303 |
| 5304 AssertionError.prototype.constructor = AssertionError; |
| 5305 |
| 5306 /** |
| 5307 * Allow errors to be converted to JSON for static transfer. |
| 5308 * |
| 5309 * @param {Boolean} include stack (default: `true`) |
| 5310 * @return {Object} object that can be `JSON.stringify` |
| 5311 */ |
| 5312 |
| 5313 AssertionError.prototype.toJSON = function (stack) { |
| 5314 var extend = exclude('constructor', 'toJSON', 'stack') |
| 5315 , props = extend({ name: this.name }, this); |
| 5316 |
| 5317 // include stack if exists and not turned off |
| 5318 if (false !== stack && this.stack) { |
| 5319 props.stack = this.stack; |
| 5320 } |
| 5321 |
| 5322 return props; |
| 5323 }; |
| 5324 |
| 5325 },{}],31:[function(require,module,exports){ |
| 5326 module.exports = require('./lib/eql'); |
| 5327 |
| 5328 },{"./lib/eql":32}],32:[function(require,module,exports){ |
| 5329 /*! |
| 5330 * deep-eql |
| 5331 * Copyright(c) 2013 Jake Luer <jake@alogicalparadox.com> |
| 5332 * MIT Licensed |
| 5333 */ |
| 5334 |
| 5335 /*! |
| 5336 * Module dependencies |
| 5337 */ |
| 5338 |
| 5339 var type = require('type-detect'); |
| 5340 |
| 5341 /*! |
| 5342 * Buffer.isBuffer browser shim |
| 5343 */ |
| 5344 |
| 5345 var Buffer; |
| 5346 try { Buffer = require('buffer').Buffer; } |
| 5347 catch(ex) { |
| 5348 Buffer = {}; |
| 5349 Buffer.isBuffer = function() { return false; } |
| 5350 } |
| 5351 |
| 5352 /*! |
| 5353 * Primary Export |
| 5354 */ |
| 5355 |
| 5356 module.exports = deepEqual; |
| 5357 |
| 5358 /** |
| 5359 * Assert super-strict (egal) equality between |
| 5360 * two objects of any type. |
| 5361 * |
| 5362 * @param {Mixed} a |
| 5363 * @param {Mixed} b |
| 5364 * @param {Array} memoised (optional) |
| 5365 * @return {Boolean} equal match |
| 5366 */ |
| 5367 |
| 5368 function deepEqual(a, b, m) { |
| 5369 if (sameValue(a, b)) { |
| 5370 return true; |
| 5371 } else if ('date' === type(a)) { |
| 5372 return dateEqual(a, b); |
| 5373 } else if ('regexp' === type(a)) { |
| 5374 return regexpEqual(a, b); |
| 5375 } else if (Buffer.isBuffer(a)) { |
| 5376 return bufferEqual(a, b); |
| 5377 } else if ('arguments' === type(a)) { |
| 5378 return argumentsEqual(a, b, m); |
| 5379 } else if (!typeEqual(a, b)) { |
| 5380 return false; |
| 5381 } else if (('object' !== type(a) && 'object' !== type(b)) |
| 5382 && ('array' !== type(a) && 'array' !== type(b))) { |
| 5383 return sameValue(a, b); |
| 5384 } else { |
| 5385 return objectEqual(a, b, m); |
| 5386 } |
| 5387 } |
| 5388 |
| 5389 /*! |
| 5390 * Strict (egal) equality test. Ensures that NaN always |
| 5391 * equals NaN and `-0` does not equal `+0`. |
| 5392 * |
| 5393 * @param {Mixed} a |
| 5394 * @param {Mixed} b |
| 5395 * @return {Boolean} equal match |
| 5396 */ |
| 5397 |
| 5398 function sameValue(a, b) { |
| 5399 if (a === b) return a !== 0 || 1 / a === 1 / b; |
| 5400 return a !== a && b !== b; |
| 5401 } |
| 5402 |
| 5403 /*! |
| 5404 * Compare the types of two given objects and |
| 5405 * return if they are equal. Note that an Array |
| 5406 * has a type of `array` (not `object`) and arguments |
| 5407 * have a type of `arguments` (not `array`/`object`). |
| 5408 * |
| 5409 * @param {Mixed} a |
| 5410 * @param {Mixed} b |
| 5411 * @return {Boolean} result |
| 5412 */ |
| 5413 |
| 5414 function typeEqual(a, b) { |
| 5415 return type(a) === type(b); |
| 5416 } |
| 5417 |
| 5418 /*! |
| 5419 * Compare two Date objects by asserting that |
| 5420 * the time values are equal using `saveValue`. |
| 5421 * |
| 5422 * @param {Date} a |
| 5423 * @param {Date} b |
| 5424 * @return {Boolean} result |
| 5425 */ |
| 5426 |
| 5427 function dateEqual(a, b) { |
| 5428 if ('date' !== type(b)) return false; |
| 5429 return sameValue(a.getTime(), b.getTime()); |
| 5430 } |
| 5431 |
| 5432 /*! |
| 5433 * Compare two regular expressions by converting them |
| 5434 * to string and checking for `sameValue`. |
| 5435 * |
| 5436 * @param {RegExp} a |
| 5437 * @param {RegExp} b |
| 5438 * @return {Boolean} result |
| 5439 */ |
| 5440 |
| 5441 function regexpEqual(a, b) { |
| 5442 if ('regexp' !== type(b)) return false; |
| 5443 return sameValue(a.toString(), b.toString()); |
| 5444 } |
| 5445 |
| 5446 /*! |
| 5447 * Assert deep equality of two `arguments` objects. |
| 5448 * Unfortunately, these must be sliced to arrays |
| 5449 * prior to test to ensure no bad behavior. |
| 5450 * |
| 5451 * @param {Arguments} a |
| 5452 * @param {Arguments} b |
| 5453 * @param {Array} memoize (optional) |
| 5454 * @return {Boolean} result |
| 5455 */ |
| 5456 |
| 5457 function argumentsEqual(a, b, m) { |
| 5458 if ('arguments' !== type(b)) return false; |
| 5459 a = [].slice.call(a); |
| 5460 b = [].slice.call(b); |
| 5461 return deepEqual(a, b, m); |
| 5462 } |
| 5463 |
| 5464 /*! |
| 5465 * Get enumerable properties of a given object. |
| 5466 * |
| 5467 * @param {Object} a |
| 5468 * @return {Array} property names |
| 5469 */ |
| 5470 |
| 5471 function enumerable(a) { |
| 5472 var res = []; |
| 5473 for (var key in a) res.push(key); |
| 5474 return res; |
| 5475 } |
| 5476 |
| 5477 /*! |
| 5478 * Simple equality for flat iterable objects |
| 5479 * such as Arrays or Node.js buffers. |
| 5480 * |
| 5481 * @param {Iterable} a |
| 5482 * @param {Iterable} b |
| 5483 * @return {Boolean} result |
| 5484 */ |
| 5485 |
| 5486 function iterableEqual(a, b) { |
| 5487 if (a.length !== b.length) return false; |
| 5488 |
| 5489 var i = 0; |
| 5490 var match = true; |
| 5491 |
| 5492 for (; i < a.length; i++) { |
| 5493 if (a[i] !== b[i]) { |
| 5494 match = false; |
| 5495 break; |
| 5496 } |
| 5497 } |
| 5498 |
| 5499 return match; |
| 5500 } |
| 5501 |
| 5502 /*! |
| 5503 * Extension to `iterableEqual` specifically |
| 5504 * for Node.js Buffers. |
| 5505 * |
| 5506 * @param {Buffer} a |
| 5507 * @param {Mixed} b |
| 5508 * @return {Boolean} result |
| 5509 */ |
| 5510 |
| 5511 function bufferEqual(a, b) { |
| 5512 if (!Buffer.isBuffer(b)) return false; |
| 5513 return iterableEqual(a, b); |
| 5514 } |
| 5515 |
| 5516 /*! |
| 5517 * Block for `objectEqual` ensuring non-existing |
| 5518 * values don't get in. |
| 5519 * |
| 5520 * @param {Mixed} object |
| 5521 * @return {Boolean} result |
| 5522 */ |
| 5523 |
| 5524 function isValue(a) { |
| 5525 return a !== null && a !== undefined; |
| 5526 } |
| 5527 |
| 5528 /*! |
| 5529 * Recursively check the equality of two objects. |
| 5530 * Once basic sameness has been established it will |
| 5531 * defer to `deepEqual` for each enumerable key |
| 5532 * in the object. |
| 5533 * |
| 5534 * @param {Mixed} a |
| 5535 * @param {Mixed} b |
| 5536 * @return {Boolean} result |
| 5537 */ |
| 5538 |
| 5539 function objectEqual(a, b, m) { |
| 5540 if (!isValue(a) || !isValue(b)) { |
| 5541 return false; |
| 5542 } |
| 5543 |
| 5544 if (a.prototype !== b.prototype) { |
| 5545 return false; |
| 5546 } |
| 5547 |
| 5548 var i; |
| 5549 if (m) { |
| 5550 for (i = 0; i < m.length; i++) { |
| 5551 if ((m[i][0] === a && m[i][1] === b) |
| 5552 || (m[i][0] === b && m[i][1] === a)) { |
| 5553 return true; |
| 5554 } |
| 5555 } |
| 5556 } else { |
| 5557 m = []; |
| 5558 } |
| 5559 |
| 5560 try { |
| 5561 var ka = enumerable(a); |
| 5562 var kb = enumerable(b); |
| 5563 } catch (ex) { |
| 5564 return false; |
| 5565 } |
| 5566 |
| 5567 ka.sort(); |
| 5568 kb.sort(); |
| 5569 |
| 5570 if (!iterableEqual(ka, kb)) { |
| 5571 return false; |
| 5572 } |
| 5573 |
| 5574 m.push([ a, b ]); |
| 5575 |
| 5576 var key; |
| 5577 for (i = ka.length - 1; i >= 0; i--) { |
| 5578 key = ka[i]; |
| 5579 if (!deepEqual(a[key], b[key], m)) { |
| 5580 return false; |
| 5581 } |
| 5582 } |
| 5583 |
| 5584 return true; |
| 5585 } |
| 5586 |
| 5587 },{"buffer":undefined,"type-detect":33}],33:[function(require,module,exports){ |
| 5588 module.exports = require('./lib/type'); |
| 5589 |
| 5590 },{"./lib/type":34}],34:[function(require,module,exports){ |
| 5591 /*! |
| 5592 * type-detect |
| 5593 * Copyright(c) 2013 jake luer <jake@alogicalparadox.com> |
| 5594 * MIT Licensed |
| 5595 */ |
| 5596 |
| 5597 /*! |
| 5598 * Primary Exports |
| 5599 */ |
| 5600 |
| 5601 var exports = module.exports = getType; |
| 5602 |
| 5603 /*! |
| 5604 * Detectable javascript natives |
| 5605 */ |
| 5606 |
| 5607 var natives = { |
| 5608 '[object Array]': 'array' |
| 5609 , '[object RegExp]': 'regexp' |
| 5610 , '[object Function]': 'function' |
| 5611 , '[object Arguments]': 'arguments' |
| 5612 , '[object Date]': 'date' |
| 5613 }; |
| 5614 |
| 5615 /** |
| 5616 * ### typeOf (obj) |
| 5617 * |
| 5618 * Use several different techniques to determine |
| 5619 * the type of object being tested. |
| 5620 * |
| 5621 * |
| 5622 * @param {Mixed} object |
| 5623 * @return {String} object type |
| 5624 * @api public |
| 5625 */ |
| 5626 |
| 5627 function getType (obj) { |
| 5628 var str = Object.prototype.toString.call(obj); |
| 5629 if (natives[str]) return natives[str]; |
| 5630 if (obj === null) return 'null'; |
| 5631 if (obj === undefined) return 'undefined'; |
| 5632 if (obj === Object(obj)) return 'object'; |
| 5633 return typeof obj; |
| 5634 } |
| 5635 |
| 5636 exports.Library = Library; |
| 5637 |
| 5638 /** |
| 5639 * ### Library |
| 5640 * |
| 5641 * Create a repository for custom type detection. |
| 5642 * |
| 5643 * ```js |
| 5644 * var lib = new type.Library; |
| 5645 * ``` |
| 5646 * |
| 5647 */ |
| 5648 |
| 5649 function Library () { |
| 5650 this.tests = {}; |
| 5651 } |
| 5652 |
| 5653 /** |
| 5654 * #### .of (obj) |
| 5655 * |
| 5656 * Expose replacement `typeof` detection to the library. |
| 5657 * |
| 5658 * ```js |
| 5659 * if ('string' === lib.of('hello world')) { |
| 5660 * // ... |
| 5661 * } |
| 5662 * ``` |
| 5663 * |
| 5664 * @param {Mixed} object to test |
| 5665 * @return {String} type |
| 5666 */ |
| 5667 |
| 5668 Library.prototype.of = getType; |
| 5669 |
| 5670 /** |
| 5671 * #### .define (type, test) |
| 5672 * |
| 5673 * Add a test to for the `.test()` assertion. |
| 5674 * |
| 5675 * Can be defined as a regular expression: |
| 5676 * |
| 5677 * ```js |
| 5678 * lib.define('int', /^[0-9]+$/); |
| 5679 * ``` |
| 5680 * |
| 5681 * ... or as a function: |
| 5682 * |
| 5683 * ```js |
| 5684 * lib.define('bln', function (obj) { |
| 5685 * if ('boolean' === lib.of(obj)) return true; |
| 5686 * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ]; |
| 5687 * if ('string' === lib.of(obj)) obj = obj.toLowerCase(); |
| 5688 * return !! ~blns.indexOf(obj); |
| 5689 * }); |
| 5690 * ``` |
| 5691 * |
| 5692 * @param {String} type |
| 5693 * @param {RegExp|Function} test |
| 5694 * @api public |
| 5695 */ |
| 5696 |
| 5697 Library.prototype.define = function (type, test) { |
| 5698 if (arguments.length === 1) return this.tests[type]; |
| 5699 this.tests[type] = test; |
| 5700 return this; |
| 5701 }; |
| 5702 |
| 5703 /** |
| 5704 * #### .test (obj, test) |
| 5705 * |
| 5706 * Assert that an object is of type. Will first |
| 5707 * check natives, and if that does not pass it will |
| 5708 * use the user defined custom tests. |
| 5709 * |
| 5710 * ```js |
| 5711 * assert(lib.test('1', 'int')); |
| 5712 * assert(lib.test('yes', 'bln')); |
| 5713 * ``` |
| 5714 * |
| 5715 * @param {Mixed} object |
| 5716 * @param {String} type |
| 5717 * @return {Boolean} result |
| 5718 * @api public |
| 5719 */ |
| 5720 |
| 5721 Library.prototype.test = function (obj, type) { |
| 5722 if (type === getType(obj)) return true; |
| 5723 var test = this.tests[type]; |
| 5724 |
| 5725 if (test && 'regexp' === getType(test)) { |
| 5726 return test.test(obj); |
| 5727 } else if (test && 'function' === getType(test)) { |
| 5728 return test(obj); |
| 5729 } else { |
| 5730 throw new ReferenceError('Type test "' + type + '" not defined or invalid.')
; |
| 5731 } |
| 5732 }; |
| 5733 |
| 5734 },{}],35:[function(require,module,exports){ |
| 5735 arguments[4][33][0].apply(exports,arguments) |
| 5736 },{"./lib/type":36,"dup":33}],36:[function(require,module,exports){ |
| 5737 /*! |
| 5738 * type-detect |
| 5739 * Copyright(c) 2013 jake luer <jake@alogicalparadox.com> |
| 5740 * MIT Licensed |
| 5741 */ |
| 5742 |
| 5743 /*! |
| 5744 * Primary Exports |
| 5745 */ |
| 5746 |
| 5747 var exports = module.exports = getType; |
| 5748 |
| 5749 /** |
| 5750 * ### typeOf (obj) |
| 5751 * |
| 5752 * Use several different techniques to determine |
| 5753 * the type of object being tested. |
| 5754 * |
| 5755 * |
| 5756 * @param {Mixed} object |
| 5757 * @return {String} object type |
| 5758 * @api public |
| 5759 */ |
| 5760 var objectTypeRegexp = /^\[object (.*)\]$/; |
| 5761 |
| 5762 function getType(obj) { |
| 5763 var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLo
werCase(); |
| 5764 // Let "new String('')" return 'object' |
| 5765 if (typeof Promise === 'function' && obj instanceof Promise) return 'promise'; |
| 5766 // PhantomJS has type "DOMWindow" for null |
| 5767 if (obj === null) return 'null'; |
| 5768 // PhantomJS has type "DOMWindow" for undefined |
| 5769 if (obj === undefined) return 'undefined'; |
| 5770 return type; |
| 5771 } |
| 5772 |
| 5773 exports.Library = Library; |
| 5774 |
| 5775 /** |
| 5776 * ### Library |
| 5777 * |
| 5778 * Create a repository for custom type detection. |
| 5779 * |
| 5780 * ```js |
| 5781 * var lib = new type.Library; |
| 5782 * ``` |
| 5783 * |
| 5784 */ |
| 5785 |
| 5786 function Library() { |
| 5787 if (!(this instanceof Library)) return new Library(); |
| 5788 this.tests = {}; |
| 5789 } |
| 5790 |
| 5791 /** |
| 5792 * #### .of (obj) |
| 5793 * |
| 5794 * Expose replacement `typeof` detection to the library. |
| 5795 * |
| 5796 * ```js |
| 5797 * if ('string' === lib.of('hello world')) { |
| 5798 * // ... |
| 5799 * } |
| 5800 * ``` |
| 5801 * |
| 5802 * @param {Mixed} object to test |
| 5803 * @return {String} type |
| 5804 */ |
| 5805 |
| 5806 Library.prototype.of = getType; |
| 5807 |
| 5808 /** |
| 5809 * #### .define (type, test) |
| 5810 * |
| 5811 * Add a test to for the `.test()` assertion. |
| 5812 * |
| 5813 * Can be defined as a regular expression: |
| 5814 * |
| 5815 * ```js |
| 5816 * lib.define('int', /^[0-9]+$/); |
| 5817 * ``` |
| 5818 * |
| 5819 * ... or as a function: |
| 5820 * |
| 5821 * ```js |
| 5822 * lib.define('bln', function (obj) { |
| 5823 * if ('boolean' === lib.of(obj)) return true; |
| 5824 * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ]; |
| 5825 * if ('string' === lib.of(obj)) obj = obj.toLowerCase(); |
| 5826 * return !! ~blns.indexOf(obj); |
| 5827 * }); |
| 5828 * ``` |
| 5829 * |
| 5830 * @param {String} type |
| 5831 * @param {RegExp|Function} test |
| 5832 * @api public |
| 5833 */ |
| 5834 |
| 5835 Library.prototype.define = function(type, test) { |
| 5836 if (arguments.length === 1) return this.tests[type]; |
| 5837 this.tests[type] = test; |
| 5838 return this; |
| 5839 }; |
| 5840 |
| 5841 /** |
| 5842 * #### .test (obj, test) |
| 5843 * |
| 5844 * Assert that an object is of type. Will first |
| 5845 * check natives, and if that does not pass it will |
| 5846 * use the user defined custom tests. |
| 5847 * |
| 5848 * ```js |
| 5849 * assert(lib.test('1', 'int')); |
| 5850 * assert(lib.test('yes', 'bln')); |
| 5851 * ``` |
| 5852 * |
| 5853 * @param {Mixed} object |
| 5854 * @param {String} type |
| 5855 * @return {Boolean} result |
| 5856 * @api public |
| 5857 */ |
| 5858 |
| 5859 Library.prototype.test = function(obj, type) { |
| 5860 if (type === getType(obj)) return true; |
| 5861 var test = this.tests[type]; |
| 5862 |
| 5863 if (test && 'regexp' === getType(test)) { |
| 5864 return test.test(obj); |
| 5865 } else if (test && 'function' === getType(test)) { |
| 5866 return test(obj); |
| 5867 } else { |
| 5868 throw new ReferenceError('Type test "' + type + '" not defined or invalid.')
; |
| 5869 } |
| 5870 }; |
| 5871 |
| 5872 },{}]},{},[1])(1) |
| 5873 }); |
OLD | NEW |