diff --git a/lib/ext/contain.js b/lib/ext/contain.js index 69ae143..808f18a 100644 --- a/lib/ext/contain.js +++ b/lib/ext/contain.js @@ -5,13 +5,7 @@ * MIT Licensed */ -import { - isIterable, - some, - isEmpty, - forEach, - iterator -} from "should-type-adaptors"; +import { isIterable, some, isEmpty, forEach, iterator } from "should-type-adaptors"; import eql from "should-equal"; @@ -113,12 +107,7 @@ export default function(should, Assertion) { } this.assert(nextOther.done); - } else if ( - obj != null && - other != null && - typeof obj == "object" && - typeof other == "object" - ) { + } else if (obj != null && typeof obj == "object" && other != null && typeof other == "object") { //TODO compare types object contains object case forEach(other, function(value, key) { should(obj[key]).containDeepOrdered(value); @@ -178,12 +167,7 @@ export default function(should, Assertion) { }, this ); - } else if ( - obj != null && - other != null && - typeof obj == "object" && - typeof other == "object" - ) { + } else if (obj != null && other != null && typeof obj == "object" && typeof other == "object") { // object contains object case forEach(other, function(value, key) { should(obj[key]).containDeep(value); diff --git a/lib/ext/match.js b/lib/ext/match.js index 4eb1677..e863858 100644 --- a/lib/ext/match.js +++ b/lib/ext/match.js @@ -8,6 +8,7 @@ import { formatProp } from "../format"; import { some, forEach } from "should-type-adaptors"; import eql from "should-equal"; +import { isPlainObject } from "../util"; export default function(should, Assertion) { var i = should.format; @@ -93,12 +94,10 @@ export default function(should, Assertion) { ); if (notMatchedProps.length) { - this.params.operator += - "\n not matched properties: " + notMatchedProps.join(", "); + this.params.operator += "\n not matched properties: " + notMatchedProps.join(", "); } if (matchedProps.length) { - this.params.operator += - "\n matched properties: " + matchedProps.join(", "); + this.params.operator += "\n matched properties: " + matchedProps.join(", "); } this.assert(notMatchedProps.length === 0); @@ -115,12 +114,7 @@ export default function(should, Assertion) { if (typeof res == "boolean") { this.assert(res); // if it is just boolean function assert on it } - } else if ( - other != null && - this.obj != null && - typeof other == "object" && - typeof this.obj == "object" - ) { + } else if (typeof this.obj == "object" && this.obj != null && (isPlainObject(other) || Array.isArray(other))) { // try to match properties (for Object and Array) notMatchedProps = []; matchedProps = []; @@ -135,9 +129,7 @@ export default function(should, Assertion) { matchedProps.push(formatProp(key)); } catch (e) { if (e instanceof should.AssertionError) { - notMatchedProps.push( - formatProp(key) + " (" + i(this.obj[key]) + ")" - ); + notMatchedProps.push(formatProp(key) + " (" + i(this.obj[key]) + ")"); } else { throw e; } @@ -147,12 +139,10 @@ export default function(should, Assertion) { ); if (notMatchedProps.length) { - this.params.operator += - "\n not matched properties: " + notMatchedProps.join(", "); + this.params.operator += "\n not matched properties: " + notMatchedProps.join(", "); } if (matchedProps.length) { - this.params.operator += - "\n matched properties: " + matchedProps.join(", "); + this.params.operator += "\n matched properties: " + matchedProps.join(", "); } this.assert(notMatchedProps.length === 0); diff --git a/lib/ext/property.js b/lib/ext/property.js index a9fea8d..db47df7 100644 --- a/lib/ext/property.js +++ b/lib/ext/property.js @@ -8,12 +8,7 @@ import { convertPropertyName } from "../util"; import { hasOwnProperty } from "should-util"; import { formatProp } from "../format"; -import { - isEmpty, - has as hasKey, - get as getValue, - size -} from "should-type-adaptors"; +import { isEmpty, has as hasKey, get as getValue, size } from "should-type-adaptors"; import eql from "should-equal"; var aSlice = Array.prototype.slice; @@ -39,62 +34,9 @@ export default function(should, Assertion) { }; var obj = this.obj; this.have.ownProperty(name); - should(Object.getOwnPropertyDescriptor(Object(obj), name)).have.properties( - desc - ); + should(Object.getOwnPropertyDescriptor(Object(obj), name)).have.properties(desc); }); - function processPropsArgs() { - var args = {}; - if (arguments.length > 1) { - args.names = aSlice.call(arguments); - } else { - var arg = arguments[0]; - if (typeof arg === "string") { - args.names = [arg]; - } else if (Array.isArray(arg)) { - args.names = arg; - } else { - args.names = Object.keys(arg); - args.values = arg; - } - } - return args; - } - - Assertion.add("enumerable", function(name, val) { - name = convertPropertyName(name); - - this.params = { - operator: - "to have enumerable property " + - formatProp(name) + - (arguments.length > 1 ? " equal to " + i(val) : "") - }; - - var desc = { enumerable: true }; - if (arguments.length > 1) { - desc.value = val; - } - this.have.propertyWithDescriptor(name, desc); - }); - - Assertion.add( - "enumerables", - function(/*names*/) { - var args = processPropsArgs.apply(null, arguments); - - this.params = { - operator: "to have enumerables " + args.names.map(formatProp) - }; - - var obj = this.obj; - args.names.forEach(function(name) { - should(obj).have.enumerable(name); - }); - } - ); - /** * Asserts given object has property with optionally value. **On success it change given object to be value of property**. * @@ -167,19 +109,14 @@ export default function(should, Assertion) { } var operator = - (props.length === 1 - ? "to have property " - : "to have " + (this.anyOne ? "any of " : "") + "properties ") + + (props.length === 1 ? "to have property " : "to have " + (this.anyOne ? "any of " : "") + "properties ") + props.join(", "); this.params = { obj: this.obj, operator: operator }; //check that all properties presented //or if we request one of them that at least one them presented - this.assert( - missingProperties.length === 0 || - (this.anyOne && missingProperties.length != names.length) - ); + this.assert(missingProperties.length === 0 || (this.anyOne && missingProperties.length != names.length)); // check if values in object matched expected var valueCheckNames = Object.keys(values); @@ -191,35 +128,25 @@ export default function(should, Assertion) { valueCheckNames.forEach(function(name) { var value = values[name]; if (eql(obj[name], value).length !== 0) { - wrongValues.push( - formatProp(name) + " of " + i(value) + " (got " + i(obj[name]) + ")" - ); + wrongValues.push(formatProp(name) + " of " + i(value) + " (got " + i(obj[name]) + ")"); } else { props.push(formatProp(name) + " of " + i(value)); } }); - if ( - (wrongValues.length !== 0 && !this.anyOne) || - (this.anyOne && props.length === 0) - ) { + if ((wrongValues.length !== 0 && !this.anyOne) || (this.anyOne && props.length === 0)) { props = wrongValues; } operator = - (props.length === 1 - ? "to have property " - : "to have " + (this.anyOne ? "any of " : "") + "properties ") + + (props.length === 1 ? "to have property " : "to have " + (this.anyOne ? "any of " : "") + "properties ") + props.join(", "); this.params = { obj: this.obj, operator: operator }; //if there is no not matched values //or there is at least one matched - this.assert( - wrongValues.length === 0 || - (this.anyOne && wrongValues.length != valueCheckNames.length) - ); + this.assert(wrongValues.length === 0 || (this.anyOne && wrongValues.length != valueCheckNames.length)); } }); @@ -318,10 +245,7 @@ export default function(should, Assertion) { return !hasKey(obj, key); }); - var verb = - "to have " + - (this.onlyThis ? "only " : "") + - (keys.length === 1 ? "key " : "keys "); + var verb = "to have " + (this.onlyThis ? "only " : "") + (keys.length === 1 ? "key " : "keys "); this.params = { operator: verb + keys.join(", ") }; @@ -401,11 +325,7 @@ export default function(should, Assertion) { while (properties.length) { currentProperty = properties.shift(); this.params = { - operator: - "to have property by path " + - allProps.join(", ") + - " - failed on " + - formatProp(currentProperty) + operator: "to have property by path " + allProps.join(", ") + " - failed on " + formatProp(currentProperty) }; obj = obj.have.property(currentProperty); foundProperties.push(currentProperty); diff --git a/lib/util.js b/lib/util.js index eb5ccf1..35a1731 100644 --- a/lib/util.js +++ b/lib/util.js @@ -7,9 +7,7 @@ import sformat from "should-format"; export function isWrapperType(obj) { - return ( - obj instanceof Number || obj instanceof String || obj instanceof Boolean - ); + return obj instanceof Number || obj instanceof String || obj instanceof Boolean; } // XXX make it more strict: numbers, strings, symbols - and nothing else @@ -18,3 +16,12 @@ export function convertPropertyName(name) { } export var functionName = sformat.functionName; + +export function isPlainObject(obj) { + if (typeof obj == "object" && obj !== null) { + var proto = Object.getPrototypeOf(obj); + return proto === Object.prototype || proto === null; + } + + return false; +} diff --git a/test/ext/contain.test.js b/test/ext/contain.test.js index 14ee175..094c37f 100644 --- a/test/ext/contain.test.js +++ b/test/ext/contain.test.js @@ -35,9 +35,7 @@ describe("contain*", function() { b: { c: 10, d: 11, a: { b: 10, c: 11 } } }.should.containDeep({ a: { b: 10 }, b: { c: 10, a: { c: 11 } } })); - [1, 2, 3, { a: { b: { d: 12 } } }].should.containDeep([ - { a: { b: { d: 12 } } } - ]); + [1, 2, 3, { a: { b: { d: 12 } } }].should.containDeep([{ a: { b: { d: 12 } } }]); [[1, [2, 3], 3], [2]].should.not.containDeep([1, 2]); @@ -56,10 +54,7 @@ describe("contain*", function() { [1, 2, 3].should.containDeep([3, 2]); ["code-for-days", "code"].should.containDeep(["code", "code-for-days"]); - ["code-for-days", "code-fast"].should.containDeep([ - "code-fast", - "code-for-days" - ]); + ["code-for-days", "code-fast"].should.containDeep(["code-fast", "code-for-days"]); err(function() { [{ a: "a" }, { b: "b", c: "c" }].should.not.containDeep([{ b: "b" }]); @@ -82,9 +77,7 @@ describe("contain*", function() { b: { c: 10, d: 11, a: { b: 10, c: 11 } } }.should.containDeepOrdered({ a: { b: 10 }, b: { c: 10, a: { c: 11 } } })); - [1, 2, 3, { a: { b: { d: 12 } } }].should.containDeepOrdered([ - { a: { b: { d: 12 } } } - ]); + [1, 2, 3, { a: { b: { d: 12 } } }].should.containDeepOrdered([{ a: { b: { d: 12 } } }]); [[1, [2, 3], 3], [2]].should.not.containDeepOrdered([1, 2]); @@ -96,9 +89,7 @@ describe("contain*", function() { [{ a: "a" }, { b: "b", c: "c" }].should.containDeepOrdered([{ b: "b" }]); err(function() { - [{ a: "a" }, { b: "b", c: "c" }].should.not.containDeepOrdered([ - { b: "b" } - ]); + [{ a: "a" }, { b: "b", c: "c" }].should.not.containDeepOrdered([{ b: "b" }]); }, "expected Array [ Object { a: 'a' }, Object { b: 'b', c: 'c' } ] not to contain Array [ Object { b: 'b' } ] (false negative fail)"); ({ hi: null }.should.containEql({ hi: null })); diff --git a/test/ext/match.test.js b/test/ext/match.test.js index a700bb3..3483b21 100644 --- a/test/ext/match.test.js +++ b/test/ext/match.test.js @@ -128,6 +128,14 @@ describe("match", function() { d.should.not.match(ds); ds.should.not.match(d); + ({ + a: new Date("2017-09-02"), + b: 12 + }.should.not.match({ + a: new Date("2017-09-03"), + b: 12 + })); + err(function() { ({ a: 10, b: "abc", c: { d: 10 }, d: 0 }.should.match({ a: 11, diff --git a/test/ext/property.test.js b/test/ext/property.test.js index e518915..0b7a506 100644 --- a/test/ext/property.test.js +++ b/test/ext/property.test.js @@ -1,39 +1,6 @@ var err = require("../util").err; describe("property", function() { - it("test enumerable(name)", function() { - ({ length: 5 }.should.have.enumerable("length")); - (4).should.not.have.enumerable("length"); - - err( - function() { - "asd".should.have.enumerable("length"); - }, - "expected 'asd' to have enumerable property length", - " expected 'asd' to have own property with descriptor Object { enumerable: true }", - " expected Object { value: 3, writable: false, enumerable: false, configurable: false } to have property enumerable of true (got false)" - ); - }); - - it("test enumerable(name, val)", function() { - ({ length: 5 }.should.have.enumerable("length", 5)); - - err( - function() { - ({ length: 3 }.should.have.enumerable("length", 5)); - }, - "expected Object { length: 3 } to have enumerable property length equal to 5", - " expected Object { length: 3 } to have own property with descriptor Object { enumerable: true, value: 5 }", - " expected Object { value: 3, writable: true, enumerable: true, configurable: true } to have property value of 5 (got 3)" - ); - }); - - it("test enumerables(names)", function() { - var obj = { a: "a", b: "b", c: "c" }; - obj.should.have.enumerables("a", "b"); - obj.should.have.enumerables(["a", "b"]); - }); - it("test property(name)", function() { "test".should.have.property("length"); (4).should.not.have.property("length");