UNPKG

83.5 kBJavaScriptView Raw
1'use strict';
2
3function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4
5var getType = _interopDefault(require('should-type'));
6var eql = _interopDefault(require('should-equal'));
7var sformat = _interopDefault(require('should-format'));
8var shouldTypeAdaptors = require('should-type-adaptors');
9var shouldUtil = require('should-util');
10
11/*
12 * should.js - assertion library
13 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
14 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
15 * MIT Licensed
16 */
17function isWrapperType(obj) {
18 return obj instanceof Number || obj instanceof String || obj instanceof Boolean;
19}
20
21// XXX make it more strict: numbers, strings, symbols - and nothing else
22function convertPropertyName(name) {
23 return typeof name === "symbol" ? name : String(name);
24}
25
26var functionName = sformat.functionName;
27
28function isPlainObject(obj) {
29 if (typeof obj == "object" && obj !== null) {
30 var proto = Object.getPrototypeOf(obj);
31 return proto === Object.prototype || proto === null;
32 }
33
34 return false;
35}
36
37/*
38 * should.js - assertion library
39 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
40 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
41 * MIT Licensed
42 */
43
44var config = {
45 typeAdaptors: shouldTypeAdaptors.defaultTypeAdaptorStorage,
46
47 getFormatter: function(opts) {
48 return new sformat.Formatter(opts || config);
49 }
50};
51
52function format(value, opts) {
53 return config.getFormatter(opts).format(value);
54}
55
56function formatProp(value) {
57 var formatter = config.getFormatter();
58 return sformat.formatPlainObjectKey.call(formatter, value);
59}
60
61/*
62 * should.js - assertion library
63 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
64 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
65 * MIT Licensed
66 */
67/**
68 * should AssertionError
69 * @param {Object} options
70 * @constructor
71 * @memberOf should
72 * @static
73 */
74function AssertionError(options) {
75 shouldUtil.merge(this, options);
76
77 if (!options.message) {
78 Object.defineProperty(this, "message", {
79 get: function() {
80 if (!this._message) {
81 this._message = this.generateMessage();
82 this.generatedMessage = true;
83 }
84 return this._message;
85 },
86 configurable: true,
87 enumerable: false
88 });
89 }
90
91 if (Error.captureStackTrace) {
92 Error.captureStackTrace(this, this.stackStartFunction);
93 } else {
94 // non v8 browsers so we can have a stacktrace
95 var err = new Error();
96 if (err.stack) {
97 var out = err.stack;
98
99 if (this.stackStartFunction) {
100 // try to strip useless frames
101 var fn_name = functionName(this.stackStartFunction);
102 var idx = out.indexOf("\n" + fn_name);
103 if (idx >= 0) {
104 // once we have located the function frame
105 // we need to strip out everything before it (and its line)
106 var next_line = out.indexOf("\n", idx + 1);
107 out = out.substring(next_line + 1);
108 }
109 }
110
111 this.stack = out;
112 }
113 }
114}
115
116var indent = " ";
117function prependIndent(line) {
118 return indent + line;
119}
120
121function indentLines(text) {
122 return text
123 .split("\n")
124 .map(prependIndent)
125 .join("\n");
126}
127
128// assert.AssertionError instanceof Error
129AssertionError.prototype = Object.create(Error.prototype, {
130 name: {
131 value: "AssertionError"
132 },
133
134 generateMessage: {
135 value: function() {
136 if (!this.operator && this.previous) {
137 return this.previous.message;
138 }
139 var actual = format(this.actual);
140 var expected = "expected" in this ? " " + format(this.expected) : "";
141 var details =
142 "details" in this && this.details ? " (" + this.details + ")" : "";
143
144 var previous = this.previous
145 ? "\n" + indentLines(this.previous.message)
146 : "";
147
148 return (
149 "expected " +
150 actual +
151 (this.negate ? " not " : " ") +
152 this.operator +
153 expected +
154 details +
155 previous
156 );
157 }
158 }
159});
160
161/*
162 * should.js - assertion library
163 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
164 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
165 * MIT Licensed
166 */
167
168// a bit hacky way how to get error to do not have stack
169function LightAssertionError(options) {
170 shouldUtil.merge(this, options);
171
172 if (!options.message) {
173 Object.defineProperty(this, "message", {
174 get: function() {
175 if (!this._message) {
176 this._message = this.generateMessage();
177 this.generatedMessage = true;
178 }
179 return this._message;
180 }
181 });
182 }
183}
184
185LightAssertionError.prototype = {
186 generateMessage: AssertionError.prototype.generateMessage
187};
188
189/**
190 * should Assertion
191 * @param {*} obj Given object for assertion
192 * @constructor
193 * @memberOf should
194 * @static
195 */
196function Assertion(obj) {
197 this.obj = obj;
198
199 this.anyOne = false;
200 this.negate = false;
201
202 this.params = { actual: obj };
203}
204
205Assertion.prototype = {
206 constructor: Assertion,
207
208 /**
209 * Base method for assertions.
210 *
211 * Before calling this method need to fill Assertion#params object. This method usually called from other assertion methods.
212 * `Assertion#params` can contain such properties:
213 * * `operator` - required string containing description of this assertion
214 * * `obj` - optional replacement for this.obj, it is useful if you prepare more clear object then given
215 * * `message` - if this property filled with string any others will be ignored and this one used as assertion message
216 * * `expected` - any object used when you need to assert relation between given object and expected. Like given == expected (== is a relation)
217 * * `details` - additional string with details to generated message
218 *
219 * @memberOf Assertion
220 * @category assertion
221 * @param {*} expr Any expression that will be used as a condition for asserting.
222 * @example
223 *
224 * var a = new should.Assertion(42);
225 *
226 * a.params = {
227 * operator: 'to be magic number',
228 * }
229 *
230 * a.assert(false);
231 * //throws AssertionError: expected 42 to be magic number
232 */
233 assert: function(expr) {
234 if (expr) {
235 return this;
236 }
237
238 var params = this.params;
239
240 if ("obj" in params && !("actual" in params)) {
241 params.actual = params.obj;
242 } else if (!("obj" in params) && !("actual" in params)) {
243 params.actual = this.obj;
244 }
245
246 params.stackStartFunction = params.stackStartFunction || this.assert;
247 params.negate = this.negate;
248
249 params.assertion = this;
250
251 if (this.light) {
252 throw new LightAssertionError(params);
253 } else {
254 throw new AssertionError(params);
255 }
256 },
257
258 /**
259 * Shortcut for `Assertion#assert(false)`.
260 *
261 * @memberOf Assertion
262 * @category assertion
263 * @example
264 *
265 * var a = new should.Assertion(42);
266 *
267 * a.params = {
268 * operator: 'to be magic number',
269 * }
270 *
271 * a.fail();
272 * //throws AssertionError: expected 42 to be magic number
273 */
274 fail: function() {
275 return this.assert(false);
276 },
277
278 assertZeroArguments: function(args) {
279 if (args.length !== 0) {
280 throw new TypeError("This assertion does not expect any arguments. You may need to check your code");
281 }
282 }
283};
284
285/**
286 * Assertion used to delegate calls of Assertion methods inside of Promise.
287 * It has almost all methods of Assertion.prototype
288 *
289 * @param {Promise} obj
290 */
291function PromisedAssertion(/* obj */) {
292 Assertion.apply(this, arguments);
293}
294
295/**
296 * Make PromisedAssertion to look like promise. Delegate resolve and reject to given promise.
297 *
298 * @private
299 * @returns {Promise}
300 */
301PromisedAssertion.prototype.then = function(resolve, reject) {
302 return this.obj.then(resolve, reject);
303};
304
305/**
306 * Way to extend Assertion function. It uses some logic
307 * to define only positive assertions and itself rule with negative assertion.
308 *
309 * All actions happen in subcontext and this method take care about negation.
310 * Potentially we can add some more modifiers that does not depends from state of assertion.
311 *
312 * @memberOf Assertion
313 * @static
314 * @param {String} name Name of assertion. It will be used for defining method or getter on Assertion.prototype
315 * @param {Function} func Function that will be called on executing assertion
316 * @example
317 *
318 * Assertion.add('asset', function() {
319 * this.params = { operator: 'to be asset' }
320 *
321 * this.obj.should.have.property('id').which.is.a.Number()
322 * this.obj.should.have.property('path')
323 * })
324 */
325Assertion.add = function(name, func) {
326 Object.defineProperty(Assertion.prototype, name, {
327 enumerable: true,
328 configurable: true,
329 value: function() {
330 var context = new Assertion(this.obj, this, name);
331 context.anyOne = this.anyOne;
332 context.onlyThis = this.onlyThis;
333 // hack
334 context.light = true;
335
336 try {
337 func.apply(context, arguments);
338 } catch (e) {
339 // check for fail
340 if (e instanceof AssertionError || e instanceof LightAssertionError) {
341 // negative fail
342 if (this.negate) {
343 this.obj = context.obj;
344 this.negate = false;
345 return this;
346 }
347
348 if (context !== e.assertion) {
349 context.params.previous = e;
350 }
351
352 // positive fail
353 context.negate = false;
354 // hack
355 context.light = false;
356 context.fail();
357 }
358 // throw if it is another exception
359 throw e;
360 }
361
362 // negative pass
363 if (this.negate) {
364 context.negate = true; // because .fail will set negate
365 context.params.details = "false negative fail";
366 // hack
367 context.light = false;
368 context.fail();
369 }
370
371 // positive pass
372 if (!this.params.operator) {
373 this.params = context.params; // shortcut
374 }
375 this.obj = context.obj;
376 this.negate = false;
377 return this;
378 }
379 });
380
381 Object.defineProperty(PromisedAssertion.prototype, name, {
382 enumerable: true,
383 configurable: true,
384 value: function() {
385 var args = arguments;
386 this.obj = this.obj.then(function(a) {
387 return a[name].apply(a, args);
388 });
389
390 return this;
391 }
392 });
393};
394
395/**
396 * Add chaining getter to Assertion like .a, .which etc
397 *
398 * @memberOf Assertion
399 * @static
400 * @param {string} name name of getter
401 * @param {function} [onCall] optional function to call
402 */
403Assertion.addChain = function(name, onCall) {
404 onCall = onCall || function() {};
405 Object.defineProperty(Assertion.prototype, name, {
406 get: function() {
407 onCall.call(this);
408 return this;
409 },
410 enumerable: true
411 });
412
413 Object.defineProperty(PromisedAssertion.prototype, name, {
414 enumerable: true,
415 configurable: true,
416 get: function() {
417 this.obj = this.obj.then(function(a) {
418 return a[name];
419 });
420
421 return this;
422 }
423 });
424};
425
426/**
427 * Create alias for some `Assertion` property
428 *
429 * @memberOf Assertion
430 * @static
431 * @param {String} from Name of to map
432 * @param {String} to Name of alias
433 * @example
434 *
435 * Assertion.alias('true', 'True')
436 */
437Assertion.alias = function(from, to) {
438 var desc = Object.getOwnPropertyDescriptor(Assertion.prototype, from);
439 if (!desc) {
440 throw new Error("Alias " + from + " -> " + to + " could not be created as " + from + " not defined");
441 }
442 Object.defineProperty(Assertion.prototype, to, desc);
443
444 var desc2 = Object.getOwnPropertyDescriptor(PromisedAssertion.prototype, from);
445 if (desc2) {
446 Object.defineProperty(PromisedAssertion.prototype, to, desc2);
447 }
448};
449/**
450 * Negation modifier. Current assertion chain become negated. Each call invert negation on current assertion.
451 *
452 * @name not
453 * @property
454 * @memberOf Assertion
455 * @category assertion
456 */
457Assertion.addChain("not", function() {
458 this.negate = !this.negate;
459});
460
461/**
462 * Any modifier - it affect on execution of sequenced assertion to do not `check all`, but `check any of`.
463 *
464 * @name any
465 * @property
466 * @memberOf Assertion
467 * @category assertion
468 */
469Assertion.addChain("any", function() {
470 this.anyOne = true;
471});
472
473/**
474 * Only modifier - currently used with .keys to check if object contains only exactly this .keys
475 *
476 * @name only
477 * @property
478 * @memberOf Assertion
479 * @category assertion
480 */
481Assertion.addChain("only", function() {
482 this.onlyThis = true;
483});
484
485// implement assert interface using already written peaces of should.js
486
487// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
488//
489// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
490//
491// Originally from narwhal.js (http://narwhaljs.org)
492// Copyright (c) 2009 Thomas Robinson <280north.com>
493//
494// Permission is hereby granted, free of charge, to any person obtaining a copy
495// of this software and associated documentation files (the 'Software'), to
496// deal in the Software without restriction, including without limitation the
497// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
498// sell copies of the Software, and to permit persons to whom the Software is
499// furnished to do so, subject to the following conditions:
500//
501// The above copyright notice and this permission notice shall be included in
502// all copies or substantial portions of the Software.
503//
504// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
505// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
506// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
507// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
508// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
509// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
510
511// when used in node, this will actually load the util module we depend on
512// versus loading the builtin util module as happens otherwise
513// this is a bug in node module loading as far as I am concerned
514var pSlice = Array.prototype.slice;
515
516// 1. The assert module provides functions that throw
517// AssertionError's when particular conditions are not met. The
518// assert module must conform to the following interface.
519
520var assert = ok;
521// 3. All of the following functions must throw an AssertionError
522// when a corresponding condition is not met, with a message that
523// may be undefined if not provided. All assertion methods provide
524// both the actual and expected values to the assertion error for
525// display purposes.
526/**
527 * Node.js standard [`assert.fail`](http://nodejs.org/api/assert.html#assert_assert_fail_actual_expected_message_operator).
528 * @static
529 * @memberOf should
530 * @category assertion assert
531 * @param {*} actual Actual object
532 * @param {*} expected Expected object
533 * @param {string} message Message for assertion
534 * @param {string} operator Operator text
535 */
536function fail(actual, expected, message, operator, stackStartFunction) {
537 var a = new Assertion(actual);
538 a.params = {
539 operator: operator,
540 expected: expected,
541 message: message,
542 stackStartFunction: stackStartFunction || fail
543 };
544
545 a.fail();
546}
547
548// EXTENSION! allows for well behaved errors defined elsewhere.
549assert.fail = fail;
550
551// 4. Pure assertion tests whether a value is truthy, as determined
552// by !!guard.
553// assert.ok(guard, message_opt);
554// This statement is equivalent to assert.equal(true, !!guard,
555// message_opt);. To test strictly for the value true, use
556// assert.strictEqual(true, guard, message_opt);.
557/**
558 * Node.js standard [`assert.ok`](http://nodejs.org/api/assert.html#assert_assert_value_message_assert_ok_value_message).
559 * @static
560 * @memberOf should
561 * @category assertion assert
562 * @param {*} value
563 * @param {string} [message]
564 */
565function ok(value, message) {
566 if (!value) {
567 fail(value, true, message, "==", assert.ok);
568 }
569}
570assert.ok = ok;
571
572// 5. The equality assertion tests shallow, coercive equality with
573// ==.
574// assert.equal(actual, expected, message_opt);
575
576/**
577 * Node.js standard [`assert.equal`](http://nodejs.org/api/assert.html#assert_assert_equal_actual_expected_message).
578 * @static
579 * @memberOf should
580 * @category assertion assert
581 * @param {*} actual
582 * @param {*} expected
583 * @param {string} [message]
584 */
585assert.equal = function equal(actual, expected, message) {
586 if (actual != expected) {
587 fail(actual, expected, message, "==", assert.equal);
588 }
589};
590
591// 6. The non-equality assertion tests for whether two objects are not equal
592// with != assert.notEqual(actual, expected, message_opt);
593/**
594 * Node.js standard [`assert.notEqual`](http://nodejs.org/api/assert.html#assert_assert_notequal_actual_expected_message).
595 * @static
596 * @memberOf should
597 * @category assertion assert
598 * @param {*} actual
599 * @param {*} expected
600 * @param {string} [message]
601 */
602assert.notEqual = function notEqual(actual, expected, message) {
603 if (actual == expected) {
604 fail(actual, expected, message, "!=", assert.notEqual);
605 }
606};
607
608// 7. The equivalence assertion tests a deep equality relation.
609// assert.deepEqual(actual, expected, message_opt);
610/**
611 * Node.js standard [`assert.deepEqual`](http://nodejs.org/api/assert.html#assert_assert_deepequal_actual_expected_message).
612 * But uses should.js .eql implementation instead of Node.js own deepEqual.
613 *
614 * @static
615 * @memberOf should
616 * @category assertion assert
617 * @param {*} actual
618 * @param {*} expected
619 * @param {string} [message]
620 */
621assert.deepEqual = function deepEqual(actual, expected, message) {
622 if (eql(actual, expected).length !== 0) {
623 fail(actual, expected, message, "deepEqual", assert.deepEqual);
624 }
625};
626
627// 8. The non-equivalence assertion tests for any deep inequality.
628// assert.notDeepEqual(actual, expected, message_opt);
629/**
630 * Node.js standard [`assert.notDeepEqual`](http://nodejs.org/api/assert.html#assert_assert_notdeepequal_actual_expected_message).
631 * But uses should.js .eql implementation instead of Node.js own deepEqual.
632 *
633 * @static
634 * @memberOf should
635 * @category assertion assert
636 * @param {*} actual
637 * @param {*} expected
638 * @param {string} [message]
639 */
640assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
641 if (eql(actual, expected).result) {
642 fail(actual, expected, message, "notDeepEqual", assert.notDeepEqual);
643 }
644};
645
646// 9. The strict equality assertion tests strict equality, as determined by ===.
647// assert.strictEqual(actual, expected, message_opt);
648/**
649 * Node.js standard [`assert.strictEqual`](http://nodejs.org/api/assert.html#assert_assert_strictequal_actual_expected_message).
650 * @static
651 * @memberOf should
652 * @category assertion assert
653 * @param {*} actual
654 * @param {*} expected
655 * @param {string} [message]
656 */
657assert.strictEqual = function strictEqual(actual, expected, message) {
658 if (actual !== expected) {
659 fail(actual, expected, message, "===", assert.strictEqual);
660 }
661};
662
663// 10. The strict non-equality assertion tests for strict inequality, as
664// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
665/**
666 * Node.js standard [`assert.notStrictEqual`](http://nodejs.org/api/assert.html#assert_assert_notstrictequal_actual_expected_message).
667 * @static
668 * @memberOf should
669 * @category assertion assert
670 * @param {*} actual
671 * @param {*} expected
672 * @param {string} [message]
673 */
674assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
675 if (actual === expected) {
676 fail(actual, expected, message, "!==", assert.notStrictEqual);
677 }
678};
679
680function expectedException(actual, expected) {
681 if (!actual || !expected) {
682 return false;
683 }
684
685 if (Object.prototype.toString.call(expected) == "[object RegExp]") {
686 return expected.test(actual);
687 } else if (actual instanceof expected) {
688 return true;
689 } else if (expected.call({}, actual) === true) {
690 return true;
691 }
692
693 return false;
694}
695
696function _throws(shouldThrow, block, expected, message) {
697 var actual;
698
699 if (typeof expected == "string") {
700 message = expected;
701 expected = null;
702 }
703
704 try {
705 block();
706 } catch (e) {
707 actual = e;
708 }
709
710 message =
711 (expected && expected.name ? " (" + expected.name + ")" : ".") +
712 (message ? " " + message : ".");
713
714 if (shouldThrow && !actual) {
715 fail(actual, expected, "Missing expected exception" + message);
716 }
717
718 if (!shouldThrow && expectedException(actual, expected)) {
719 fail(actual, expected, "Got unwanted exception" + message);
720 }
721
722 if (
723 (shouldThrow &&
724 actual &&
725 expected &&
726 !expectedException(actual, expected)) ||
727 (!shouldThrow && actual)
728 ) {
729 throw actual;
730 }
731}
732
733// 11. Expected to throw an error:
734// assert.throws(block, Error_opt, message_opt);
735/**
736 * Node.js standard [`assert.throws`](http://nodejs.org/api/assert.html#assert_assert_throws_block_error_message).
737 * @static
738 * @memberOf should
739 * @category assertion assert
740 * @param {Function} block
741 * @param {Function} [error]
742 * @param {String} [message]
743 */
744assert.throws = function(/*block, error, message*/) {
745 _throws.apply(this, [true].concat(pSlice.call(arguments)));
746};
747
748// EXTENSION! This is annoying to write outside this module.
749/**
750 * Node.js standard [`assert.doesNotThrow`](http://nodejs.org/api/assert.html#assert_assert_doesnotthrow_block_message).
751 * @static
752 * @memberOf should
753 * @category assertion assert
754 * @param {Function} block
755 * @param {String} [message]
756 */
757assert.doesNotThrow = function(/*block, message*/) {
758 _throws.apply(this, [false].concat(pSlice.call(arguments)));
759};
760
761/**
762 * Node.js standard [`assert.ifError`](http://nodejs.org/api/assert.html#assert_assert_iferror_value).
763 * @static
764 * @memberOf should
765 * @category assertion assert
766 * @param {Error} err
767 */
768assert.ifError = function(err) {
769 if (err) {
770 throw err;
771 }
772};
773
774/*
775 * should.js - assertion library
776 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
777 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
778 * MIT Licensed
779 */
780
781function assertExtensions(should) {
782 var i = should.format;
783
784 /*
785 * Expose assert to should
786 *
787 * This allows you to do things like below
788 * without require()ing the assert module.
789 *
790 * should.equal(foo.bar, undefined);
791 *
792 */
793 shouldUtil.merge(should, assert);
794
795 /**
796 * Assert _obj_ exists, with optional message.
797 *
798 * @static
799 * @memberOf should
800 * @category assertion assert
801 * @alias should.exists
802 * @param {*} obj
803 * @param {String} [msg]
804 * @example
805 *
806 * should.exist(1);
807 * should.exist(new Date());
808 */
809 should.exist = should.exists = function(obj, msg) {
810 if (null == obj) {
811 throw new AssertionError({
812 message: msg || "expected " + i(obj) + " to exist",
813 stackStartFunction: should.exist
814 });
815 }
816 };
817
818 should.not = {};
819 /**
820 * Asserts _obj_ does not exist, with optional message.
821 *
822 * @name not.exist
823 * @static
824 * @memberOf should
825 * @category assertion assert
826 * @alias should.not.exists
827 * @param {*} obj
828 * @param {String} [msg]
829 * @example
830 *
831 * should.not.exist(null);
832 * should.not.exist(void 0);
833 */
834 should.not.exist = should.not.exists = function(obj, msg) {
835 if (null != obj) {
836 throw new AssertionError({
837 message: msg || "expected " + i(obj) + " to not exist",
838 stackStartFunction: should.not.exist
839 });
840 }
841 };
842}
843
844/*
845 * should.js - assertion library
846 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
847 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
848 * MIT Licensed
849 */
850
851function chainAssertions(should, Assertion) {
852 /**
853 * Simple chaining to improve readability. Does nothing.
854 *
855 * @memberOf Assertion
856 * @name be
857 * @property {should.Assertion} be
858 * @alias Assertion#an
859 * @alias Assertion#of
860 * @alias Assertion#a
861 * @alias Assertion#and
862 * @alias Assertion#been
863 * @alias Assertion#have
864 * @alias Assertion#has
865 * @alias Assertion#with
866 * @alias Assertion#is
867 * @alias Assertion#which
868 * @alias Assertion#the
869 * @alias Assertion#it
870 * @category assertion chaining
871 */
872 [
873 "an",
874 "of",
875 "a",
876 "and",
877 "be",
878 "been",
879 "has",
880 "have",
881 "with",
882 "is",
883 "which",
884 "the",
885 "it"
886 ].forEach(function(name) {
887 Assertion.addChain(name);
888 });
889}
890
891/*
892 * should.js - assertion library
893 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
894 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
895 * MIT Licensed
896 */
897
898function booleanAssertions(should, Assertion) {
899 /**
900 * Assert given object is exactly `true`.
901 *
902 * @name true
903 * @memberOf Assertion
904 * @category assertion bool
905 * @alias Assertion#True
906 * @param {string} [message] Optional message
907 * @example
908 *
909 * (true).should.be.true();
910 * false.should.not.be.true();
911 *
912 * ({ a: 10}).should.not.be.true();
913 */
914 Assertion.add("true", function(message) {
915 this.is.exactly(true, message);
916 });
917
918 Assertion.alias("true", "True");
919
920 /**
921 * Assert given object is exactly `false`.
922 *
923 * @name false
924 * @memberOf Assertion
925 * @category assertion bool
926 * @alias Assertion#False
927 * @param {string} [message] Optional message
928 * @example
929 *
930 * (true).should.not.be.false();
931 * false.should.be.false();
932 */
933 Assertion.add("false", function(message) {
934 this.is.exactly(false, message);
935 });
936
937 Assertion.alias("false", "False");
938
939 /**
940 * Assert given object is truthy according javascript type conversions.
941 *
942 * @name ok
943 * @memberOf Assertion
944 * @category assertion bool
945 * @example
946 *
947 * (true).should.be.ok();
948 * ''.should.not.be.ok();
949 * should(null).not.be.ok();
950 * should(void 0).not.be.ok();
951 *
952 * (10).should.be.ok();
953 * (0).should.not.be.ok();
954 */
955 Assertion.add("ok", function() {
956 this.assertZeroArguments(arguments);
957 this.params = { operator: "to be truthy" };
958
959 this.assert(this.obj);
960 });
961}
962
963/*
964 * should.js - assertion library
965 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
966 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
967 * MIT Licensed
968 */
969
970function numberAssertions(should, Assertion) {
971 /**
972 * Assert given object is NaN
973 * @name NaN
974 * @memberOf Assertion
975 * @category assertion numbers
976 * @example
977 *
978 * (10).should.not.be.NaN();
979 * NaN.should.be.NaN();
980 */
981 Assertion.add("NaN", function() {
982 this.assertZeroArguments(arguments);
983 this.params = { operator: "to be NaN" };
984
985 this.assert(this.obj !== this.obj);
986 });
987
988 /**
989 * Assert given object is not finite (positive or negative)
990 *
991 * @name Infinity
992 * @memberOf Assertion
993 * @category assertion numbers
994 * @example
995 *
996 * (10).should.not.be.Infinity();
997 * NaN.should.not.be.Infinity();
998 */
999 Assertion.add("Infinity", function() {
1000 this.assertZeroArguments(arguments);
1001 this.params = { operator: "to be Infinity" };
1002
1003 this.is.a
1004 .Number()
1005 .and.not.a.NaN()
1006 .and.assert(!isFinite(this.obj));
1007 });
1008
1009 /**
1010 * Assert given number between `start` and `finish` or equal one of them.
1011 *
1012 * @name within
1013 * @memberOf Assertion
1014 * @category assertion numbers
1015 * @param {number} start Start number
1016 * @param {number} finish Finish number
1017 * @param {string} [description] Optional message
1018 * @example
1019 *
1020 * (10).should.be.within(0, 20);
1021 */
1022 Assertion.add("within", function(start, finish, description) {
1023 this.params = {
1024 operator: "to be within " + start + ".." + finish,
1025 message: description
1026 };
1027
1028 this.assert(this.obj >= start && this.obj <= finish);
1029 });
1030
1031 /**
1032 * Assert given number near some other `value` within `delta`
1033 *
1034 * @name approximately
1035 * @memberOf Assertion
1036 * @category assertion numbers
1037 * @param {number} value Center number
1038 * @param {number} delta Radius
1039 * @param {string} [description] Optional message
1040 * @example
1041 *
1042 * (9.99).should.be.approximately(10, 0.1);
1043 */
1044 Assertion.add("approximately", function(value, delta, description) {
1045 this.params = {
1046 operator: "to be approximately " + value + " ±" + delta,
1047 message: description
1048 };
1049
1050 this.assert(Math.abs(this.obj - value) <= delta);
1051 });
1052
1053 /**
1054 * Assert given number above `n`.
1055 *
1056 * @name above
1057 * @alias Assertion#greaterThan
1058 * @memberOf Assertion
1059 * @category assertion numbers
1060 * @param {number} n Margin number
1061 * @param {string} [description] Optional message
1062 * @example
1063 *
1064 * (10).should.be.above(0);
1065 */
1066 Assertion.add("above", function(n, description) {
1067 this.params = { operator: "to be above " + n, message: description };
1068
1069 this.assert(this.obj > n);
1070 });
1071
1072 /**
1073 * Assert given number below `n`.
1074 *
1075 * @name below
1076 * @alias Assertion#lessThan
1077 * @memberOf Assertion
1078 * @category assertion numbers
1079 * @param {number} n Margin number
1080 * @param {string} [description] Optional message
1081 * @example
1082 *
1083 * (0).should.be.below(10);
1084 */
1085 Assertion.add("below", function(n, description) {
1086 this.params = { operator: "to be below " + n, message: description };
1087
1088 this.assert(this.obj < n);
1089 });
1090
1091 Assertion.alias("above", "greaterThan");
1092 Assertion.alias("below", "lessThan");
1093
1094 /**
1095 * Assert given number above `n`.
1096 *
1097 * @name aboveOrEqual
1098 * @alias Assertion#greaterThanOrEqual
1099 * @memberOf Assertion
1100 * @category assertion numbers
1101 * @param {number} n Margin number
1102 * @param {string} [description] Optional message
1103 * @example
1104 *
1105 * (10).should.be.aboveOrEqual(0);
1106 * (10).should.be.aboveOrEqual(10);
1107 */
1108 Assertion.add("aboveOrEqual", function(n, description) {
1109 this.params = {
1110 operator: "to be above or equal " + n,
1111 message: description
1112 };
1113
1114 this.assert(this.obj >= n);
1115 });
1116
1117 /**
1118 * Assert given number below `n`.
1119 *
1120 * @name belowOrEqual
1121 * @alias Assertion#lessThanOrEqual
1122 * @memberOf Assertion
1123 * @category assertion numbers
1124 * @param {number} n Margin number
1125 * @param {string} [description] Optional message
1126 * @example
1127 *
1128 * (0).should.be.belowOrEqual(10);
1129 * (0).should.be.belowOrEqual(0);
1130 */
1131 Assertion.add("belowOrEqual", function(n, description) {
1132 this.params = {
1133 operator: "to be below or equal " + n,
1134 message: description
1135 };
1136
1137 this.assert(this.obj <= n);
1138 });
1139
1140 Assertion.alias("aboveOrEqual", "greaterThanOrEqual");
1141 Assertion.alias("belowOrEqual", "lessThanOrEqual");
1142}
1143
1144/*
1145 * should.js - assertion library
1146 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
1147 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
1148 * MIT Licensed
1149 */
1150
1151function typeAssertions(should, Assertion) {
1152 /**
1153 * Assert given object is number
1154 * @name Number
1155 * @memberOf Assertion
1156 * @category assertion types
1157 */
1158 Assertion.add("Number", function() {
1159 this.assertZeroArguments(arguments);
1160 this.params = { operator: "to be a number" };
1161
1162 this.have.type("number");
1163 });
1164
1165 /**
1166 * Assert given object is arguments
1167 * @name arguments
1168 * @alias Assertion#Arguments
1169 * @memberOf Assertion
1170 * @category assertion types
1171 */
1172 Assertion.add("arguments", function() {
1173 this.assertZeroArguments(arguments);
1174 this.params = { operator: "to be arguments" };
1175
1176 this.have.class("Arguments");
1177 });
1178
1179 Assertion.alias("arguments", "Arguments");
1180
1181 /**
1182 * Assert given object has some type using `typeof`
1183 * @name type
1184 * @memberOf Assertion
1185 * @param {string} type Type name
1186 * @param {string} [description] Optional message
1187 * @category assertion types
1188 */
1189 Assertion.add("type", function(type, description) {
1190 this.params = { operator: "to have type " + type, message: description };
1191
1192 should(typeof this.obj).be.exactly(type);
1193 });
1194
1195 /**
1196 * Assert given object is instance of `constructor`
1197 * @name instanceof
1198 * @alias Assertion#instanceOf
1199 * @memberOf Assertion
1200 * @param {Function} constructor Constructor function
1201 * @param {string} [description] Optional message
1202 * @category assertion types
1203 */
1204 Assertion.add("instanceof", function(constructor, description) {
1205 this.params = {
1206 operator: "to be an instance of " + functionName(constructor),
1207 message: description
1208 };
1209
1210 this.assert(Object(this.obj) instanceof constructor);
1211 });
1212
1213 Assertion.alias("instanceof", "instanceOf");
1214
1215 /**
1216 * Assert given object is function
1217 * @name Function
1218 * @memberOf Assertion
1219 * @category assertion types
1220 */
1221 Assertion.add("Function", function() {
1222 this.assertZeroArguments(arguments);
1223 this.params = { operator: "to be a function" };
1224
1225 this.have.type("function");
1226 });
1227
1228 /**
1229 * Assert given object is object
1230 * @name Object
1231 * @memberOf Assertion
1232 * @category assertion types
1233 */
1234 Assertion.add("Object", function() {
1235 this.assertZeroArguments(arguments);
1236 this.params = { operator: "to be an object" };
1237
1238 this.is.not.null().and.have.type("object");
1239 });
1240
1241 /**
1242 * Assert given object is string
1243 * @name String
1244 * @memberOf Assertion
1245 * @category assertion types
1246 */
1247 Assertion.add("String", function() {
1248 this.assertZeroArguments(arguments);
1249 this.params = { operator: "to be a string" };
1250
1251 this.have.type("string");
1252 });
1253
1254 /**
1255 * Assert given object is array
1256 * @name Array
1257 * @memberOf Assertion
1258 * @category assertion types
1259 */
1260 Assertion.add("Array", function() {
1261 this.assertZeroArguments(arguments);
1262 this.params = { operator: "to be an array" };
1263
1264 this.have.class("Array");
1265 });
1266
1267 /**
1268 * Assert given object is boolean
1269 * @name Boolean
1270 * @memberOf Assertion
1271 * @category assertion types
1272 */
1273 Assertion.add("Boolean", function() {
1274 this.assertZeroArguments(arguments);
1275 this.params = { operator: "to be a boolean" };
1276
1277 this.have.type("boolean");
1278 });
1279
1280 /**
1281 * Assert given object is error
1282 * @name Error
1283 * @memberOf Assertion
1284 * @category assertion types
1285 */
1286 Assertion.add("Error", function() {
1287 this.assertZeroArguments(arguments);
1288 this.params = { operator: "to be an error" };
1289
1290 this.have.instanceOf(Error);
1291 });
1292
1293 /**
1294 * Assert given object is a date
1295 * @name Date
1296 * @memberOf Assertion
1297 * @category assertion types
1298 */
1299 Assertion.add("Date", function() {
1300 this.assertZeroArguments(arguments);
1301 this.params = { operator: "to be a date" };
1302
1303 this.have.instanceOf(Date);
1304 });
1305
1306 /**
1307 * Assert given object is null
1308 * @name null
1309 * @alias Assertion#Null
1310 * @memberOf Assertion
1311 * @category assertion types
1312 */
1313 Assertion.add("null", function() {
1314 this.assertZeroArguments(arguments);
1315 this.params = { operator: "to be null" };
1316
1317 this.assert(this.obj === null);
1318 });
1319
1320 Assertion.alias("null", "Null");
1321
1322 /**
1323 * Assert given object has some internal [[Class]], via Object.prototype.toString call
1324 * @name class
1325 * @alias Assertion#Class
1326 * @memberOf Assertion
1327 * @category assertion types
1328 */
1329 Assertion.add("class", function(cls) {
1330 this.params = { operator: "to have [[Class]] " + cls };
1331
1332 this.assert(Object.prototype.toString.call(this.obj) === "[object " + cls + "]");
1333 });
1334
1335 Assertion.alias("class", "Class");
1336
1337 /**
1338 * Assert given object is undefined
1339 * @name undefined
1340 * @alias Assertion#Undefined
1341 * @memberOf Assertion
1342 * @category assertion types
1343 */
1344 Assertion.add("undefined", function() {
1345 this.assertZeroArguments(arguments);
1346 this.params = { operator: "to be undefined" };
1347
1348 this.assert(this.obj === void 0);
1349 });
1350
1351 Assertion.alias("undefined", "Undefined");
1352
1353 /**
1354 * Assert given object supports es6 iterable protocol (just check
1355 * that object has property Symbol.iterator, which is a function)
1356 * @name iterable
1357 * @memberOf Assertion
1358 * @category assertion es6
1359 */
1360 Assertion.add("iterable", function() {
1361 this.assertZeroArguments(arguments);
1362 this.params = { operator: "to be iterable" };
1363
1364 should(this.obj)
1365 .have.property(Symbol.iterator)
1366 .which.is.a.Function();
1367 });
1368
1369 /**
1370 * Assert given object supports es6 iterator protocol (just check
1371 * that object has property next, which is a function)
1372 * @name iterator
1373 * @memberOf Assertion
1374 * @category assertion es6
1375 */
1376 Assertion.add("iterator", function() {
1377 this.assertZeroArguments(arguments);
1378 this.params = { operator: "to be iterator" };
1379
1380 should(this.obj)
1381 .have.property("next")
1382 .which.is.a.Function();
1383 });
1384
1385 /**
1386 * Assert given object is a generator object
1387 * @name generator
1388 * @memberOf Assertion
1389 * @category assertion es6
1390 */
1391 Assertion.add("generator", function() {
1392 this.assertZeroArguments(arguments);
1393 this.params = { operator: "to be generator" };
1394
1395 should(this.obj).be.iterable.and.iterator.and.it.is.equal(this.obj[Symbol.iterator]());
1396 });
1397}
1398
1399/*
1400 * should.js - assertion library
1401 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
1402 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
1403 * MIT Licensed
1404 */
1405
1406function formatEqlResult(r, a, b) {
1407 return ((r.path.length > 0
1408 ? "at " + r.path.map(formatProp).join(" -> ")
1409 : "") +
1410 (r.a === a ? "" : ", A has " + format(r.a)) +
1411 (r.b === b ? "" : " and B has " + format(r.b)) +
1412 (r.showReason ? " because " + r.reason : "")).trim();
1413}
1414
1415function equalityAssertions(should, Assertion) {
1416 /**
1417 * Deep object equality comparison. For full spec see [`should-equal tests`](https://github.com/shouldjs/equal/blob/master/test.js).
1418 *
1419 * @name eql
1420 * @memberOf Assertion
1421 * @category assertion equality
1422 * @alias Assertion#eqls
1423 * @alias Assertion#deepEqual
1424 * @param {*} val Expected value
1425 * @param {string} [description] Optional message
1426 * @example
1427 *
1428 * (10).should.be.eql(10);
1429 * ('10').should.not.be.eql(10);
1430 * (-0).should.not.be.eql(+0);
1431 *
1432 * NaN.should.be.eql(NaN);
1433 *
1434 * ({ a: 10}).should.be.eql({ a: 10 });
1435 * [ 'a' ].should.not.be.eql({ '0': 'a' });
1436 */
1437 Assertion.add("eql", function(val, description) {
1438 this.params = { operator: "to equal", expected: val, message: description };
1439 var obj = this.obj;
1440 var fails = eql(this.obj, val, should.config);
1441 this.params.details = fails
1442 .map(function(fail) {
1443 return formatEqlResult(fail, obj, val);
1444 })
1445 .join(", ");
1446
1447 this.params.showDiff = eql(getType(obj), getType(val)).length === 0;
1448
1449 this.assert(fails.length === 0);
1450 });
1451
1452 /**
1453 * Exact comparison using ===.
1454 *
1455 * @name equal
1456 * @memberOf Assertion
1457 * @category assertion equality
1458 * @alias Assertion#equals
1459 * @alias Assertion#exactly
1460 * @param {*} val Expected value
1461 * @param {string} [description] Optional message
1462 * @example
1463 *
1464 * 10.should.be.equal(10);
1465 * 'a'.should.be.exactly('a');
1466 *
1467 * should(null).be.exactly(null);
1468 */
1469 Assertion.add("equal", function(val, description) {
1470 this.params = { operator: "to be", expected: val, message: description };
1471
1472 this.params.showDiff = eql(getType(this.obj), getType(val)).length === 0;
1473
1474 this.assert(val === this.obj);
1475 });
1476
1477 Assertion.alias("equal", "equals");
1478 Assertion.alias("equal", "exactly");
1479 Assertion.alias("eql", "eqls");
1480 Assertion.alias("eql", "deepEqual");
1481
1482 function addOneOf(name, message, method) {
1483 Assertion.add(name, function(vals) {
1484 if (arguments.length !== 1) {
1485 vals = Array.prototype.slice.call(arguments);
1486 } else {
1487 should(vals).be.Array();
1488 }
1489
1490 this.params = { operator: message, expected: vals };
1491
1492 var obj = this.obj;
1493 var found = false;
1494
1495 shouldTypeAdaptors.forEach(vals, function(val) {
1496 try {
1497 should(val)[method](obj);
1498 found = true;
1499 return false;
1500 } catch (e) {
1501 if (e instanceof should.AssertionError) {
1502 return; //do nothing
1503 }
1504 throw e;
1505 }
1506 });
1507
1508 this.assert(found);
1509 });
1510 }
1511
1512 /**
1513 * Exact comparison using === to be one of supplied objects.
1514 *
1515 * @name equalOneOf
1516 * @memberOf Assertion
1517 * @category assertion equality
1518 * @param {Array|*} vals Expected values
1519 * @example
1520 *
1521 * 'ab'.should.be.equalOneOf('a', 10, 'ab');
1522 * 'ab'.should.be.equalOneOf(['a', 10, 'ab']);
1523 */
1524 addOneOf("equalOneOf", "to be equals one of", "equal");
1525
1526 /**
1527 * Exact comparison using .eql to be one of supplied objects.
1528 *
1529 * @name oneOf
1530 * @memberOf Assertion
1531 * @category assertion equality
1532 * @param {Array|*} vals Expected values
1533 * @example
1534 *
1535 * ({a: 10}).should.be.oneOf('a', 10, 'ab', {a: 10});
1536 * ({a: 10}).should.be.oneOf(['a', 10, 'ab', {a: 10}]);
1537 */
1538 addOneOf("oneOf", "to be one of", "eql");
1539}
1540
1541/*
1542 * should.js - assertion library
1543 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
1544 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
1545 * MIT Licensed
1546 */
1547
1548function promiseAssertions(should, Assertion$$1) {
1549 /**
1550 * Assert given object is a Promise
1551 *
1552 * @name Promise
1553 * @memberOf Assertion
1554 * @category assertion promises
1555 * @example
1556 *
1557 * promise.should.be.Promise()
1558 * (new Promise(function(resolve, reject) { resolve(10); })).should.be.a.Promise()
1559 * (10).should.not.be.a.Promise()
1560 */
1561 Assertion$$1.add("Promise", function() {
1562 this.assertZeroArguments(arguments);
1563 this.params = { operator: "to be promise" };
1564
1565 var obj = this.obj;
1566
1567 should(obj)
1568 .have.property("then")
1569 .which.is.a.Function();
1570 });
1571
1572 /**
1573 * Assert given promise will be fulfilled. Result of assertion is still .thenable and should be handled accordingly.
1574 *
1575 * @name fulfilled
1576 * @memberOf Assertion
1577 * @alias Assertion#resolved
1578 * @returns {Promise}
1579 * @category assertion promises
1580 * @example
1581 *
1582 * // don't forget to handle async nature
1583 * (new Promise(function(resolve, reject) { resolve(10); })).should.be.fulfilled();
1584 *
1585 * // test example with mocha it is possible to return promise
1586 * it('is async', () => {
1587 * return new Promise(resolve => resolve(10))
1588 * .should.be.fulfilled();
1589 * });
1590 */
1591 Assertion$$1.prototype.fulfilled = function Assertion$fulfilled() {
1592 this.assertZeroArguments(arguments);
1593 this.params = { operator: "to be fulfilled" };
1594
1595 should(this.obj).be.a.Promise();
1596
1597 var that = this;
1598 return this.obj.then(
1599 function next$onResolve(value) {
1600 if (that.negate) {
1601 that.fail();
1602 }
1603 return value;
1604 },
1605 function next$onReject(err) {
1606 if (!that.negate) {
1607 that.params.operator += ", but it was rejected with " + should.format(err);
1608 that.fail();
1609 }
1610 return err;
1611 }
1612 );
1613 };
1614
1615 Assertion$$1.prototype.resolved = Assertion$$1.prototype.fulfilled;
1616
1617 /**
1618 * Assert given promise will be rejected. Result of assertion is still .thenable and should be handled accordingly.
1619 *
1620 * @name rejected
1621 * @memberOf Assertion
1622 * @category assertion promises
1623 * @returns {Promise}
1624 * @example
1625 *
1626 * // don't forget to handle async nature
1627 * (new Promise(function(resolve, reject) { resolve(10); }))
1628 * .should.not.be.rejected();
1629 *
1630 * // test example with mocha it is possible to return promise
1631 * it('is async', () => {
1632 * return new Promise((resolve, reject) => reject(new Error('boom')))
1633 * .should.be.rejected();
1634 * });
1635 */
1636 Assertion$$1.prototype.rejected = function() {
1637 this.assertZeroArguments(arguments);
1638 this.params = { operator: "to be rejected" };
1639
1640 should(this.obj).be.a.Promise();
1641
1642 var that = this;
1643 return this.obj.then(
1644 function(value) {
1645 if (!that.negate) {
1646 that.params.operator += ", but it was fulfilled";
1647 if (arguments.length != 0) {
1648 that.params.operator += " with " + should.format(value);
1649 }
1650 that.fail();
1651 }
1652 return value;
1653 },
1654 function next$onError(err) {
1655 if (that.negate) {
1656 that.fail();
1657 }
1658 return err;
1659 }
1660 );
1661 };
1662
1663 /**
1664 * Assert given promise will be fulfilled with some expected value (value compared using .eql).
1665 * Result of assertion is still .thenable and should be handled accordingly.
1666 *
1667 * @name fulfilledWith
1668 * @memberOf Assertion
1669 * @alias Assertion#resolvedWith
1670 * @category assertion promises
1671 * @returns {Promise}
1672 * @example
1673 *
1674 * // don't forget to handle async nature
1675 * (new Promise(function(resolve, reject) { resolve(10); }))
1676 * .should.be.fulfilledWith(10);
1677 *
1678 * // test example with mocha it is possible to return promise
1679 * it('is async', () => {
1680 * return new Promise((resolve, reject) => resolve(10))
1681 * .should.be.fulfilledWith(10);
1682 * });
1683 */
1684 Assertion$$1.prototype.fulfilledWith = function(expectedValue) {
1685 this.params = {
1686 operator: "to be fulfilled with " + should.format(expectedValue)
1687 };
1688
1689 should(this.obj).be.a.Promise();
1690
1691 var that = this;
1692 return this.obj.then(
1693 function(value) {
1694 if (that.negate) {
1695 that.fail();
1696 }
1697 should(value).eql(expectedValue);
1698 return value;
1699 },
1700 function next$onError(err) {
1701 if (!that.negate) {
1702 that.params.operator += ", but it was rejected with " + should.format(err);
1703 that.fail();
1704 }
1705 return err;
1706 }
1707 );
1708 };
1709
1710 Assertion$$1.prototype.resolvedWith = Assertion$$1.prototype.fulfilledWith;
1711
1712 /**
1713 * Assert given promise will be rejected with some sort of error. Arguments is the same for Assertion#throw.
1714 * Result of assertion is still .thenable and should be handled accordingly.
1715 *
1716 * @name rejectedWith
1717 * @memberOf Assertion
1718 * @category assertion promises
1719 * @returns {Promise}
1720 * @example
1721 *
1722 * function failedPromise() {
1723 * return new Promise(function(resolve, reject) {
1724 * reject(new Error('boom'))
1725 * })
1726 * }
1727 * failedPromise().should.be.rejectedWith(Error);
1728 * failedPromise().should.be.rejectedWith('boom');
1729 * failedPromise().should.be.rejectedWith(/boom/);
1730 * failedPromise().should.be.rejectedWith(Error, { message: 'boom' });
1731 * failedPromise().should.be.rejectedWith({ message: 'boom' });
1732 *
1733 * // test example with mocha it is possible to return promise
1734 * it('is async', () => {
1735 * return failedPromise().should.be.rejectedWith({ message: 'boom' });
1736 * });
1737 */
1738 Assertion$$1.prototype.rejectedWith = function(message, properties) {
1739 this.params = { operator: "to be rejected" };
1740
1741 should(this.obj).be.a.Promise();
1742
1743 var that = this;
1744 return this.obj.then(
1745 function(value) {
1746 if (!that.negate) {
1747 that.fail();
1748 }
1749 return value;
1750 },
1751 function next$onError(err) {
1752 if (that.negate) {
1753 that.fail();
1754 }
1755
1756 var errorMatched = true;
1757 var errorInfo = "";
1758
1759 if ("string" === typeof message) {
1760 errorMatched = message === err.message;
1761 } else if (message instanceof RegExp) {
1762 errorMatched = message.test(err.message);
1763 } else if ("function" === typeof message) {
1764 errorMatched = err instanceof message;
1765 } else if (message !== null && typeof message === "object") {
1766 try {
1767 should(err).match(message);
1768 } catch (e) {
1769 if (e instanceof should.AssertionError) {
1770 errorInfo = ": " + e.message;
1771 errorMatched = false;
1772 } else {
1773 throw e;
1774 }
1775 }
1776 }
1777
1778 if (!errorMatched) {
1779 if (typeof message === "string" || message instanceof RegExp) {
1780 errorInfo = " with a message matching " + should.format(message) + ", but got '" + err.message + "'";
1781 } else if ("function" === typeof message) {
1782 errorInfo = " of type " + functionName(message) + ", but got " + functionName(err.constructor);
1783 }
1784 } else if ("function" === typeof message && properties) {
1785 try {
1786 should(err).match(properties);
1787 } catch (e) {
1788 if (e instanceof should.AssertionError) {
1789 errorInfo = ": " + e.message;
1790 errorMatched = false;
1791 } else {
1792 throw e;
1793 }
1794 }
1795 }
1796
1797 that.params.operator += errorInfo;
1798
1799 that.assert(errorMatched);
1800
1801 return err;
1802 }
1803 );
1804 };
1805
1806 /**
1807 * Assert given object is promise and wrap it in PromisedAssertion, which has all properties of Assertion.
1808 * That means you can chain as with usual Assertion.
1809 * Result of assertion is still .thenable and should be handled accordingly.
1810 *
1811 * @name finally
1812 * @memberOf Assertion
1813 * @alias Assertion#eventually
1814 * @category assertion promises
1815 * @returns {PromisedAssertion} Like Assertion, but .then this.obj in Assertion
1816 * @example
1817 *
1818 * (new Promise(function(resolve, reject) { resolve(10); }))
1819 * .should.be.eventually.equal(10);
1820 *
1821 * // test example with mocha it is possible to return promise
1822 * it('is async', () => {
1823 * return new Promise(resolve => resolve(10))
1824 * .should.be.finally.equal(10);
1825 * });
1826 */
1827 Object.defineProperty(Assertion$$1.prototype, "finally", {
1828 get: function() {
1829 should(this.obj).be.a.Promise();
1830
1831 var that = this;
1832
1833 return new PromisedAssertion(
1834 this.obj.then(function(obj) {
1835 var a = should(obj);
1836
1837 a.negate = that.negate;
1838 a.anyOne = that.anyOne;
1839
1840 return a;
1841 })
1842 );
1843 }
1844 });
1845
1846 Assertion$$1.alias("finally", "eventually");
1847}
1848
1849/*
1850 * should.js - assertion library
1851 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
1852 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
1853 * MIT Licensed
1854 */
1855
1856function stringAssertions(should, Assertion) {
1857 /**
1858 * Assert given string starts with prefix
1859 * @name startWith
1860 * @memberOf Assertion
1861 * @category assertion strings
1862 * @param {string} str Prefix
1863 * @param {string} [description] Optional message
1864 * @example
1865 *
1866 * 'abc'.should.startWith('a');
1867 */
1868 Assertion.add("startWith", function(str, description) {
1869 this.params = {
1870 operator: "to start with " + should.format(str),
1871 message: description
1872 };
1873
1874 this.assert(0 === this.obj.indexOf(str));
1875 });
1876
1877 /**
1878 * Assert given string ends with prefix
1879 * @name endWith
1880 * @memberOf Assertion
1881 * @category assertion strings
1882 * @param {string} str Prefix
1883 * @param {string} [description] Optional message
1884 * @example
1885 *
1886 * 'abca'.should.endWith('a');
1887 */
1888 Assertion.add("endWith", function(str, description) {
1889 this.params = {
1890 operator: "to end with " + should.format(str),
1891 message: description
1892 };
1893
1894 this.assert(this.obj.indexOf(str, this.obj.length - str.length) >= 0);
1895 });
1896}
1897
1898/*
1899 * should.js - assertion library
1900 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
1901 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
1902 * MIT Licensed
1903 */
1904
1905function containAssertions(should, Assertion) {
1906 var i = should.format;
1907
1908 /**
1909 * Assert that given object contain something that equal to `other`. It uses `should-equal` for equality checks.
1910 * If given object is array it search that one of elements was equal to `other`.
1911 * If given object is string it checks if `other` is a substring - expected that `other` is a string.
1912 * If given object is Object it checks that `other` is a subobject - expected that `other` is a object.
1913 *
1914 * @name containEql
1915 * @memberOf Assertion
1916 * @category assertion contain
1917 * @param {*} other Nested object
1918 * @example
1919 *
1920 * [1, 2, 3].should.containEql(1);
1921 * [{ a: 1 }, 'a', 10].should.containEql({ a: 1 });
1922 *
1923 * 'abc'.should.containEql('b');
1924 * 'ab1c'.should.containEql(1);
1925 *
1926 * ({ a: 10, c: { d: 10 }}).should.containEql({ a: 10 });
1927 * ({ a: 10, c: { d: 10 }}).should.containEql({ c: { d: 10 }});
1928 * ({ a: 10, c: { d: 10 }}).should.containEql({ b: 10 });
1929 * // throws AssertionError: expected { a: 10, c: { d: 10 } } to contain { b: 10 }
1930 * // expected { a: 10, c: { d: 10 } } to have property b
1931 */
1932 Assertion.add("containEql", function(other) {
1933 this.params = { operator: "to contain " + i(other) };
1934
1935 this.is.not.null().and.not.undefined();
1936
1937 var obj = this.obj;
1938
1939 if (typeof obj == "string") {
1940 this.assert(obj.indexOf(String(other)) >= 0);
1941 } else if (shouldTypeAdaptors.isIterable(obj)) {
1942 this.assert(
1943 shouldTypeAdaptors.some(obj, function(v) {
1944 return eql(v, other).length === 0;
1945 })
1946 );
1947 } else {
1948 shouldTypeAdaptors.forEach(
1949 other,
1950 function(value, key) {
1951 should(obj).have.value(key, value);
1952 },
1953 this
1954 );
1955 }
1956 });
1957
1958 /**
1959 * Assert that given object is contain equally structured object on the same depth level.
1960 * If given object is an array and `other` is an array it checks that the eql elements is going in the same sequence in given array (recursive)
1961 * If given object is an object it checks that the same keys contain deep equal values (recursive)
1962 * On other cases it try to check with `.eql`
1963 *
1964 * @name containDeepOrdered
1965 * @memberOf Assertion
1966 * @category assertion contain
1967 * @param {*} other Nested object
1968 * @example
1969 *
1970 * [ 1, 2, 3].should.containDeepOrdered([1, 2]);
1971 * [ 1, 2, [ 1, 2, 3 ]].should.containDeepOrdered([ 1, [ 2, 3 ]]);
1972 *
1973 * ({ a: 10, b: { c: 10, d: [1, 2, 3] }}).should.containDeepOrdered({a: 10});
1974 * ({ a: 10, b: { c: 10, d: [1, 2, 3] }}).should.containDeepOrdered({b: {c: 10}});
1975 * ({ a: 10, b: { c: 10, d: [1, 2, 3] }}).should.containDeepOrdered({b: {d: [1, 3]}});
1976 */
1977 Assertion.add("containDeepOrdered", function(other) {
1978 this.params = { operator: "to contain " + i(other) };
1979
1980 var obj = this.obj;
1981 if (typeof obj == "string") {
1982 // expect other to be string
1983 this.is.equal(String(other));
1984 } else if (shouldTypeAdaptors.isIterable(obj) && shouldTypeAdaptors.isIterable(other)) {
1985 var objIterator = shouldTypeAdaptors.iterator(obj);
1986 var otherIterator = shouldTypeAdaptors.iterator(other);
1987
1988 var nextObj = objIterator.next();
1989 var nextOther = otherIterator.next();
1990 while (!nextObj.done && !nextOther.done) {
1991 try {
1992 should(nextObj.value[1]).containDeepOrdered(nextOther.value[1]);
1993 nextOther = otherIterator.next();
1994 } catch (e) {
1995 if (!(e instanceof should.AssertionError)) {
1996 throw e;
1997 }
1998 }
1999 nextObj = objIterator.next();
2000 }
2001
2002 this.assert(nextOther.done);
2003 } else if (obj != null && typeof obj == "object" && other != null && typeof other == "object") {
2004 //TODO compare types object contains object case
2005 shouldTypeAdaptors.forEach(other, function(value, key) {
2006 should(obj[key]).containDeepOrdered(value);
2007 });
2008
2009 // if both objects is empty means we finish traversing - and we need to compare for hidden values
2010 if (shouldTypeAdaptors.isEmpty(other)) {
2011 this.eql(other);
2012 }
2013 } else {
2014 this.eql(other);
2015 }
2016 });
2017
2018 /**
2019 * The same like `Assertion#containDeepOrdered` but all checks on arrays without order.
2020 *
2021 * @name containDeep
2022 * @memberOf Assertion
2023 * @category assertion contain
2024 * @param {*} other Nested object
2025 * @example
2026 *
2027 * [ 1, 2, 3].should.containDeep([2, 1]);
2028 * [ 1, 2, [ 1, 2, 3 ]].should.containDeep([ 1, [ 3, 1 ]]);
2029 */
2030 Assertion.add("containDeep", function(other) {
2031 this.params = { operator: "to contain " + i(other) };
2032
2033 var obj = this.obj;
2034 if (typeof obj === "string" && typeof other === "string") {
2035 // expect other to be string
2036 this.is.equal(String(other));
2037 } else if (shouldTypeAdaptors.isIterable(obj) && shouldTypeAdaptors.isIterable(other)) {
2038 var usedKeys = {};
2039 shouldTypeAdaptors.forEach(
2040 other,
2041 function(otherItem) {
2042 this.assert(
2043 shouldTypeAdaptors.some(obj, function(item, index) {
2044 if (index in usedKeys) {
2045 return false;
2046 }
2047
2048 try {
2049 should(item).containDeep(otherItem);
2050 usedKeys[index] = true;
2051 return true;
2052 } catch (e) {
2053 if (e instanceof should.AssertionError) {
2054 return false;
2055 }
2056 throw e;
2057 }
2058 })
2059 );
2060 },
2061 this
2062 );
2063 } else if (obj != null && other != null && typeof obj == "object" && typeof other == "object") {
2064 // object contains object case
2065 shouldTypeAdaptors.forEach(other, function(value, key) {
2066 should(obj[key]).containDeep(value);
2067 });
2068
2069 // if both objects is empty means we finish traversing - and we need to compare for hidden values
2070 if (shouldTypeAdaptors.isEmpty(other)) {
2071 this.eql(other);
2072 }
2073 } else {
2074 this.eql(other);
2075 }
2076 });
2077}
2078
2079/*
2080 * should.js - assertion library
2081 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
2082 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
2083 * MIT Licensed
2084 */
2085
2086var aSlice = Array.prototype.slice;
2087
2088function propertyAssertions(should, Assertion) {
2089 var i = should.format;
2090 /**
2091 * Asserts given object has some descriptor. **On success it change given object to be value of property**.
2092 *
2093 * @name propertyWithDescriptor
2094 * @memberOf Assertion
2095 * @category assertion property
2096 * @param {string} name Name of property
2097 * @param {Object} desc Descriptor like used in Object.defineProperty (not required to add all properties)
2098 * @example
2099 *
2100 * ({ a: 10 }).should.have.propertyWithDescriptor('a', { enumerable: true });
2101 */
2102 Assertion.add("propertyWithDescriptor", function(name, desc) {
2103 this.params = {
2104 actual: this.obj,
2105 operator: "to have own property with descriptor " + i(desc)
2106 };
2107 var obj = this.obj;
2108 this.have.ownProperty(name);
2109 should(Object.getOwnPropertyDescriptor(Object(obj), name)).have.properties(desc);
2110 });
2111
2112 /**
2113 * Asserts given object has property with optionally value. **On success it change given object to be value of property**.
2114 *
2115 * @name property
2116 * @memberOf Assertion
2117 * @category assertion property
2118 * @param {string} name Name of property
2119 * @param {*} [val] Optional property value to check
2120 * @example
2121 *
2122 * ({ a: 10 }).should.have.property('a');
2123 */
2124 Assertion.add("property", function(name, val) {
2125 name = convertPropertyName(name);
2126 if (arguments.length > 1) {
2127 var p = {};
2128 p[name] = val;
2129 this.have.properties(p);
2130 } else {
2131 this.have.properties(name);
2132 }
2133 this.obj = this.obj[name];
2134 });
2135
2136 /**
2137 * Asserts given object has properties. On this method affect .any modifier, which allow to check not all properties.
2138 *
2139 * @name properties
2140 * @memberOf Assertion
2141 * @category assertion property
2142 * @param {Array|...string|Object} names Names of property
2143 * @example
2144 *
2145 * ({ a: 10 }).should.have.properties('a');
2146 * ({ a: 10, b: 20 }).should.have.properties([ 'a' ]);
2147 * ({ a: 10, b: 20 }).should.have.properties({ b: 20 });
2148 */
2149 Assertion.add("properties", function(names) {
2150 var values = {};
2151 if (arguments.length > 1) {
2152 names = aSlice.call(arguments);
2153 } else if (!Array.isArray(names)) {
2154 if (typeof names == "string" || typeof names == "symbol") {
2155 names = [names];
2156 } else {
2157 values = names;
2158 names = Object.keys(names);
2159 }
2160 }
2161
2162 var obj = Object(this.obj),
2163 missingProperties = [];
2164
2165 //just enumerate properties and check if they all present
2166 names.forEach(function(name) {
2167 if (!(name in obj)) {
2168 missingProperties.push(formatProp(name));
2169 }
2170 });
2171
2172 var props = missingProperties;
2173 if (props.length === 0) {
2174 props = names.map(formatProp);
2175 } else if (this.anyOne) {
2176 props = names
2177 .filter(function(name) {
2178 return missingProperties.indexOf(formatProp(name)) < 0;
2179 })
2180 .map(formatProp);
2181 }
2182
2183 var operator =
2184 (props.length === 1
2185 ? "to have property "
2186 : "to have " + (this.anyOne ? "any of " : "") + "properties ") + props.join(", ");
2187
2188 this.params = { obj: this.obj, operator: operator };
2189
2190 //check that all properties presented
2191 //or if we request one of them that at least one them presented
2192 this.assert(
2193 missingProperties.length === 0 || (this.anyOne && missingProperties.length != names.length)
2194 );
2195
2196 // check if values in object matched expected
2197 var valueCheckNames = Object.keys(values);
2198 if (valueCheckNames.length) {
2199 var wrongValues = [];
2200 props = [];
2201
2202 // now check values, as there we have all properties
2203 valueCheckNames.forEach(function(name) {
2204 var value = values[name];
2205 if (eql(obj[name], value).length !== 0) {
2206 wrongValues.push(formatProp(name) + " of " + i(value) + " (got " + i(obj[name]) + ")");
2207 } else {
2208 props.push(formatProp(name) + " of " + i(value));
2209 }
2210 });
2211
2212 if ((wrongValues.length !== 0 && !this.anyOne) || (this.anyOne && props.length === 0)) {
2213 props = wrongValues;
2214 }
2215
2216 operator =
2217 (props.length === 1
2218 ? "to have property "
2219 : "to have " + (this.anyOne ? "any of " : "") + "properties ") + props.join(", ");
2220
2221 this.params = { obj: this.obj, operator: operator };
2222
2223 //if there is no not matched values
2224 //or there is at least one matched
2225 this.assert(
2226 wrongValues.length === 0 || (this.anyOne && wrongValues.length != valueCheckNames.length)
2227 );
2228 }
2229 });
2230
2231 /**
2232 * Asserts given object has property `length` with given value `n`
2233 *
2234 * @name length
2235 * @alias Assertion#lengthOf
2236 * @memberOf Assertion
2237 * @category assertion property
2238 * @param {number} n Expected length
2239 * @param {string} [description] Optional message
2240 * @example
2241 *
2242 * [1, 2].should.have.length(2);
2243 */
2244 Assertion.add("length", function(n, description) {
2245 this.have.property("length", n, description);
2246 });
2247
2248 Assertion.alias("length", "lengthOf");
2249
2250 /**
2251 * Asserts given object has own property. **On success it change given object to be value of property**.
2252 *
2253 * @name ownProperty
2254 * @alias Assertion#hasOwnProperty
2255 * @memberOf Assertion
2256 * @category assertion property
2257 * @param {string} name Name of property
2258 * @param {string} [description] Optional message
2259 * @example
2260 *
2261 * ({ a: 10 }).should.have.ownProperty('a');
2262 */
2263 Assertion.add("ownProperty", function(name, description) {
2264 name = convertPropertyName(name);
2265 this.params = {
2266 actual: this.obj,
2267 operator: "to have own property " + formatProp(name),
2268 message: description
2269 };
2270
2271 this.assert(shouldUtil.hasOwnProperty(this.obj, name));
2272
2273 this.obj = this.obj[name];
2274 });
2275
2276 Assertion.alias("ownProperty", "hasOwnProperty");
2277
2278 /**
2279 * Asserts given object is empty. For strings, arrays and arguments it checks .length property, for objects it checks keys.
2280 *
2281 * @name empty
2282 * @memberOf Assertion
2283 * @category assertion property
2284 * @example
2285 *
2286 * ''.should.be.empty();
2287 * [].should.be.empty();
2288 * ({}).should.be.empty();
2289 */
2290 Assertion.add(
2291 "empty",
2292 function() {
2293 this.params = { operator: "to be empty" };
2294 this.assert(shouldTypeAdaptors.isEmpty(this.obj));
2295 },
2296 true
2297 );
2298
2299 /**
2300 * Asserts given object has such keys. Compared to `properties`, `keys` does not accept Object as a argument.
2301 * When calling via .key current object in assertion changed to value of this key
2302 *
2303 * @name keys
2304 * @alias Assertion#key
2305 * @memberOf Assertion
2306 * @category assertion property
2307 * @param {...*} keys Keys to check
2308 * @example
2309 *
2310 * ({ a: 10 }).should.have.keys('a');
2311 * ({ a: 10, b: 20 }).should.have.keys('a', 'b');
2312 * (new Map([[1, 2]])).should.have.key(1);
2313 *
2314 * json.should.have.only.keys('type', 'version')
2315 */
2316 Assertion.add("keys", function(keys) {
2317 keys = aSlice.call(arguments);
2318
2319 var obj = Object(this.obj);
2320
2321 // first check if some keys are missing
2322 var missingKeys = keys.filter(function(key) {
2323 return !shouldTypeAdaptors.has(obj, key);
2324 });
2325
2326 var verb = "to have " + (this.onlyThis ? "only " : "") + (keys.length === 1 ? "key " : "keys ");
2327
2328 this.params = { operator: verb + keys.join(", ") };
2329
2330 if (missingKeys.length > 0) {
2331 this.params.operator += "\n\tmissing keys: " + missingKeys.join(", ");
2332 }
2333
2334 this.assert(missingKeys.length === 0);
2335
2336 if (this.onlyThis) {
2337 should(obj).have.size(keys.length);
2338 }
2339 });
2340
2341 Assertion.add("key", function(key) {
2342 this.have.keys(key);
2343 this.obj = shouldTypeAdaptors.get(this.obj, key);
2344 });
2345
2346 /**
2347 * Asserts given object has such value for given key
2348 *
2349 * @name value
2350 * @memberOf Assertion
2351 * @category assertion property
2352 * @param {*} key Key to check
2353 * @param {*} value Value to check
2354 * @example
2355 *
2356 * ({ a: 10 }).should.have.value('a', 10);
2357 * (new Map([[1, 2]])).should.have.value(1, 2);
2358 */
2359 Assertion.add("value", function(key, value) {
2360 this.have.key(key).which.is.eql(value);
2361 });
2362
2363 /**
2364 * Asserts given object has such size.
2365 *
2366 * @name size
2367 * @memberOf Assertion
2368 * @category assertion property
2369 * @param {number} s Size to check
2370 * @example
2371 *
2372 * ({ a: 10 }).should.have.size(1);
2373 * (new Map([[1, 2]])).should.have.size(1);
2374 */
2375 Assertion.add("size", function(s) {
2376 this.params = { operator: "to have size " + s };
2377 should(shouldTypeAdaptors.size(this.obj)).be.exactly(s);
2378 });
2379
2380 /**
2381 * Asserts given object has nested property in depth by path. **On success it change given object to be value of final property**.
2382 *
2383 * @name propertyByPath
2384 * @memberOf Assertion
2385 * @category assertion property
2386 * @param {Array|...string} properties Properties path to search
2387 * @example
2388 *
2389 * ({ a: {b: 10}}).should.have.propertyByPath('a', 'b').eql(10);
2390 */
2391 Assertion.add("propertyByPath", function(properties) {
2392 properties = aSlice.call(arguments);
2393
2394 var allProps = properties.map(formatProp);
2395
2396 properties = properties.map(convertPropertyName);
2397
2398 var obj = should(Object(this.obj));
2399
2400 var foundProperties = [];
2401
2402 var currentProperty;
2403 while (properties.length) {
2404 currentProperty = properties.shift();
2405 this.params = {
2406 operator:
2407 "to have property by path " +
2408 allProps.join(", ") +
2409 " - failed on " +
2410 formatProp(currentProperty)
2411 };
2412 obj = obj.have.property(currentProperty);
2413 foundProperties.push(currentProperty);
2414 }
2415
2416 this.params = {
2417 obj: this.obj,
2418 operator: "to have property by path " + allProps.join(", ")
2419 };
2420
2421 this.obj = obj.obj;
2422 });
2423}
2424
2425/*
2426 * should.js - assertion library
2427 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
2428 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
2429 * MIT Licensed
2430 */
2431function errorAssertions(should, Assertion) {
2432 var i = should.format;
2433
2434 /**
2435 * Assert given function throws error with such message.
2436 *
2437 * @name throw
2438 * @memberOf Assertion
2439 * @category assertion errors
2440 * @alias Assertion#throwError
2441 * @param {string|RegExp|Function|Object|GeneratorFunction|GeneratorObject} [message] Message to match or properties
2442 * @param {Object} [properties] Optional properties that will be matched to thrown error
2443 * @example
2444 *
2445 * (function(){ throw new Error('fail') }).should.throw();
2446 * (function(){ throw new Error('fail') }).should.throw('fail');
2447 * (function(){ throw new Error('fail') }).should.throw(/fail/);
2448 *
2449 * (function(){ throw new Error('fail') }).should.throw(Error);
2450 * var error = new Error();
2451 * error.a = 10;
2452 * (function(){ throw error; }).should.throw(Error, { a: 10 });
2453 * (function(){ throw error; }).should.throw({ a: 10 });
2454 * (function*() {
2455 * yield throwError();
2456 * }).should.throw();
2457 */
2458 Assertion.add("throw", function(message, properties) {
2459 var fn = this.obj;
2460 var err = {};
2461 var errorInfo = "";
2462 var thrown = false;
2463
2464 if (shouldUtil.isGeneratorFunction(fn)) {
2465 return should(fn()).throw(message, properties);
2466 } else if (shouldUtil.isIterator(fn)) {
2467 return should(fn.next.bind(fn)).throw(message, properties);
2468 }
2469
2470 this.is.a.Function();
2471
2472 var errorMatched = true;
2473
2474 try {
2475 fn();
2476 } catch (e) {
2477 thrown = true;
2478 err = e;
2479 }
2480
2481 if (thrown) {
2482 if (message) {
2483 if ("string" == typeof message) {
2484 errorMatched = message == err.message;
2485 } else if (message instanceof RegExp) {
2486 errorMatched = message.test(err.message);
2487 } else if ("function" == typeof message) {
2488 errorMatched = err instanceof message;
2489 } else if (null != message) {
2490 try {
2491 should(err).match(message);
2492 } catch (e) {
2493 if (e instanceof should.AssertionError) {
2494 errorInfo = ": " + e.message;
2495 errorMatched = false;
2496 } else {
2497 throw e;
2498 }
2499 }
2500 }
2501
2502 if (!errorMatched) {
2503 if ("string" == typeof message || message instanceof RegExp) {
2504 errorInfo =
2505 " with a message matching " +
2506 i(message) +
2507 ", but got '" +
2508 err.message +
2509 "'";
2510 } else if ("function" == typeof message) {
2511 errorInfo =
2512 " of type " +
2513 functionName(message) +
2514 ", but got " +
2515 functionName(err.constructor);
2516 }
2517 } else if ("function" == typeof message && properties) {
2518 try {
2519 should(err).match(properties);
2520 } catch (e) {
2521 if (e instanceof should.AssertionError) {
2522 errorInfo = ": " + e.message;
2523 errorMatched = false;
2524 } else {
2525 throw e;
2526 }
2527 }
2528 }
2529 } else {
2530 errorInfo = " (got " + i(err) + ")";
2531 }
2532 }
2533
2534 this.params = { operator: "to throw exception" + errorInfo };
2535
2536 this.assert(thrown);
2537 this.assert(errorMatched);
2538 });
2539
2540 Assertion.alias("throw", "throwError");
2541}
2542
2543/*
2544 * should.js - assertion library
2545 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
2546 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
2547 * MIT Licensed
2548 */
2549
2550function matchingAssertions(should, Assertion) {
2551 var i = should.format;
2552
2553 /**
2554 * Asserts if given object match `other` object, using some assumptions:
2555 * First object matched if they are equal,
2556 * If `other` is a regexp and given object is a string check on matching with regexp
2557 * If `other` is a regexp and given object is an array check if all elements matched regexp
2558 * If `other` is a regexp and given object is an object check values on matching regexp
2559 * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched
2560 * If `other` is an object check if the same keys matched with above rules
2561 * All other cases failed.
2562 *
2563 * Usually it is right idea to add pre type assertions, like `.String()` or `.Object()` to be sure assertions will do what you are expecting.
2564 * Object iteration happen by keys (properties with enumerable: true), thus some objects can cause small pain. Typical example is js
2565 * Error - it by default has 2 properties `name` and `message`, but they both non-enumerable. In this case make sure you specify checking props (see examples).
2566 *
2567 * @name match
2568 * @memberOf Assertion
2569 * @category assertion matching
2570 * @param {*} other Object to match
2571 * @param {string} [description] Optional message
2572 * @example
2573 * 'foobar'.should.match(/^foo/);
2574 * 'foobar'.should.not.match(/^bar/);
2575 *
2576 * ({ a: 'foo', c: 'barfoo' }).should.match(/foo$/);
2577 *
2578 * ['a', 'b', 'c'].should.match(/[a-z]/);
2579 *
2580 * (5).should.not.match(function(n) {
2581 * return n < 0;
2582 * });
2583 * (5).should.not.match(function(it) {
2584 * it.should.be.an.Array();
2585 * });
2586 * ({ a: 10, b: 'abc', c: { d: 10 }, d: 0 }).should
2587 * .match({ a: 10, b: /c$/, c: function(it) {
2588 * return it.should.have.property('d', 10);
2589 * }});
2590 *
2591 * [10, 'abc', { d: 10 }, 0].should
2592 * .match({ '0': 10, '1': /c$/, '2': function(it) {
2593 * return it.should.have.property('d', 10);
2594 * }});
2595 *
2596 * var myString = 'abc';
2597 *
2598 * myString.should.be.a.String().and.match(/abc/);
2599 *
2600 * myString = {};
2601 *
2602 * myString.should.match(/abc/); //yes this will pass
2603 * //better to do
2604 * myString.should.be.an.Object().and.not.empty().and.match(/abc/);//fixed
2605 *
2606 * (new Error('boom')).should.match(/abc/);//passed because no keys
2607 * (new Error('boom')).should.not.match({ message: /abc/ });//check specified property
2608 */
2609 Assertion.add("match", function(other, description) {
2610 this.params = { operator: "to match " + i(other), message: description };
2611
2612 if (eql(this.obj, other).length !== 0) {
2613 if (other instanceof RegExp) {
2614 // something - regex
2615
2616 if (typeof this.obj == "string") {
2617 this.assert(other.exec(this.obj));
2618 } else if (null != this.obj && typeof this.obj == "object") {
2619 var notMatchedProps = [],
2620 matchedProps = [];
2621 shouldTypeAdaptors.forEach(
2622 this.obj,
2623 function(value, name) {
2624 if (other.exec(value)) {
2625 matchedProps.push(formatProp(name));
2626 } else {
2627 notMatchedProps.push(formatProp(name) + " (" + i(value) + ")");
2628 }
2629 },
2630 this
2631 );
2632
2633 if (notMatchedProps.length) {
2634 this.params.operator += "\n not matched properties: " + notMatchedProps.join(", ");
2635 }
2636 if (matchedProps.length) {
2637 this.params.operator += "\n matched properties: " + matchedProps.join(", ");
2638 }
2639
2640 this.assert(notMatchedProps.length === 0);
2641 } else {
2642 // should we try to convert to String and exec?
2643 this.assert(false);
2644 }
2645 } else if (typeof other == "function") {
2646 var res;
2647
2648 res = other(this.obj);
2649
2650 //if we throw exception ok - it is used .should inside
2651 if (typeof res == "boolean") {
2652 this.assert(res); // if it is just boolean function assert on it
2653 }
2654 } else if (typeof this.obj == "object" && this.obj != null && (isPlainObject(other) || Array.isArray(other))) {
2655 // try to match properties (for Object and Array)
2656 notMatchedProps = [];
2657 matchedProps = [];
2658
2659 shouldTypeAdaptors.forEach(
2660 other,
2661 function(value, key) {
2662 try {
2663 should(this.obj)
2664 .have.property(key)
2665 .which.match(value);
2666 matchedProps.push(formatProp(key));
2667 } catch (e) {
2668 if (e instanceof should.AssertionError) {
2669 notMatchedProps.push(formatProp(key) + " (" + i(this.obj[key]) + ")");
2670 } else {
2671 throw e;
2672 }
2673 }
2674 },
2675 this
2676 );
2677
2678 if (notMatchedProps.length) {
2679 this.params.operator += "\n not matched properties: " + notMatchedProps.join(", ");
2680 }
2681 if (matchedProps.length) {
2682 this.params.operator += "\n matched properties: " + matchedProps.join(", ");
2683 }
2684
2685 this.assert(notMatchedProps.length === 0);
2686 } else {
2687 this.assert(false);
2688 }
2689 }
2690 });
2691
2692 /**
2693 * Asserts if given object values or array elements all match `other` object, using some assumptions:
2694 * First object matched if they are equal,
2695 * If `other` is a regexp - matching with regexp
2696 * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched
2697 * All other cases check if this `other` equal to each element
2698 *
2699 * @name matchEach
2700 * @memberOf Assertion
2701 * @category assertion matching
2702 * @alias Assertion#matchEvery
2703 * @param {*} other Object to match
2704 * @param {string} [description] Optional message
2705 * @example
2706 * [ 'a', 'b', 'c'].should.matchEach(/\w+/);
2707 * [ 'a', 'a', 'a'].should.matchEach('a');
2708 *
2709 * [ 'a', 'a', 'a'].should.matchEach(function(value) { value.should.be.eql('a') });
2710 *
2711 * { a: 'a', b: 'a', c: 'a' }.should.matchEach(function(value) { value.should.be.eql('a') });
2712 */
2713 Assertion.add("matchEach", function(other, description) {
2714 this.params = {
2715 operator: "to match each " + i(other),
2716 message: description
2717 };
2718
2719 shouldTypeAdaptors.forEach(
2720 this.obj,
2721 function(value) {
2722 should(value).match(other);
2723 },
2724 this
2725 );
2726 });
2727
2728 /**
2729 * Asserts if any of given object values or array elements match `other` object, using some assumptions:
2730 * First object matched if they are equal,
2731 * If `other` is a regexp - matching with regexp
2732 * If `other` is a function check if this function throws AssertionError on given object or return false - it will be assumed as not matched
2733 * All other cases check if this `other` equal to each element
2734 *
2735 * @name matchAny
2736 * @memberOf Assertion
2737 * @category assertion matching
2738 * @param {*} other Object to match
2739 * @alias Assertion#matchSome
2740 * @param {string} [description] Optional message
2741 * @example
2742 * [ 'a', 'b', 'c'].should.matchAny(/\w+/);
2743 * [ 'a', 'b', 'c'].should.matchAny('a');
2744 *
2745 * [ 'a', 'b', 'c'].should.matchAny(function(value) { value.should.be.eql('a') });
2746 *
2747 * { a: 'a', b: 'b', c: 'c' }.should.matchAny(function(value) { value.should.be.eql('a') });
2748 */
2749 Assertion.add("matchAny", function(other, description) {
2750 this.params = {
2751 operator: "to match any " + i(other),
2752 message: description
2753 };
2754
2755 this.assert(
2756 shouldTypeAdaptors.some(this.obj, function(value) {
2757 try {
2758 should(value).match(other);
2759 return true;
2760 } catch (e) {
2761 if (e instanceof should.AssertionError) {
2762 // Caught an AssertionError, return false to the iterator
2763 return false;
2764 }
2765 throw e;
2766 }
2767 })
2768 );
2769 });
2770
2771 Assertion.alias("matchAny", "matchSome");
2772 Assertion.alias("matchEach", "matchEvery");
2773}
2774
2775/*
2776 * should.js - assertion library
2777 * Copyright(c) 2010-2013 TJ Holowaychuk <tj@vision-media.ca>
2778 * Copyright(c) 2013-2017 Denis Bardadym <bardadymchik@gmail.com>
2779 * MIT Licensed
2780 */
2781/**
2782 * Our function should
2783 *
2784 * @param {*} obj Object to assert
2785 * @returns {should.Assertion} Returns new Assertion for beginning assertion chain
2786 * @example
2787 *
2788 * var should = require('should');
2789 * should('abc').be.a.String();
2790 */
2791function should(obj) {
2792 return new Assertion(obj);
2793}
2794
2795should.AssertionError = AssertionError;
2796should.Assertion = Assertion;
2797
2798// exposing modules dirty way
2799should.modules = {
2800 format: sformat,
2801 type: getType,
2802 equal: eql
2803};
2804should.format = format;
2805
2806/**
2807 * Object with configuration.
2808 * It contains such properties:
2809 * * `checkProtoEql` boolean - Affect if `.eql` will check objects prototypes
2810 * * `plusZeroAndMinusZeroEqual` boolean - Affect if `.eql` will treat +0 and -0 as equal
2811 * Also it can contain options for should-format.
2812 *
2813 * @type {Object}
2814 * @memberOf should
2815 * @static
2816 * @example
2817 *
2818 * var a = { a: 10 }, b = Object.create(null);
2819 * b.a = 10;
2820 *
2821 * a.should.be.eql(b);
2822 * //not throws
2823 *
2824 * should.config.checkProtoEql = true;
2825 * a.should.be.eql(b);
2826 * //throws AssertionError: expected { a: 10 } to equal { a: 10 } (because A and B have different prototypes)
2827 */
2828should.config = config;
2829
2830/**
2831 * Allow to extend given prototype with should property using given name. This getter will **unwrap** all standard wrappers like `Number`, `Boolean`, `String`.
2832 * Using `should(obj)` is the equivalent of using `obj.should` with known issues (like nulls and method calls etc).
2833 *
2834 * To add new assertions, need to use Assertion.add method.
2835 *
2836 * @param {string} [propertyName] Name of property to add. Default is `'should'`.
2837 * @param {Object} [proto] Prototype to extend with. Default is `Object.prototype`.
2838 * @memberOf should
2839 * @returns {{ name: string, descriptor: Object, proto: Object }} Descriptor enough to return all back
2840 * @static
2841 * @example
2842 *
2843 * var prev = should.extend('must', Object.prototype);
2844 *
2845 * 'abc'.must.startWith('a');
2846 *
2847 * var should = should.noConflict(prev);
2848 * should.not.exist(Object.prototype.must);
2849 */
2850should.extend = function(propertyName, proto) {
2851 propertyName = propertyName || "should";
2852 proto = proto || Object.prototype;
2853
2854 var prevDescriptor = Object.getOwnPropertyDescriptor(proto, propertyName);
2855
2856 Object.defineProperty(proto, propertyName, {
2857 set: function() {},
2858 get: function() {
2859 return should(isWrapperType(this) ? this.valueOf() : this);
2860 },
2861 configurable: true
2862 });
2863
2864 return { name: propertyName, descriptor: prevDescriptor, proto: proto };
2865};
2866
2867/**
2868 * Delete previous extension. If `desc` missing it will remove default extension.
2869 *
2870 * @param {{ name: string, descriptor: Object, proto: Object }} [desc] Returned from `should.extend` object
2871 * @memberOf should
2872 * @returns {Function} Returns should function
2873 * @static
2874 * @example
2875 *
2876 * var should = require('should').noConflict();
2877 *
2878 * should(Object.prototype).not.have.property('should');
2879 *
2880 * var prev = should.extend('must', Object.prototype);
2881 * 'abc'.must.startWith('a');
2882 * should.noConflict(prev);
2883 *
2884 * should(Object.prototype).not.have.property('must');
2885 */
2886should.noConflict = function(desc) {
2887 desc = desc || should._prevShould;
2888
2889 if (desc) {
2890 delete desc.proto[desc.name];
2891
2892 if (desc.descriptor) {
2893 Object.defineProperty(desc.proto, desc.name, desc.descriptor);
2894 }
2895 }
2896 return should;
2897};
2898
2899/**
2900 * Simple utility function for a bit more easier should assertion extension
2901 * @param {Function} f So called plugin function. It should accept 2 arguments: `should` function and `Assertion` constructor
2902 * @memberOf should
2903 * @returns {Function} Returns `should` function
2904 * @static
2905 * @example
2906 *
2907 * should.use(function(should, Assertion) {
2908 * Assertion.add('asset', function() {
2909 * this.params = { operator: 'to be asset' };
2910 *
2911 * this.obj.should.have.property('id').which.is.a.Number();
2912 * this.obj.should.have.property('path');
2913 * })
2914 * })
2915 */
2916should.use = function(f) {
2917 f(should, should.Assertion);
2918 return this;
2919};
2920
2921should
2922 .use(assertExtensions)
2923 .use(chainAssertions)
2924 .use(booleanAssertions)
2925 .use(numberAssertions)
2926 .use(equalityAssertions)
2927 .use(typeAssertions)
2928 .use(stringAssertions)
2929 .use(propertyAssertions)
2930 .use(errorAssertions)
2931 .use(matchingAssertions)
2932 .use(containAssertions)
2933 .use(promiseAssertions);
2934
2935module.exports = should;