diff options
| -rw-r--r-- | src/ng/filter/limitTo.js | 83 | ||||
| -rw-r--r-- | test/ng/filter/limitToSpec.js | 29 |
2 files changed, 74 insertions, 38 deletions
diff --git a/src/ng/filter/limitTo.js b/src/ng/filter/limitTo.js index 536c7038..bbbeb83c 100644 --- a/src/ng/filter/limitTo.js +++ b/src/ng/filter/limitTo.js @@ -6,20 +6,20 @@ * @function * * @description - * Creates a new array containing only a specified number of elements in an array. The elements - * are taken from either the beginning or the end of the source array, as specified by the - * value and sign (positive or negative) of `limit`. + * Creates a new array or string containing only a specified number of elements. The elements + * are taken from either the beginning or the end of the source array or string, as specified by + * the value and sign (positive or negative) of `limit`. * * Note: This function is used to augment the `Array` type in Angular expressions. See * {@link ng.$filter} for more information about Angular arrays. * - * @param {Array} array Source array to be limited. - * @param {string|Number} limit The length of the returned array. If the `limit` number is - * positive, `limit` number of items from the beginning of the source array are copied. - * If the number is negative, `limit` number of items from the end of the source array are - * copied. The `limit` will be trimmed if it exceeds `array.length` - * @returns {Array} A new sub-array of length `limit` or less if input array had less than `limit` - * elements. + * @param {Array|string} input Source array or string to be limited. + * @param {string|number} limit The length of the returned array or string. If the `limit` number + * is positive, `limit` number of items from the beginning of the source array/string are copied. + * If the number is negative, `limit` number of items from the end of the source array/string + * are copied. The `limit` will be trimmed if it exceeds `array.length` + * @returns {Array|string} A new sub-array or substring of length `limit` or less if input array + * had less than `limit` elements. * * @example <doc:example> @@ -27,59 +27,76 @@ <script> function Ctrl($scope) { $scope.numbers = [1,2,3,4,5,6,7,8,9]; - $scope.limit = 3; + $scope.letters = "abcdefghi"; + $scope.numLimit = 3; + $scope.letterLimit = 3; } </script> <div ng-controller="Ctrl"> - Limit {{numbers}} to: <input type="integer" ng-model="limit"> - <p>Output: {{ numbers | limitTo:limit }}</p> + Limit {{numbers}} to: <input type="integer" ng-model="numLimit"> + <p>Output numbers: {{ numbers | limitTo:numLimit }}</p> + Limit {{letters}} to: <input type="integer" ng-model="letterLimit"> + <p>Output letters: {{ letters | limitTo:letterLimit }}</p> </div> </doc:source> <doc:scenario> - it('should limit the numer array to first three items', function() { - expect(element('.doc-example-live input[ng-model=limit]').val()).toBe('3'); - expect(binding('numbers | limitTo:limit')).toEqual('[1,2,3]'); + it('should limit the number array to first three items', function() { + expect(element('.doc-example-live input[ng-model=numLimit]').val()).toBe('3'); + expect(element('.doc-example-live input[ng-model=letterLimit]').val()).toBe('3'); + expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3]'); + expect(binding('letters | limitTo:letterLimit')).toEqual('abc'); }); it('should update the output when -3 is entered', function() { - input('limit').enter(-3); - expect(binding('numbers | limitTo:limit')).toEqual('[7,8,9]'); + input('numLimit').enter(-3); + input('letterLimit').enter(-3); + expect(binding('numbers | limitTo:numLimit')).toEqual('[7,8,9]'); + expect(binding('letters | limitTo:letterLimit')).toEqual('ghi'); }); it('should not exceed the maximum size of input array', function() { - input('limit').enter(100); - expect(binding('numbers | limitTo:limit')).toEqual('[1,2,3,4,5,6,7,8,9]'); + input('numLimit').enter(100); + input('letterLimit').enter(100); + expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3,4,5,6,7,8,9]'); + expect(binding('letters | limitTo:letterLimit')).toEqual('abcdefghi'); }); </doc:scenario> </doc:example> */ function limitToFilter(){ - return function(array, limit) { - if (!(array instanceof Array)) return array; + return function(input, limit) { + if (!isArray(input) && !isString(input)) return input; + limit = int(limit); + + if (isString(input)) { + //NaN check on limit + if (limit) { + return limit >= 0 ? input.slice(0, limit) : input.slice(limit, input.length); + } else { + return ""; + } + } + var out = [], i, n; - // check that array is iterable - if (!array || !(array instanceof Array)) - return out; - // if abs(limit) exceeds maximum length, trim it - if (limit > array.length) - limit = array.length; - else if (limit < -array.length) - limit = -array.length; + if (limit > input.length) + limit = input.length; + else if (limit < -input.length) + limit = -input.length; if (limit > 0) { i = 0; n = limit; } else { - i = array.length + limit; - n = array.length; + i = input.length + limit; + n = input.length; } for (; i<n; i++) { - out.push(array[i]); + out.push(input[i]); } return out; diff --git a/test/ng/filter/limitToSpec.js b/test/ng/filter/limitToSpec.js index b0977235..2ebdc214 100644 --- a/test/ng/filter/limitToSpec.js +++ b/test/ng/filter/limitToSpec.js @@ -2,10 +2,12 @@ describe('Filter: limitTo', function() { var items; + var str var limitTo; beforeEach(inject(function($filter) { items = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']; + str = "tuvwxyz"; limitTo = $filter('limitTo'); })); @@ -13,12 +15,16 @@ describe('Filter: limitTo', function() { it('should return the first X items when X is positive', function() { expect(limitTo(items, 3)).toEqual(['a', 'b', 'c']); expect(limitTo(items, '3')).toEqual(['a', 'b', 'c']); + expect(limitTo(str, 3)).toEqual("tuv"); + expect(limitTo(str, '3')).toEqual("tuv"); }); it('should return the last X items when X is negative', function() { expect(limitTo(items, -3)).toEqual(['f', 'g', 'h']); expect(limitTo(items, '-3')).toEqual(['f', 'g', 'h']); + expect(limitTo(str, -3)).toEqual("xyz"); + expect(limitTo(str, '-3')).toEqual("xyz"); }); @@ -30,11 +36,17 @@ describe('Filter: limitTo', function() { expect(limitTo(items, undefined)).toEqual([]); }); + it('should return an empty string when X cannot be parsed', function() { + expect(limitTo(str, 'bogus')).toEqual(""); + expect(limitTo(str, 'null')).toEqual(""); + expect(limitTo(str, 'undefined')).toEqual(""); + expect(limitTo(str, null)).toEqual(""); + expect(limitTo(str, undefined)).toEqual(""); + }); - it('should return an empty array when input is not Array type', function() { - expect(limitTo('bogus', 1)).toEqual('bogus'); - expect(limitTo(null, 1)).toEqual(null); - expect(limitTo(undefined, 1)).toEqual(undefined); + + it('should return input if not String or Array', function() { + expect(limitTo(1,1)).toEqual(1); expect(limitTo(null, 1)).toEqual(null); expect(limitTo(undefined, 1)).toEqual(undefined); expect(limitTo({}, 1)).toEqual({}); @@ -42,11 +54,18 @@ describe('Filter: limitTo', function() { it('should return a copy of input array if X is exceeds array length', function () { - expect(limitTo(items, 19)).toEqual(items); + expect(limitTo(items, 9)).toEqual(items); expect(limitTo(items, '9')).toEqual(items); expect(limitTo(items, -9)).toEqual(items); expect(limitTo(items, '-9')).toEqual(items); expect(limitTo(items, 9)).not.toBe(items); }); + + it('should return the entire string if X exceeds input length', function() { + expect(limitTo(str, 9)).toEqual(str); + expect(limitTo(str, '9')).toEqual(str); + expect(limitTo(str, -9)).toEqual(str); + expect(limitTo(str, '-9')).toEqual(str); + }) }); |
