Skip to content
This repository has been archived by the owner on Nov 4, 2020. It is now read-only.

Commit

Permalink
Fix #150
Browse files Browse the repository at this point in the history
  • Loading branch information
btd committed Sep 5, 2017
1 parent c4924be commit fe1ae5c
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 175 deletions.
22 changes: 3 additions & 19 deletions lib/ext/contain.js
Expand Up @@ -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";

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
24 changes: 7 additions & 17 deletions lib/ext/match.js
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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 = [];
Expand All @@ -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;
}
Expand All @@ -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);
Expand Down
100 changes: 10 additions & 90 deletions lib/ext/property.js
Expand Up @@ -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;
Expand All @@ -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**.
*
Expand Down Expand Up @@ -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);
Expand All @@ -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));
}
});

Expand Down Expand Up @@ -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(", ") };

Expand Down Expand Up @@ -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);
Expand Down
13 changes: 10 additions & 3 deletions lib/util.js
Expand Up @@ -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
Expand All @@ -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;
}
17 changes: 4 additions & 13 deletions test/ext/contain.test.js
Expand Up @@ -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]);

Expand All @@ -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" }]);
Expand All @@ -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]);

Expand All @@ -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 }));
Expand Down
8 changes: 8 additions & 0 deletions test/ext/match.test.js
Expand Up @@ -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,
Expand Down
33 changes: 0 additions & 33 deletions 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");
Expand Down

0 comments on commit fe1ae5c

Please sign in to comment.