diff options
| -rw-r--r-- | src/filters.js | 53 | ||||
| -rw-r--r-- | test/FiltersSpec.js | 106 | ||||
| -rw-r--r-- | test/FiltersTest.js | 70 |
3 files changed, 154 insertions, 75 deletions
diff --git a/src/filters.js b/src/filters.js index f1fc89f1..e2e0e92c 100644 --- a/src/filters.js +++ b/src/filters.js @@ -30,12 +30,55 @@ angularFilter.number = function(amount, fractionSize){ } return text; }; +function padNumber(num, digits, trim) { + var neg = ''; + if (num < 0) { + neg = '-'; + num = -num; + } + num = '' + num; + while(num.length < digits) num = '0' + num; + if (trim) + num = num.substr(num.length - digits); + return neg + num; +} +function dateGetter(name, size, option) { + return function(date) { + var value = date[name].call(date) + 1*(option===1); + if (option == -12 && value > 12) value += option; + return padNumber(value, size, option === true); + }; +} +var DATE_FORMATS = { + yyyy: dateGetter('getFullYear', 4), + yy: dateGetter('getFullYear', 2, true), + MM: dateGetter('getMonth', 2, 1), + dd: dateGetter('getDate', 2), + HH: dateGetter('getHours', 2), + KK: dateGetter('getHours', 2, -12), + mm: dateGetter('getMinutes', 2), + ss: dateGetter('getSeconds', 2), + a: function(date){return date.getHours() < 12 ? 'am' : 'pm'; }, + Z: function(date){ + var offset = date.getTimezoneOffset(); + return padNumber(offset / 60, 2) + padNumber(Math.abs(offset % 60), 2); + } +}; +var DATE_FORMATS_SPLIT = new RegExp('('+ + map(DATE_FORMATS, function(value, key){return key;}).join('|')+')'); +console.log(DATE_FORMATS_SPLIT); -angularFilter.date = function(date) { - if (date instanceof Date) - return date.toLocaleDateString(); - else - return date; +angularFilter.date = function(date, format) { + if (!date instanceof Date) return date; + var text = date.toLocaleDateString(), fn; + if (format && isString(format)) { + text = ''; + foreach(format.split(DATE_FORMATS_SPLIT), function(value){ + fn = DATE_FORMATS[value]; + text += fn ? fn(date) : value; + }); + } + return text; }; angularFilter.json = function(object) { diff --git a/test/FiltersSpec.js b/test/FiltersSpec.js new file mode 100644 index 00000000..1767bede --- /dev/null +++ b/test/FiltersSpec.js @@ -0,0 +1,106 @@ +describe('filter', function(){ + + var filter = angular.filter; + + describe('Currency', function(){ + it('should do basic filter', function(){ + var html = jqLite('<span/>'); + var context = {$element:html}; + var currency = bind(context, filter.currency); + + assertEquals(currency(0), '$0.00'); + assertEquals(html.hasClass('ng:format-negative'), false); + assertEquals(currency(-999), '$-999.00'); + assertEquals(html.hasClass('ng:format-negative'), true); + assertEquals(currency(1234.5678), '$1,234.57'); + assertEquals(html.hasClass('ng:format-negative'), false); + }); + }); + + describe('FilterThisIsContext', function(){ + it('should do basic filter', function(){ + expectAsserts(1); + var scope = createScope(); + scope.name = 'misko'; + filter.testFn = function () { + assertEquals('scope not equal', 'misko', this.name); + }; + scope.$eval("0|testFn"); + delete angular.filter['testFn']; + }); + }); + + describe('NumberFormat', function(){ + it('should do basic filter', function(){ + var context = {jqElement:jqLite('<span/>')}; + var number = bind(context, filter.number); + + assertEquals('0', number(0, 0)); + assertEquals('0.00', number(0)); + assertEquals('-999.00', number(-999)); + assertEquals('1,234.57', number(1234.5678)); + assertEquals('', number(Number.NaN)); + assertEquals('1,234.57', number("1234.5678")); + assertEquals("", number(1/0)); + }); + }); + + describe('Json', function () { + it('should do basic filter', function(){ + assertEquals(toJson({a:"b"}, true), filter.json.call({$element:jqLite('<div></div>')}, {a:"b"})); + }); + }); + + describe('Lowercase', function() { + it('should do basic filter', function(){ + assertEquals('abc', filter.lowercase('AbC')); + assertEquals(null, filter.lowercase(null)); + }); + }); + + describe('Uppercase', function() { + it('should do basic filter', function(){ + assertEquals('ABC', filter.uppercase('AbC')); + assertEquals(null, filter.uppercase(null)); + }); + }); + + describe('Html', function() { + it('should do basic filter', function(){ + var html = filter.html("a<b>c</b>d"); + expect(html instanceof HTML).toBeTruthy(); + expect(html.html).toEqual("a<b>c</b>d"); + }); + }); + + describe('Linky', function() { + it('should do basic filter', function(){ + var linky = filter.linky; + assertEquals( + '<a href="http://ab/">http://ab/</a> ' + + '(<a href="http://a/">http://a/</a>) ' + + '<<a href="http://a/">http://a/</a>> ' + + '<a href="http://1.2/v:~-123">http://1.2/v:~-123</a>. c', + linky("http://ab/ (http://a/) <http://a/> http://1.2/v:~-123. c").html); + assertEquals(undefined, linky(undefined)); + }); + }); + + describe('date', function(){ + var date = angular.String.toDate('2010-10-13T14:45:23Z'); + date.setHours(14); + + it('should do basic filter', function() { + expect(filter.date(date)).toEqual(date.toLocaleDateString()); + expect(filter.date(date, '')).toEqual(date.toLocaleDateString()); + }); + + it('should accept format', function() { + expect(filter.date(date, "yyyy-MM-dd HH:mm:ss")).toEqual('2010-10-13 14:45:23'); + expect(filter.date(date, "yy-MM-dd KK:mm:ssaZ")).toEqual('10-10-13 02:45:23pm0700'); + }); + + + }); +}); + diff --git a/test/FiltersTest.js b/test/FiltersTest.js deleted file mode 100644 index d5484fd0..00000000 --- a/test/FiltersTest.js +++ /dev/null @@ -1,70 +0,0 @@ -FiltersTest = TestCase('FiltersTest'); - -FiltersTest.prototype.testCurrency = function(){ - var html = jqLite('<span/>'); - var context = {$element:html}; - var currency = bind(context, angular.filter.currency); - - assertEquals(currency(0), '$0.00'); - assertEquals(html.hasClass('ng:format-negative'), false); - assertEquals(currency(-999), '$-999.00'); - assertEquals(html.hasClass('ng:format-negative'), true); - assertEquals(currency(1234.5678), '$1,234.57'); - assertEquals(html.hasClass('ng:format-negative'), false); -}; - -FiltersTest.prototype.testFilterThisIsContext = function(){ - expectAsserts(1); - var scope = createScope(); - scope.name = 'misko'; - angular.filter.testFn = function () { - assertEquals('scope not equal', 'misko', this.name); - }; - scope.$eval("0|testFn"); - delete angular.filter['testFn']; -}; - -FiltersTest.prototype.testNumberFormat = function(){ - var context = {jqElement:jqLite('<span/>')}; - var number = bind(context, angular.filter.number); - - assertEquals('0', number(0, 0)); - assertEquals('0.00', number(0)); - assertEquals('-999.00', number(-999)); - assertEquals('1,234.57', number(1234.5678)); - assertEquals('', number(Number.NaN)); - assertEquals('1,234.57', number("1234.5678")); - assertEquals("", number(1/0)); -}; - -FiltersTest.prototype.testJson = function () { - assertEquals(toJson({a:"b"}, true), angular.filter.json.call({$element:jqLite('<div></div>')}, {a:"b"})); -}; - -FiltersTest.prototype.testLowercase = function() { - assertEquals('abc', angular.filter.lowercase('AbC')); - assertEquals(null, angular.filter.lowercase(null)); -}; - -FiltersTest.prototype.testUppercase = function() { - assertEquals('ABC', angular.filter.uppercase('AbC')); - assertEquals(null, angular.filter.uppercase(null)); -}; - -FiltersTest.prototype.testHtml = function() { - var html = angular.filter.html("a<b>c</b>d"); - expect(html instanceof HTML).toBeTruthy(); - expect(html.html).toEqual("a<b>c</b>d"); -}; - -FiltersTest.prototype.testLinky = function() { - var linky = angular.filter.linky; - assertEquals( - '<a href="http://ab/">http://ab/</a> ' + - '(<a href="http://a/">http://a/</a>) ' + - '<<a href="http://a/">http://a/</a>> ' + - '<a href="http://1.2/v:~-123">http://1.2/v:~-123</a>. c', - linky("http://ab/ (http://a/) <http://a/> http://1.2/v:~-123. c").html); - assertEquals(undefined, linky(undefined)); -}; - |
