Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds sinon.match.hasNested #1560

Merged
merged 2 commits into from
Sep 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/release-source/release/matchers.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,26 @@ 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");

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

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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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