From 3df4285e3bd1a6913119604e6b9c19c9513935fd Mon Sep 17 00:00:00 2001 From: Andrey Pushkarev Date: Fri, 2 Jan 2015 21:56:58 +0530 Subject: [PATCH] fix(filterFilter): do not filter objects properly in case a property is an array In JavaScript, an array is a special type of object, therefore typeof [] returns object. Added corresponding unit tests. Changed condition for array type to isArray. --- src/ng/filter/filter.js | 2 +- test/ng/filter/filterSpec.js | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/ng/filter/filter.js b/src/ng/filter/filter.js index 7a251e0b97cc..70a35a305d77 100644 --- a/src/ng/filter/filter.js +++ b/src/ng/filter/filter.js @@ -186,7 +186,7 @@ function deepCompare(actual, expected, comparator, matchAgainstAnyProp, dontMatc if ((expectedType === 'string') && (expected.charAt(0) === '!')) { return !deepCompare(actual, expected.substring(1), comparator, matchAgainstAnyProp); - } else if (actualType === 'array') { + } else if (isArray(actual)) { // In case `actual` is an array, consider it a match // if ANY of it's items matches `expected` return actual.some(function(item) { diff --git a/test/ng/filter/filterSpec.js b/test/ng/filter/filterSpec.js index 818588fc3cc8..3c3c30c23d9e 100644 --- a/test/ng/filter/filterSpec.js +++ b/test/ng/filter/filterSpec.js @@ -92,6 +92,41 @@ describe('Filter: filter', function() { ); + it('should match in case actual object property is an array ' + + 'and any of it\'s items matches same property in expected object', + function() { + var items, expr; + + items = [ + {tags: ['web', 'html', 'css', 'js']}, + {tags: ['hybrid', 'html', 'css', 'js', 'ios', 'android']}, + {tags: ['mobile', 'ios', 'android']} + ]; + expr = {tags: 'html'}; + expect(filter(items, expr).length).toBe(2); + expect(filter(items, expr)).toEqual([items[0], items[1]]); + + items = [ + {nums: [1, 345, 12]}, + {nums: [0, 46, 78]}, + {nums: [123, 4, 67]} + ]; + expr = {nums: 12}; + expect(filter(items, expr).length).toBe(2); + expect(filter(items, expr)).toEqual([items[0], items[2]]); + + items = [ + {customers: [{name: 'John'}, {name: 'Elena'}, {name: 'Bill'}]}, + {customers: [{name: 'Sam'}, {name: 'Klara'}, {name: 'Bill'}]}, + {customers: [{name: 'Molli'}, {name: 'Elena'}, {name: 'Lora'}]} + ]; + expr = {customers: {name: 'Bill'}}; + expect(filter(items, expr).length).toBe(2); + expect(filter(items, expr)).toEqual([items[0], items[1]]); + } + ); + + it('should take object as predicate', function() { var items = [{first: 'misko', last: 'hevery'}, {first: 'adam', last: 'abrons'}];