14
14
*
15
15
* Can be one of:
16
16
*
17
- * - `string`: The string is evaluated as an expression and the resulting value is used for substring match against
18
- * the contents of the `array`. All strings or objects with string properties in `array` that contain this string
19
- * will be returned. The predicate can be negated by prefixing the string with `!`.
17
+ * - `string`: The string is used for matching against the contents of the `array`. All strings or
18
+ * objects with string properties in `array` that match this string will be returned. This also
19
+ * applies to nested object properties.
20
+ * The predicate can be negated by prefixing the string with `!`.
20
21
*
21
22
* - `Object`: A pattern object can be used to filter specific properties on objects contained
22
23
* by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items
23
24
* which have property `name` containing "M" and property `phone` containing "1". A special
24
25
* property name `$` can be used (as in `{$:"text"}`) to accept a match against any
25
- * property of the object. That's equivalent to the simple substring match with a `string`
26
- * as described above. The predicate can be negated by prefixing the string with `!`.
27
- * For Example `{name: "!M"}` predicate will return an array of items which have property `name`
26
+ * property of the object or its nested object properties. That's equivalent to the simple
27
+ * substring match with a `string` as described above. The predicate can be negated by prefixing
28
+ * the string with `!`.
29
+ * For example `{name: "!M"}` predicate will return an array of items which have property `name`
28
30
* not containing "M".
29
31
*
32
+ * Note that a named property will match properties on the same level only, while the special
33
+ * `$` property will match properties on the same level or deeper. E.g. an array item like
34
+ * `{name: {first: 'John', last: 'Doe'}}` will **not** be matched by `{name: 'John'}`, but
35
+ * **will** be matched by `{$: 'John'}`.
36
+ *
30
37
* - `function(value, index)`: A predicate function can be used to write arbitrary filters. The
31
38
* function is called for each element of `array`. The final result is an array of those
32
39
* elements that the predicate returned true for.
39
46
*
40
47
* - `function(actual, expected)`:
41
48
* The function will be given the object value and the predicate value to compare and
42
- * should return true if the item should be included in filtered result .
49
+ * should return true if both values should be considered equal .
43
50
*
44
- * - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual )}`.
45
- * this is essentially strict comparison of expected and actual.
51
+ * - `true`: A shorthand for `function(actual, expected) { return angular.equals(actual, expected )}`.
52
+ * This is essentially strict comparison of expected and actual.
46
53
*
47
54
* - `false|undefined`: A short hand for a function which will look for a substring match in case
48
55
* insensitive way.
@@ -169,7 +176,7 @@ function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
169
176
return predicateFn ;
170
177
}
171
178
172
- function deepCompare ( actual , expected , comparator , matchAgainstAnyProp ) {
179
+ function deepCompare ( actual , expected , comparator , matchAgainstAnyProp , dontMatchWholeObject ) {
173
180
var actualType = typeof actual ;
174
181
var expectedType = typeof expected ;
175
182
@@ -188,21 +195,21 @@ function deepCompare(actual, expected, comparator, matchAgainstAnyProp) {
188
195
var key ;
189
196
if ( matchAgainstAnyProp ) {
190
197
for ( key in actual ) {
191
- if ( ( key . charAt ( 0 ) !== '$' ) && deepCompare ( actual [ key ] , expected , comparator ) ) {
198
+ if ( ( key . charAt ( 0 ) !== '$' ) && deepCompare ( actual [ key ] , expected , comparator , true ) ) {
192
199
return true ;
193
200
}
194
201
}
195
- return false ;
202
+ return dontMatchWholeObject ? false : deepCompare ( actual , expected , comparator , false ) ;
196
203
} else if ( expectedType === 'object' ) {
197
204
for ( key in expected ) {
198
205
var expectedVal = expected [ key ] ;
199
206
if ( isFunction ( expectedVal ) ) {
200
207
continue ;
201
208
}
202
209
203
- var keyIsDollar = key === '$' ;
204
- var actualVal = keyIsDollar ? actual : actual [ key ] ;
205
- if ( ! deepCompare ( actualVal , expectedVal , comparator , keyIsDollar ) ) {
210
+ var matchAnyProperty = key === '$' ;
211
+ var actualVal = matchAnyProperty ? actual : actual [ key ] ;
212
+ if ( ! deepCompare ( actualVal , expectedVal , comparator , matchAnyProperty , matchAnyProperty ) ) {
206
213
return false ;
207
214
}
208
215
}
0 commit comments