Skip to content

Commit

Permalink
Adds sinon.match.hasNested
Browse files Browse the repository at this point in the history
  • Loading branch information
servel333 committed Sep 13, 2017
1 parent 5fbd9ee commit 04ba963
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
16 changes: 16 additions & 0 deletions docs/release-source/release/matchers.md
Expand Up @@ -220,6 +220,22 @@ The property might be inherited via the prototype chain. If the optional expecta
Same as `sinon.match.has` but the property must be defined by the value itself. Inherited properties are ignored.


#### `sinon.match.hasNested(propertyPath[, expectation])`

Requires the value to define the given `propertyPath`. Dot (`prop.prop`) and bracket (`prop[0]`) notations are supported as in (Lodash.get)[https://lodash.com/docs/4.4.2#get].

The propertyPath might be inherited via the prototype chain. If the optional expectation is given, the value at the propertyPath is deeply compared with the expectation. The expectation can be another matcher.


```javascript
sinon.match.hasNested("a[0].b.c");
sinon.match.hasNested("a.b.c");

// Where actual is something like
var actual = { "a": [{ "b": { "c": 3 } }] };
```


## Combining matchers

All matchers implement `and` and `or`. This allows to logically combine mutliple matchers. The result is a new matchers that requires both (and) or one of the matchers (or) to return `true`.
Expand Down
18 changes: 18 additions & 0 deletions lib/sinon/match.js
Expand Up @@ -3,6 +3,7 @@
var deepEqual = require("./util/core/deep-equal").use(match); // eslint-disable-line no-use-before-define
var every = require("./util/core/every");
var functionName = require("./util/core/function-name");
var get = require("lodash.get");
var iterableToString = require("./util/core/iterable-to-string");
var typeOf = require("./util/core/typeOf");
var valueToString = require("./util/core/value-to-string");
Expand Down Expand Up @@ -225,6 +226,23 @@ match.hasOwn = createPropertyMatcher(function (actual, property) {
return actual.hasOwnProperty(property);
}, "hasOwn");

match.hasNested = function (property, value) {
assertType(property, "string", "property");
var onlyProperty = arguments.length === 1;
var message = "hasNested(\"" + property + "\"";
if (!onlyProperty) {
message += ", " + valueToString(value);
}
message += ")";
return match(function (actual) {
if (actual === undefined || actual === null ||
get(actual, property) === undefined) {
return false;
}
return onlyProperty || deepEqual(value, get(actual, property));
}, message);
};

match.array = match.typeOf("array");

match.array.deepEquals = function (expectation) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -37,6 +37,7 @@
"dependencies": {
"diff": "^3.1.0",
"formatio": "1.2.0",
"lodash.get": "^4.4.2",
"lolex": "^2.1.2",
"native-promise-only": "^0.8.1",
"nise": "^1.0.1",
Expand Down
22 changes: 21 additions & 1 deletion test/match-test.js
Expand Up @@ -3,7 +3,7 @@
var assert = require("referee").assert;
var sinonMatch = require("../lib/sinon/match");

function propertyMatcherTests(matcher) {
function propertyMatcherTests(matcher, additionalTests) {
return function () {
it("returns matcher", function () {
var has = matcher("foo");
Expand Down Expand Up @@ -69,6 +69,10 @@ function propertyMatcherTests(matcher) {

assert(has.test({ callback: function () {} }));
});

if (typeof additionalTests === "function") {
additionalTests();
}
};
}

Expand Down Expand Up @@ -523,6 +527,22 @@ describe("sinonMatch", function () {
describe(".has", propertyMatcherTests(sinonMatch.has));
describe(".hasOwn", propertyMatcherTests(sinonMatch.hasOwn));

describe(".hasNested", propertyMatcherTests(sinonMatch.hasNested, function () {

it("compares nested value", function () {
var hasNested = sinonMatch.hasNested("foo.bar", "doo");

assert(hasNested.test({ foo: { bar: "doo" } }));
});

it("compares nested array value", function () {
var hasNested = sinonMatch.hasNested("foo[0].bar", "doo");

assert(hasNested.test({ foo: [{ bar: "doo" }] }));
});

}));

describe(".hasSpecial", function () {
it("returns true if object has inherited property", function () {
var has = sinonMatch.has("toString");
Expand Down

0 comments on commit 04ba963

Please sign in to comment.