Skip to content

Commit 7200eab

Browse files
committed
Merge branch 'lgandecki-lgandecki-containsMatchers'
2 parents f97989e + a8cb113 commit 7200eab

File tree

2 files changed

+90
-18
lines changed

2 files changed

+90
-18
lines changed

regression/src/matchers-test.coffee

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,72 @@ describe '.matchers', ->
8787
Then -> @matches(td.matchers.contains(true, 5, null, undefined), [true, 5, undefined, null]) == true
8888
Then -> @matches(td.matchers.contains(true, 5, null, undefined), [true, 5, null]) == false
8989

90+
describe 'elements containing matchers', ->
91+
Then -> @matches(td.matchers.contains('b', td.matchers.isA(Number)), ['a', 3, 'b']) == true
92+
9093
context 'objects', ->
9194
Then -> @matches(td.matchers.contains(foo: 'bar', baz: 42), foo: 'bar', baz: 42, stuff: this) == true
9295
Then -> @matches(td.matchers.contains(foo: 'bar', lol: 42), foo: 'bar', baz: 42) == false
9396
Then -> @matches(td.matchers.contains(lol: {deep: [4,2]}), lol: {deep: [4,2], other: "stuff"}) == true
9497
Then -> @matches(td.matchers.contains(deep: {thing: 'stuff'}), {}) == false
95-
Then -> @matches(td.matchers.contains(deep: {thing: 'stuff'}), deep: {thing: 'stuff', shallow: 5}) == true
96-
Then -> @matches(td.matchers.contains({container: {size: 'S'}}), {ingredient: 'beans', container: { type: 'cup', size: 'S'}}) == true
98+
Then -> @matches(td.matchers.contains(deep: {thing: 'stuff'}),
99+
deep: {thing: 'stuff', shallow: 5}
100+
) == true
101+
Then -> @matches(td.matchers.contains({container: {size: 'S'}}),
102+
{ingredient: 'beans', container: { type: 'cup', size: 'S'}}
103+
) == true
104+
105+
describe 'objects containing matchers', ->
106+
Then -> @matches(td.matchers.contains(td.matchers.isA(Number)),
107+
{a: 'foo', b: 32}
108+
) == true
109+
Then -> @matches(td.matchers.contains(td.matchers.isA(Function)),
110+
{a: 'foo', b: 32}
111+
) == false
112+
Then -> @matches(td.matchers.contains({a: td.matchers.contains(1,2)}),
113+
{a: [4,1,2,3]}
114+
) == true
115+
Then -> @matches(td.matchers.contains({a: td.matchers.contains(1,5)}),
116+
{a: [4,1,2,3]}
117+
) == false
118+
Then -> @matches(
119+
td.matchers.contains({someString: td.matchers.isA(String)}),
120+
{someString: "beautifulString"}
121+
) == true
122+
Then -> @matches(
123+
td.matchers.contains({someString: td.matchers.isA(String)}),
124+
{someString: "beautifulString", irrelevant: true}
125+
) == true
126+
Then -> @matches(
127+
td.matchers.contains(
128+
{nested: {someString: td.matchers.isA(String)}, relevant: true}
129+
),
130+
{nested: {someString: "beautifulString"}, relevant: true}
131+
) == true
132+
Then -> @matches(
133+
td.matchers.contains({someString: td.matchers.isA(String)}),
134+
{someString: 4}
135+
) == false
136+
Then -> @matches(
137+
td.matchers.contains({
138+
nested: td.matchers.contains({
139+
nestedString: td.matchers.isA(String)
140+
})
141+
}),
142+
{nested: {nestedString: "abc", irrelevant: true}, irrelevantHere: "alsoTrue"}
143+
) == true
144+
Then -> @matches(
145+
td.matchers.contains({
146+
nested: td.matchers.contains({
147+
nestedString: td.matchers.isA(Number)
148+
})
149+
}),
150+
{nested: {nestedString: "abc", irrelevant: true}, irrelevantHere: "not a number!"}
151+
) == false
152+
Then -> @matches(td.matchers.contains({a: [td.matchers.isA(Number)]}),
153+
{a: [5]}
154+
) == true
155+
97156

98157
context 'regexp', ->
99158
Then -> @matches(td.matchers.contains(/abc/), 'abc') == true

src/matchers/builtin/contains.js

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,40 @@
11
import _ from '../../wrap/lodash'
22
import create from '../create'
3+
import isMatcher from '../is-matcher'
34

45
export default create({
56
name: 'contains',
67
matches (containings, actualArg) {
78
if (containings.length === 0) return false
89

9-
return _.every(containings, (containing) => {
10-
if (_.isArray(containing)) {
11-
return _.some(actualArg, actualElement => _.isEqual(actualElement, containing))
12-
} else if (_.isRegExp(containing)) {
13-
return containing.test(actualArg)
14-
} else if (_.isObjectLike(containing) && _.isObjectLike(actualArg)) {
15-
return containsAllSpecified(containing, actualArg)
16-
} else {
17-
return _.includes(actualArg, containing)
18-
}
19-
})
10+
return _.every(containings, (containing) =>
11+
argumentContains(containing, actualArg)
12+
)
2013
}
2114
})
2215

23-
var containsAllSpecified = (containing, actual) =>
24-
actual != null && _.every(containing, (val, key) =>
25-
_.isObjectLike(val)
26-
? containsAllSpecified(val, actual[key])
27-
: _.isEqual(val, actual[key]))
16+
const argumentContains = function (containing, actualArg) {
17+
if (_.isArray(containing)) {
18+
return _.some(actualArg, actualElement => _.isEqual(actualElement, containing))
19+
} else if (_.isRegExp(containing)) {
20+
return containing.test(actualArg)
21+
} else if (isMatcher(containing)) {
22+
return _.some(actualArg, containing.__matches)
23+
} else if (_.isObjectLike(containing) && _.isObjectLike(actualArg)) {
24+
return containsPartialObject(containing, actualArg)
25+
} else {
26+
return _.includes(actualArg, containing)
27+
}
28+
}
29+
30+
var containsPartialObject = (containing, actual) => {
31+
return actual != null && _.every(containing, (val, key) => {
32+
if (isMatcher(val)) {
33+
return val.__matches(actual[key])
34+
} else if (_.isObjectLike(val)) {
35+
return containsPartialObject(val, actual[key])
36+
} else {
37+
return _.isEqual(val, actual[key])
38+
}
39+
})
40+
}

0 commit comments

Comments
 (0)