| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * chai | |
| 3 | * Copyright(c) 2011-2012 Jake Luer <jake@alogicalparadox.com> | |
| 4 | * MIT Licensed | |
| 5 | */ | |
| 6 | ||
| 7 | 1 | var used = []; |
| 8 | 1 | var exports = module.exports = {}; |
| 9 | ||
| 10 | 1 | exports.version = '0.5.2'; |
| 11 | ||
| 12 | 1 | exports.Assertion = require('./assertion'); |
| 13 | 1 | exports.AssertionError = require('./error'); |
| 14 | ||
| 15 | 1 | exports.inspect = require('./utils/inspect'); |
| 16 | ||
| 17 | 1 | exports.use = function (fn) { |
| 18 | 5 | if (!~used.indexOf(fn)) { |
| 19 | 4 | fn(this); |
| 20 | 4 | used.push(fn); |
| 21 | } | |
| 22 | ||
| 23 | 5 | return this; |
| 24 | }; | |
| 25 | ||
| 26 | 1 | var expect = require('./interface/expect'); |
| 27 | 1 | exports.use(expect); |
| 28 | ||
| 29 | 1 | var should = require('./interface/should'); |
| 30 | 1 | exports.use(should); |
| 31 | ||
| 32 | 1 | var assert = require('./interface/assert'); |
| 33 | 1 | exports.use(assert); |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * chai | |
| 3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
| 4 | * MIT Licensed | |
| 5 | * | |
| 6 | * Primarily a refactor of: should.js | |
| 7 | * https://github.com/visionmedia/should.js | |
| 8 | * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca> | |
| 9 | * MIT Licensed | |
| 10 | */ | |
| 11 | ||
| 12 | /** | |
| 13 | * ### BDD Style Introduction | |
| 14 | * | |
| 15 | * The BDD style is exposed through `expect` or `should` interfaces. In both | |
| 16 | * scenarios, you chain together natural language assertions. | |
| 17 | * | |
| 18 | * // expect | |
| 19 | * var expect = require('chai').expect; | |
| 20 | * expect(foo).to.equal('bar'); | |
| 21 | * | |
| 22 | * // should | |
| 23 | * var should = require('chai').should(); | |
| 24 | * foo.should.equal('bar'); | |
| 25 | * | |
| 26 | * #### Differences | |
| 27 | * | |
| 28 | * The `expect` interface provides a function as a starting point for chaining | |
| 29 | * your language assertions. It works on node.js and in all browsers. | |
| 30 | * | |
| 31 | * The `should` interface extends `Object.prototype` to provide a single getter as | |
| 32 | * the starting point for your language assertions. It works on node.js and in | |
| 33 | * all browsers except Internet Explorer. | |
| 34 | * | |
| 35 | * #### Configuration | |
| 36 | * | |
| 37 | * By default, Chai does not show stack traces upon an AssertionError. This can | |
| 38 | * be changed by modifying the `includeStack` parameter for chai.Assertion. For example: | |
| 39 | * | |
| 40 | * var chai = require('chai'); | |
| 41 | * chai.Assertion.includeStack = true; // defaults to false | |
| 42 | */ | |
| 43 | ||
| 44 | /*! | |
| 45 | * Module dependencies. | |
| 46 | */ | |
| 47 | ||
| 48 | 1 | var AssertionError = require('./error') |
| 49 | , eql = require('./utils/eql') | |
| 50 | , toString = Object.prototype.toString | |
| 51 | , inspect = require('./utils/inspect'); | |
| 52 | ||
| 53 | /*! | |
| 54 | * Module export. | |
| 55 | */ | |
| 56 | ||
| 57 | 1 | module.exports = Assertion; |
| 58 | ||
| 59 | ||
| 60 | /*! | |
| 61 | * # Assertion Constructor | |
| 62 | * | |
| 63 | * Creates object for chaining. | |
| 64 | * | |
| 65 | * @api private | |
| 66 | */ | |
| 67 | ||
| 68 | 1 | function Assertion (obj, msg, stack) { |
| 69 | 738 | this.ssfi = stack || arguments.callee; |
| 70 | 738 | this.obj = obj; |
| 71 | 738 | this.msg = msg; |
| 72 | } | |
| 73 | ||
| 74 | /*! | |
| 75 | * ## Assertion.includeStack | |
| 76 | * , toString = Object.prototype.toString | |
| 77 | * | |
| 78 | * User configurable property, influences whether stack trace | |
| 79 | * is included in Assertion error message. Default of false | |
| 80 | * suppresses stack trace in the error message | |
| 81 | * | |
| 82 | * Assertion.includeStack = true; // enable stack on error | |
| 83 | * | |
| 84 | * @api public | |
| 85 | */ | |
| 86 | ||
| 87 | 1 | Assertion.includeStack = false; |
| 88 | ||
| 89 | /*! | |
| 90 | * # .assert(expression, message, negateMessage, expected, actual) | |
| 91 | * | |
| 92 | * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. | |
| 93 | * | |
| 94 | * @name assert | |
| 95 | * @param {Philosophical} expression to be tested | |
| 96 | * @param {String} message to display if fails | |
| 97 | * @param {String} negatedMessage to display if negated expression fails | |
| 98 | * @param {*} expected value (remember to check for negation) | |
| 99 | * @param {*} actual (optional) will default to `this.obj` | |
| 100 | * @api private | |
| 101 | */ | |
| 102 | ||
| 103 | 1 | Assertion.prototype.assert = function (expr, msg, negateMsg, expected, actual) { |
| 104 | 744 | actual = actual || this.obj; |
| 105 | 744 | var msg = (this.negate ? negateMsg : msg) |
| 106 | , ok = this.negate ? !expr : expr; | |
| 107 | ||
| 108 | 744 | if (!ok) { |
| 109 | 167 | throw new AssertionError({ |
| 110 | message: this.msg ? this.msg + ': ' + msg : msg // include custom message if available | |
| 111 | , actual: actual | |
| 112 | , expected: expected | |
| 113 | , stackStartFunction: (Assertion.includeStack) ? this.assert : this.ssfi | |
| 114 | }); | |
| 115 | } | |
| 116 | }; | |
| 117 | ||
| 118 | /*! | |
| 119 | * # inspect | |
| 120 | * | |
| 121 | * Returns the current object stringified. | |
| 122 | * | |
| 123 | * @name inspect | |
| 124 | * @api private | |
| 125 | */ | |
| 126 | ||
| 127 | 1 | Object.defineProperty(Assertion.prototype, 'inspect', |
| 128 | { get: function () { | |
| 129 | 1462 | return inspect(this.obj); |
| 130 | } | |
| 131 | , configurable: true | |
| 132 | }); | |
| 133 | ||
| 134 | /** | |
| 135 | * # to | |
| 136 | * | |
| 137 | * Language chain. | |
| 138 | * | |
| 139 | * @name to | |
| 140 | * @api public | |
| 141 | */ | |
| 142 | ||
| 143 | 1 | Object.defineProperty(Assertion.prototype, 'to', |
| 144 | { get: function () { | |
| 145 | 408 | return this; |
| 146 | } | |
| 147 | , configurable: true | |
| 148 | }); | |
| 149 | ||
| 150 | /** | |
| 151 | * # be | |
| 152 | * | |
| 153 | * Language chain. | |
| 154 | * | |
| 155 | * @name be | |
| 156 | * @api public | |
| 157 | */ | |
| 158 | ||
| 159 | 1 | Object.defineProperty(Assertion.prototype, 'be', |
| 160 | { get: function () { | |
| 161 | 163 | return this; |
| 162 | } | |
| 163 | , configurable: true | |
| 164 | }); | |
| 165 | ||
| 166 | /** | |
| 167 | * # been | |
| 168 | * | |
| 169 | * Language chain. Also tests `tense` to past for addon | |
| 170 | * modules that use the tense feature. | |
| 171 | * | |
| 172 | * @name been | |
| 173 | * @api public | |
| 174 | */ | |
| 175 | ||
| 176 | 1 | Object.defineProperty(Assertion.prototype, 'been', |
| 177 | { get: function () { | |
| 178 | 1 | this.tense = 'past'; |
| 179 | 1 | return this; |
| 180 | } | |
| 181 | , configurable: true | |
| 182 | }); | |
| 183 | ||
| 184 | /** | |
| 185 | * # an | |
| 186 | * | |
| 187 | * Language chain. | |
| 188 | * | |
| 189 | * @name an | |
| 190 | * @api public | |
| 191 | */ | |
| 192 | ||
| 193 | 1 | Object.defineProperty(Assertion.prototype, 'an', |
| 194 | { get: function () { | |
| 195 | 4 | return this; |
| 196 | } | |
| 197 | , configurable: true | |
| 198 | }); | |
| 199 | /** | |
| 200 | * # is | |
| 201 | * | |
| 202 | * Language chain. | |
| 203 | * | |
| 204 | * @name is | |
| 205 | * @api public | |
| 206 | */ | |
| 207 | ||
| 208 | 1 | Object.defineProperty(Assertion.prototype, 'is', |
| 209 | { get: function () { | |
| 210 | 94 | return this; |
| 211 | } | |
| 212 | , configurable: true | |
| 213 | }); | |
| 214 | ||
| 215 | /** | |
| 216 | * # and | |
| 217 | * | |
| 218 | * Language chain. | |
| 219 | * | |
| 220 | * @name and | |
| 221 | * @api public | |
| 222 | */ | |
| 223 | ||
| 224 | 1 | Object.defineProperty(Assertion.prototype, 'and', |
| 225 | { get: function () { | |
| 226 | 1 | return this; |
| 227 | } | |
| 228 | , configurable: true | |
| 229 | }); | |
| 230 | ||
| 231 | /** | |
| 232 | * # have | |
| 233 | * | |
| 234 | * Language chain. | |
| 235 | * | |
| 236 | * @name have | |
| 237 | * @api public | |
| 238 | */ | |
| 239 | ||
| 240 | 1 | Object.defineProperty(Assertion.prototype, 'have', |
| 241 | { get: function () { | |
| 242 | 92 | return this; |
| 243 | } | |
| 244 | , configurable: true | |
| 245 | }); | |
| 246 | ||
| 247 | /** | |
| 248 | * # with | |
| 249 | * | |
| 250 | * Language chain. | |
| 251 | * | |
| 252 | * @name with | |
| 253 | * @api public | |
| 254 | */ | |
| 255 | ||
| 256 | 1 | Object.defineProperty(Assertion.prototype, 'with', |
| 257 | { get: function () { | |
| 258 | 2 | return this; |
| 259 | } | |
| 260 | , configurable: true | |
| 261 | }); | |
| 262 | ||
| 263 | /** | |
| 264 | * # .not | |
| 265 | * | |
| 266 | * Negates any of assertions following in the chain. | |
| 267 | * | |
| 268 | * @name not | |
| 269 | * @api public | |
| 270 | */ | |
| 271 | ||
| 272 | 1 | Object.defineProperty(Assertion.prototype, 'not', |
| 273 | { get: function () { | |
| 274 | 145 | this.negate = true; |
| 275 | 145 | return this; |
| 276 | } | |
| 277 | , configurable: true | |
| 278 | }); | |
| 279 | ||
| 280 | /** | |
| 281 | * # .ok | |
| 282 | * | |
| 283 | * Assert object truthiness. | |
| 284 | * | |
| 285 | * expect('everthing').to.be.ok; | |
| 286 | * expect(false).to.not.be.ok; | |
| 287 | * expect(undefined).to.not.be.ok; | |
| 288 | * expect(null).to.not.be.ok; | |
| 289 | * | |
| 290 | * @name ok | |
| 291 | * @api public | |
| 292 | */ | |
| 293 | ||
| 294 | 1 | Object.defineProperty(Assertion.prototype, 'ok', |
| 295 | { get: function () { | |
| 296 | 23 | this.assert( |
| 297 | this.obj | |
| 298 | , 'expected ' + this.inspect + ' to be truthy' | |
| 299 | , 'expected ' + this.inspect + ' to be falsy'); | |
| 300 | ||
| 301 | 15 | return this; |
| 302 | } | |
| 303 | , configurable: true | |
| 304 | }); | |
| 305 | ||
| 306 | /** | |
| 307 | * # .true | |
| 308 | * | |
| 309 | * Assert object is true | |
| 310 | * | |
| 311 | * @name true | |
| 312 | * @api public | |
| 313 | */ | |
| 314 | ||
| 315 | 1 | Object.defineProperty(Assertion.prototype, 'true', |
| 316 | { get: function () { | |
| 317 | 12 | this.assert( |
| 318 | true === this.obj | |
| 319 | , 'expected ' + this.inspect + ' to be true' | |
| 320 | , 'expected ' + this.inspect + ' to be false' | |
| 321 | , this.negate ? false : true | |
| 322 | ); | |
| 323 | ||
| 324 | 7 | return this; |
| 325 | } | |
| 326 | , configurable: true | |
| 327 | }); | |
| 328 | ||
| 329 | /** | |
| 330 | * # .false | |
| 331 | * | |
| 332 | * Assert object is false | |
| 333 | * | |
| 334 | * @name false | |
| 335 | * @api public | |
| 336 | */ | |
| 337 | ||
| 338 | 1 | Object.defineProperty(Assertion.prototype, 'false', |
| 339 | { get: function () { | |
| 340 | 12 | this.assert( |
| 341 | false === this.obj | |
| 342 | , 'expected ' + this.inspect + ' to be false' | |
| 343 | , 'expected ' + this.inspect + ' to be true' | |
| 344 | , this.negate ? true : false | |
| 345 | ); | |
| 346 | ||
| 347 | 8 | return this; |
| 348 | } | |
| 349 | , configurable: true | |
| 350 | }); | |
| 351 | ||
| 352 | /** | |
| 353 | * # .exist | |
| 354 | * | |
| 355 | * Assert object exists (null). | |
| 356 | * | |
| 357 | * var foo = 'hi' | |
| 358 | * , bar; | |
| 359 | * expect(foo).to.exist; | |
| 360 | * expect(bar).to.not.exist; | |
| 361 | * | |
| 362 | * @name exist | |
| 363 | * @api public | |
| 364 | */ | |
| 365 | ||
| 366 | 1 | Object.defineProperty(Assertion.prototype, 'exist', |
| 367 | { get: function () { | |
| 368 | 6 | this.assert( |
| 369 | null != this.obj | |
| 370 | , 'expected ' + this.inspect + ' to exist' | |
| 371 | , 'expected ' + this.inspect + ' to not exist' | |
| 372 | ); | |
| 373 | ||
| 374 | 4 | return this; |
| 375 | } | |
| 376 | , configurable: true | |
| 377 | }); | |
| 378 | ||
| 379 | /** | |
| 380 | * # .empty | |
| 381 | * | |
| 382 | * Assert object's length to be 0. | |
| 383 | * | |
| 384 | * expect([]).to.be.empty; | |
| 385 | * | |
| 386 | * @name empty | |
| 387 | * @api public | |
| 388 | */ | |
| 389 | ||
| 390 | 1 | Object.defineProperty(Assertion.prototype, 'empty', |
| 391 | { get: function () { | |
| 392 | 32 | var expected = this.obj; |
| 393 | ||
| 394 | 32 | if (Array.isArray(this.obj)) { |
| 395 | 8 | expected = this.obj.length; |
| 396 | 24 | } else if (typeof this.obj === 'object') { |
| 397 | 16 | expected = Object.keys(this.obj).length; |
| 398 | } | |
| 399 | ||
| 400 | 32 | this.assert( |
| 401 | !expected | |
| 402 | , 'expected ' + this.inspect + ' to be empty' | |
| 403 | , 'expected ' + this.inspect + ' not to be empty'); | |
| 404 | ||
| 405 | 16 | return this; |
| 406 | } | |
| 407 | , configurable: true | |
| 408 | }); | |
| 409 | ||
| 410 | /** | |
| 411 | * # .arguments | |
| 412 | * | |
| 413 | * Assert object is an instanceof arguments. | |
| 414 | * | |
| 415 | * function test () { | |
| 416 | * expect(arguments).to.be.arguments; | |
| 417 | * } | |
| 418 | * | |
| 419 | * @name arguments | |
| 420 | * @api public | |
| 421 | */ | |
| 422 | ||
| 423 | 1 | Object.defineProperty(Assertion.prototype, 'arguments', |
| 424 | { get: function () { | |
| 425 | 4 | this.assert( |
| 426 | '[object Arguments]' == Object.prototype.toString.call(this.obj) | |
| 427 | , 'expected ' + this.inspect + ' to be arguments' | |
| 428 | , 'expected ' + this.inspect + ' to not be arguments' | |
| 429 | , '[object Arguments]' | |
| 430 | , Object.prototype.toString.call(this.obj) | |
| 431 | ); | |
| 432 | ||
| 433 | 4 | return this; |
| 434 | } | |
| 435 | , configurable: true | |
| 436 | }); | |
| 437 | ||
| 438 | /** | |
| 439 | * # .equal(value) | |
| 440 | * | |
| 441 | * Assert strict equality. | |
| 442 | * | |
| 443 | * expect('hello').to.equal('hello'); | |
| 444 | * | |
| 445 | * @name equal | |
| 446 | * @param {*} value | |
| 447 | * @api public | |
| 448 | */ | |
| 449 | ||
| 450 | 1 | Assertion.prototype.equal = function (val) { |
| 451 | 161 | this.assert( |
| 452 | val === this.obj | |
| 453 | , 'expected ' + this.inspect + ' to equal ' + inspect(val) | |
| 454 | , 'expected ' + this.inspect + ' to not equal ' + inspect(val) | |
| 455 | , val ); | |
| 456 | ||
| 457 | 151 | return this; |
| 458 | }; | |
| 459 | ||
| 460 | /** | |
| 461 | * # .eql(value) | |
| 462 | * | |
| 463 | * Assert deep equality. | |
| 464 | * | |
| 465 | * expect({ foo: 'bar' }).to.eql({ foo: 'bar' }); | |
| 466 | * | |
| 467 | * @name eql | |
| 468 | * @param {*} value | |
| 469 | * @api public | |
| 470 | */ | |
| 471 | ||
| 472 | 1 | Assertion.prototype.eql = function (obj) { |
| 473 | 14 | this.assert( |
| 474 | eql(obj, this.obj) | |
| 475 | , 'expected ' + this.inspect + ' to equal ' + inspect(obj) | |
| 476 | , 'expected ' + this.inspect + ' to not equal ' + inspect(obj) | |
| 477 | , obj ); | |
| 478 | ||
| 479 | 10 | return this; |
| 480 | }; | |
| 481 | ||
| 482 | /** | |
| 483 | * # .above(value) | |
| 484 | * | |
| 485 | * Assert greater than `value`. | |
| 486 | * | |
| 487 | * expect(10).to.be.above(5); | |
| 488 | * | |
| 489 | * @name above | |
| 490 | * @param {Number} value | |
| 491 | * @api public | |
| 492 | */ | |
| 493 | ||
| 494 | 1 | Assertion.prototype.above = function (val) { |
| 495 | 12 | this.assert( |
| 496 | this.obj > val | |
| 497 | , 'expected ' + this.inspect + ' to be above ' + val | |
| 498 | , 'expected ' + this.inspect + ' to be below ' + val); | |
| 499 | ||
| 500 | 8 | return this; |
| 501 | }; | |
| 502 | ||
| 503 | /** | |
| 504 | * # .below(value) | |
| 505 | * | |
| 506 | * Assert less than `value`. | |
| 507 | * | |
| 508 | * expect(5).to.be.below(10); | |
| 509 | * | |
| 510 | * @name below | |
| 511 | * @param {Number} value | |
| 512 | * @api public | |
| 513 | */ | |
| 514 | ||
| 515 | 1 | Assertion.prototype.below = function (val) { |
| 516 | 12 | this.assert( |
| 517 | this.obj < val | |
| 518 | , 'expected ' + this.inspect + ' to be below ' + val | |
| 519 | , 'expected ' + this.inspect + ' to be above ' + val); | |
| 520 | ||
| 521 | 8 | return this; |
| 522 | }; | |
| 523 | ||
| 524 | /** | |
| 525 | * # .within(start, finish) | |
| 526 | * | |
| 527 | * Assert that a number is within a range. | |
| 528 | * | |
| 529 | * expect(7).to.be.within(5,10); | |
| 530 | * | |
| 531 | * @name within | |
| 532 | * @param {Number} start lowerbound inclusive | |
| 533 | * @param {Number} finish upperbound inclusive | |
| 534 | * @api public | |
| 535 | */ | |
| 536 | ||
| 537 | 1 | Assertion.prototype.within = function (start, finish) { |
| 538 | 12 | var range = start + '..' + finish; |
| 539 | ||
| 540 | 12 | this.assert( |
| 541 | this.obj >= start && this.obj <= finish | |
| 542 | , 'expected ' + this.inspect + ' to be within ' + range | |
| 543 | , 'expected ' + this.inspect + ' to not be within ' + range); | |
| 544 | ||
| 545 | 8 | return this; |
| 546 | }; | |
| 547 | ||
| 548 | /** | |
| 549 | * # .a(type) | |
| 550 | * | |
| 551 | * Assert typeof. | |
| 552 | * | |
| 553 | * expect('test').to.be.a('string'); | |
| 554 | * | |
| 555 | * @name a | |
| 556 | * @param {String} type | |
| 557 | * @api public | |
| 558 | */ | |
| 559 | ||
| 560 | 1 | Assertion.prototype.a = function (type) { |
| 561 | 128 | var klass = type.charAt(0).toUpperCase() + type.slice(1); |
| 562 | ||
| 563 | 128 | this.assert( |
| 564 | '[object ' + klass + ']' === toString.call(this.obj) | |
| 565 | , 'expected ' + this.inspect + ' to be a ' + type | |
| 566 | , 'expected ' + this.inspect + ' not to be a ' + type | |
| 567 | , '[object ' + klass + ']' | |
| 568 | , toString.call(this.obj) | |
| 569 | ); | |
| 570 | ||
| 571 | 114 | return this; |
| 572 | }; | |
| 573 | ||
| 574 | /** | |
| 575 | * # .instanceof(constructor) | |
| 576 | * | |
| 577 | * Assert instanceof. | |
| 578 | * | |
| 579 | * var Tea = function (name) { this.name = name; } | |
| 580 | * , Chai = new Tea('chai'); | |
| 581 | * | |
| 582 | * expect(Chai).to.be.an.instanceOf(Tea); | |
| 583 | * | |
| 584 | * @name instanceof | |
| 585 | * @param {Constructor} | |
| 586 | * @alias instanceOf | |
| 587 | * @api public | |
| 588 | */ | |
| 589 | ||
| 590 | 1 | Assertion.prototype.instanceof = function (constructor) { |
| 591 | 9 | var name = constructor.name; |
| 592 | 9 | this.assert( |
| 593 | this.obj instanceof constructor | |
| 594 | , 'expected ' + this.inspect + ' to be an instance of ' + name | |
| 595 | , 'expected ' + this.inspect + ' to not be an instance of ' + name); | |
| 596 | ||
| 597 | 5 | return this; |
| 598 | }; | |
| 599 | ||
| 600 | /** | |
| 601 | * # .property(name, [value]) | |
| 602 | * | |
| 603 | * Assert that property of `name` exists, optionally with `value`. | |
| 604 | * | |
| 605 | * var obj = { foo: 'bar' } | |
| 606 | * expect(obj).to.have.property('foo'); | |
| 607 | * expect(obj).to.have.property('foo', 'bar'); | |
| 608 | * expect(obj).to.have.property('foo').to.be.a('string'); | |
| 609 | * | |
| 610 | * @name property | |
| 611 | * @param {String} name | |
| 612 | * @param {*} value (optional) | |
| 613 | * @returns value of property for chaining | |
| 614 | * @api public | |
| 615 | */ | |
| 616 | ||
| 617 | 1 | Assertion.prototype.property = function (name, val) { |
| 618 | 37 | if (this.negate && undefined !== val) { |
| 619 | 4 | if (undefined === this.obj[name]) { |
| 620 | 2 | throw new Error(this.inspect + ' has no property ' + inspect(name)); |
| 621 | } | |
| 622 | } else { | |
| 623 | 33 | this.assert( |
| 624 | undefined !== this.obj[name] | |
| 625 | , 'expected ' + this.inspect + ' to have a property ' + inspect(name) | |
| 626 | , 'expected ' + this.inspect + ' to not have property ' + inspect(name)); | |
| 627 | } | |
| 628 | ||
| 629 | 30 | if (undefined !== val) { |
| 630 | 11 | this.assert( |
| 631 | val === this.obj[name] | |
| 632 | , 'expected ' + this.inspect + ' to have a property ' + inspect(name) + ' of ' + | |
| 633 | inspect(val) + ', but got ' + inspect(this.obj[name]) | |
| 634 | , 'expected ' + this.inspect + ' to not have a property ' + inspect(name) + ' of ' + inspect(val) | |
| 635 | , val | |
| 636 | , this.obj[val] | |
| 637 | ); | |
| 638 | } | |
| 639 | ||
| 640 | 24 | this.obj = this.obj[name]; |
| 641 | 24 | return this; |
| 642 | }; | |
| 643 | ||
| 644 | /** | |
| 645 | * # .ownProperty(name) | |
| 646 | * | |
| 647 | * Assert that has own property by `name`. | |
| 648 | * | |
| 649 | * expect('test').to.have.ownProperty('length'); | |
| 650 | * | |
| 651 | * @name ownProperty | |
| 652 | * @alias haveOwnProperty | |
| 653 | * @param {String} name | |
| 654 | * @api public | |
| 655 | */ | |
| 656 | ||
| 657 | 1 | Assertion.prototype.ownProperty = function (name) { |
| 658 | 8 | this.assert( |
| 659 | this.obj.hasOwnProperty(name) | |
| 660 | , 'expected ' + this.inspect + ' to have own property ' + inspect(name) | |
| 661 | , 'expected ' + this.inspect + ' to not have own property ' + inspect(name)); | |
| 662 | 6 | return this; |
| 663 | }; | |
| 664 | ||
| 665 | /** | |
| 666 | * # .length(val) | |
| 667 | * | |
| 668 | * Assert that object has expected length. | |
| 669 | * | |
| 670 | * expect([1,2,3]).to.have.length(3); | |
| 671 | * expect('foobar').to.have.length(6); | |
| 672 | * | |
| 673 | * @name length | |
| 674 | * @alias lengthOf | |
| 675 | * @param {Number} length | |
| 676 | * @api public | |
| 677 | */ | |
| 678 | ||
| 679 | 1 | Assertion.prototype.length = function (n) { |
| 680 | 16 | new Assertion(this.obj).to.have.property('length'); |
| 681 | 13 | var len = this.obj.length; |
| 682 | ||
| 683 | 13 | this.assert( |
| 684 | len == n | |
| 685 | , 'expected ' + this.inspect + ' to have a length of ' + n + ' but got ' + len | |
| 686 | , 'expected ' + this.inspect + ' to not have a length of ' + len | |
| 687 | , n | |
| 688 | , len | |
| 689 | ); | |
| 690 | ||
| 691 | 9 | return this; |
| 692 | }; | |
| 693 | ||
| 694 | /** | |
| 695 | * # .match(regexp) | |
| 696 | * | |
| 697 | * Assert that matches regular expression. | |
| 698 | * | |
| 699 | * expect('foobar').to.match(/^foo/); | |
| 700 | * | |
| 701 | * @name match | |
| 702 | * @param {RegExp} RegularExpression | |
| 703 | * @api public | |
| 704 | */ | |
| 705 | ||
| 706 | 1 | Assertion.prototype.match = function (re) { |
| 707 | 11 | this.assert( |
| 708 | re.exec(this.obj) | |
| 709 | , 'expected ' + this.inspect + ' to match ' + re | |
| 710 | , 'expected ' + this.inspect + ' not to match ' + re); | |
| 711 | ||
| 712 | 7 | return this; |
| 713 | }; | |
| 714 | ||
| 715 | /** | |
| 716 | * # .include(obj) | |
| 717 | * | |
| 718 | * Assert the inclusion of an object in an Array or substring in string. | |
| 719 | * | |
| 720 | * expect([1,2,3]).to.include(2); | |
| 721 | * | |
| 722 | * @name include | |
| 723 | * @param {Object|String|Number} obj | |
| 724 | * @api public | |
| 725 | */ | |
| 726 | ||
| 727 | 1 | Assertion.prototype.include = function (obj) { |
| 728 | 17 | this.assert( |
| 729 | ~this.obj.indexOf(obj) | |
| 730 | , 'expected ' + this.inspect + ' to include ' + inspect(obj) | |
| 731 | , 'expected ' + this.inspect + ' to not include ' + inspect(obj)); | |
| 732 | ||
| 733 | 13 | return this; |
| 734 | }; | |
| 735 | ||
| 736 | /** | |
| 737 | * # .string(string) | |
| 738 | * | |
| 739 | * Assert inclusion of string in string. | |
| 740 | * | |
| 741 | * expect('foobar').to.have.string('bar'); | |
| 742 | * | |
| 743 | * @name string | |
| 744 | * @param {String} string | |
| 745 | * @api public | |
| 746 | */ | |
| 747 | ||
| 748 | 1 | Assertion.prototype.string = function (str) { |
| 749 | 15 | new Assertion(this.obj).is.a('string'); |
| 750 | ||
| 751 | 13 | this.assert( |
| 752 | ~this.obj.indexOf(str) | |
| 753 | , 'expected ' + this.inspect + ' to contain ' + inspect(str) | |
| 754 | , 'expected ' + this.inspect + ' to not contain ' + inspect(str)); | |
| 755 | ||
| 756 | 8 | return this; |
| 757 | }; | |
| 758 | ||
| 759 | ||
| 760 | ||
| 761 | /** | |
| 762 | * # contain | |
| 763 | * | |
| 764 | * Toggles the `contain` flag for the `keys` assertion. | |
| 765 | * | |
| 766 | * @name contain | |
| 767 | * @api public | |
| 768 | */ | |
| 769 | ||
| 770 | 1 | Object.defineProperty(Assertion.prototype, 'contain', |
| 771 | { get: function () { | |
| 772 | 37 | this.contains = true; |
| 773 | 37 | return this; |
| 774 | }, | |
| 775 | configurable: true | |
| 776 | }); | |
| 777 | ||
| 778 | /** | |
| 779 | * # .keys(key1, [key2], [...]) | |
| 780 | * | |
| 781 | * Assert exact keys or the inclusing of keys using the `contain` modifier. | |
| 782 | * | |
| 783 | * expect({ foo: 1, bar: 2 }).to.have.keys(['foo', 'bar']); | |
| 784 | * expect({ foo: 1, bar: 2, baz: 3 }).to.contain.keys('foo', 'bar'); | |
| 785 | * | |
| 786 | * @name keys | |
| 787 | * @alias key | |
| 788 | * @param {String|Array} Keys | |
| 789 | * @api public | |
| 790 | */ | |
| 791 | ||
| 792 | 1 | Assertion.prototype.keys = function(keys) { |
| 793 | 56 | var str |
| 794 | , ok = true; | |
| 795 | ||
| 796 | 56 | keys = keys instanceof Array |
| 797 | ? keys | |
| 798 | : Array.prototype.slice.call(arguments); | |
| 799 | ||
| 800 | 64 | if (!keys.length) throw new Error('keys required'); |
| 801 | ||
| 802 | 48 | var actual = Object.keys(this.obj) |
| 803 | , len = keys.length; | |
| 804 | ||
| 805 | // Inclusion | |
| 806 | 48 | ok = keys.every(function(key){ |
| 807 | 70 | return ~actual.indexOf(key); |
| 808 | }); | |
| 809 | ||
| 810 | // Strict | |
| 811 | 48 | if (!this.negate && !this.contains) { |
| 812 | 12 | ok = ok && keys.length == actual.length; |
| 813 | } | |
| 814 | ||
| 815 | // Key string | |
| 816 | 48 | if (len > 1) { |
| 817 | 26 | keys = keys.map(function(key){ |
| 818 | 54 | return inspect(key); |
| 819 | }); | |
| 820 | 26 | var last = keys.pop(); |
| 821 | 26 | str = keys.join(', ') + ', and ' + last; |
| 822 | } else { | |
| 823 | 22 | str = inspect(keys[0]); |
| 824 | } | |
| 825 | ||
| 826 | // Form | |
| 827 | 48 | str = (len > 1 ? 'keys ' : 'key ') + str; |
| 828 | ||
| 829 | // Have / include | |
| 830 | 48 | str = (this.contains ? 'contain ' : 'have ') + str; |
| 831 | ||
| 832 | // Assertion | |
| 833 | 48 | this.assert( |
| 834 | ok | |
| 835 | , 'expected ' + this.inspect + ' to ' + str | |
| 836 | , 'expected ' + this.inspect + ' to not ' + str | |
| 837 | , keys | |
| 838 | , Object.keys(this.obj) | |
| 839 | ); | |
| 840 | ||
| 841 | 32 | return this; |
| 842 | } | |
| 843 | ||
| 844 | /** | |
| 845 | * # .throw(constructor) | |
| 846 | * | |
| 847 | * Assert that a function will throw a specific type of error or that error | |
| 848 | * thrown will match a RegExp or include a string. | |
| 849 | * | |
| 850 | * var fn = function () { throw new ReferenceError('This is a bad function.'); } | |
| 851 | * expect(fn).to.throw(ReferenceError); | |
| 852 | * expect(fn).to.throw(/bad function/); | |
| 853 | * expect(fn).to.not.throw('good function'); | |
| 854 | * expect(fn).to.throw(ReferenceError, /bad function/); | |
| 855 | * | |
| 856 | * Please note that when a throw expectation is negated, it will check each | |
| 857 | * parameter independently, starting with Error constructor type. The appropriate way | |
| 858 | * to check for the existence of a type of error but for a message that does not match | |
| 859 | * is to use `and`. | |
| 860 | * | |
| 861 | * expect(fn).to.throw(ReferenceError).and.not.throw(/good function/); | |
| 862 | * | |
| 863 | * @name throw | |
| 864 | * @alias throws | |
| 865 | * @alias Throw | |
| 866 | * @param {ErrorConstructor} constructor | |
| 867 | * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types | |
| 868 | * @api public | |
| 869 | */ | |
| 870 | ||
| 871 | 1 | Assertion.prototype.throw = function (constructor, msg) { |
| 872 | 65 | new Assertion(this.obj).is.a('function'); |
| 873 | ||
| 874 | 65 | var thrown = false; |
| 875 | ||
| 876 | 65 | if (arguments.length === 0) { |
| 877 | 11 | msg = null; |
| 878 | 11 | constructor = null; |
| 879 | 54 | } else if (constructor && (constructor instanceof RegExp || 'string' === typeof constructor)) { |
| 880 | 11 | msg = constructor; |
| 881 | 11 | constructor = null; |
| 882 | } | |
| 883 | ||
| 884 | 65 | try { |
| 885 | 65 | this.obj(); |
| 886 | } catch (err) { | |
| 887 | // first, check constructor | |
| 888 | 52 | if (constructor && 'function' === typeof constructor) { |
| 889 | 31 | this.assert( |
| 890 | err instanceof constructor && err.name == constructor.name | |
| 891 | , 'expected ' + this.inspect + ' to throw ' + constructor.name + ' but a ' + err.name + ' was thrown' | |
| 892 | , 'expected ' + this.inspect + ' to not throw ' + constructor.name ); | |
| 893 | 36 | if (!msg) return this; |
| 894 | } | |
| 895 | // next, check message | |
| 896 | 31 | if (err.message && msg && msg instanceof RegExp) { |
| 897 | 13 | this.assert( |
| 898 | msg.exec(err.message) | |
| 899 | , 'expected ' + this.inspect + ' to throw error matching ' + msg + ' but got ' + inspect(err.message) | |
| 900 | , 'expected ' + this.inspect + ' to throw error not matching ' + msg | |
| 901 | ); | |
| 902 | 7 | return this; |
| 903 | 18 | } else if (err.message && msg && 'string' === typeof msg) { |
| 904 | 8 | this.assert( |
| 905 | ~err.message.indexOf(msg) | |
| 906 | , 'expected ' + this.inspect + ' to throw error including ' + inspect(msg) + ' but got ' + inspect(err.message) | |
| 907 | , 'expected ' + this.inspect + ' to throw error not including ' + inspect(msg) | |
| 908 | ); | |
| 909 | 6 | return this; |
| 910 | } else { | |
| 911 | 10 | thrown = true; |
| 912 | } | |
| 913 | } | |
| 914 | ||
| 915 | 23 | var name = (constructor ? constructor.name : 'an error'); |
| 916 | ||
| 917 | 23 | this.assert( |
| 918 | thrown === true | |
| 919 | , 'expected ' + this.inspect + ' to throw ' + name | |
| 920 | , 'expected ' + this.inspect + ' to not throw ' + name); | |
| 921 | ||
| 922 | 15 | return this; |
| 923 | }; | |
| 924 | ||
| 925 | /** | |
| 926 | * # .respondTo(method) | |
| 927 | * | |
| 928 | * Assert that object/class will respond to a method. | |
| 929 | * | |
| 930 | * expect(Klass).to.respondTo('bar'); | |
| 931 | * expect(obj).to.respondTo('bar'); | |
| 932 | * | |
| 933 | * @name respondTo | |
| 934 | * @param {String} method | |
| 935 | * @api public | |
| 936 | */ | |
| 937 | ||
| 938 | 1 | Assertion.prototype.respondTo = function (method) { |
| 939 | 10 | var context = ('function' === typeof this.obj) |
| 940 | ? this.obj.prototype[method] | |
| 941 | : this.obj[method]; | |
| 942 | ||
| 943 | 10 | this.assert( |
| 944 | 'function' === typeof context | |
| 945 | , 'expected ' + this.inspect + ' to respond to ' + inspect(method) | |
| 946 | , 'expected ' + this.inspect + ' to not respond to ' + inspect(method) | |
| 947 | , 'function' | |
| 948 | , typeof context | |
| 949 | ); | |
| 950 | ||
| 951 | 6 | return this; |
| 952 | }; | |
| 953 | ||
| 954 | /** | |
| 955 | * # .satisfy(method) | |
| 956 | * | |
| 957 | * Assert that passes a truth test. | |
| 958 | * | |
| 959 | * expect(1).to.satisfy(function(num) { return num > 0; }); | |
| 960 | * | |
| 961 | * @name satisfy | |
| 962 | * @param {Function} matcher | |
| 963 | * @api public | |
| 964 | */ | |
| 965 | ||
| 966 | 1 | Assertion.prototype.satisfy = function (matcher) { |
| 967 | 4 | this.assert( |
| 968 | matcher(this.obj) | |
| 969 | , 'expected ' + this.inspect + ' to satisfy ' + inspect(matcher) | |
| 970 | , 'expected ' + this.inspect + ' to not satisfy' + inspect(matcher) | |
| 971 | , this.negate ? false : true | |
| 972 | , matcher(this.obj) | |
| 973 | ); | |
| 974 | ||
| 975 | 2 | return this; |
| 976 | }; | |
| 977 | ||
| 978 | /** | |
| 979 | * # .closeTo(expected, delta) | |
| 980 | * | |
| 981 | * Assert that actual is equal to +/- delta. | |
| 982 | * | |
| 983 | * expect(1.5).to.be.closeTo(1, 0.5); | |
| 984 | * | |
| 985 | * @name closeTo | |
| 986 | * @param {Number} expected | |
| 987 | * @param {Number} delta | |
| 988 | * @api public | |
| 989 | */ | |
| 990 | ||
| 991 | 1 | Assertion.prototype.closeTo = function (expected, delta) { |
| 992 | 4 | this.assert( |
| 993 | (this.obj - delta === expected) || (this.obj + delta === expected) | |
| 994 | , 'expected ' + this.inspect + ' to be close to ' + expected + ' +/- ' + delta | |
| 995 | , 'expected ' + this.inspect + ' not to be close to ' + expected + ' +/- ' + delta); | |
| 996 | ||
| 997 | 2 | return this; |
| 998 | }; | |
| 999 | ||
| 1000 | /*! | |
| 1001 | * Aliases. | |
| 1002 | */ | |
| 1003 | ||
| 1004 | 1 | (function alias(name, as){ |
| 1005 | 8 | Assertion.prototype[as] = Assertion.prototype[name]; |
| 1006 | 8 | return alias; |
| 1007 | }) | |
| 1008 | ('length', 'lengthOf') | |
| 1009 | ('keys', 'key') | |
| 1010 | ('ownProperty', 'haveOwnProperty') | |
| 1011 | ('above', 'greaterThan') | |
| 1012 | ('below', 'lessThan') | |
| 1013 | ('throw', 'throws') | |
| 1014 | ('throw', 'Throw') // for troublesome browsers | |
| 1015 | ('instanceof', 'instanceOf'); |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * chai | |
| 3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
| 4 | * MIT Licensed | |
| 5 | */ | |
| 6 | ||
| 7 | 1 | var fail = require('./chai').fail; |
| 8 | ||
| 9 | 1 | module.exports = AssertionError; |
| 10 | ||
| 11 | /*! | |
| 12 | * Inspired by node.js assert module | |
| 13 | * https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js | |
| 14 | */ | |
| 15 | 1 | function AssertionError (options) { |
| 16 | 168 | options = options || {}; |
| 17 | 168 | this.name = 'AssertionError'; |
| 18 | 168 | this.message = options.message; |
| 19 | 168 | this.actual = options.actual; |
| 20 | 168 | this.expected = options.expected; |
| 21 | 168 | this.operator = options.operator; |
| 22 | 168 | var stackStartFunction = options.stackStartFunction || fail; |
| 23 | ||
| 24 | 168 | if (Error.captureStackTrace) { |
| 25 | 168 | Error.captureStackTrace(this, stackStartFunction); |
| 26 | } | |
| 27 | } | |
| 28 | ||
| 29 | 1 | AssertionError.prototype.__proto__ = Error.prototype; |
| 30 | ||
| 31 | 1 | AssertionError.prototype.toString = function() { |
| 32 | 2 | return this.message; |
| 33 | }; |
| Line | Hits | Source |
|---|---|---|
| 1 | // This is directly from Node.js assert | |
| 2 | // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/assert.js | |
| 3 | ||
| 4 | ||
| 5 | 1 | module.exports = _deepEqual; |
| 6 | ||
| 7 | // For browser implementation | |
| 8 | 1 | if (!Buffer) { |
| 9 | 1 | var Buffer = { |
| 10 | isBuffer: function () { | |
| 11 | 12 | return false; |
| 12 | } | |
| 13 | }; | |
| 14 | } | |
| 15 | ||
| 16 | 1 | function _deepEqual(actual, expected) { |
| 17 | // 7.1. All identical values are equivalent, as determined by ===. | |
| 18 | 20 | if (actual === expected) { |
| 19 | 8 | return true; |
| 20 | ||
| 21 | 12 | } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { |
| 22 | 0 | if (actual.length != expected.length) return false; |
| 23 | ||
| 24 | 0 | for (var i = 0; i < actual.length; i++) { |
| 25 | 0 | if (actual[i] !== expected[i]) return false; |
| 26 | } | |
| 27 | ||
| 28 | 0 | return true; |
| 29 | ||
| 30 | // 7.2. If the expected value is a Date object, the actual value is | |
| 31 | // equivalent if it is also a Date object that refers to the same time. | |
| 32 | 12 | } else if (actual instanceof Date && expected instanceof Date) { |
| 33 | 0 | return actual.getTime() === expected.getTime(); |
| 34 | ||
| 35 | // 7.3. Other pairs that do not both pass typeof value == 'object', | |
| 36 | // equivalence is determined by ==. | |
| 37 | 12 | } else if (typeof actual != 'object' && typeof expected != 'object') { |
| 38 | 6 | return actual === expected; |
| 39 | ||
| 40 | // 7.4. For all other Object pairs, including Array objects, equivalence is | |
| 41 | // determined by having the same number of owned properties (as verified | |
| 42 | // with Object.prototype.hasOwnProperty.call), the same set of keys | |
| 43 | // (although not necessarily the same order), equivalent values for every | |
| 44 | // corresponding key, and an identical 'prototype' property. Note: this | |
| 45 | // accounts for both named and indexed properties on Arrays. | |
| 46 | } else { | |
| 47 | 6 | return objEquiv(actual, expected); |
| 48 | } | |
| 49 | } | |
| 50 | ||
| 51 | 1 | function isUndefinedOrNull(value) { |
| 52 | 12 | return value === null || value === undefined; |
| 53 | } | |
| 54 | ||
| 55 | 1 | function isArguments(object) { |
| 56 | 6 | return Object.prototype.toString.call(object) == '[object Arguments]'; |
| 57 | } | |
| 58 | ||
| 59 | 1 | function objEquiv(a, b) { |
| 60 | 6 | if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) |
| 61 | 0 | return false; |
| 62 | // an identical 'prototype' property. | |
| 63 | 6 | if (a.prototype !== b.prototype) return false; |
| 64 | //~~~I've managed to break Object.keys through screwy arguments passing. | |
| 65 | // Converting to array solves the problem. | |
| 66 | 6 | if (isArguments(a)) { |
| 67 | 0 | if (!isArguments(b)) { |
| 68 | 0 | return false; |
| 69 | } | |
| 70 | 0 | a = pSlice.call(a); |
| 71 | 0 | b = pSlice.call(b); |
| 72 | 0 | return _deepEqual(a, b); |
| 73 | } | |
| 74 | 6 | try { |
| 75 | 6 | var ka = Object.keys(a), |
| 76 | kb = Object.keys(b), | |
| 77 | key, i; | |
| 78 | } catch (e) {//happens when one is a string literal and the other isn't | |
| 79 | 0 | return false; |
| 80 | } | |
| 81 | // having the same number of owned properties (keys incorporates | |
| 82 | // hasOwnProperty) | |
| 83 | 6 | if (ka.length != kb.length) |
| 84 | 0 | return false; |
| 85 | //the same set of keys (although not necessarily the same order), | |
| 86 | 6 | ka.sort(); |
| 87 | 6 | kb.sort(); |
| 88 | //~~~cheap key test | |
| 89 | 6 | for (i = ka.length - 1; i >= 0; i--) { |
| 90 | 6 | if (ka[i] != kb[i]) |
| 91 | 0 | return false; |
| 92 | } | |
| 93 | //equivalent values for every corresponding key, and | |
| 94 | //~~~possibly expensive deep test | |
| 95 | 6 | for (i = ka.length - 1; i >= 0; i--) { |
| 96 | 6 | key = ka[i]; |
| 97 | 8 | if (!_deepEqual(a[key], b[key])) return false; |
| 98 | } | |
| 99 | 4 | return true; |
| 100 | } |
| Line | Hits | Source |
|---|---|---|
| 1 | // This is (almost) directly from Node.js utils | |
| 2 | // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js | |
| 3 | ||
| 4 | 1 | module.exports = inspect; |
| 5 | ||
| 6 | /** | |
| 7 | * Echos the value of a value. Trys to print the value out | |
| 8 | * in the best way possible given the different types. | |
| 9 | * | |
| 10 | * @param {Object} obj The object to print out. | |
| 11 | * @param {Boolean} showHidden Flag that shows hidden (not enumerable) | |
| 12 | * properties of objects. | |
| 13 | * @param {Number} depth Depth in which to descend in object. Default is 2. | |
| 14 | * @param {Boolean} colors Flag to turn on ANSI escape codes to color the | |
| 15 | * output. Default is false (no coloring). | |
| 16 | */ | |
| 17 | 1 | function inspect(obj, showHidden, depth, colors) { |
| 18 | 2300 | var ctx = { |
| 19 | showHidden: showHidden, | |
| 20 | seen: [], | |
| 21 | 2692 | stylize: function (str) { return str; } |
| 22 | }; | |
| 23 | 2300 | return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); |
| 24 | } | |
| 25 | ||
| 26 | 1 | function formatValue(ctx, value, recurseTimes) { |
| 27 | // Provide a hook for user-specified inspect functions. | |
| 28 | // Check that value is an object with an inspect function on it | |
| 29 | 2730 | if (value && typeof value.inspect === 'function' && |
| 30 | // Filter out the util module, it's inspect function is special | |
| 31 | value.inspect !== exports.inspect && | |
| 32 | // Also filter out any prototype objects using the circular check. | |
| 33 | !(value.constructor && value.constructor.prototype === value)) { | |
| 34 | 0 | return value.inspect(recurseTimes); |
| 35 | } | |
| 36 | ||
| 37 | // Primitive types cannot have properties | |
| 38 | 2730 | var primitive = formatPrimitive(ctx, value); |
| 39 | 2730 | if (primitive) { |
| 40 | 2098 | return primitive; |
| 41 | } | |
| 42 | ||
| 43 | // Look up the keys of the object. | |
| 44 | 632 | var visibleKeys = Object.keys(value); |
| 45 | 632 | var keys = ctx.showHidden ? Object.getOwnPropertyNames(value) : visibleKeys; |
| 46 | ||
| 47 | // Some type of object without properties can be shortcutted. | |
| 48 | 632 | if (keys.length === 0) { |
| 49 | 392 | if (typeof value === 'function') { |
| 50 | 328 | var name = value.name ? ': ' + value.name : ''; |
| 51 | 328 | return ctx.stylize('[Function' + name + ']', 'special'); |
| 52 | } | |
| 53 | 64 | if (isRegExp(value)) { |
| 54 | 0 | return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
| 55 | } | |
| 56 | 64 | if (isDate(value)) { |
| 57 | 0 | return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); |
| 58 | } | |
| 59 | 64 | if (isError(value)) { |
| 60 | 0 | return formatError(value); |
| 61 | } | |
| 62 | } | |
| 63 | ||
| 64 | 304 | var base = '', array = false, braces = ['{', '}']; |
| 65 | ||
| 66 | // Make Array say that they are Array | |
| 67 | 304 | if (isArray(value)) { |
| 68 | 96 | array = true; |
| 69 | 96 | braces = ['[', ']']; |
| 70 | } | |
| 71 | ||
| 72 | // Make functions say that they are functions | |
| 73 | 304 | if (typeof value === 'function') { |
| 74 | 0 | var n = value.name ? ': ' + value.name : ''; |
| 75 | 0 | base = ' [Function' + n + ']'; |
| 76 | } | |
| 77 | ||
| 78 | // Make RegExps say that they are RegExps | |
| 79 | 304 | if (isRegExp(value)) { |
| 80 | 0 | base = ' ' + RegExp.prototype.toString.call(value); |
| 81 | } | |
| 82 | ||
| 83 | // Make dates with properties first say the date | |
| 84 | 304 | if (isDate(value)) { |
| 85 | 0 | base = ' ' + Date.prototype.toUTCString.call(value); |
| 86 | } | |
| 87 | ||
| 88 | // Make error with message first say the error | |
| 89 | 304 | if (isError(value)) { |
| 90 | 0 | base = ' ' + formatError(value); |
| 91 | } | |
| 92 | ||
| 93 | 304 | if (keys.length === 0 && (!array || value.length == 0)) { |
| 94 | 64 | return braces[0] + base + braces[1]; |
| 95 | } | |
| 96 | ||
| 97 | 240 | if (recurseTimes < 0) { |
| 98 | 0 | if (isRegExp(value)) { |
| 99 | 0 | return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); |
| 100 | } else { | |
| 101 | 0 | return ctx.stylize('[Object]', 'special'); |
| 102 | } | |
| 103 | } | |
| 104 | ||
| 105 | 240 | ctx.seen.push(value); |
| 106 | ||
| 107 | 240 | var output; |
| 108 | 240 | if (array) { |
| 109 | 72 | output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); |
| 110 | } else { | |
| 111 | 168 | output = keys.map(function(key) { |
| 112 | 266 | return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); |
| 113 | }); | |
| 114 | } | |
| 115 | ||
| 116 | 240 | ctx.seen.pop(); |
| 117 | ||
| 118 | 240 | return reduceToSingleString(output, base, braces); |
| 119 | } | |
| 120 | ||
| 121 | ||
| 122 | 1 | function formatPrimitive(ctx, value) { |
| 123 | 2730 | switch (typeof value) { |
| 124 | case 'undefined': | |
| 125 | 36 | return ctx.stylize('undefined', 'undefined'); |
| 126 | ||
| 127 | case 'string': | |
| 128 | 1444 | var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') |
| 129 | .replace(/'/g, "\\'") | |
| 130 | .replace(/\\"/g, '"') + '\''; | |
| 131 | 1444 | return ctx.stylize(simple, 'string'); |
| 132 | ||
| 133 | case 'number': | |
| 134 | 546 | return ctx.stylize('' + value, 'number'); |
| 135 | ||
| 136 | case 'boolean': | |
| 137 | 54 | return ctx.stylize('' + value, 'boolean'); |
| 138 | } | |
| 139 | // For some reason typeof null is "object", so special case here. | |
| 140 | 650 | if (value === null) { |
| 141 | 18 | return ctx.stylize('null', 'null'); |
| 142 | } | |
| 143 | } | |
| 144 | ||
| 145 | ||
| 146 | 1 | function formatError(value) { |
| 147 | 0 | return '[' + Error.prototype.toString.call(value) + ']'; |
| 148 | } | |
| 149 | ||
| 150 | ||
| 151 | 1 | function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { |
| 152 | 72 | var output = []; |
| 153 | 72 | for (var i = 0, l = value.length; i < l; ++i) { |
| 154 | 164 | if (Object.prototype.hasOwnProperty.call(value, String(i))) { |
| 155 | 164 | output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
| 156 | String(i), true)); | |
| 157 | } else { | |
| 158 | 0 | output.push(''); |
| 159 | } | |
| 160 | } | |
| 161 | 72 | keys.forEach(function(key) { |
| 162 | 164 | if (!key.match(/^\d+$/)) { |
| 163 | 0 | output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, |
| 164 | key, true)); | |
| 165 | } | |
| 166 | }); | |
| 167 | 72 | return output; |
| 168 | } | |
| 169 | ||
| 170 | ||
| 171 | 1 | function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { |
| 172 | 430 | var name, str; |
| 173 | 430 | if (value.__lookupGetter__) { |
| 174 | 430 | if (value.__lookupGetter__(key)) { |
| 175 | 0 | if (value.__lookupSetter__(key)) { |
| 176 | 0 | str = ctx.stylize('[Getter/Setter]', 'special'); |
| 177 | } else { | |
| 178 | 0 | str = ctx.stylize('[Getter]', 'special'); |
| 179 | } | |
| 180 | } else { | |
| 181 | 430 | if (value.__lookupSetter__(key)) { |
| 182 | 0 | str = ctx.stylize('[Setter]', 'special'); |
| 183 | } | |
| 184 | } | |
| 185 | } | |
| 186 | 430 | if (visibleKeys.indexOf(key) < 0) { |
| 187 | 0 | name = '[' + key + ']'; |
| 188 | } | |
| 189 | 430 | if (!str) { |
| 190 | 430 | if (ctx.seen.indexOf(value[key]) < 0) { |
| 191 | 430 | if (recurseTimes === null) { |
| 192 | 0 | str = formatValue(ctx, value[key], null); |
| 193 | } else { | |
| 194 | 430 | str = formatValue(ctx, value[key], recurseTimes - 1); |
| 195 | } | |
| 196 | 430 | if (str.indexOf('\n') > -1) { |
| 197 | 0 | if (array) { |
| 198 | 0 | str = str.split('\n').map(function(line) { |
| 199 | 0 | return ' ' + line; |
| 200 | }).join('\n').substr(2); | |
| 201 | } else { | |
| 202 | 0 | str = '\n' + str.split('\n').map(function(line) { |
| 203 | 0 | return ' ' + line; |
| 204 | }).join('\n'); | |
| 205 | } | |
| 206 | } | |
| 207 | } else { | |
| 208 | 0 | str = ctx.stylize('[Circular]', 'special'); |
| 209 | } | |
| 210 | } | |
| 211 | 430 | if (typeof name === 'undefined') { |
| 212 | 430 | if (array && key.match(/^\d+$/)) { |
| 213 | 164 | return str; |
| 214 | } | |
| 215 | 266 | name = JSON.stringify('' + key); |
| 216 | 266 | if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { |
| 217 | 248 | name = name.substr(1, name.length - 2); |
| 218 | 248 | name = ctx.stylize(name, 'name'); |
| 219 | } else { | |
| 220 | 18 | name = name.replace(/'/g, "\\'") |
| 221 | .replace(/\\"/g, '"') | |
| 222 | .replace(/(^"|"$)/g, "'"); | |
| 223 | 18 | name = ctx.stylize(name, 'string'); |
| 224 | } | |
| 225 | } | |
| 226 | ||
| 227 | 266 | return name + ': ' + str; |
| 228 | } | |
| 229 | ||
| 230 | ||
| 231 | 1 | function reduceToSingleString(output, base, braces) { |
| 232 | 240 | var numLinesEst = 0; |
| 233 | 240 | var length = output.reduce(function(prev, cur) { |
| 234 | 430 | numLinesEst++; |
| 235 | 430 | if (cur.indexOf('\n') >= 0) numLinesEst++; |
| 236 | 430 | return prev + cur.length + 1; |
| 237 | }, 0); | |
| 238 | ||
| 239 | 240 | if (length > 60) { |
| 240 | 0 | return braces[0] + |
| 241 | (base === '' ? '' : base + '\n ') + | |
| 242 | ' ' + | |
| 243 | output.join(',\n ') + | |
| 244 | ' ' + | |
| 245 | braces[1]; | |
| 246 | } | |
| 247 | ||
| 248 | 240 | return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; |
| 249 | } | |
| 250 | ||
| 251 | 1 | function isArray(ar) { |
| 252 | 304 | return Array.isArray(ar) || |
| 253 | (typeof ar === 'object' && objectToString(ar) === '[object Array]'); | |
| 254 | } | |
| 255 | ||
| 256 | 1 | function isRegExp(re) { |
| 257 | 368 | return typeof re === 'object' && objectToString(re) === '[object RegExp]'; |
| 258 | } | |
| 259 | ||
| 260 | 1 | function isDate(d) { |
| 261 | 368 | return typeof d === 'object' && objectToString(d) === '[object Date]'; |
| 262 | } | |
| 263 | ||
| 264 | 1 | function isError(e) { |
| 265 | 368 | return typeof e === 'object' && objectToString(e) === '[object Error]'; |
| 266 | } | |
| 267 | ||
| 268 | 1 | function objectToString(o) { |
| 269 | 1312 | return Object.prototype.toString.call(o); |
| 270 | } |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * chai | |
| 3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
| 4 | * MIT Licensed | |
| 5 | */ | |
| 6 | ||
| 7 | 1 | module.exports = function (chai) { |
| 8 | 1 | chai.expect = function (val, message) { |
| 9 | 252 | return new chai.Assertion(val, message); |
| 10 | }; | |
| 11 | }; | |
| 12 |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * chai | |
| 3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
| 4 | * MIT Licensed | |
| 5 | */ | |
| 6 | ||
| 7 | 1 | module.exports = function (chai) { |
| 8 | 1 | var Assertion = chai.Assertion; |
| 9 | ||
| 10 | 1 | chai.should = function () { |
| 11 | // modify Object.prototype to have `should` | |
| 12 | 1 | Object.defineProperty(Object.prototype, 'should', { |
| 13 | set: function(){}, | |
| 14 | get: function(){ | |
| 15 | 175 | if (this instanceof String || this instanceof Number) { |
| 16 | 1 | return new Assertion(this.constructor(this)); |
| 17 | 174 | } else if (this instanceof Boolean) { |
| 18 | 0 | return new Assertion(this == true); |
| 19 | } | |
| 20 | 174 | return new Assertion(this); |
| 21 | }, | |
| 22 | configurable: true | |
| 23 | }); | |
| 24 | ||
| 25 | 1 | var should = {}; |
| 26 | ||
| 27 | 1 | should.equal = function (val1, val2) { |
| 28 | 70 | new Assertion(val1).to.equal(val2); |
| 29 | }; | |
| 30 | ||
| 31 | 1 | should.throw = function (fn, errt, errs) { |
| 32 | 4 | new Assertion(fn).to.throw(errt, errs); |
| 33 | }; | |
| 34 | ||
| 35 | 1 | should.exist = function (val) { |
| 36 | 2 | new Assertion(val).to.exist; |
| 37 | } | |
| 38 | ||
| 39 | // negation | |
| 40 | 1 | should.not = {} |
| 41 | ||
| 42 | 1 | should.not.equal = function (val1, val2) { |
| 43 | 1 | new Assertion(val1).to.not.equal(val2); |
| 44 | }; | |
| 45 | ||
| 46 | 1 | should.not.throw = function (fn, errt, errs) { |
| 47 | 2 | new Assertion(fn).to.not.throw(errt, errs); |
| 48 | }; | |
| 49 | ||
| 50 | 1 | should.not.exist = function (val) { |
| 51 | 2 | new Assertion(val).to.not.exist; |
| 52 | } | |
| 53 | ||
| 54 | 1 | return should; |
| 55 | }; | |
| 56 | }; |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * chai | |
| 3 | * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> | |
| 4 | * MIT Licensed | |
| 5 | */ | |
| 6 | ||
| 7 | /** | |
| 8 | * ### TDD Style Introduction | |
| 9 | * | |
| 10 | * The TDD style is exposed through `assert` interfaces. This provides | |
| 11 | * the classic assert.`test` notation, similiar to that packaged with | |
| 12 | * node.js. This assert module, however, provides several additional | |
| 13 | * tests and is browser compatible. | |
| 14 | * | |
| 15 | * // assert | |
| 16 | * var assert = require('chai').assert; | |
| 17 | * , foo = 'bar'; | |
| 18 | * | |
| 19 | * assert.typeOf(foo, 'string'); | |
| 20 | * assert.equal(foo, 'bar'); | |
| 21 | * | |
| 22 | * #### Configuration | |
| 23 | * | |
| 24 | * By default, Chai does not show stack traces upon an AssertionError. This can | |
| 25 | * be changed by modifying the `includeStack` parameter for chai.Assertion. For example: | |
| 26 | * | |
| 27 | * var chai = require('chai'); | |
| 28 | * chai.Assertion.includeStack = true; // defaults to false | |
| 29 | */ | |
| 30 | ||
| 31 | 1 | module.exports = function (chai) { |
| 32 | /*! | |
| 33 | * Chai dependencies. | |
| 34 | */ | |
| 35 | 1 | var Assertion = chai.Assertion |
| 36 | , inspect = chai.inspect; | |
| 37 | ||
| 38 | /*! | |
| 39 | * Module export. | |
| 40 | */ | |
| 41 | ||
| 42 | 1 | var assert = chai.assert = {}; |
| 43 | ||
| 44 | /** | |
| 45 | * # .fail(actual, expect, msg, operator) | |
| 46 | * | |
| 47 | * Throw a failure. Node.js compatible. | |
| 48 | * | |
| 49 | * @name fail | |
| 50 | * @param {*} actual value | |
| 51 | * @param {*} expected value | |
| 52 | * @param {String} message | |
| 53 | * @param {String} operator | |
| 54 | * @api public | |
| 55 | */ | |
| 56 | ||
| 57 | 1 | assert.fail = function (actual, expected, message, operator) { |
| 58 | 1 | throw new chai.AssertionError({ |
| 59 | actual: actual | |
| 60 | , expected: expected | |
| 61 | , message: message | |
| 62 | , operator: operator | |
| 63 | , stackStartFunction: assert.fail | |
| 64 | }); | |
| 65 | } | |
| 66 | ||
| 67 | /** | |
| 68 | * # .ok(object, [message]) | |
| 69 | * | |
| 70 | * Assert object is truthy. | |
| 71 | * | |
| 72 | * assert.ok('everthing', 'everything is ok'); | |
| 73 | * assert.ok(false, 'this will fail'); | |
| 74 | * | |
| 75 | * @name ok | |
| 76 | * @param {*} object to test | |
| 77 | * @param {String} message | |
| 78 | * @api public | |
| 79 | */ | |
| 80 | ||
| 81 | 1 | assert.ok = function (val, msg) { |
| 82 | 7 | new Assertion(val, msg).is.ok; |
| 83 | }; | |
| 84 | ||
| 85 | /** | |
| 86 | * # .equal(actual, expected, [message]) | |
| 87 | * | |
| 88 | * Assert strict equality. | |
| 89 | * | |
| 90 | * assert.equal(3, 3, 'these numbers are equal'); | |
| 91 | * | |
| 92 | * @name equal | |
| 93 | * @param {*} actual | |
| 94 | * @param {*} expected | |
| 95 | * @param {String} message | |
| 96 | * @api public | |
| 97 | */ | |
| 98 | ||
| 99 | 1 | assert.equal = function (act, exp, msg) { |
| 100 | 44 | var test = new Assertion(act, msg); |
| 101 | ||
| 102 | 44 | test.assert( |
| 103 | exp == test.obj | |
| 104 | , 'expected ' + test.inspect + ' to equal ' + inspect(exp) | |
| 105 | , 'expected ' + test.inspect + ' to not equal ' + inspect(exp)); | |
| 106 | }; | |
| 107 | ||
| 108 | /** | |
| 109 | * # .notEqual(actual, expected, [message]) | |
| 110 | * | |
| 111 | * Assert not equal. | |
| 112 | * | |
| 113 | * assert.notEqual(3, 4, 'these numbers are not equal'); | |
| 114 | * | |
| 115 | * @name notEqual | |
| 116 | * @param {*} actual | |
| 117 | * @param {*} expected | |
| 118 | * @param {String} message | |
| 119 | * @api public | |
| 120 | */ | |
| 121 | ||
| 122 | 1 | assert.notEqual = function (act, exp, msg) { |
| 123 | 2 | var test = new Assertion(act, msg); |
| 124 | ||
| 125 | 2 | test.assert( |
| 126 | exp != test.obj | |
| 127 | , 'expected ' + test.inspect + ' to equal ' + inspect(exp) | |
| 128 | , 'expected ' + test.inspect + ' to not equal ' + inspect(exp)); | |
| 129 | }; | |
| 130 | ||
| 131 | /** | |
| 132 | * # .strictEqual(actual, expected, [message]) | |
| 133 | * | |
| 134 | * Assert strict equality. | |
| 135 | * | |
| 136 | * assert.strictEqual(true, true, 'these booleans are strictly equal'); | |
| 137 | * | |
| 138 | * @name strictEqual | |
| 139 | * @param {*} actual | |
| 140 | * @param {*} expected | |
| 141 | * @param {String} message | |
| 142 | * @api public | |
| 143 | */ | |
| 144 | ||
| 145 | 1 | assert.strictEqual = function (act, exp, msg) { |
| 146 | 2 | new Assertion(act, msg).to.equal(exp); |
| 147 | }; | |
| 148 | ||
| 149 | /** | |
| 150 | * # .notStrictEqual(actual, expected, [message]) | |
| 151 | * | |
| 152 | * Assert strict equality. | |
| 153 | * | |
| 154 | * assert.notStrictEqual(1, true, 'these booleans are not strictly equal'); | |
| 155 | * | |
| 156 | * @name notStrictEqual | |
| 157 | * @param {*} actual | |
| 158 | * @param {*} expected | |
| 159 | * @param {String} message | |
| 160 | * @api public | |
| 161 | */ | |
| 162 | ||
| 163 | 1 | assert.notStrictEqual = function (act, exp, msg) { |
| 164 | 2 | new Assertion(act, msg).to.not.equal(exp); |
| 165 | }; | |
| 166 | ||
| 167 | /** | |
| 168 | * # .deepEqual(actual, expected, [message]) | |
| 169 | * | |
| 170 | * Assert not deep equality. | |
| 171 | * | |
| 172 | * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); | |
| 173 | * | |
| 174 | * @name deepEqual | |
| 175 | * @param {*} actual | |
| 176 | * @param {*} expected | |
| 177 | * @param {String} message | |
| 178 | * @api public | |
| 179 | */ | |
| 180 | ||
| 181 | 1 | assert.deepEqual = function (act, exp, msg) { |
| 182 | 2 | new Assertion(act, msg).to.eql(exp); |
| 183 | }; | |
| 184 | ||
| 185 | /** | |
| 186 | * # .notDeepEqual(actual, expected, [message]) | |
| 187 | * | |
| 188 | * Assert not deep equality. | |
| 189 | * | |
| 190 | * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); | |
| 191 | * | |
| 192 | * @name notDeepEqual | |
| 193 | * @param {*} actual | |
| 194 | * @param {*} expected | |
| 195 | * @param {String} message | |
| 196 | * @api public | |
| 197 | */ | |
| 198 | ||
| 199 | 1 | assert.notDeepEqual = function (act, exp, msg) { |
| 200 | 2 | new Assertion(act, msg).to.not.eql(exp); |
| 201 | }; | |
| 202 | ||
| 203 | /** | |
| 204 | * # .isTrue(value, [message]) | |
| 205 | * | |
| 206 | * Assert `value` is true. | |
| 207 | * | |
| 208 | * var tea_served = true; | |
| 209 | * assert.isTrue(tea_served, 'the tea has been served'); | |
| 210 | * | |
| 211 | * @name isTrue | |
| 212 | * @param {Boolean} value | |
| 213 | * @param {String} message | |
| 214 | * @api public | |
| 215 | */ | |
| 216 | ||
| 217 | 1 | assert.isTrue = function (val, msg) { |
| 218 | 4 | new Assertion(val, msg).is.true; |
| 219 | }; | |
| 220 | ||
| 221 | /** | |
| 222 | * # .isFalse(value, [message]) | |
| 223 | * | |
| 224 | * Assert `value` is false. | |
| 225 | * | |
| 226 | * var tea_served = false; | |
| 227 | * assert.isFalse(tea_served, 'no tea yet? hmm...'); | |
| 228 | * | |
| 229 | * @name isFalse | |
| 230 | * @param {Boolean} value | |
| 231 | * @param {String} message | |
| 232 | * @api public | |
| 233 | */ | |
| 234 | ||
| 235 | 1 | assert.isFalse = function (val, msg) { |
| 236 | 3 | new Assertion(val, msg).is.false; |
| 237 | }; | |
| 238 | ||
| 239 | /** | |
| 240 | * # .isNull(value, [message]) | |
| 241 | * | |
| 242 | * Assert `value` is null. | |
| 243 | * | |
| 244 | * assert.isNull(err, 'no errors'); | |
| 245 | * | |
| 246 | * @name isNull | |
| 247 | * @param {*} value | |
| 248 | * @param {String} message | |
| 249 | * @api public | |
| 250 | */ | |
| 251 | ||
| 252 | 1 | assert.isNull = function (val, msg) { |
| 253 | 2 | new Assertion(val, msg).to.equal(null); |
| 254 | }; | |
| 255 | ||
| 256 | /** | |
| 257 | * # .isNotNull(value, [message]) | |
| 258 | * | |
| 259 | * Assert `value` is not null. | |
| 260 | * | |
| 261 | * var tea = 'tasty chai'; | |
| 262 | * assert.isNotNull(tea, 'great, time for tea!'); | |
| 263 | * | |
| 264 | * @name isNotNull | |
| 265 | * @param {*} value | |
| 266 | * @param {String} message | |
| 267 | * @api public | |
| 268 | */ | |
| 269 | ||
| 270 | 1 | assert.isNotNull = function (val, msg) { |
| 271 | 2 | new Assertion(val, msg).to.not.equal(null); |
| 272 | }; | |
| 273 | ||
| 274 | /** | |
| 275 | * # .isUndefined(value, [message]) | |
| 276 | * | |
| 277 | * Assert `value` is undefined. | |
| 278 | * | |
| 279 | * assert.isUndefined(tea, 'no tea defined'); | |
| 280 | * | |
| 281 | * @name isUndefined | |
| 282 | * @param {*} value | |
| 283 | * @param {String} message | |
| 284 | * @api public | |
| 285 | */ | |
| 286 | ||
| 287 | 1 | assert.isUndefined = function (val, msg) { |
| 288 | 2 | new Assertion(val, msg).to.equal(undefined); |
| 289 | }; | |
| 290 | ||
| 291 | /** | |
| 292 | * # .isDefined(value, [message]) | |
| 293 | * | |
| 294 | * Assert `value` is not undefined. | |
| 295 | * | |
| 296 | * var tea = 'cup of chai'; | |
| 297 | * assert.isDefined(tea, 'no tea defined'); | |
| 298 | * | |
| 299 | * @name isUndefined | |
| 300 | * @param {*} value | |
| 301 | * @param {String} message | |
| 302 | * @api public | |
| 303 | */ | |
| 304 | ||
| 305 | 1 | assert.isDefined = function (val, msg) { |
| 306 | 2 | new Assertion(val, msg).to.not.equal(undefined); |
| 307 | }; | |
| 308 | ||
| 309 | /** | |
| 310 | * # .isFunction(value, [message]) | |
| 311 | * | |
| 312 | * Assert `value` is a function. | |
| 313 | * | |
| 314 | * var serve_tea = function () { return 'cup of tea'; }; | |
| 315 | * assert.isFunction(serve_tea, 'great, we can have tea now'); | |
| 316 | * | |
| 317 | * @name isFunction | |
| 318 | * @param {Function} value | |
| 319 | * @param {String} message | |
| 320 | * @api public | |
| 321 | */ | |
| 322 | ||
| 323 | 1 | assert.isFunction = function (val, msg) { |
| 324 | 2 | new Assertion(val, msg).to.be.a('function'); |
| 325 | }; | |
| 326 | ||
| 327 | /** | |
| 328 | * # .isObject(value, [message]) | |
| 329 | * | |
| 330 | * Assert `value` is an object. | |
| 331 | * | |
| 332 | * var selection = { name: 'Chai', serve: 'with spices' }; | |
| 333 | * assert.isObject(selection, 'tea selection is an object'); | |
| 334 | * | |
| 335 | * @name isObject | |
| 336 | * @param {Object} value | |
| 337 | * @param {String} message | |
| 338 | * @api public | |
| 339 | */ | |
| 340 | ||
| 341 | 1 | assert.isObject = function (val, msg) { |
| 342 | 5 | new Assertion(val, msg).to.be.a('object'); |
| 343 | }; | |
| 344 | ||
| 345 | /** | |
| 346 | * # .isArray(value, [message]) | |
| 347 | * | |
| 348 | * Assert `value` is an instance of Array. | |
| 349 | * | |
| 350 | * var menu = [ 'green', 'chai', 'oolong' ]; | |
| 351 | * assert.isArray(menu, 'what kind of tea do we want?'); | |
| 352 | * | |
| 353 | * @name isArray | |
| 354 | * @param {*} value | |
| 355 | * @param {String} message | |
| 356 | * @api public | |
| 357 | */ | |
| 358 | ||
| 359 | 1 | assert.isArray = function (val, msg) { |
| 360 | 3 | new Assertion(val, msg).to.be.instanceof(Array); |
| 361 | }; | |
| 362 | ||
| 363 | /** | |
| 364 | * # .isString(value, [message]) | |
| 365 | * | |
| 366 | * Assert `value` is a string. | |
| 367 | * | |
| 368 | * var teaorder = 'chai'; | |
| 369 | * assert.isString(tea_order, 'order placed'); | |
| 370 | * | |
| 371 | * @name isString | |
| 372 | * @param {String} value | |
| 373 | * @param {String} message | |
| 374 | * @api public | |
| 375 | */ | |
| 376 | ||
| 377 | 1 | assert.isString = function (val, msg) { |
| 378 | 3 | new Assertion(val, msg).to.be.a('string'); |
| 379 | }; | |
| 380 | ||
| 381 | /** | |
| 382 | * # .isNumber(value, [message]) | |
| 383 | * | |
| 384 | * Assert `value` is a number | |
| 385 | * | |
| 386 | * var cups = 2; | |
| 387 | * assert.isNumber(cups, 'how many cups'); | |
| 388 | * | |
| 389 | * @name isNumber | |
| 390 | * @param {Number} value | |
| 391 | * @param {String} message | |
| 392 | * @api public | |
| 393 | */ | |
| 394 | ||
| 395 | 1 | assert.isNumber = function (val, msg) { |
| 396 | 3 | new Assertion(val, msg).to.be.a('number'); |
| 397 | }; | |
| 398 | ||
| 399 | /** | |
| 400 | * # .isBoolean(value, [message]) | |
| 401 | * | |
| 402 | * Assert `value` is a boolean | |
| 403 | * | |
| 404 | * var teaready = true | |
| 405 | * , teaserved = false; | |
| 406 | * | |
| 407 | * assert.isBoolean(tea_ready, 'is the tea ready'); | |
| 408 | * assert.isBoolean(tea_served, 'has tea been served'); | |
| 409 | * | |
| 410 | * @name isBoolean | |
| 411 | * @param {*} value | |
| 412 | * @param {String} message | |
| 413 | * @api public | |
| 414 | */ | |
| 415 | ||
| 416 | 1 | assert.isBoolean = function (val, msg) { |
| 417 | 3 | new Assertion(val, msg).to.be.a('boolean'); |
| 418 | }; | |
| 419 | ||
| 420 | /** | |
| 421 | * # .typeOf(value, name, [message]) | |
| 422 | * | |
| 423 | * Assert typeof `value` is `name`. | |
| 424 | * | |
| 425 | * assert.typeOf('tea', 'string', 'we have a string'); | |
| 426 | * | |
| 427 | * @name typeOf | |
| 428 | * @param {*} value | |
| 429 | * @param {String} typeof name | |
| 430 | * @param {String} message | |
| 431 | * @api public | |
| 432 | */ | |
| 433 | ||
| 434 | 1 | assert.typeOf = function (val, type, msg) { |
| 435 | 4 | new Assertion(val, msg).to.be.a(type); |
| 436 | }; | |
| 437 | ||
| 438 | /** | |
| 439 | * # .instanceOf(object, constructor, [message]) | |
| 440 | * | |
| 441 | * Assert `value` is instanceof `constructor`. | |
| 442 | * | |
| 443 | * var Tea = function (name) { this.name = name; } | |
| 444 | * , Chai = new Tea('chai'); | |
| 445 | * | |
| 446 | * assert.instanceOf(Chai, Tea, 'chai is an instance of tea'); | |
| 447 | * | |
| 448 | * @name instanceOf | |
| 449 | * @param {Object} object | |
| 450 | * @param {Constructor} constructor | |
| 451 | * @param {String} message | |
| 452 | * @api public | |
| 453 | */ | |
| 454 | ||
| 455 | 1 | assert.instanceOf = function (val, type, msg) { |
| 456 | 2 | new Assertion(val, msg).to.be.instanceof(type); |
| 457 | }; | |
| 458 | ||
| 459 | /** | |
| 460 | * # .include(value, includes, [message]) | |
| 461 | * | |
| 462 | * Assert the inclusion of an object in another. Works | |
| 463 | * for strings and arrays. | |
| 464 | * | |
| 465 | * assert.include('foobar', 'bar', 'foobar contains string `var`); | |
| 466 | * assert.include([ 1, 2, 3], 3, 'array contains value); | |
| 467 | * | |
| 468 | * @name include | |
| 469 | * @param {Array|String} value | |
| 470 | * @param {*} includes | |
| 471 | * @param {String} message | |
| 472 | * @api public | |
| 473 | */ | |
| 474 | ||
| 475 | 1 | assert.include = function (exp, inc, msg) { |
| 476 | 4 | var obj = new Assertion(exp, msg); |
| 477 | ||
| 478 | 4 | if (Array.isArray(exp)) { |
| 479 | 1 | obj.to.include(inc); |
| 480 | 3 | } else if ('string' === typeof exp) { |
| 481 | 3 | obj.to.contain.string(inc); |
| 482 | } | |
| 483 | }; | |
| 484 | ||
| 485 | /** | |
| 486 | * # .match(value, regex, [message]) | |
| 487 | * | |
| 488 | * Assert that `value` matches regular expression. | |
| 489 | * | |
| 490 | * assert.match('foobar', /^foo/, 'Regexp matches'); | |
| 491 | * | |
| 492 | * @name match | |
| 493 | * @param {*} value | |
| 494 | * @param {RegExp} RegularExpression | |
| 495 | * @param {String} message | |
| 496 | * @api public | |
| 497 | */ | |
| 498 | ||
| 499 | 1 | assert.match = function (exp, re, msg) { |
| 500 | 1 | new Assertion(exp, msg).to.match(re); |
| 501 | }; | |
| 502 | ||
| 503 | /** | |
| 504 | * # .length(value, constructor, [message]) | |
| 505 | * | |
| 506 | * Assert that object has expected length. | |
| 507 | * | |
| 508 | * assert.length([1,2,3], 3, 'Array has length of 3'); | |
| 509 | * assert.length('foobar', 5, 'String has length of 6'); | |
| 510 | * | |
| 511 | * @name length | |
| 512 | * @param {*} value | |
| 513 | * @param {Number} length | |
| 514 | * @param {String} message | |
| 515 | * @api public | |
| 516 | */ | |
| 517 | ||
| 518 | 1 | assert.length = function (exp, len, msg) { |
| 519 | 4 | new Assertion(exp, msg).to.have.length(len); |
| 520 | }; | |
| 521 | ||
| 522 | /** | |
| 523 | * # .throws(function, [constructor/regexp], [message]) | |
| 524 | * | |
| 525 | * Assert that a function will throw a specific | |
| 526 | * type of error. | |
| 527 | * | |
| 528 | * assert.throw(fn, ReferenceError, 'function throw reference error'); | |
| 529 | * | |
| 530 | * @name throws | |
| 531 | * @alias throw | |
| 532 | * @param {Function} function to test | |
| 533 | * @param {ErrorConstructor} constructor | |
| 534 | * @param {String} message | |
| 535 | * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types | |
| 536 | * @api public | |
| 537 | */ | |
| 538 | ||
| 539 | 1 | assert.throws = function (fn, type, msg) { |
| 540 | 3 | if ('string' === typeof type) { |
| 541 | 1 | msg = type; |
| 542 | 1 | type = null; |
| 543 | } | |
| 544 | ||
| 545 | 3 | new Assertion(fn, msg).to.throw(type); |
| 546 | }; | |
| 547 | ||
| 548 | /** | |
| 549 | * # .doesNotThrow(function, [constructor/regexp], [message]) | |
| 550 | * | |
| 551 | * Assert that a function will throw a specific | |
| 552 | * type of error. | |
| 553 | * | |
| 554 | * var fn = function (err) { if (err) throw Error(err) }; | |
| 555 | * assert.doesNotThrow(fn, Error, 'function throw reference error'); | |
| 556 | * | |
| 557 | * @name doesNotThrow | |
| 558 | * @param {Function} function to test | |
| 559 | * @param {ErrorConstructor} constructor | |
| 560 | * @param {String} message | |
| 561 | * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types | |
| 562 | * @api public | |
| 563 | */ | |
| 564 | ||
| 565 | 1 | assert.doesNotThrow = function (fn, type, msg) { |
| 566 | 3 | if ('string' === typeof type) { |
| 567 | 1 | msg = type; |
| 568 | 1 | type = null; |
| 569 | } | |
| 570 | ||
| 571 | 3 | new Assertion(fn, msg).to.not.throw(type); |
| 572 | }; | |
| 573 | ||
| 574 | /** | |
| 575 | * # .operator(val, operator, val2, [message]) | |
| 576 | * | |
| 577 | * Compare two values using operator. | |
| 578 | * | |
| 579 | * assert.operator(1, '<', 2, 'everything is ok'); | |
| 580 | * assert.operator(1, '>', 2, 'this will fail'); | |
| 581 | * | |
| 582 | * @name operator | |
| 583 | * @param {*} object to test | |
| 584 | * @param {String} operator | |
| 585 | * @param {*} second object | |
| 586 | * @param {String} message | |
| 587 | * @api public | |
| 588 | */ | |
| 589 | ||
| 590 | 1 | assert.operator = function (val, operator, val2, msg) { |
| 591 | 15 | if (!~['==', '===', '>', '>=', '<', '<=', '!=', '!=='].indexOf(operator)) { |
| 592 | 1 | throw new Error('Invalid operator "' + operator + '"'); |
| 593 | } | |
| 594 | 14 | var test = new Assertion(eval(val + operator + val2), msg); |
| 595 | 14 | test.assert( |
| 596 | true === test.obj | |
| 597 | , 'expected ' + inspect(val) + ' to be ' + operator + ' ' + inspect(val2) | |
| 598 | , 'expected ' + inspect(val) + ' to not be ' + operator + ' ' + inspect(val2) ); | |
| 599 | }; | |
| 600 | ||
| 601 | /*! | |
| 602 | * Undocumented / untested | |
| 603 | */ | |
| 604 | ||
| 605 | 1 | assert.ifError = function (val, msg) { |
| 606 | 4 | new Assertion(val, msg).to.not.be.ok; |
| 607 | }; | |
| 608 | ||
| 609 | /*! | |
| 610 | * Aliases. | |
| 611 | */ | |
| 612 | ||
| 613 | 1 | (function alias(name, as){ |
| 614 | 2 | assert[as] = assert[name]; |
| 615 | 2 | return alias; |
| 616 | }) | |
| 617 | ('length', 'lengthOf') | |
| 618 | ('throws', 'throw'); | |
| 619 | }; |