var validator = require('../validator') , format = require('util').format , assert = require('assert') , path = require('path') , fs = require('fs') , vm = require('vm'); var validator_js = fs.readFileSync(path.join(__dirname, '../validator.js')).toString(); function test(options) { var args = options.args || []; args.unshift(null); if (options.valid) { options.valid.forEach(function (valid) { args[0] = valid; if (validator[options.validator].apply(validator, args) !== true) { var warning = format('validator.%s(%s) failed but should have passed', options.validator, args.join(', ')); throw new Error(warning); } }); } if (options.invalid) { options.invalid.forEach(function (invalid) { args[0] = invalid; if (validator[options.validator].apply(validator, args) !== false) { var warning = format('validator.%s(%s) passed but should have failed', options.validator, args.join(', ')); throw new Error(warning); } }); } } function repeat(str, count) { var result = ''; while (count--) { result += str; } return result; } describe('Validators', function () { it('should validate email addresses', function () { test({ validator: 'isEmail' , valid: [ 'foo@bar.com' , 'x@x.au' , 'foo@bar.com.au' , 'foo+bar@bar.com' , 'hans.m端ller@test.com' , 'hans@m端ller.com' , 'test|123@m端ller.com' , 'test+ext@gmail.com' , 'some.name.midd.leNa.me.+extension@GoogleMail.com' , 'gmail...ignores...dots...@gmail.com' , '"foobar"@example.com' , '" foo m端ller "@example.com' , '"foo\\@bar"@example.com' , repeat('a', 64) + '@' + repeat('a', 252) + '.com' ] , invalid: [ 'invalidemail@' , 'invalid.com' , '@invalid.com' , 'foo@bar.com.' , 'somename@gmail.com' , 'foo@bar.co.uk.' , 'z@co.c' , 'gmailgmailgmailgmailgmail@gmail.com' , repeat('a', 64) + '@' + repeat('a', 253) + '.com' , repeat('a', 65) + '@' + repeat('a', 252) + '.com' ] }); }); it('should validate email addresses without UTF8 characters in local part', function () { test({ validator: 'isEmail' , args: [{ allow_utf8_local_part: false }] , valid: [ 'foo@bar.com' , 'x@x.au' , 'foo@bar.com.au' , 'foo+bar@bar.com' , 'hans@m端ller.com' , 'test|123@m端ller.com' , 'test+ext@gmail.com' , 'some.name.midd.leNa.me.+extension@GoogleMail.com' , '"foobar"@example.com' , '"foo\\@bar"@example.com' , '" foo bar "@example.com' ] , invalid: [ 'invalidemail@' , 'invalid.com' , '@invalid.com' , 'foo@bar.com.' , 'foo@bar.co.uk.' , 'somename@gmail.com' , 'hans.m端ller@test.com' , 'z@co.c' ] }); }); it('should validate email addresses with display names', function () { test({ validator: 'isEmail' , args: [{ allow_display_name: true }] , valid: [ 'foo@bar.com' , 'x@x.au' , 'foo@bar.com.au' , 'foo+bar@bar.com' , 'hans.m端ller@test.com' , 'hans@m端ller.com' , 'test|123@m端ller.com' , 'test+ext@gmail.com' , 'some.name.midd.leNa.me.+extension@GoogleMail.com' , 'Some Name ' , 'Some Name ' , 'Some Name ' , 'Some Name ' , 'Some Name ' , 'Some Name ' , 'Some Name ' , 'Some Name ' , 'Some Name ' , 'Some Middle Name ' , 'Name ' , 'Name' ] , invalid: [ 'invalidemail@' , 'invalid.com' , '@invalid.com' , 'foo@bar.com.' , 'foo@bar.co.uk.' , 'Some Name ' , 'Some Name ' , 'Some Name <@invalid.com>' , 'Some Name ' , 'Some Name ' , 'Some Name foo@bar.co.uk.>' , 'Some Name ' , 'Name foo@bar.co.uk' ] }); }); it('should validate URLs', function () { test({ validator: 'isURL' , valid: [ 'foobar.com' , 'www.foobar.com' , 'foobar.com/' , 'valid.au' , 'http://www.foobar.com/' , 'http://www.foobar.com:23/' , 'http://www.foobar.com:65535/' , 'http://www.foobar.com:5/' , 'https://www.foobar.com/' , 'ftp://www.foobar.com/' , 'http://www.foobar.com/~foobar' , 'http://user:pass@www.foobar.com/' , 'http://user:@www.foobar.com/' , 'http://127.0.0.1/' , 'http://10.0.0.0/' , 'http://189.123.14.13/' , 'http://duckduckgo.com/?q=%2F' , 'http://foobar.com/t$-_.+!*\'(),' , 'http://localhost:3000/' , 'http://foobar.com/?foo=bar#baz=qux' , 'http://foobar.com?foo=bar' , 'http://foobar.com#baz=qux' , 'http://www.xn--froschgrn-x9a.net/' , 'http://xn--froschgrn-x9a.com/' , 'http://foo--bar.com' , 'http://høyfjellet.no' , 'http://xn--j1aac5a4g.xn--j1amh' , 'http://кулік.укр' ] , invalid: [ 'xyz://foobar.com' , 'invalid/' , 'invalid.x' , 'invalid.' , '.com' , 'http://com/' , 'http://300.0.0.1/' , 'mailto:foo@bar.com' , 'rtmp://foobar.com' , 'http://www.xn--.com/' , 'http://xn--.com/' , 'http://www.foobar.com:0/' , 'http://www.foobar.com:70000/' , 'http://www.foobar.com:99999/' , 'http://www.-foobar.com/' , 'http://www.foobar-.com/' , 'http://www.foo---bar.com/' , 'http://foobar/# lol' , 'http://foobar/? lol' , 'http://foobar/ lol/' , 'http://lol @foobar.com/' , 'http://lol:lol @foobar.com/' , 'http://lol:lol:lol@foobar.com/' , 'http://lol: @foobar.com/' , 'http://www.foo_bar.com/' , 'http://www.foobar.com/\t' , 'http://\n@www.foobar.com/' , '' , 'http://foobar.com/' + new Array(2083).join('f') , 'http://*.foo.com' , '*.foo.com' , '!.foo.com' , 'http://example.com.' , 'http://localhost:61500this is an invalid url!!!!' , '////foobar.com' , 'http:////foobar.com' ] }); }); it('should validate URLs with custom protocols', function () { test({ validator: 'isURL' , args: [{ protocols: [ 'rtmp' ] }] , valid: [ 'rtmp://foobar.com' ] , invalid: [ 'http://foobar.com' ] }); }); it('should validate URLs with any protocol', function () { test({ validator: 'isURL' , args: [{ require_valid_protocol: false }] , valid: [ 'rtmp://foobar.com', 'http://foobar.com', 'test://foobar.com' ] , invalid: [ 'mailto:test@example.com' ] }); }); it('should validate URLs with underscores', function () { test({ validator: 'isURL' , args: [{ allow_underscores: true }] , valid: [ 'http://foo_bar.com' , 'http://pr.example_com.294.example.com/' ] , invalid: [ 'http://foo__bar.com' ] }); }); it('should validate URLs that do not have a TLD', function () { test({ validator: 'isURL' , args: [{ require_tld: false }] , valid: [ 'http://foobar.com/' , 'http://foobar/' , 'foobar/' , 'foobar' ] , invalid: [ ] }); }); it('should validate URLs with a trailing dot option', function () { test({ validator: 'isURL' , args: [{ allow_trailing_dot: true , require_tld: false }] , valid: [ 'http://example.com.' , 'foobar.' ] }); }); it('should validate protocol relative URLs', function () { test({ validator: 'isURL' , args: [{ allow_protocol_relative_urls: true }] , valid: [ '//foobar.com' , 'http://foobar.com' , 'foobar.com' ] , invalid: [ '://foobar.com' , '/foobar.com' , '////foobar.com' , 'http:////foobar.com' ] }); }); it('should not validate protocol relative URLs when require protocol is true', function () { test({ validator: 'isURL' , args: [{ allow_protocol_relative_urls: true, require_protocol: true }] , valid: [ 'http://foobar.com' ] , invalid: [ '//foobar.com' , '://foobar.com' , '/foobar.com' , 'foobar.com' ] }); }); it('should let users specify whether URLs require a protocol', function () { test({ validator: 'isURL' , args: [{ require_protocol: true }] , valid: [ 'http://foobar.com/' , 'http://localhost/' ] , invalid: [ 'foobar.com' , 'foobar' ] }); }); it('should let users specify a host whitelist', function () { test({ validator: 'isURL' , args: [{ host_whitelist: ['foo.com', 'bar.com'] }] , valid: [ 'http://bar.com/' , 'http://foo.com/' ] , invalid: [ 'http://foobar.com' , 'http://foo.bar.com/' , 'http://qux.com' ] }); }); it('should let users specify a host blacklist', function () { test({ validator: 'isURL' , args: [{ host_blacklist: ['foo.com', 'bar.com'] }] , valid: [ 'http://foobar.com' , 'http://foo.bar.com/' , 'http://qux.com' ] , invalid: [ 'http://bar.com/' , 'http://foo.com/' ] }); }); it('should validate IP addresses', function () { test({ validator: 'isIP' , valid: [ '127.0.0.1' , '0.0.0.0' , '255.255.255.255' , '1.2.3.4' , '::1' , '2001:db8:0000:1:1:1:1:1' , '2001:41d0:2:a141::1' , '::ffff:127.0.0.1' , '::0000' , '0000::' , '1::' , '1111:1:1:1:1:1:1:1' , 'fe80::a6db:30ff:fe98:e946' , '::' , '::ffff:127.0.0.1' , '0:0:0:0:0:ffff:127.0.0.1' ] , invalid: [ 'abc' , '256.0.0.0' , '0.0.0.256' , '26.0.0.256' , '::banana' , 'banana::' , '::1banana' , '::1::' , '1:' , ':1' , ':1:1:1::2' , '1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1' , '::11111' , '11111:1:1:1:1:1:1:1' , '2001:db8:0000:1:1:1:1::1' , '0:0:0:0:0:0:ffff:127.0.0.1' , '0:0:0:0:ffff:127.0.0.1' ] }); test({ validator: 'isIP' , args: [ 4 ] , valid: [ '127.0.0.1' , '0.0.0.0' , '255.255.255.255' , '1.2.3.4' ] , invalid: [ '::1' , '2001:db8:0000:1:1:1:1:1' , '::ffff:127.0.0.1' ] }); test({ validator: 'isIP' , args: [ 6 ] , valid: [ '::1' , '2001:db8:0000:1:1:1:1:1' , '::ffff:127.0.0.1' ] , invalid: [ '127.0.0.1' , '0.0.0.0' , '255.255.255.255' , '1.2.3.4' , '::ffff:287.0.0.1' ] }); test({ validator: 'isIP' , args: [ 10 ] , valid: [ ] , invalid: [ '127.0.0.1' , '0.0.0.0' , '255.255.255.255' , '1.2.3.4' , '::1' , '2001:db8:0000:1:1:1:1:1' ] }); }); it('should validate FQDN', function () { test({ validator: 'isFQDN' , valid: [ 'domain.com' , 'dom.plato' , 'a.domain.co' , 'foo--bar.com' , 'xn--froschgrn-x9a.com' , 'rebecca.blackfriday' ] , invalid: [ 'abc' , '256.0.0.0' , '_.com' , '*.some.com' , 's!ome.com' , 'domain.com/' , '/more.com' ] }); }); it('should validate FQDN with trailing dot option', function() { test({ validator: 'isFQDN' , args: [ {allow_trailing_dot:true} ] , valid: [ 'example.com.' ] }); }); it('should validate alpha strings', function () { test({ validator: 'isAlpha' , valid: [ 'abc' , 'ABC' , 'FoObar' ] , invalid: [ 'abc1' , ' foo ' , '' ] }); }); it('should validate alphanumeric strings', function () { test({ validator: 'isAlphanumeric' , valid: [ 'abc123' , 'ABC11' ] , invalid: [ 'abc ' , 'foo!!' ] }); }); it('should validate numeric strings', function () { test({ validator: 'isNumeric' , valid: [ '123' , '00123' , '-00123' , '0' , '-0' , '+123' ] , invalid: [ '123.123' , ' ' , '.' ] }); }); it('should validate decimal numbers', function () { test({ validator: 'isDecimal' , valid: [ '123' , '00123' , '-00123' , '0' , '-0' , '+123' , '0.01' , '.1' , '1.0' , '-.25' , '-0' , '0.0000000000001' ] , invalid: [ '....' , ' ' , '' , '-' , '+' , '.' , '0.1a' , 'a' , '\n' ] }); }); it('should validate lowercase strings', function () { test({ validator: 'isLowercase' , valid: [ 'abc' , 'abc123' , 'this is lowercase.' , 'tr竪s 端ber' ] , invalid: [ 'fooBar' , '123A' ] }); }); it('should validate uppercase strings', function () { test({ validator: 'isUppercase' , valid: [ 'ABC' , 'ABC123' , 'ALL CAPS IS FUN.' , ' .' ] , invalid: [ 'fooBar' , '123abc' ] }); }); it('should validate integers', function () { test({ validator: 'isInt' , valid: [ '13' , '123' , '0' , '123' , '-0' , '+1' ] , invalid: [ '01' , '-01' , '000' , '100e10' , '123.123' , ' ' , '' ] }); test({ validator: 'isInt', args: [{ min: 10 }], valid: [15, 80, 99], invalid: [9, 6, 3.2, 'a'] } ); test({ validator: 'isInt', args: [{ min: 10, max: 15 }], valid: [15, 11, 13], invalid: [9, 2, 17, 3.2, 33, 'a'] } ); }); it('should validate floats', function () { test({ validator: 'isFloat' , valid: [ '123' , '123.' , '123.123' , '-123.123' , '-0.123' , '+0.123' , '0.123' , '.0' , '01.123' , '-0.22250738585072011e-307' ] , invalid: [ '-.123' , ' ' , '' , '.' , 'foo' ] }); test({ validator: 'isFloat', args: [{ min: 3.7 }], valid: [3.888, 3.92, 4.5, 50, 3.7, 3.71], invalid: [3.6, 3.69, 3, 1.5, 'a'] } ); test({ validator: 'isFloat', args: [{ min: 0.1, max: 1.0 }], valid: [0.1, 1.0, 0.15, 0.33, 0.57, 0.7], invalid: [0, 0.0, 'a', 1.3, 0.05, 5] } ); }); it('should validate hexadecimal strings', function () { test({ validator: 'isHexadecimal' , valid: [ 'deadBEEF' , 'ff0044' ] , invalid: [ 'abcdefg' , '' , '..' ] }); }); it('should validate hexadecimal color strings', function () { test({ validator: 'isHexColor' , valid: [ '#ff0034' , '#CCCCCC' , 'fff' , '#f00' ] , invalid: [ '#ff' , 'fff0' , '#ff12FG' ] }); }); it('should validate null strings', function () { test({ validator: 'isNull' , valid: [ '' , NaN , [] , undefined , null ] , invalid: [ ' ' , 'foo' ] }); }); it('should validate strings against an expected value', function () { test({ validator: 'equals', args: ['abc'], valid: ['abc'], invalid: ['Abc', '123'] }); }); it('should validate strings contain another string', function () { test({ validator: 'contains', args: ['foo'], valid: ['foo', 'foobar', 'bazfoo'], invalid: ['bar', 'fobar'] }); }); it('should validate strings against a pattern', function () { test({ validator: 'matches', args: [/abc/], valid: ['abc', 'abcdef', '123abc'], invalid: ['acb', 'Abc'] }); test({ validator: 'matches', args: ['abc'], valid: ['abc', 'abcdef', '123abc'], invalid: ['acb', 'Abc'] }); test({ validator: 'matches', args: ['abc', 'i'], valid: ['abc', 'abcdef', '123abc', 'AbC'], invalid: ['acb'] }); }); it('should validate strings by length', function () { test({ validator: 'isLength', args: [2], valid: ['abc', 'de', 'abcd'], invalid: [ '', 'a' ] }); test({ validator: 'isLength', args: [2, 3], valid: ['abc', 'de'], invalid: [ '', 'a', 'abcd' ] }); test({ validator: 'isLength', args: [2, 3], valid: ['干𩸽', '𠮷野家'], invalid: [ '', '𠀋', '千竈通り' ] }); }); it('should validate strings by byte length', function () { test({ validator: 'isByteLength', args: [2], valid: ['abc', 'de', 'abcd', 'gmail'], invalid: [ '', 'a' ] }); test({ validator: 'isByteLength', args: [2, 3], valid: ['abc', 'de', 'g'], invalid: [ '', 'a', 'abcd', 'gm' ] }); }); it('should validate UUIDs', function () { test({ validator: 'isUUID' , valid: [ 'A987FBC9-4BED-3078-CF07-9141BA07C9F3' , 'A987FBC9-4BED-4078-8F07-9141BA07C9F3' , 'A987FBC9-4BED-5078-AF07-9141BA07C9F3' ] , invalid: [ '' , 'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3' , 'A987FBC9-4BED-3078-CF07-9141BA07C9F3xxx' , 'A987FBC94BED3078CF079141BA07C9F3' , '934859' , '987FBC9-4BED-3078-CF07A-9141BA07C9F3' , 'AAAAAAAA-1111-1111-AAAG-111111111111' ] }); test({ validator: 'isUUID' , args: [ 3 ] , valid: [ 'A987FBC9-4BED-3078-CF07-9141BA07C9F3' ] , invalid: [ '' , 'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3' , '934859' , 'AAAAAAAA-1111-1111-AAAG-111111111111' , 'A987FBC9-4BED-4078-8F07-9141BA07C9F3' , 'A987FBC9-4BED-5078-AF07-9141BA07C9F3' ] }); test({ validator: 'isUUID' , args: [ 4 ] , valid: [ '713ae7e3-cb32-45f9-adcb-7c4fa86b90c1' , '625e63f3-58f5-40b7-83a1-a72ad31acffb' , '57b73598-8764-4ad0-a76a-679bb6640eb1' , '9c858901-8a57-4791-81fe-4c455b099bc9' ] , invalid: [ '' , 'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3' , '934859' , 'AAAAAAAA-1111-1111-AAAG-111111111111' , 'A987FBC9-4BED-5078-AF07-9141BA07C9F3' , 'A987FBC9-4BED-3078-CF07-9141BA07C9F3' ] }); test({ validator: 'isUUID' , args: [ 5 ] , valid: [ '987FBC97-4BED-5078-AF07-9141BA07C9F3' , '987FBC97-4BED-5078-BF07-9141BA07C9F3' , '987FBC97-4BED-5078-8F07-9141BA07C9F3' , '987FBC97-4BED-5078-9F07-9141BA07C9F3' ] , invalid: [ '' , 'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3' , '934859' , 'AAAAAAAA-1111-1111-AAAG-111111111111' , '9c858901-8a57-4791-81fe-4c455b099bc9' , 'A987FBC9-4BED-3078-CF07-9141BA07C9F3' ] }); }); it('should validate a string that is in another string or array', function () { test({ validator: 'isIn', args: ['foobar'], valid: ['foo', 'bar', 'foobar', ''], invalid: ['foobarbaz', 'barfoo'] }); test({ validator: 'isIn', args: [['foo', 'bar']], valid: ['foo', 'bar'], invalid: ['foobar', 'barfoo', ''] }); test({ validator: 'isIn', args: [[1, 2, 3]], valid: ['1', '2', '3'], invalid: ['4', ''] }); test({ validator: 'isIn', invalid: ['foo', ''] }); }); it('should validate a string that is in another object', function () { test({ validator: 'isIn', args: [{'foo':1, 'bar':2, 'foobar':3}], valid: ['foo', 'bar', 'foobar'], invalid: ['foobarbaz', 'barfoo', ''] }); test({ validator: 'isIn', args: [{1:3, 2:0, 3:1}], valid: ['1', '2', '3'], invalid: ['4', ''] }); }); it('should validate dates', function () { test({ validator: 'isDate' , valid: [ '2011-08-04' , '2011-09-30' , '04. 08. 2011.' , '08/04/2011' , '08/31/2011' , '2011.08.04' , '2/29/24' , '2-29-24' , '4. 8. 2011. GMT' , '2. 28. 2011. GMT' , '2. 29. 2008. GMT' , '2011-08-04 12:00' , '2/22/23' , '2-23-22' , '12' , '11/2/23 12:24' , new Date() , 'Mon Aug 17 2015 00:24:56 GMT-0500 (CDT)' , '2/22/23 23:24:26' // valid ISO 8601 dates below , '2009-12T12:34' , '2009' , '2009-05-19' , '2009-05-19' , '2009-05' , '2009-001' , '2009-05-19' , '2009-05-19 00:00' , '2009-05-19 14:31' , '2009-05-19 14:39:22' , '2009-05-19T14:39Z' , '2009-05-19 14:39:22-06:00' , '2009-05-19 14:39:22+0600' , '2009-05-19 14:39:22-01' , '2015-10-20T00:53:09+08:00' , '2015-10-20T00:53:09+09:00' , '2015-10-20T00:53:09+10:00' , '2015-10-20T00:53:09+11:00' , '2015-10-20T00:53:09+12:00' , '2007-04-06T00:00' , '2010-02-18T16:23:48.5' , '200905' , '2009-' , '2009-05-19 14:' , '200912-01' // RFC 2882 tests below borrowed from the timerep package in Hackage: // https://hackage.haskell.org/package/timerep-1.0.3/docs/src/Data-Time-RFC2822.html , 'Fri, 21 Nov 1997 09:55:06 -0600' , 'Tue, 15 Nov 1994 12:45:26 GMT' , 'Tue, 1 Jul 2003 10:52:37 +0200' , 'Thu, 13 Feb 1969 23:32:54 -0330' , 'Mon, 24 Nov 1997 14:22:01 -0800' , 'Mon Sep 28 1964 00:05:49 GMT+1100 (AEDST)' , 'Mon Sep 28 1964 00:05:49 +1100 (AEDST)' , 'Mon Sep 28 1964 00:05:49 +1100' , 'Mon Sep 28 1964 00:05:49 \nGMT\n+1100\n' , 'Mon Sep 28 1964 00:05:49 \nGMT\n+1100\n(AEDST)' , 'Thu, 13\n Feb\n 1969\n 23:32\n -0330' , 'Thu, 13\n Feb\n 1969\n 23:32\n -0330 (Newfoundland Time)' ,'24 Nov 1997 14:22:01 -0800' // slight variations of the above with end-of-month , 'Thu, 29\n Feb\n 1968\n 13:32\n -0330' , 'Fri, 30 Nov 1997 09:55:06 -0600' // more RFC 2882 tests borrowed from libgit2: // https://github.com/libgit2/libgit2/blob/master/tests/date/rfc2822.c , 'Wed, 10 Apr 2014 08:21:03 +0000' , 'Wed, 9 Apr 2014 10:21:03 +0200' , 'Wed, 9 Apr 2014 06:21:03 -0200' , 'Wed, 9 Apr 2014 08:21:03 +0000' ] , invalid: [ 'foo' , '2011-foo-04' , '2011-09-31' , '2. 29. 1987. GMT' , '2. 29. 2011. GMT' , '2/29/25' , '2-29-25' , 'GMT' //invalid ISO 8601 dates below , '2009367' , '2007-04-05T24:50' , '2009-000' , '2009-M511' , '2009M511' , '2009-05-19T14a39r' , '2009-05-19T14:3924' , '2009-0519' , '2009-05-1914:39' , '2009-05-19r14:39' , '2009-05-19 14a39a22' , '2009-05-19 14:39:22+06a00' , '2009-05-19 146922.500' , '2010-02-18T16.5:23.35:48' , '2010-02-18T16:23.35:48' , '2010-02-18T16:23.35:48.45' , '2009-05-19 14.5.44' , '2010-02-18T16:23.33.600' , '2010-02-18T16,25:23:48,444' , '2009-02-30 14:' , '200912-32' // hackage RFC2822 variants with invalid end-of-month , 'Thu, 29\n Feb\n 1969\n 13:32\n -0330' , 'Fri, 31 Nov 1997 09:55:06 -0600' ] }); }); it('should validate dates against a start date', function () { test({ validator: 'isAfter', args: ['2011-08-03'], valid: [ '2011-08-04', new Date(2011, 8, 10) ], invalid: [ '2010-07-02', '2011-08-03', new Date(0), 'foo'] }); test({ validator: 'isAfter', valid: [ '2100-08-04', new Date(Date.now() + 86400000) ], invalid: [ '2010-07-02', new Date(0) ] }); test({ validator: 'isAfter', args: ['2011-08-03'], valid: [ '2015-09-17' ], invalid: [ 'invalid date' ] }); test({ validator: 'isAfter', args: ['invalid date'], invalid: [ 'invalid date', '2015-09-17' ] }); }); it('should validate dates against an end date', function () { test({ validator: 'isBefore', args: ['08/04/2011'], valid: [ '2010-07-02', '2010-08-04', new Date(0) ], invalid: [ '08/04/2011', new Date(2011, 9, 10) ] }); test({ validator: 'isBefore', args: [ new Date(2011, 7, 4) ], valid: [ '2010-07-02', '2010-08-04', new Date(0) ], invalid: [ '08/04/2011', new Date(2011, 9, 10) ] }); test({ validator: 'isBefore', valid: [ '2000-08-04', new Date(0), new Date(Date.now() - 86400000) ], invalid: [ '2100-07-02', new Date(2017, 10, 10) ] }); test({ validator: 'isBefore', args: ['2011-08-03'], valid: [ '1999-12-31' ], invalid: [ 'invalid date' ] }); test({ validator: 'isBefore', args: ['invalid date'], invalid: [ 'invalid date', '1999-12-31' ] }); }); it('should validate that integer strings are divisible by a number', function () { test({ validator: 'isDivisibleBy' , args: [ 2 ] , valid: [ '2', '4', '100', '1000' ] , invalid: [ '1' , '2.5' , '101' , 'foo' , '' ] }); }); it('should validate credit cards', function () { test({ validator: 'isCreditCard' , valid: [ '375556917985515' , '36050234196908' , '4716461583322103' , '4716-2210-5188-5662' , '4929 7226 5379 7141' , '5398228707871527' ] , invalid: [ 'foo' , 'foo' , '5398228707871528' ] }); }); it('should validate ISINs', function () { test({ validator: 'isISIN' , valid: [ 'AU0000XVGZA3' , 'DE000BAY0017' , 'BE0003796134' , 'SG1G55870362' , 'GB0001411924' , 'DE000WCH8881' , 'PLLWBGD00016' ] , invalid: [ 'DE000BAY0018' , 'PLLWBGD00019' , 'foo' , '5398228707871528' ] }); }); it('should validate ISBNs', function () { test({ validator: 'isISBN' , args: [ 10 ] , valid: [ '3836221195', '3-8362-2119-5', '3 8362 2119 5' , '1617290858', '1-61729-085-8', '1 61729 085-8' , '0007269706', '0-00-726970-6', '0 00 726970 6' , '3423214120', '3-423-21412-0', '3 423 21412 0' , '340101319X', '3-401-01319-X', '3 401 01319 X' ] , invalid: [ '3423214121', '3-423-21412-1', '3 423 21412 1' , '978-3836221191', '9783836221191' , '123456789a', 'foo', '' ] }); test({ validator: 'isISBN' , args: [ 13 ] , valid: [ '9783836221191', '978-3-8362-2119-1', '978 3 8362 2119 1' , '9783401013190', '978-3401013190', '978 3401013190' , '9784873113685', '978-4-87311-368-5', '978 4 87311 368 5' ] , invalid: [ '9783836221190', '978-3-8362-2119-0', '978 3 8362 2119 0' , '3836221195', '3-8362-2119-5', '3 8362 2119 5' , '01234567890ab', 'foo', '' ] }); test({ validator: 'isISBN' , valid: [ '340101319X' , '9784873113685' ] , invalid: [ '3423214121' , '9783836221190' ] }); test({ validator: 'isISBN' , args: [ 'foo' ] , invalid: [ '340101319X' , '9784873113685' ] }); }); it('should validate JSON', function () { test({ validator: 'isJSON' , valid: [ '{ "key": "value" }' , '{}' ] , invalid: [ '{ key: "value" }' , { "key": "value" } , { key: 'value' } , '{ \'key\': \'value\' }' , 'null' , '1234' , 'false' , '"nope"' ] }); }); it('should validate multibyte strings', function () { test({ validator: 'isMultibyte' , valid: [ 'ひらがな・カタカナ、.漢字' , 'あいうえお foobar' , 'test@example.com' , '1234abcDExyz' , 'カタカナ' , '中文' ] , invalid: [ 'abc' , 'abc123' , '<>@" *.' ] }); }); it('should validate ascii strings', function () { test({ validator: 'isAscii' , valid: [ 'foobar' , '0987654321' , 'test@example.com' , '1234abcDEF' ] , invalid: [ 'foobar' , 'xyz098' , '123456' , 'カタカナ' ] }); }); it('should validate full-width strings', function () { test({ validator: 'isFullWidth' , valid: [ 'ひらがな・カタカナ、.漢字' , '3ー0 a@com' , 'Fカタカナ゙ᆲ' , 'Good=Parts' ] , invalid: [ 'abc' , 'abc123' , '!"#$%&()<>/+=-_? ~^|.,@`{}[]' ] }); }); it('should validate half-width strings', function () { test({ validator: 'isHalfWidth' , valid: [ '!"#$%&()<>/+=-_? ~^|.,@`{}[]' , 'l-btn_02--active' , 'abc123い' , 'カタカナ゙ᆲ←' ] , invalid: [ 'あいうえお' , '0011' ] }); }); it('should validate variable-width strings', function () { test({ validator: 'isVariableWidth' , valid: [ 'ひらがなカタカナ漢字ABCDE' , '3ー0123' , 'Fカタカナ゙ᆲ' , 'Good=Parts' ] , invalid: [ 'abc' , 'abc123' , '!"#$%&()<>/+=-_? ~^|.,@`{}[]' , 'ひらがな・カタカナ、.漢字' , '123456' , 'カタカナ゙ᆲ' ] }); }); it('should validate surrogate pair strings', function () { test({ validator: 'isSurrogatePair' , valid: [ '𠮷野𠮷' , '𩸽' , 'ABC千𥧄1-2-3' ] , invalid: [ '吉野竈' , '鮪' , 'ABC1-2-3' ] }); }); it('should validate base64 strings', function () { test({ validator: 'isBase64' , valid: [ 'TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=' , 'Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==' , 'U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==' , 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw'+ 'UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye'+ 'rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619'+ 'FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx'+ 'QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ'+ 'Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ'+ 'HQIDAQAB' ] , invalid: [ '12345' , '' , 'Vml2YW11cyBmZXJtZtesting123' ] }); for (var i = 0, str = '', encoded; i < 1000; i++) { str += String.fromCharCode(Math.random() * 26 | 97); encoded = new Buffer(str).toString('base64'); if (!validator.isBase64(encoded)) { var msg = format('validator.isBase64() failed with "%s"', encoded); throw new Error(msg); } } }); it('should validate hex-encoded MongoDB ObjectId', function () { test({ validator: 'isMongoId' , valid: [ '507f1f77bcf86cd799439011' ] , invalid: [ '507f1f77bcf86cd7994390' , '507f1f77bcf86cd79943901z' , '' , '507f1f77bcf86cd799439011 ' ] }); }); it('should define the module using an AMD-compatible loader', function () { var window = { validator: null , define: function (module) { this.validator = module; } }; window.define.amd = true; var sandbox = vm.createContext(window); vm.runInContext(validator_js, sandbox); assert.equal(window.validator.trim(' foobar '), 'foobar'); }); it('should bind validator to the window if no module loaders are available', function () { var window = {}; var sandbox = vm.createContext(window); vm.runInContext(validator_js, sandbox); assert.equal(window.validator.trim(' foobar '), 'foobar'); }); it('should validate mobile phone number', function () { test({ validator: 'isMobilePhone' , valid: [ '15323456787' , '13523333233' , '13898728332' , '+086-13238234822' , '08613487234567' , '8617823492338' , '86-17823492338' ] , invalid: [ '12345' , '' , 'Vml2YW11cyBmZXJtZtesting123' , '010-38238383' ], args: ['zh-CN'] }); test({ validator: 'isMobilePhone' , valid: [ '0987123456' , '+886987123456' , '886987123456' , '+886-987123456' , '886-987123456' ] , invalid: [ '12345' , '' , 'Vml2YW11cyBmZXJtZtesting123' , '0-987123456' ], args: ['zh-TW'] }); test({ validator: 'isMobilePhone' , invalid: [ '15323456787' , '13523333233' , '13898728332' , '+086-13238234822' , '08613487234567' , '8617823492338' , '86-17823492338' ], args: ['en'] }); test({ validator: 'isMobilePhone' , valid: [ '0821231234' , '+27821231234' , '27821231234' ] , invalid: [ '082123' , '08212312345' , '21821231234' , '+21821231234' , '+0821231234' ], args: ['en-ZA'] }); test({ validator: 'isMobilePhone' , valid: [ '61404111222' , '+61411222333' , '0417123456' ] , invalid: [ '082123' , '08212312345' , '21821231234' , '+21821231234' , '+0821231234' , '04123456789' ], args: ['en-AU'] }); test({ validator: 'isMobilePhone' , valid: [ '91234567' , '9123-4567' , '61234567' , '51234567' , '+85291234567' , '+852-91234567' , '+852-9123-4567' , '852-91234567' ] , invalid: [ '999' , '+852-912345678' , '123456789' , '+852-1234-56789' ], args: ['en-HK'] }); test({ validator: 'isMobilePhone' , valid: [ '0612457898' , '+33612457898' , '33612457898' , '0712457898' , '+33712457898' , '33712457898' ] , invalid: [ '061245789' , '06124578980' , '0112457898' , '0212457898' , '0312457898' , '0412457898' , '0512457898' , '0812457898' , '0912457898' , '+34612457898' , '+336124578980' , '+3361245789' ] , args: ['fr-FR'] }); test({ validator: 'isMobilePhone' , valid: [ '2102323234' , '+302646041461' , '+306944848966' , '6944848966' ] , invalid: [ '120000000' , '20000000000' , '68129485729' , '6589394827' , '298RI89572' ] , args: ['el-GR'] }); test({ validator: 'isMobilePhone' , valid: [ '447789345856' , '+447861235675' , '07888814488' ] , invalid: [ '67699567' , '0773894868' , '077389f8688' , '+07888814488' , '0152456999' , '442073456754' , '+443003434751' , '05073456754' , '08001123123' ] , args: ['en-GB'] }); test({ validator: 'isMobilePhone' , valid: [ '19876543210' , '8005552222' , '+15673628910' ] , invalid: [ '564785' , '0123456789' , '1437439210' , '8009112340' , '+10345672645' , '11435213543' , '2436119753' , '16532116190' ] , args: ['en-US'] }); test({ validator: 'isMobilePhone' , valid: [ '0956684590' , '0966684590' , '0976684590' , '+260956684590' , '+260966684590' , '+260976684590' ] , invalid: [ '12345' , '' , 'Vml2YW11cyBmZXJtZtesting123' , '010-38238383' , '966684590' , '260976684590' ], args: ['en-ZM'] }); test({ validator: 'isMobilePhone' , valid: [ '+79676338855' , '79676338855' , '89676338855' , '9676338855' ] , invalid: [ '12345' , '' , 'Vml2YW11cyBmZXJtZtesting123' , '010-38238383' , '+9676338855' , '19676338855' , '6676338855' , '+99676338855' ], args: ['ru-RU'] }); var norwegian = { valid: [ '+4796338855' , '+4746338855' , '4796338855' , '4746338855' , '46338855' , '96338855' ] , invalid: [ '12345' , '' , 'Vml2YW11cyBmZXJtZtesting123' , '+4676338855' , '19676338855' , '+4726338855' , '4736338855' , '66338855' ]}; test({ validator: 'isMobilePhone' , valid: norwegian.valid , invalid: norwegian.invalid, args: ['nb-NO'] }); test({ validator: 'isMobilePhone' , valid: norwegian.valid , invalid: norwegian.invalid, args: ['nn-NO'] }); }); it('should validate currency', function() { test({ validator: 'isCurrency' , args: [ {} , '-$##,###.## (en-US, en-CA, en-AU, en-NZ, en-HK)' ] , valid: [ '-$10,123.45' , '$10,123.45' , '$10123.45' , '10,123.45' , '10123.45' , '10,123' , '1,123,456' , '1123456' , '1.39' , '.03' , '0.10' , '$0.10' , '-$0.01' , '-$.99' , '$100,234,567.89' , '$10,123' , '10,123' , '-10123' ] , invalid: [ '1.234' , '$1.1' , '$ 32.50' , '500$' , '.0001' , '$.001' , '$0.001' , '12,34.56' , '123456,123,123456' , '123,4' , ',123' , '$-,123' , '$' , '.' , ',' , '00' , '$-' , '$-,.' , '-' , '-$' , '' , '- $' ] }); test({ validator: 'isCurrency' , args: [ { require_symbol: true } , '-$##,###.## with $ required (en-US, en-CA, en-AU, en-NZ, en-HK)' ] , valid: [ '-$10,123.45' , '$10,123.45' , '$10123.45' , '$10,123.45' , '$10,123' , '$1,123,456' , '$1123456' , '$1.39' , '$.03' , '$0.10' , '$0.10' , '-$0.01' , '-$.99' , '$100,234,567.89' , '$10,123' , '-$10123' ] , invalid: [ '1.234' , '$1.234' , '1.1' , '$1.1' , '$ 32.50' , ' 32.50' , '500' , '10,123,456' , '.0001' , '$.001' , '$0.001' , '1,234.56' , '123456,123,123456' , '$123456,123,123456' , '123.4' , '$123.4' , ',123' , '$,123' , '$-,123' , '$' , '.' , '$.' , ',' , '$,' , '00' , '$00' , '$-' , '$-,.' , '-' , '-$' , '' , '$ ' , '- $' ] }); test({ validator: 'isCurrency' , args: [ { symbol:'¥' , negative_sign_before_digits:true } , '¥-##,###.## (zh-CN)' ] , valid: [ '123,456.78' , '-123,456.78' , '¥6,954,231' , '¥-6,954,231' , '¥10.03' , '¥-10.03' , '10.03' , '1.39' , '.03' , '0.10' , '¥-10567.01' , '¥0.01' , '¥1,234,567.89' , '¥10,123' , '¥-10,123' , '¥-10,123.45' , '10,123' , '10123' , '¥-100' ] , invalid: [ '1.234' , '¥1.1' , '5,00' , '.0001' , '¥.001' , '¥0.001' , '12,34.56' , '123456,123,123456' , '123 456' , ',123' , '¥-,123' , '' , ' ' , '¥' , '¥-' , '¥-,.' , '-' , '- ¥' , '-¥' ] }); test({ validator: 'isCurrency' , args: [ { symbol:'¥' , allow_negatives: false } , '¥##,###.## with no negatives (zh-CN)' ] , valid: [ '123,456.78' , '¥6,954,231' , '¥10.03' , '10.03' , '1.39' , '.03' , '0.10' , '¥0.01' , '¥1,234,567.89' , '¥10,123' , '10,123' , '10123' , '¥100' ] , invalid: [ '1.234' , '-123,456.78' , '¥-6,954,231' , '¥-10.03' , '¥-10567.01' , '¥1.1' , '¥-10,123' , '¥-10,123.45' , '5,00' , '¥-100' , '.0001' , '¥.001' , '¥-.001' , '¥0.001' , '12,34.56' , '123456,123,123456' , '123 456' , ',123' , '¥-,123' , '' , ' ' , '¥' , '¥-' , '¥-,.' , '-' , '- ¥' , '-¥' ] }); test({ validator: 'isCurrency' , args: [ { symbol: 'R' , negative_sign_before_digits: true , thousands_separator: ' ' , decimal_separator: ',' , allow_negative_sign_placeholder: true } , 'R ## ###,## and R-10 123,25 (el-ZA)' ] , valid: [ '123 456,78' , '-10 123' , 'R-10 123' , 'R 6 954 231' , 'R10,03' , '10,03' , '1,39' , ',03' , '0,10' , 'R10567,01' , 'R0,01' , 'R1 234 567,89' , 'R10 123' , 'R 10 123' , 'R 10123' , 'R-10123' , '10 123' , '10123' ] , invalid: [ '1,234' , 'R -10123' , 'R- 10123' , 'R,1' , ',0001' , 'R,001' , 'R0,001' , '12 34,56' , '123456 123 123456' , ' 123' , '- 123' , '123 ' , '' , ' ' , 'R' , 'R- .1' , 'R-' , '-' , '-R 10123' , 'R00' , 'R -' , '-R' ] }); test({ validator: 'isCurrency' , args: [ { symbol: '€' , thousands_separator: '.' , decimal_separator: ',' , allow_space_after_symbol: true } , '-€ ##.###,## (it-IT)' ] , valid: [ '123.456,78' , '-123.456,78' , '€6.954.231' , '-€6.954.231' , '€ 896.954.231' , '-€ 896.954.231' , '16.954.231' , '-16.954.231' , '€10,03' , '-€10,03' , '10,03' , '-10,03' , '-1,39' , ',03' , '0,10' , '-€10567,01' , '-€ 10567,01' , '€ 0,01' , '€1.234.567,89' , '€10.123' , '10.123' , '-€10.123' , '€ 10.123' , '€10.123' , '€ 10123' , '10.123' , '-10123' ] , invalid: [ '1,234' , '€ 1,1' , '50#,50' , '123,@€ ' , '€€500' , ',0001' , '€ ,001' , '€0,001' , '12.34,56' , '123456.123.123456' , '€123€' , '' , ' ' , '€' , ' €' , '€ ' , '€€' , ' 123' , '- 123' , '.123' , '-€.123' , '123 ' , '€-' , '- €' , '€ - ' , '-' , '- ' , '-€' ] }); test({ validator: 'isCurrency' , args: [ { symbol: '€' , thousands_separator: '.' , symbol_after_digits: true , decimal_separator: ',' , allow_space_after_digits: true } , '-##.###,## € (el-GR)' ] , valid: [ '123.456,78' , '-123.456,78' , '6.954.231 €' , '-6.954.231 €' , '896.954.231' , '-896.954.231' , '16.954.231' , '-16.954.231' , '10,03€' , '-10,03€' , '10,03' , '-10,03' , '1,39' , ',03' , '-,03' , '-,03 €' , '-,03€' , '0,10' , '10567,01€' , '0,01 €' , '1.234.567,89€' , '10.123€' , '10.123' , '10.123€' , '10.123 €' , '10123 €' , '10.123' , '10123' ] , invalid: [ '1,234' , '1,1 €' , ',0001' , ',001 €' , '0,001€' , '12.34,56' , '123456.123.123456' , '€123€' , '' , ' ' , '€' , ' €' , '€ ' , ' 123' , '- 123' , '.123' , '-.123€' , '-.123 €' , '123 ' , '-€' , '- €' , '-' , '- ' ] }); test({ validator: 'isCurrency' , args: [ { symbol: 'kr.' , negative_sign_before_digits: true , thousands_separator: '.' , decimal_separator: ',' , allow_space_after_symbol: true } , 'kr. -##.###,## (da-DK)' ] , valid: [ '123.456,78' , '-10.123' , 'kr. -10.123' , 'kr.-10.123' , 'kr. 6.954.231' , 'kr.10,03' , 'kr. -10,03' , '10,03' , '1,39' , ',03' , '0,10' , 'kr. 10567,01' , 'kr. 0,01' , 'kr. 1.234.567,89' , 'kr. -1.234.567,89' , '10.123' , 'kr. 10.123' , 'kr.10.123' , '10123' , '10.123' , 'kr.-10123' ] , invalid: [ '1,234' , 'kr. -10123' , 'kr.,1' , ',0001' , 'kr. ,001' , 'kr.0,001' , '12.34,56' , '123456.123.123456' , '.123' , 'kr.-.123' , 'kr. -.123' , '- 123' , '123 ' , '' , ' ' , 'kr.' , ' kr.' , 'kr. ' , 'kr.-' , 'kr. -' , 'kr. - ' , ' - ' , '-' , '- kr.' , '-kr.' ] }); test({ validator: 'isCurrency' , args: [ { symbol: 'kr.' , allow_negatives: false , negative_sign_before_digits: true , thousands_separator: '.' , decimal_separator: ',' , allow_space_after_symbol: true } , 'kr. ##.###,## with no negatives (da-DK)' ] , valid: [ '123.456,78' , '10.123' , 'kr. 10.123' , 'kr.10.123' , 'kr. 6.954.231' , 'kr.10,03' , 'kr. 10,03' , '10,03' , '1,39' , ',03' , '0,10' , 'kr. 10567,01' , 'kr. 0,01' , 'kr. 1.234.567,89' , 'kr.1.234.567,89' , '10.123' , 'kr. 10.123' , 'kr.10.123' , '10123' , '10.123' , 'kr.10123' ] , invalid: [ '1,234' , '-10.123' , 'kr. -10.123' , 'kr. -1.234.567,89' , 'kr.-10123' , 'kr. -10123' , 'kr.-10.123' , 'kr. -10,03' , 'kr.,1' , ',0001' , 'kr. ,001' , 'kr.0,001' , '12.34,56' , '123456.123.123456' , '.123' , 'kr.-.123' , 'kr. -.123' , '- 123' , '123 ' , '' , ' ' , 'kr.' , ' kr.' , 'kr. ' , 'kr.-' , 'kr. -' , 'kr. - ' , ' - ' , '-' , '- kr.' , '-kr.' ] }); test({ validator: 'isCurrency' , args: [ { parens_for_negatives: true } , '($##,###.##) (en-US, en-HK)' ] , valid: [ '1,234' , '(1,234)' , '($6,954,231)' , '$10.03' , '(10.03)' , '($10.03)' , '1.39' , '.03' , '(.03)' , '($.03)' , '0.10' , '$10567.01' , '($0.01)' , '$1,234,567.89' , '$10,123' , '(10,123)' , '10123' ] , invalid: [ '1.234' , '($1.1)' , '-$1.10' , '$ 32.50' , '500$' , '.0001' , '$.001' , '($0.001)' , '12,34.56' , '123456,123,123456' , '( 123)' , ',123' , '$-,123' , '' , ' ' , ' ' , ' ' , '$' , '$ ' , ' $' , ' 123' , '(123) ' , '.' , ',' , '00' , '$-' , '$ - ' , '$- ' , ' - ' , '-' , '- $' , '-$' , '()' , '( )' , '( -)' , '( - )' , '( - )' , '(-)' , '(-$)' ] }); test({ validator: 'isCurrency' , args: [ {allow_negatives: false} , '$##,###.## with no negatives (en-US, en-CA, en-AU, en-HK)' ] , valid: [ '$10,123.45' , '$10123.45' , '10,123.45' , '10123.45' , '10,123' , '1,123,456' , '1123456' , '1.39' , '.03' , '0.10' , '$0.10' , '$100,234,567.89' , '$10,123' , '10,123' ] , invalid: [ '1.234' , '-1.234' , '-10123' , '-$0.01' , '-$.99' , '$1.1' , '-$1.1' , '$ 32.50' , '500$' , '.0001' , '$.001' , '$0.001' , '12,34.56' , '123456,123,123456' , '-123456,123,123456' , '123,4' , ',123' , '$-,123' , '$' , '.' , ',' , '00' , '$-' , '$-,.' , '-' , '-$' , '' , '- $' , '-$10,123.45' ] }); test({ validator: 'isBoolean' , valid: [ 'true' , 'false' , '0' , '1' ] , invalid: [ '1.0' , '0.0' , 'true ' , 'False' , 'True' , 'yes' ] }); }); it('should validate ISO 8601 dates', function () { // from http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/ test({ validator: 'isISO8601' , valid: [ '2009-12T12:34' , '2009' , '2009-05-19' , '2009-05-19' , '20090519' , '2009123' , '2009-05' , '2009-123' , '2009-222' , '2009-001' , '2009-W01-1' , '2009-W51-1' , '2009-W511' , '2009-W33' , '2009W511' , '2009-05-19' , '2009-05-19 00:00' , '2009-05-19 14' , '2009-05-19 14:31' , '2009-05-19 14:39:22' , '2009-05-19T14:39Z' , '2009-W21-2' , '2009-W21-2T01:22' , '2009-139' , '2009-05-19 14:39:22-06:00' , '2009-05-19 14:39:22+0600' , '2009-05-19 14:39:22-01' , '20090621T0545Z' , '2007-04-06T00:00' , '2007-04-05T24:00' , '2010-02-18T16:23:48.5' , '2010-02-18T16:23:48,444' , '2010-02-18T16:23:48,3-06:00' , '2010-02-18T16:23.4' , '2010-02-18T16:23,25' , '2010-02-18T16:23.33+0600' , '2010-02-18T16.23334444' , '2010-02-18T16,2283' , '2009-05-19 143922.500' , '2009-05-19 1439,55' ] , invalid: [ '200905' , '2009367' , '2009-' , '2007-04-05T24:50' , '2009-000' , '2009-M511' , '2009M511' , '2009-05-19T14a39r' , '2009-05-19T14:3924' , '2009-0519' , '2009-05-1914:39' , '2009-05-19 14:' , '2009-05-19r14:39' , '2009-05-19 14a39a22' , '200912-01' , '2009-05-19 14:39:22+06a00' , '2009-05-19 146922.500' , '2010-02-18T16.5:23.35:48' , '2010-02-18T16:23.35:48' , '2010-02-18T16:23.35:48.45' , '2009-05-19 14.5.44' , '2010-02-18T16:23.33.600' , '2010-02-18T16,25:23:48,444' ] }); }); });