From a17a11722bdb3fbb7bb0e0159b8fc6835250bff3 Mon Sep 17 00:00:00 2001 From: Pablo Villoslada Puigcerber Date: Sat, 6 Dec 2014 18:29:31 +0100 Subject: [PATCH] fix(filter): throw error if not used with an array Throw error if filter is not used with an array. Closes #9992 BREAKING CHANGE: Previously, the filter was not applied if used with a non array. Now, it throws an error. --- docs/content/error/filter/notarray.ngdoc | 8 ++++++ src/ng/filter/filter.js | 8 +++++- test/ng/filter/filterSpec.js | 31 +++++++++++++++++++++++- test/ngScenario/dslSpec.js | 2 +- 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 docs/content/error/filter/notarray.ngdoc diff --git a/docs/content/error/filter/notarray.ngdoc b/docs/content/error/filter/notarray.ngdoc new file mode 100644 index 000000000000..c46befba598c --- /dev/null +++ b/docs/content/error/filter/notarray.ngdoc @@ -0,0 +1,8 @@ +@ngdoc error +@name filter:notarray +@fullName Not an array +@description + +This error occurs when {@link ng.filter filter} is not used with an array. +Filter must be used with an array so a subset of items can be returned. +The array can be initialized asynchronously so null or undefined won't throw this error. diff --git a/src/ng/filter/filter.js b/src/ng/filter/filter.js index a739a1ca21c7..8b95b7a04f7f 100644 --- a/src/ng/filter/filter.js +++ b/src/ng/filter/filter.js @@ -117,7 +117,13 @@ */ function filterFilter() { return function(array, expression, comparator) { - if (!isArray(array)) return array; + if (!isArray(array)) { + if (array == null) { + return array; + } else { + throw minErr('filter')('notarray', 'Expected array but received: {0}', array); + } + } var predicateFn; var matchAgainstAnyProp; diff --git a/test/ng/filter/filterSpec.js b/test/ng/filter/filterSpec.js index 7e14f5f567f4..3c07d2496aed 100644 --- a/test/ng/filter/filterSpec.js +++ b/test/ng/filter/filterSpec.js @@ -195,7 +195,7 @@ describe('Filter: filter', function() { expect(filter(items, expr, true).length).toBe(1); expect(filter(items, expr, true)[0]).toBe(items[0]); - // Inherited function proprties + // Inherited function properties function Item(text) { this.text = text; } @@ -323,6 +323,35 @@ describe('Filter: filter', function() { }); + it('should throw an error when is not used with an array', function() { + var item = {'not': 'array'}; + expect(function() { filter(item, {}); }). + toThrowMinErr('filter', 'notarray', 'Expected array but received: {"not":"array"}'); + + item = Object.create(null); + expect(function() { filter(item, {}); }). + toThrowMinErr('filter', 'notarray', 'Expected array but received: {}'); + + item = { + toString: null, + valueOf: null + }; + expect(function() { filter(item, {}); }). + toThrowMinErr('filter', 'notarray', 'Expected array but received: {"toString":null,"valueOf":null}'); + }); + + + it('should return undefined when the array is undefined', function() { + expect(filter(undefined, {})).toBeUndefined(); + }); + + + it('should return null when the value of the array is null', function() { + var item = null; + expect(filter(item, {})).toBe(null); + }); + + describe('should support comparator', function() { it('not consider `object === "[object Object]"` in non-strict comparison', function() { diff --git a/test/ngScenario/dslSpec.js b/test/ngScenario/dslSpec.js index 2287b6bf3071..5db5801ca551 100644 --- a/test/ngScenario/dslSpec.js +++ b/test/ngScenario/dslSpec.js @@ -624,7 +624,7 @@ describe("angular.scenario.dsl", function() { }); it('should match bindings by substring match', function() { - compile('
', 'binding value');
+        compile('
', 'binding value');
         $root.dsl.binding('foo . bar');
         expect($root.futureResult).toEqual('binding value');
       });