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.
@@ -173,7 +180,7 @@ function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
173
180
return predicateFn ;
174
181
}
175
182
176
- function deepCompare ( actual , expected , comparator , matchAgainstAnyProp ) {
183
+ function deepCompare ( actual , expected , comparator , matchAgainstAnyProp , dontMatchWholeObject ) {
177
184
var actualType = typeof actual ;
178
185
var expectedType = typeof expected ;
179
186
@@ -192,21 +199,21 @@ function deepCompare(actual, expected, comparator, matchAgainstAnyProp) {
192
199
var key ;
193
200
if ( matchAgainstAnyProp ) {
194
201
for ( key in actual ) {
195
- if ( ( key . charAt ( 0 ) !== '$' ) && deepCompare ( actual [ key ] , expected , comparator ) ) {
202
+ if ( ( key . charAt ( 0 ) !== '$' ) && deepCompare ( actual [ key ] , expected , comparator , true ) ) {
196
203
return true ;
197
204
}
198
205
}
199
- return false ;
206
+ return dontMatchWholeObject ? false : deepCompare ( actual , expected , comparator , false ) ;
200
207
} else if ( expectedType === 'object' ) {
201
208
for ( key in expected ) {
202
209
var expectedVal = expected [ key ] ;
203
210
if ( isFunction ( expectedVal ) ) {
204
211
continue ;
205
212
}
206
213
207
- var keyIsDollar = key === '$' ;
208
- var actualVal = keyIsDollar ? actual : actual [ key ] ;
209
- if ( ! deepCompare ( actualVal , expectedVal , comparator , keyIsDollar ) ) {
214
+ var matchAnyProperty = key === '$' ;
215
+ var actualVal = matchAnyProperty ? actual : actual [ key ] ;
216
+ if ( ! deepCompare ( actualVal , expectedVal , comparator , matchAnyProperty , matchAnyProperty ) ) {
210
217
return false ;
211
218
}
212
219
}
0 commit comments