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