├── .gitignore ├── .travis.yml ├── Gruntfile.js ├── README.md ├── index.js ├── package.json └── test └── validators.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.zip 2 | node_modules -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.12" 4 | before_install: 5 | - npm install --global grunt-cli titanium 6 | - npm install -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | grunt.initConfig({ 3 | 4 | mochaTest: { 5 | test: { 6 | options: { 7 | reporter: 'spec', 8 | ui: 'bdd' 9 | }, 10 | src: ['test/*.js'] 11 | } 12 | }, 13 | 14 | titaniumifier: { 15 | "module": { 16 | files: { '.' : '.' }, 17 | options: {} 18 | } 19 | } 20 | }); 21 | 22 | // Load dependencies 23 | grunt.loadNpmTasks('grunt-titaniumifier'); 24 | grunt.loadNpmTasks('grunt-mocha-test'); 25 | 26 | // Tasks 27 | grunt.registerTask('test', ['mochaTest']); 28 | grunt.registerTask('default', ['titaniumifier:module', 'test']); 29 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ti-validator 2 | ============= 3 | 4 | [![Build Status](https://img.shields.io/travis/manumaticx/ti-validator.svg?style=flat-square)](https://travis-ci.org/manumaticx/ti-validator) 5 | [![Available on NPM](https://img.shields.io/npm/v/validator.svg?style=flat-square)](https://www.npmjs.com/package/validator) 6 | [![Available on gitTio](https://img.shields.io/badge/available_on-gitTio-00B4CC.svg?style=flat-square)](http://gitt.io/component/validator) 7 | 8 | String validation and sanitization 9 | 10 | This is a [titaniumified][ti] version of [validator](https://github.com/chriso/validator.js). 11 | 12 | [ti]: https://github.com/smclab/titaniumifier 13 | 14 | ### Installation 15 | 16 | With **gitTio** for **Titanium SDK** you can easily install it with 17 | 18 | $ gittio install validator 19 | 20 | 21 | Usage overview 22 | -------------- 23 | 24 | For the full documentation head over the [original repository](https://github.com/chriso/validator.js). 25 | 26 | ```js 27 | var validator = require('validator'); 28 | 29 | validator.isEmail('foo@bar.com'); //=> true 30 | ``` 31 | 32 | Credits 33 | ------- 34 | 35 | * [@chriso](https://github.com/fb55) for [validator](https://github.com/chriso/validator.js) 36 | * [@smclab](https://github.com/smclab/titaniumifier) for [titaniumifier](https://github.com/smclab/titaniumifier) 37 | 38 | 39 | License 40 | ------- 41 | 42 | The MIT License (MIT) 43 | 44 | Copyright (c) 2015 Manuel Lehner 45 | 46 | Permission is hereby granted, free of charge, to any person obtaining a copy 47 | of this software and associated documentation files (the "Software"), to deal 48 | in the Software without restriction, including without limitation the rights 49 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 50 | copies of the Software, and to permit persons to whom the Software is 51 | furnished to do so, subject to the following conditions: 52 | 53 | The above copyright notice and this permission notice shall be included in 54 | all copies or substantial portions of the Software. 55 | 56 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 57 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 58 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 59 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 60 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 61 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 62 | THE SOFTWARE. 63 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('validator'); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ti-validator", 3 | "version": "1.0.0", 4 | "description": "A library of string validators and sanitizers", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "grunt" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/manumaticx/ti-validator" 12 | }, 13 | "keywords": [ 14 | "validator", 15 | "validation" 16 | ], 17 | "author": "Manuel Lehner", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/manumaticx/ti-validator/issues" 21 | }, 22 | "homepage": "https://github.com/manumaticx/ti-validator", 23 | "titaniumManifest": { 24 | "name": "ti-validator", 25 | "guid": "f7b26940-be56-2add-6498-4d41f3254e80", 26 | "moduleid": "validator" 27 | }, 28 | "dependencies": { 29 | "validator": "~3.34.0" 30 | }, 31 | "devDependencies": { 32 | "grunt-titaniumifier": "~1.1.0", 33 | "grunt": "~0.4.5", 34 | "should": "~5.2.0", 35 | "mocha": "~2.2.1", 36 | "grunt-mocha-test": "~0.12.7" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/validators.js: -------------------------------------------------------------------------------- 1 | var validator = require('../index.js') 2 | , format = require('util').format; 3 | 4 | function test(options) { 5 | var args = options.args || []; 6 | args.unshift(null); 7 | if (options.valid) { 8 | options.valid.forEach(function (valid) { 9 | args[0] = valid; 10 | if (validator[options.validator].apply(validator, args) !== true) { 11 | var warning = format('validator.%s(%s) failed but should have passed', 12 | options.validator, args.join(', ')); 13 | throw new Error(warning); 14 | } 15 | }); 16 | } 17 | if (options.invalid) { 18 | options.invalid.forEach(function (invalid) { 19 | args[0] = invalid; 20 | if (validator[options.validator].apply(validator, args) !== false) { 21 | var warning = format('validator.%s(%s) passed but should have failed', 22 | options.validator, args.join(', ')); 23 | throw new Error(warning); 24 | } 25 | }); 26 | } 27 | } 28 | 29 | describe('Validators', function () { 30 | 31 | it('should validate email addresses', function () { 32 | test({ 33 | validator: 'isEmail' 34 | , valid: [ 35 | 'foo@bar.com' 36 | , 'x@x.x' 37 | , 'foo@bar.com.au' 38 | , 'foo+bar@bar.com' 39 | , 'hans.m端ller@test.com' 40 | , 'hans@m端ller.com' 41 | , 'test|123@m端ller.com' 42 | , 'test+ext@gmail.com' 43 | , 'some.name.midd.leNa.me.+extension@GoogleMail.com' 44 | ] 45 | , invalid: [ 46 | 'invalidemail@' 47 | , 'invalid.com' 48 | , '@invalid.com' 49 | , 'foo@bar.com.' 50 | , 'foo@bar.co.uk.' 51 | ] 52 | }); 53 | }); 54 | 55 | it('should validate email addresses with display names', function () { 56 | test({ 57 | validator: 'isEmail' 58 | , args: [{ allow_display_name: true }] 59 | , valid: [ 60 | 'foo@bar.com' 61 | , 'x@x.x' 62 | , 'foo@bar.com.au' 63 | , 'foo+bar@bar.com' 64 | , 'hans.m端ller@test.com' 65 | , 'hans@m端ller.com' 66 | , 'test|123@m端ller.com' 67 | , 'test+ext@gmail.com' 68 | , 'some.name.midd.leNa.me.+extension@GoogleMail.com' 69 | , 'Some Name ' 70 | , 'Some Name ' 71 | , 'Some Name ' 72 | , 'Some Name ' 73 | , 'Some Name ' 74 | , 'Some Name ' 75 | , 'Some Name ' 76 | , 'Some Name ' 77 | , 'Some Name ' 78 | , 'Some Middle Name ' 79 | , 'Name ' 80 | , 'Name' 81 | ] 82 | , invalid: [ 83 | 'invalidemail@' 84 | , 'invalid.com' 85 | , '@invalid.com' 86 | , 'foo@bar.com.' 87 | , 'foo@bar.co.uk.' 88 | , 'Some Name ' 89 | , 'Some Name ' 90 | , 'Some Name <@invalid.com>' 91 | , 'Some Name ' 92 | , 'Some Name ' 93 | , 'Some Name foo@bar.co.uk.>' 94 | , 'Some Name ' 96 | , 'Name foo@bar.co.uk' 97 | ] 98 | }); 99 | }); 100 | 101 | it('should validate URLs', function () { 102 | test({ 103 | validator: 'isURL' 104 | , valid: [ 105 | 'foobar.com' 106 | , 'www.foobar.com' 107 | , 'foobar.com/' 108 | , 'valid.au' 109 | , 'http://www.foobar.com/' 110 | , 'http://www.foobar.com:23/' 111 | , 'http://www.foobar.com:65535/' 112 | , 'http://www.foobar.com:5/' 113 | , 'https://www.foobar.com/' 114 | , 'ftp://www.foobar.com/' 115 | , 'http://www.foobar.com/~foobar' 116 | , 'http://user:pass@www.foobar.com/' 117 | , 'http://127.0.0.1/' 118 | , 'http://10.0.0.0/' 119 | , 'http://189.123.14.13/' 120 | , 'http://duckduckgo.com/?q=%2F' 121 | , 'http://foobar.com/t$-_.+!*\'(),' 122 | , 'http://localhost:3000/' 123 | , 'http://foobar.com/?foo=bar#baz=qux' 124 | , 'http://foobar.com?foo=bar' 125 | , 'http://foobar.com#baz=qux' 126 | , 'http://www.xn--froschgrn-x9a.net/' 127 | , 'http://xn--froschgrn-x9a.com/' 128 | , 'http://foo--bar.com' 129 | , 'http://høyfjellet.no' 130 | , 'http://xn--j1aac5a4g.xn--j1amh' 131 | , 'http://кулік.укр' 132 | ] 133 | , invalid: [ 134 | 'xyz://foobar.com' 135 | , 'invalid/' 136 | , 'invalid.x' 137 | , 'invalid.' 138 | , '.com' 139 | , 'http://com/' 140 | , 'http://300.0.0.1/' 141 | , 'mailto:foo@bar.com' 142 | , 'rtmp://foobar.com' 143 | , 'http://www.xn--.com/' 144 | , 'http://xn--.com/' 145 | , 'http://www.foobar.com:0/' 146 | , 'http://www.foobar.com:70000/' 147 | , 'http://www.foobar.com:99999/' 148 | , 'http://www.-foobar.com/' 149 | , 'http://www.foobar-.com/' 150 | , 'http://www.foo---bar.com/' 151 | , 'http://www.foo_bar.com/' 152 | , '' 153 | , 'http://foobar.com/' + new Array(2083).join('f') 154 | , 'http://*.foo.com' 155 | , '*.foo.com' 156 | , '!.foo.com' 157 | , 'http://example.com.' 158 | , 'http://localhost:61500this is an invalid url!!!!' 159 | , '////foobar.com' 160 | , 'http:////foobar.com' 161 | ] 162 | }); 163 | }); 164 | 165 | it('should validate URLs with custom protocols', function () { 166 | test({ 167 | validator: 'isURL' 168 | , args: [{ 169 | protocols: [ 'rtmp' ] 170 | }] 171 | , valid: [ 172 | 'rtmp://foobar.com' 173 | ] 174 | , invalid: [ 175 | 'http://foobar.com' 176 | ] 177 | }); 178 | }); 179 | 180 | it('should validate URLs with underscores', function () { 181 | test({ 182 | validator: 'isURL' 183 | , args: [{ 184 | allow_underscores: true 185 | }] 186 | , valid: [ 187 | 'http://foo_bar.com' 188 | , 'http://pr.example_com.294.example.com/' 189 | ] 190 | , invalid: [ 191 | 'http://foo__bar.com' 192 | ] 193 | }); 194 | }); 195 | 196 | it('should validate URLs that do not have a TLD', function () { 197 | test({ 198 | validator: 'isURL' 199 | , args: [{ 200 | require_tld: false 201 | }] 202 | , valid: [ 203 | 'http://foobar.com/' 204 | , 'http://foobar/' 205 | , 'foobar/' 206 | , 'foobar' 207 | ] 208 | , invalid: [ 209 | ] 210 | }); 211 | }); 212 | 213 | it('should validate URLs with a trailing dot option', function () { 214 | test({ 215 | validator: 'isURL' 216 | , args: [{ 217 | allow_trailing_dot: true 218 | , require_tld: false 219 | }] 220 | , valid: [ 221 | 'http://example.com.' 222 | , 'foobar.' 223 | ] 224 | }); 225 | }); 226 | 227 | it('should validate protocol relative URLs', function () { 228 | test({ 229 | validator: 'isURL' 230 | , args: [{ 231 | allow_protocol_relative_urls: true 232 | }] 233 | , valid: [ 234 | '//foobar.com' 235 | , 'http://foobar.com' 236 | , 'foobar.com' 237 | ] 238 | , invalid: [ 239 | '://foobar.com' 240 | , '/foobar.com' 241 | , '////foobar.com' 242 | , 'http:////foobar.com' 243 | ] 244 | }); 245 | }); 246 | 247 | it('should not validate protocol relative URLs when require protocol is true', function () { 248 | test({ 249 | validator: 'isURL' 250 | , args: [{ 251 | allow_protocol_relative_urls: true, 252 | require_protocol: true 253 | }] 254 | , valid: [ 255 | 'http://foobar.com' 256 | ] 257 | , invalid: [ 258 | '//foobar.com' 259 | , '://foobar.com' 260 | , '/foobar.com' 261 | , 'foobar.com' 262 | ] 263 | }); 264 | }); 265 | 266 | it('should let users specify whether URLs require a protocol', function () { 267 | test({ 268 | validator: 'isURL' 269 | , args: [{ 270 | require_protocol: true 271 | }] 272 | , valid: [ 273 | 'http://foobar.com/' 274 | , 'http://localhost/' 275 | ] 276 | , invalid: [ 277 | 'foobar.com' 278 | , 'foobar' 279 | ] 280 | }); 281 | }); 282 | 283 | it('should let users specify a host whitelist', function () { 284 | test({ 285 | validator: 'isURL' 286 | , args: [{ 287 | host_whitelist: ['foo.com', 'bar.com'] 288 | }] 289 | , valid: [ 290 | 'http://bar.com/' 291 | , 'http://foo.com/' 292 | ] 293 | , invalid: [ 294 | 'http://foobar.com' 295 | , 'http://foo.bar.com/' 296 | , 'http://qux.com' 297 | ] 298 | }); 299 | }); 300 | 301 | it('should let users specify a host blacklist', function () { 302 | test({ 303 | validator: 'isURL' 304 | , args: [{ 305 | host_blacklist: ['foo.com', 'bar.com'] 306 | }] 307 | , valid: [ 308 | 'http://foobar.com' 309 | , 'http://foo.bar.com/' 310 | , 'http://qux.com' 311 | ] 312 | , invalid: [ 313 | 'http://bar.com/' 314 | , 'http://foo.com/' 315 | ] 316 | }); 317 | }); 318 | 319 | it('should validate IP addresses', function () { 320 | test({ 321 | validator: 'isIP' 322 | , valid: [ 323 | '127.0.0.1' 324 | , '0.0.0.0' 325 | , '255.255.255.255' 326 | , '1.2.3.4' 327 | , '::1' 328 | , '2001:db8:0000:1:1:1:1:1' 329 | , '2001:41d0:2:a141::1' 330 | , '::0000' 331 | , '0000::' 332 | , '1::' 333 | , '1111:1:1:1:1:1:1:1' 334 | , 'fe80::a6db:30ff:fe98:e946' 335 | , '::' 336 | ] 337 | , invalid: [ 338 | 'abc' 339 | , '256.0.0.0' 340 | , '0.0.0.256' 341 | , '26.0.0.256' 342 | , '::banana' 343 | , 'banana::' 344 | , '::1banana' 345 | , '::1::' 346 | , '1:' 347 | , ':1' 348 | , ':1:1:1::2' 349 | , '1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1' 350 | , '::11111' 351 | , '11111:1:1:1:1:1:1:1' 352 | , '2001:db8:0000:1:1:1:1::1' 353 | ] 354 | }); 355 | test({ 356 | validator: 'isIP' 357 | , args: [ 4 ] 358 | , valid: [ 359 | '127.0.0.1' 360 | , '0.0.0.0' 361 | , '255.255.255.255' 362 | , '1.2.3.4' 363 | ] 364 | , invalid: [ 365 | '::1' 366 | , '2001:db8:0000:1:1:1:1:1' 367 | ] 368 | }); 369 | test({ 370 | validator: 'isIP' 371 | , args: [ 6 ] 372 | , valid: [ 373 | '::1' 374 | , '2001:db8:0000:1:1:1:1:1' 375 | ] 376 | , invalid: [ 377 | '127.0.0.1' 378 | , '0.0.0.0' 379 | , '255.255.255.255' 380 | , '1.2.3.4' 381 | ] 382 | }); 383 | test({ 384 | validator: 'isIP' 385 | , args: [ 10 ] 386 | , valid: [ 387 | ] 388 | , invalid: [ 389 | '127.0.0.1' 390 | , '0.0.0.0' 391 | , '255.255.255.255' 392 | , '1.2.3.4' 393 | , '::1' 394 | , '2001:db8:0000:1:1:1:1:1' 395 | ] 396 | }); 397 | }); 398 | 399 | it('should validate FQDN', function () { 400 | test({ 401 | validator: 'isFQDN' 402 | , valid: [ 403 | 'domain.com' 404 | , 'dom.plato' 405 | , 'a.domain.co' 406 | , 'foo--bar.com' 407 | , 'xn--froschgrn-x9a.com' 408 | , 'rebecca.blackfriday' 409 | ] 410 | , invalid: [ 411 | 'abc' 412 | , '256.0.0.0' 413 | , '_.com' 414 | , '*.some.com' 415 | , 's!ome.com' 416 | , 'domain.com/' 417 | , '/more.com' 418 | ] 419 | }); 420 | }); 421 | it('should validate FQDN with trailing dot option', function() { 422 | test({ 423 | validator: 'isFQDN' 424 | , args: [ 425 | {allow_trailing_dot:true} 426 | ] 427 | , valid: [ 428 | 'example.com.' 429 | ] 430 | }); 431 | }); 432 | 433 | it('should validate alpha strings', function () { 434 | test({ 435 | validator: 'isAlpha' 436 | , valid: [ 437 | 'abc' 438 | , 'ABC' 439 | , 'FoObar' 440 | ] 441 | , invalid: [ 442 | 'abc1' 443 | , ' foo ' 444 | , '' 445 | ] 446 | }); 447 | }); 448 | 449 | it('should validate alphanumeric strings', function () { 450 | test({ 451 | validator: 'isAlphanumeric' 452 | , valid: [ 453 | 'abc123' 454 | , 'ABC11' 455 | ] 456 | , invalid: [ 457 | 'abc ' 458 | , 'foo!!' 459 | ] 460 | }); 461 | }); 462 | 463 | it('should validate numeric strings', function () { 464 | test({ 465 | validator: 'isNumeric' 466 | , valid: [ 467 | '123' 468 | , '00123' 469 | , '-00123' 470 | , '0' 471 | , '-0' 472 | , '+123' 473 | ] 474 | , invalid: [ 475 | '123.123' 476 | , ' ' 477 | , '.' 478 | ] 479 | }); 480 | }); 481 | 482 | it('should validate lowercase strings', function () { 483 | test({ 484 | validator: 'isLowercase' 485 | , valid: [ 486 | 'abc' 487 | , 'abc123' 488 | , 'this is lowercase.' 489 | , 'tr竪s 端ber' 490 | ] 491 | , invalid: [ 492 | 'fooBar' 493 | , '123A' 494 | ] 495 | }); 496 | }); 497 | 498 | it('should validate uppercase strings', function () { 499 | test({ 500 | validator: 'isUppercase' 501 | , valid: [ 502 | 'ABC' 503 | , 'ABC123' 504 | , 'ALL CAPS IS FUN.' 505 | , ' .' 506 | ] 507 | , invalid: [ 508 | 'fooBar' 509 | , '123abc' 510 | ] 511 | }); 512 | }); 513 | 514 | it('should validate integers', function () { 515 | test({ 516 | validator: 'isInt' 517 | , valid: [ 518 | '13' 519 | , '123' 520 | , '0' 521 | , '123' 522 | , '-0' 523 | , '+1' 524 | ] 525 | , invalid: [ 526 | '01' 527 | , '-01' 528 | , '000' 529 | , '100e10' 530 | , '123.123' 531 | , ' ' 532 | , '' 533 | ] 534 | }); 535 | }); 536 | 537 | it('should validate floats', function () { 538 | test({ 539 | validator: 'isFloat' 540 | , valid: [ 541 | '123' 542 | , '123.' 543 | , '123.123' 544 | , '-123.123' 545 | , '-0.123' 546 | , '+0.123' 547 | , '0.123' 548 | , '.0' 549 | , '01.123' 550 | , '-0.22250738585072011e-307' 551 | ] 552 | , invalid: [ 553 | '-.123' 554 | , ' ' 555 | , '' 556 | , 'foo' 557 | ] 558 | }); 559 | }); 560 | 561 | it('should validate hexadecimal strings', function () { 562 | test({ 563 | validator: 'isHexadecimal' 564 | , valid: [ 565 | 'deadBEEF' 566 | , 'ff0044' 567 | ] 568 | , invalid: [ 569 | 'abcdefg' 570 | , '' 571 | , '..' 572 | ] 573 | }); 574 | }); 575 | 576 | it('should validate hexadecimal color strings', function () { 577 | test({ 578 | validator: 'isHexColor' 579 | , valid: [ 580 | '#ff0034' 581 | , '#CCCCCC' 582 | , 'fff' 583 | , '#f00' 584 | ] 585 | , invalid: [ 586 | '#ff' 587 | , 'fff0' 588 | , '#ff12FG' 589 | ] 590 | }); 591 | }); 592 | 593 | it('should validate null strings', function () { 594 | test({ 595 | validator: 'isNull' 596 | , valid: [ 597 | '' 598 | , NaN 599 | , [] 600 | , undefined 601 | , null 602 | ] 603 | , invalid: [ 604 | ' ' 605 | , 'foo' 606 | ] 607 | }); 608 | }); 609 | 610 | it('should validate strings against an expected value', function () { 611 | test({ validator: 'equals', args: ['abc'], valid: ['abc'], invalid: ['Abc', '123'] }); 612 | }); 613 | 614 | it('should validate strings contain another string', function () { 615 | test({ validator: 'contains', args: ['foo'], valid: ['foo', 'foobar', 'bazfoo'], 616 | invalid: ['bar', 'fobar'] }); 617 | }); 618 | 619 | it('should validate strings against a pattern', function () { 620 | test({ validator: 'matches', args: [/abc/], valid: ['abc', 'abcdef', '123abc'], 621 | invalid: ['acb', 'Abc'] }); 622 | test({ validator: 'matches', args: ['abc'], valid: ['abc', 'abcdef', '123abc'], 623 | invalid: ['acb', 'Abc'] }); 624 | test({ validator: 'matches', args: ['abc', 'i'], valid: ['abc', 'abcdef', '123abc', 'AbC'], 625 | invalid: ['acb'] }); 626 | }); 627 | 628 | it('should validate strings by length', function () { 629 | test({ validator: 'isLength', args: [2], valid: ['abc', 'de', 'abcd'], invalid: [ '', 'a' ] }); 630 | test({ validator: 'isLength', args: [2, 3], valid: ['abc', 'de'], invalid: [ '', 'a', 'abcd' ] }); 631 | test({ validator: 'isLength', args: [2, 3], valid: ['干𩸽', '𠮷野家'], invalid: [ '', '𠀋', '千竈通り' ] }); 632 | }); 633 | 634 | it('should validate strings by byte length', function () { 635 | test({ validator: 'isByteLength', args: [2], valid: ['abc', 'de', 'abcd'], invalid: [ '', 'a' ] }); 636 | test({ validator: 'isByteLength', args: [2, 3], valid: ['abc', 'de'], invalid: [ '', 'a', 'abcd' ] }); 637 | }); 638 | 639 | it('should validate UUIDs', function () { 640 | test({ 641 | validator: 'isUUID' 642 | , valid: [ 643 | 'A987FBC9-4BED-3078-CF07-9141BA07C9F3' 644 | , 'A987FBC9-4BED-4078-8F07-9141BA07C9F3' 645 | , 'A987FBC9-4BED-5078-AF07-9141BA07C9F3' 646 | ] 647 | , invalid: [ 648 | '' 649 | , 'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3' 650 | , 'A987FBC9-4BED-3078-CF07-9141BA07C9F3xxx' 651 | , 'A987FBC94BED3078CF079141BA07C9F3' 652 | , '934859' 653 | , '987FBC9-4BED-3078-CF07A-9141BA07C9F3' 654 | , 'AAAAAAAA-1111-1111-AAAG-111111111111' 655 | ] 656 | }); 657 | test({ 658 | validator: 'isUUID' 659 | , args: [ 3 ] 660 | , valid: [ 661 | 'A987FBC9-4BED-3078-CF07-9141BA07C9F3' 662 | ] 663 | , invalid: [ 664 | '' 665 | , 'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3' 666 | , '934859' 667 | , 'AAAAAAAA-1111-1111-AAAG-111111111111' 668 | , 'A987FBC9-4BED-4078-8F07-9141BA07C9F3' 669 | , 'A987FBC9-4BED-5078-AF07-9141BA07C9F3' 670 | ] 671 | }); 672 | test({ 673 | validator: 'isUUID' 674 | , args: [ 4 ] 675 | , valid: [ 676 | '713ae7e3-cb32-45f9-adcb-7c4fa86b90c1' 677 | , '625e63f3-58f5-40b7-83a1-a72ad31acffb' 678 | , '57b73598-8764-4ad0-a76a-679bb6640eb1' 679 | , '9c858901-8a57-4791-81fe-4c455b099bc9' 680 | ] 681 | , invalid: [ 682 | '' 683 | , 'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3' 684 | , '934859' 685 | , 'AAAAAAAA-1111-1111-AAAG-111111111111' 686 | , 'A987FBC9-4BED-5078-AF07-9141BA07C9F3' 687 | , 'A987FBC9-4BED-3078-CF07-9141BA07C9F3' 688 | ] 689 | }); 690 | test({ 691 | validator: 'isUUID' 692 | , args: [ 5 ] 693 | , valid: [ 694 | '987FBC97-4BED-5078-AF07-9141BA07C9F3' 695 | , '987FBC97-4BED-5078-BF07-9141BA07C9F3' 696 | , '987FBC97-4BED-5078-8F07-9141BA07C9F3' 697 | , '987FBC97-4BED-5078-9F07-9141BA07C9F3' 698 | ] 699 | , invalid: [ 700 | '' 701 | , 'xxxA987FBC9-4BED-3078-CF07-9141BA07C9F3' 702 | , '934859' 703 | , 'AAAAAAAA-1111-1111-AAAG-111111111111' 704 | , '9c858901-8a57-4791-81fe-4c455b099bc9' 705 | , 'A987FBC9-4BED-3078-CF07-9141BA07C9F3' 706 | ] 707 | }); 708 | }); 709 | 710 | it('should validate a string that is in another string or array', function () { 711 | test({ validator: 'isIn', args: ['foobar'], valid: ['foo', 'bar', 'foobar', ''], 712 | invalid: ['foobarbaz', 'barfoo'] }); 713 | test({ validator: 'isIn', args: [['foo', 'bar']], valid: ['foo', 'bar'], 714 | invalid: ['foobar', 'barfoo', ''] }); 715 | test({ validator: 'isIn', args: [[1, 2, 3]], valid: ['1', '2', '3'], 716 | invalid: ['4', ''] }); 717 | test({ validator: 'isIn', invalid: ['foo', ''] }); 718 | }); 719 | 720 | it('should validate a string that is in another object', function () { 721 | test({ validator: 'isIn', args: [{'foo':1, 'bar':2, 'foobar':3}], valid: ['foo', 'bar', 'foobar'], 722 | invalid: ['foobarbaz', 'barfoo', ''] }); 723 | test({ validator: 'isIn', args: [{1:3, 2:0, 3:1}], valid: ['1', '2', '3'], 724 | invalid: ['4', ''] }); 725 | }); 726 | 727 | it('should validate dates', function () { 728 | test({ 729 | validator: 'isDate' 730 | , valid: [ 731 | '2011-08-04' 732 | , '04. 08. 2011.' 733 | , '08/04/2011' 734 | , '2011.08.04' 735 | , '4. 8. 2011. GMT' 736 | , '2011-08-04 12:00' 737 | ] 738 | , invalid: [ 739 | 'foo' 740 | , '2011-foo-04' 741 | , 'GMT' 742 | ] 743 | }); 744 | }); 745 | 746 | it('should validate dates against a start date', function () { 747 | test({ validator: 'isAfter', args: ['2011-08-03'], 748 | valid: [ '2011-08-04', new Date(2011, 8, 10) ], 749 | invalid: [ '2010-07-02', '2011-08-03', new Date(0), 'foo'] }); 750 | test({ validator: 'isAfter', 751 | valid: [ '2100-08-04', new Date(Date.now() + 86400000) ], 752 | invalid: [ '2010-07-02', new Date(0) ] }); 753 | }); 754 | 755 | it('should validate dates against an end date', function () { 756 | test({ validator: 'isBefore', args: ['08/04/2011'], 757 | valid: [ '2010-07-02', '2010-08-04', new Date(0) ], 758 | invalid: [ '08/04/2011', new Date(2011, 9, 10) ] }); 759 | test({ validator: 'isBefore', args: [ new Date(2011, 7, 4) ], 760 | valid: [ '2010-07-02', '2010-08-04', new Date(0) ], 761 | invalid: [ '08/04/2011', new Date(2011, 9, 10) ] }); 762 | test({ validator: 'isBefore', 763 | valid: [ '2000-08-04', new Date(0), new Date(Date.now() - 86400000) ], 764 | invalid: [ '2100-07-02', new Date(2017, 10, 10) ] }); 765 | }); 766 | 767 | it('should validate that integer strings are divisible by a number', function () { 768 | test({ 769 | validator: 'isDivisibleBy' 770 | , args: [ 2 ] 771 | , valid: [ '2', '4', '100', '1000' ] 772 | , invalid: [ 773 | '1' 774 | , '2.5' 775 | , '101' 776 | , 'foo' 777 | , '' 778 | ] 779 | }); 780 | }); 781 | 782 | it('should validate credit cards', function () { 783 | test({ 784 | validator: 'isCreditCard' 785 | , valid: [ 786 | '375556917985515' 787 | , '36050234196908' 788 | , '4716461583322103' 789 | , '4716-2210-5188-5662' 790 | , '4929 7226 5379 7141' 791 | , '5398228707871527' 792 | ] 793 | , invalid: [ 794 | 'foo' 795 | , 'foo' 796 | , '5398228707871528' 797 | ] 798 | }); 799 | }); 800 | 801 | it('should validate ISINs', function () { 802 | test({ 803 | validator: 'isISIN' 804 | , valid: [ 805 | 'AU0000XVGZA3' 806 | , 'DE000BAY0017' 807 | , 'BE0003796134' 808 | , 'SG1G55870362' 809 | , 'GB0001411924' 810 | , 'DE000WCH8881' 811 | , 'PLLWBGD00016' 812 | ] 813 | , invalid: [ 814 | 'DE000BAY0018' 815 | , 'PLLWBGD00019' 816 | , 'foo' 817 | , '5398228707871528' 818 | ] 819 | }); 820 | }); 821 | 822 | it('should validate ISBNs', function () { 823 | test({ 824 | validator: 'isISBN' 825 | , args: [ 10 ] 826 | , valid: [ 827 | '3836221195', '3-8362-2119-5', '3 8362 2119 5' 828 | , '1617290858', '1-61729-085-8', '1 61729 085-8' 829 | , '0007269706', '0-00-726970-6', '0 00 726970 6' 830 | , '3423214120', '3-423-21412-0', '3 423 21412 0' 831 | , '340101319X', '3-401-01319-X', '3 401 01319 X' 832 | ] 833 | , invalid: [ 834 | '3423214121', '3-423-21412-1', '3 423 21412 1' 835 | , '978-3836221191', '9783836221191' 836 | , '123456789a', 'foo', '' 837 | ] 838 | }); 839 | test({ 840 | validator: 'isISBN' 841 | , args: [ 13 ] 842 | , valid: [ 843 | '9783836221191', '978-3-8362-2119-1', '978 3 8362 2119 1' 844 | , '9783401013190', '978-3401013190', '978 3401013190' 845 | , '9784873113685', '978-4-87311-368-5', '978 4 87311 368 5' 846 | ] 847 | , invalid: [ 848 | '9783836221190', '978-3-8362-2119-0', '978 3 8362 2119 0' 849 | , '3836221195', '3-8362-2119-5', '3 8362 2119 5' 850 | , '01234567890ab', 'foo', '' 851 | ] 852 | }); 853 | test({ 854 | validator: 'isISBN' 855 | , valid: [ 856 | '340101319X' 857 | , '9784873113685' 858 | ] 859 | , invalid: [ 860 | '3423214121' 861 | , '9783836221190' 862 | ] 863 | }); 864 | test({ 865 | validator: 'isISBN' 866 | , args: [ 'foo' ] 867 | , invalid: [ 868 | '340101319X' 869 | , '9784873113685' 870 | ] 871 | }); 872 | }); 873 | 874 | it('should validate JSON', function () { 875 | test({ 876 | validator: 'isJSON' 877 | , valid: [ 878 | '{ "key": "value" }' 879 | ] 880 | , invalid: [ 881 | '{ key: "value" }' 882 | , { "key": "value" } 883 | , { key: 'value' } 884 | , '{ \'key\': \'value\' }' 885 | ] 886 | }); 887 | }); 888 | 889 | it('should validate multibyte strings', function () { 890 | test({ 891 | validator: 'isMultibyte' 892 | , valid: [ 893 | 'ひらがな・カタカナ、.漢字' 894 | , 'あいうえお foobar' 895 | , 'test@example.com' 896 | , '1234abcDExyz' 897 | , 'カタカナ' 898 | , '中文' 899 | ] 900 | , invalid: [ 901 | 'abc' 902 | , 'abc123' 903 | , '<>@" *.' 904 | ] 905 | }); 906 | }); 907 | 908 | it('should validate ascii strings', function () { 909 | test({ 910 | validator: 'isAscii' 911 | , valid: [ 912 | 'foobar' 913 | , '0987654321' 914 | , 'test@example.com' 915 | , '1234abcDEF' 916 | ] 917 | , invalid: [ 918 | 'foobar' 919 | , 'xyz098' 920 | , '123456' 921 | , 'カタカナ' 922 | ] 923 | }); 924 | }); 925 | 926 | it('should validate full-width strings', function () { 927 | test({ 928 | validator: 'isFullWidth' 929 | , valid: [ 930 | 'ひらがな・カタカナ、.漢字' 931 | , '3ー0 a@com' 932 | , 'Fカタカナ゙ᆲ' 933 | , 'Good=Parts' 934 | ] 935 | , invalid: [ 936 | 'abc' 937 | , 'abc123' 938 | , '!"#$%&()<>/+=-_? ~^|.,@`{}[]' 939 | ] 940 | }); 941 | }); 942 | 943 | it('should validate half-width strings', function () { 944 | test({ 945 | validator: 'isHalfWidth' 946 | , valid: [ 947 | '!"#$%&()<>/+=-_? ~^|.,@`{}[]' 948 | , 'l-btn_02--active' 949 | , 'abc123い' 950 | , 'カタカナ゙ᆲ←' 951 | ] 952 | , invalid: [ 953 | 'あいうえお' 954 | , '0011' 955 | ] 956 | }); 957 | }); 958 | 959 | it('should validate variable-width strings', function () { 960 | test({ 961 | validator: 'isVariableWidth' 962 | , valid: [ 963 | 'ひらがなカタカナ漢字ABCDE' 964 | , '3ー0123' 965 | , 'Fカタカナ゙ᆲ' 966 | , 'Good=Parts' 967 | ] 968 | , invalid: [ 969 | 'abc' 970 | , 'abc123' 971 | , '!"#$%&()<>/+=-_? ~^|.,@`{}[]' 972 | , 'ひらがな・カタカナ、.漢字' 973 | , '123456' 974 | , 'カタカナ゙ᆲ' 975 | ] 976 | }); 977 | }); 978 | 979 | it('should validate surrogate pair strings', function () { 980 | test({ 981 | validator: 'isSurrogatePair' 982 | , valid: [ 983 | '𠮷野𠮷' 984 | , '𩸽' 985 | , 'ABC千𥧄1-2-3' 986 | ] 987 | , invalid: [ 988 | '吉野竈' 989 | , '鮪' 990 | , 'ABC1-2-3' 991 | ] 992 | }); 993 | }); 994 | 995 | it('should validate base64 strings', function () { 996 | test({ 997 | validator: 'isBase64' 998 | , valid: [ 999 | 'TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=' 1000 | , 'Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==' 1001 | , 'U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==' 1002 | , 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw'+ 1003 | 'UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye'+ 1004 | 'rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619'+ 1005 | 'FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx'+ 1006 | 'QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ'+ 1007 | 'Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ'+ 1008 | 'HQIDAQAB' 1009 | ] 1010 | , invalid: [ 1011 | '12345' 1012 | , '' 1013 | , 'Vml2YW11cyBmZXJtZtesting123' 1014 | ] 1015 | }); 1016 | for (var i = 0, str = '', encoded; i < 1000; i++) { 1017 | str += String.fromCharCode(Math.random() * 26 | 97); 1018 | encoded = new Buffer(str).toString('base64'); 1019 | if (!validator.isBase64(encoded)) { 1020 | var msg = format('validator.isBase64() failed with "%s"', encoded); 1021 | throw new Error(msg); 1022 | } 1023 | } 1024 | }); 1025 | 1026 | it('should validate hex-encoded MongoDB ObjectId', function () { 1027 | test({ 1028 | validator: 'isMongoId' 1029 | , valid: [ 1030 | '507f1f77bcf86cd799439011' 1031 | ] 1032 | , invalid: [ 1033 | '507f1f77bcf86cd7994390' 1034 | , '507f1f77bcf86cd79943901z' 1035 | , '' 1036 | , '507f1f77bcf86cd799439011 ' 1037 | ] 1038 | }); 1039 | }); 1040 | 1041 | it('should validate mobile phone number', function () { 1042 | test({ 1043 | validator: 'isMobilePhone' 1044 | , valid: [ 1045 | '15323456787' 1046 | , '13523333233' 1047 | , '13898728332' 1048 | , '+086-13238234822' 1049 | , '08613487234567' 1050 | , '8617823492338' 1051 | , '86-17823492338' 1052 | ] 1053 | , invalid: [ 1054 | '12345' 1055 | , '' 1056 | , 'Vml2YW11cyBmZXJtZtesting123' 1057 | , '010-38238383' 1058 | ], 1059 | args: ['zh-CN'] 1060 | }); 1061 | 1062 | test({ 1063 | validator: 'isMobilePhone' 1064 | , invalid: [ 1065 | '15323456787' 1066 | , '13523333233' 1067 | , '13898728332' 1068 | , '+086-13238234822' 1069 | , '08613487234567' 1070 | , '8617823492338' 1071 | , '86-17823492338' 1072 | ], 1073 | args: ['en'] 1074 | }); 1075 | 1076 | test({ 1077 | validator: 'isMobilePhone' 1078 | , valid: [ 1079 | '0821231234' 1080 | , '+27821231234' 1081 | , '27821231234' 1082 | ] 1083 | , invalid: [ 1084 | '082123' 1085 | , '08212312345' 1086 | , '21821231234' 1087 | , '+21821231234' 1088 | , '+0821231234' 1089 | ], 1090 | args: ['en-ZA'] 1091 | }); 1092 | 1093 | test({ 1094 | validator: 'isMobilePhone' 1095 | , valid: [ 1096 | '61404111222' 1097 | , '+61411222333' 1098 | , '0417123456' 1099 | ] 1100 | , invalid: [ 1101 | '082123' 1102 | , '08212312345' 1103 | , '21821231234' 1104 | , '+21821231234' 1105 | , '+0821231234' 1106 | , '04123456789' 1107 | ], 1108 | args: ['en-AU'] 1109 | }); 1110 | 1111 | test({ 1112 | validator: 'isMobilePhone' 1113 | , valid: [ 1114 | '91234567' 1115 | , '9123-4567' 1116 | , '61234567' 1117 | , '51234567' 1118 | , '+85291234567' 1119 | , '+852-91234567' 1120 | , '+852-9123-4567' 1121 | , '852-91234567' 1122 | ] 1123 | , invalid: [ 1124 | '999' 1125 | , '+852-912345678' 1126 | , '123456789' 1127 | , '+852-1234-56789' 1128 | ], 1129 | args: ['en-HK'] 1130 | }); 1131 | 1132 | test({ 1133 | validator: 'isMobilePhone' 1134 | , valid: [ 1135 | '0612457898' 1136 | , '+33612457898' 1137 | , '33612457898' 1138 | , '0712457898' 1139 | , '+33712457898' 1140 | , '33712457898' 1141 | ] 1142 | , invalid: [ 1143 | '061245789' 1144 | , '06124578980' 1145 | , '0112457898' 1146 | , '0212457898' 1147 | , '0312457898' 1148 | , '0412457898' 1149 | , '0512457898' 1150 | , '0812457898' 1151 | , '0912457898' 1152 | , '+34612457898' 1153 | , '+336124578980' 1154 | , '+3361245789' 1155 | ] 1156 | , args: ['fr-FR'] 1157 | }); 1158 | 1159 | test({ 1160 | validator: 'isMobilePhone' 1161 | , valid: [ 1162 | '2102323234' 1163 | , '+302646041461' 1164 | , '+306944848966' 1165 | , '6944848966' 1166 | ] 1167 | , invalid: [ 1168 | '120000000' 1169 | , '20000000000' 1170 | , '68129485729' 1171 | , '6589394827' 1172 | , '298RI89572' 1173 | ] 1174 | , args: ['el-GR'] 1175 | }); 1176 | }); 1177 | 1178 | it('should validate currency', function() { 1179 | test({ 1180 | validator: 'isCurrency' 1181 | , args: [ 1182 | {} 1183 | , '-$##,###.## (en-US, en-CA, en-AU, en-NZ, en-HK)' 1184 | ] 1185 | , valid: [ 1186 | '-$10,123.45' 1187 | , '$10,123.45' 1188 | , '$10123.45' 1189 | , '10,123.45' 1190 | , '10123.45' 1191 | , '10,123' 1192 | , '1,123,456' 1193 | , '1123456' 1194 | , '1.39' 1195 | , '.03' 1196 | , '0.10' 1197 | , '$0.10' 1198 | , '-$0.01' 1199 | , '-$.99' 1200 | , '$100,234,567.89' 1201 | , '$10,123' 1202 | , '10,123' 1203 | , '-10123' 1204 | ] 1205 | , invalid: [ 1206 | '1.234' 1207 | , '$1.1' 1208 | , '$ 32.50' 1209 | , '500$' 1210 | , '.0001' 1211 | , '$.001' 1212 | , '$0.001' 1213 | , '12,34.56' 1214 | , '123456,123,123456' 1215 | , '123,4' 1216 | , ',123' 1217 | , '$-,123' 1218 | , '$' 1219 | , '.' 1220 | , ',' 1221 | , '00' 1222 | , '$-' 1223 | , '$-,.' 1224 | , '-' 1225 | , '-$' 1226 | , '' 1227 | , '- $' 1228 | ] 1229 | }); 1230 | 1231 | test({ 1232 | validator: 'isCurrency' 1233 | , args: [ 1234 | { 1235 | require_symbol: true 1236 | } 1237 | , '-$##,###.## with $ required (en-US, en-CA, en-AU, en-NZ, en-HK)' 1238 | ] 1239 | , valid: [ 1240 | '-$10,123.45' 1241 | , '$10,123.45' 1242 | , '$10123.45' 1243 | , '$10,123.45' 1244 | , '$10,123' 1245 | , '$1,123,456' 1246 | , '$1123456' 1247 | , '$1.39' 1248 | , '$.03' 1249 | , '$0.10' 1250 | , '$0.10' 1251 | , '-$0.01' 1252 | , '-$.99' 1253 | , '$100,234,567.89' 1254 | , '$10,123' 1255 | , '-$10123' 1256 | ] 1257 | , invalid: [ 1258 | '1.234' 1259 | , '$1.234' 1260 | , '1.1' 1261 | , '$1.1' 1262 | , '$ 32.50' 1263 | , ' 32.50' 1264 | , '500' 1265 | , '10,123,456' 1266 | , '.0001' 1267 | , '$.001' 1268 | , '$0.001' 1269 | , '1,234.56' 1270 | , '123456,123,123456' 1271 | , '$123456,123,123456' 1272 | , '123.4' 1273 | , '$123.4' 1274 | , ',123' 1275 | , '$,123' 1276 | , '$-,123' 1277 | , '$' 1278 | , '.' 1279 | , '$.' 1280 | , ',' 1281 | , '$,' 1282 | , '00' 1283 | , '$00' 1284 | , '$-' 1285 | , '$-,.' 1286 | , '-' 1287 | , '-$' 1288 | , '' 1289 | , '$ ' 1290 | , '- $' 1291 | ] 1292 | }); 1293 | 1294 | test({ 1295 | validator: 'isCurrency' 1296 | , args: [ 1297 | { 1298 | symbol:'¥' 1299 | , negative_sign_before_digits:true 1300 | } 1301 | , '¥-##,###.## (zh-CN)' 1302 | ] 1303 | , valid: [ 1304 | '123,456.78' 1305 | , '-123,456.78' 1306 | , '¥6,954,231' 1307 | , '¥-6,954,231' 1308 | , '¥10.03' 1309 | , '¥-10.03' 1310 | , '10.03' 1311 | , '1.39' 1312 | , '.03' 1313 | , '0.10' 1314 | , '¥-10567.01' 1315 | , '¥0.01' 1316 | , '¥1,234,567.89' 1317 | , '¥10,123' 1318 | , '¥-10,123' 1319 | , '¥-10,123.45' 1320 | , '10,123' 1321 | , '10123' 1322 | , '¥-100' 1323 | ] 1324 | , invalid: [ 1325 | '1.234' 1326 | , '¥1.1' 1327 | , '5,00' 1328 | , '.0001' 1329 | , '¥.001' 1330 | , '¥0.001' 1331 | , '12,34.56' 1332 | , '123456,123,123456' 1333 | , '123 456' 1334 | , ',123' 1335 | , '¥-,123' 1336 | , '' 1337 | , ' ' 1338 | , '¥' 1339 | , '¥-' 1340 | , '¥-,.' 1341 | , '-' 1342 | , '- ¥' 1343 | , '-¥' 1344 | ] 1345 | }); 1346 | 1347 | test({ 1348 | validator: 'isCurrency' 1349 | , args: [ 1350 | { 1351 | symbol:'¥' 1352 | , allow_negatives: false 1353 | } 1354 | , '¥##,###.## with no negatives (zh-CN)' 1355 | ] 1356 | , valid: [ 1357 | '123,456.78' 1358 | , '¥6,954,231' 1359 | , '¥10.03' 1360 | , '10.03' 1361 | , '1.39' 1362 | , '.03' 1363 | , '0.10' 1364 | , '¥0.01' 1365 | , '¥1,234,567.89' 1366 | , '¥10,123' 1367 | , '10,123' 1368 | , '10123' 1369 | , '¥100' 1370 | ] 1371 | , invalid: [ 1372 | '1.234' 1373 | , '-123,456.78' 1374 | , '¥-6,954,231' 1375 | , '¥-10.03' 1376 | , '¥-10567.01' 1377 | , '¥1.1' 1378 | , '¥-10,123' 1379 | , '¥-10,123.45' 1380 | , '5,00' 1381 | , '¥-100' 1382 | , '.0001' 1383 | , '¥.001' 1384 | , '¥-.001' 1385 | , '¥0.001' 1386 | , '12,34.56' 1387 | , '123456,123,123456' 1388 | , '123 456' 1389 | , ',123' 1390 | , '¥-,123' 1391 | , '' 1392 | , ' ' 1393 | , '¥' 1394 | , '¥-' 1395 | , '¥-,.' 1396 | , '-' 1397 | , '- ¥' 1398 | , '-¥' 1399 | ] 1400 | }); 1401 | 1402 | test({ 1403 | validator: 'isCurrency' 1404 | , args: [ 1405 | { 1406 | symbol: 'R' 1407 | , negative_sign_before_digits: true 1408 | , thousands_separator: ' ' 1409 | , decimal_separator: ',' 1410 | , allow_negative_sign_placeholder: true 1411 | } 1412 | , 'R ## ###,## and R-10 123,25 (el-ZA)' 1413 | ] 1414 | , valid: [ 1415 | '123 456,78' 1416 | , '-10 123' 1417 | , 'R-10 123' 1418 | , 'R 6 954 231' 1419 | , 'R10,03' 1420 | , '10,03' 1421 | , '1,39' 1422 | , ',03' 1423 | , '0,10' 1424 | , 'R10567,01' 1425 | , 'R0,01' 1426 | , 'R1 234 567,89' 1427 | , 'R10 123' 1428 | , 'R 10 123' 1429 | , 'R 10123' 1430 | , 'R-10123' 1431 | , '10 123' 1432 | , '10123' 1433 | ] 1434 | , invalid: [ 1435 | '1,234' 1436 | , 'R -10123' 1437 | , 'R- 10123' 1438 | , 'R,1' 1439 | , ',0001' 1440 | , 'R,001' 1441 | , 'R0,001' 1442 | , '12 34,56' 1443 | , '123456 123 123456' 1444 | , ' 123' 1445 | , '- 123' 1446 | , '123 ' 1447 | , '' 1448 | , ' ' 1449 | , 'R' 1450 | , 'R- .1' 1451 | , 'R-' 1452 | , '-' 1453 | , '-R 10123' 1454 | , 'R00' 1455 | , 'R -' 1456 | , '-R' 1457 | ] 1458 | }); 1459 | 1460 | test({ 1461 | validator: 'isCurrency' 1462 | , args: [ 1463 | { 1464 | symbol: '€' 1465 | , thousands_separator: '.' 1466 | , decimal_separator: ',' 1467 | , allow_space_after_symbol: true 1468 | } 1469 | , '-€ ##.###,## (it-IT)' 1470 | ] 1471 | , valid: [ 1472 | '123.456,78' 1473 | , '-123.456,78' 1474 | , '€6.954.231' 1475 | , '-€6.954.231' 1476 | , '€ 896.954.231' 1477 | , '-€ 896.954.231' 1478 | , '16.954.231' 1479 | , '-16.954.231' 1480 | , '€10,03' 1481 | , '-€10,03' 1482 | , '10,03' 1483 | , '-10,03' 1484 | , '-1,39' 1485 | , ',03' 1486 | , '0,10' 1487 | , '-€10567,01' 1488 | , '-€ 10567,01' 1489 | , '€ 0,01' 1490 | , '€1.234.567,89' 1491 | , '€10.123' 1492 | , '10.123' 1493 | , '-€10.123' 1494 | , '€ 10.123' 1495 | , '€10.123' 1496 | , '€ 10123' 1497 | , '10.123' 1498 | , '-10123' 1499 | ] 1500 | , invalid: [ 1501 | '1,234' 1502 | , '€ 1,1' 1503 | , '50#,50' 1504 | , '123,@€ ' 1505 | , '€€500' 1506 | , ',0001' 1507 | , '€ ,001' 1508 | , '€0,001' 1509 | , '12.34,56' 1510 | , '123456.123.123456' 1511 | , '€123€' 1512 | , '' 1513 | , ' ' 1514 | , '€' 1515 | , ' €' 1516 | , '€ ' 1517 | , '€€' 1518 | , ' 123' 1519 | , '- 123' 1520 | , '.123' 1521 | , '-€.123' 1522 | , '123 ' 1523 | , '€-' 1524 | , '- €' 1525 | , '€ - ' 1526 | , '-' 1527 | , '- ' 1528 | , '-€' 1529 | ] 1530 | }); 1531 | 1532 | test({ 1533 | validator: 'isCurrency' 1534 | , args: [ 1535 | { 1536 | symbol: '€' 1537 | , thousands_separator: '.' 1538 | , symbol_after_digits: true 1539 | , decimal_separator: ',' 1540 | , allow_space_after_digits: true 1541 | } 1542 | , '-##.###,## € (el-GR)' 1543 | ] 1544 | , valid: [ 1545 | '123.456,78' 1546 | , '-123.456,78' 1547 | , '6.954.231 €' 1548 | , '-6.954.231 €' 1549 | , '896.954.231' 1550 | , '-896.954.231' 1551 | , '16.954.231' 1552 | , '-16.954.231' 1553 | , '10,03€' 1554 | , '-10,03€' 1555 | , '10,03' 1556 | , '-10,03' 1557 | , '1,39' 1558 | , ',03' 1559 | , '-,03' 1560 | , '-,03 €' 1561 | , '-,03€' 1562 | , '0,10' 1563 | , '10567,01€' 1564 | , '0,01 €' 1565 | , '1.234.567,89€' 1566 | , '10.123€' 1567 | , '10.123' 1568 | , '10.123€' 1569 | , '10.123 €' 1570 | , '10123 €' 1571 | , '10.123' 1572 | , '10123' 1573 | ] 1574 | , invalid: [ 1575 | '1,234' 1576 | , '1,1 €' 1577 | , ',0001' 1578 | , ',001 €' 1579 | , '0,001€' 1580 | , '12.34,56' 1581 | , '123456.123.123456' 1582 | , '€123€' 1583 | , '' 1584 | , ' ' 1585 | , '€' 1586 | , ' €' 1587 | , '€ ' 1588 | , ' 123' 1589 | , '- 123' 1590 | , '.123' 1591 | , '-.123€' 1592 | , '-.123 €' 1593 | , '123 ' 1594 | , '-€' 1595 | , '- €' 1596 | , '-' 1597 | , '- ' 1598 | ] 1599 | }); 1600 | 1601 | test({ 1602 | validator: 'isCurrency' 1603 | , args: [ 1604 | { 1605 | symbol: 'kr.' 1606 | , negative_sign_before_digits: true 1607 | , thousands_separator: '.' 1608 | , decimal_separator: ',' 1609 | , allow_space_after_symbol: true 1610 | } 1611 | , 'kr. -##.###,## (da-DK)' 1612 | ] 1613 | , valid: [ 1614 | '123.456,78' 1615 | , '-10.123' 1616 | , 'kr. -10.123' 1617 | , 'kr.-10.123' 1618 | , 'kr. 6.954.231' 1619 | , 'kr.10,03' 1620 | , 'kr. -10,03' 1621 | , '10,03' 1622 | , '1,39' 1623 | , ',03' 1624 | , '0,10' 1625 | , 'kr. 10567,01' 1626 | , 'kr. 0,01' 1627 | , 'kr. 1.234.567,89' 1628 | , 'kr. -1.234.567,89' 1629 | , '10.123' 1630 | , 'kr. 10.123' 1631 | , 'kr.10.123' 1632 | , '10123' 1633 | , '10.123' 1634 | , 'kr.-10123' 1635 | ] 1636 | , invalid: [ 1637 | '1,234' 1638 | , 'kr. -10123' 1639 | , 'kr.,1' 1640 | , ',0001' 1641 | , 'kr. ,001' 1642 | , 'kr.0,001' 1643 | , '12.34,56' 1644 | , '123456.123.123456' 1645 | , '.123' 1646 | , 'kr.-.123' 1647 | , 'kr. -.123' 1648 | , '- 123' 1649 | , '123 ' 1650 | , '' 1651 | , ' ' 1652 | , 'kr.' 1653 | , ' kr.' 1654 | , 'kr. ' 1655 | , 'kr.-' 1656 | , 'kr. -' 1657 | , 'kr. - ' 1658 | , ' - ' 1659 | , '-' 1660 | , '- kr.' 1661 | , '-kr.' 1662 | ] 1663 | }); 1664 | 1665 | test({ 1666 | validator: 'isCurrency' 1667 | , args: [ 1668 | { 1669 | symbol: 'kr.' 1670 | , allow_negatives: false 1671 | , negative_sign_before_digits: true 1672 | , thousands_separator: '.' 1673 | , decimal_separator: ',' 1674 | , allow_space_after_symbol: true 1675 | } 1676 | , 'kr. ##.###,## with no negatives (da-DK)' 1677 | ] 1678 | , valid: [ 1679 | '123.456,78' 1680 | , '10.123' 1681 | , 'kr. 10.123' 1682 | , 'kr.10.123' 1683 | , 'kr. 6.954.231' 1684 | , 'kr.10,03' 1685 | , 'kr. 10,03' 1686 | , '10,03' 1687 | , '1,39' 1688 | , ',03' 1689 | , '0,10' 1690 | , 'kr. 10567,01' 1691 | , 'kr. 0,01' 1692 | , 'kr. 1.234.567,89' 1693 | , 'kr.1.234.567,89' 1694 | , '10.123' 1695 | , 'kr. 10.123' 1696 | , 'kr.10.123' 1697 | , '10123' 1698 | , '10.123' 1699 | , 'kr.10123' 1700 | ] 1701 | , invalid: [ 1702 | '1,234' 1703 | , '-10.123' 1704 | , 'kr. -10.123' 1705 | , 'kr. -1.234.567,89' 1706 | , 'kr.-10123' 1707 | , 'kr. -10123' 1708 | , 'kr.-10.123' 1709 | , 'kr. -10,03' 1710 | , 'kr.,1' 1711 | , ',0001' 1712 | , 'kr. ,001' 1713 | , 'kr.0,001' 1714 | , '12.34,56' 1715 | , '123456.123.123456' 1716 | , '.123' 1717 | , 'kr.-.123' 1718 | , 'kr. -.123' 1719 | , '- 123' 1720 | , '123 ' 1721 | , '' 1722 | , ' ' 1723 | , 'kr.' 1724 | , ' kr.' 1725 | , 'kr. ' 1726 | , 'kr.-' 1727 | , 'kr. -' 1728 | , 'kr. - ' 1729 | , ' - ' 1730 | , '-' 1731 | , '- kr.' 1732 | , '-kr.' 1733 | ] 1734 | }); 1735 | 1736 | test({ 1737 | validator: 'isCurrency' 1738 | , args: [ 1739 | { 1740 | parens_for_negatives: true 1741 | } 1742 | , '($##,###.##) (en-US, en-HK)' 1743 | ] 1744 | , valid: [ 1745 | '1,234' 1746 | , '(1,234)' 1747 | , '($6,954,231)' 1748 | , '$10.03' 1749 | , '(10.03)' 1750 | , '($10.03)' 1751 | , '1.39' 1752 | , '.03' 1753 | , '(.03)' 1754 | , '($.03)' 1755 | , '0.10' 1756 | , '$10567.01' 1757 | , '($0.01)' 1758 | , '$1,234,567.89' 1759 | , '$10,123' 1760 | , '(10,123)' 1761 | , '10123' 1762 | ] 1763 | , invalid: [ 1764 | '1.234' 1765 | , '($1.1)' 1766 | , '-$1.10' 1767 | , '$ 32.50' 1768 | , '500$' 1769 | , '.0001' 1770 | , '$.001' 1771 | , '($0.001)' 1772 | , '12,34.56' 1773 | , '123456,123,123456' 1774 | , '( 123)' 1775 | , ',123' 1776 | , '$-,123' 1777 | , '' 1778 | , ' ' 1779 | , ' ' 1780 | , ' ' 1781 | , '$' 1782 | , '$ ' 1783 | , ' $' 1784 | , ' 123' 1785 | , '(123) ' 1786 | , '.' 1787 | , ',' 1788 | , '00' 1789 | , '$-' 1790 | , '$ - ' 1791 | , '$- ' 1792 | , ' - ' 1793 | , '-' 1794 | , '- $' 1795 | , '-$' 1796 | , '()' 1797 | , '( )' 1798 | , '( -)' 1799 | , '( - )' 1800 | , '( - )' 1801 | , '(-)' 1802 | , '(-$)' 1803 | ] 1804 | }); 1805 | 1806 | test({ 1807 | validator: 'isCurrency' 1808 | , args: [ 1809 | {allow_negatives: false} 1810 | , '$##,###.## with no negatives (en-US, en-CA, en-AU, en-HK)' 1811 | ] 1812 | , valid: [ 1813 | '$10,123.45' 1814 | , '$10123.45' 1815 | , '10,123.45' 1816 | , '10123.45' 1817 | , '10,123' 1818 | , '1,123,456' 1819 | , '1123456' 1820 | , '1.39' 1821 | , '.03' 1822 | , '0.10' 1823 | , '$0.10' 1824 | , '$100,234,567.89' 1825 | , '$10,123' 1826 | , '10,123' 1827 | ] 1828 | , invalid: [ 1829 | '1.234' 1830 | , '-1.234' 1831 | , '-10123' 1832 | , '-$0.01' 1833 | , '-$.99' 1834 | , '$1.1' 1835 | , '-$1.1' 1836 | , '$ 32.50' 1837 | , '500$' 1838 | , '.0001' 1839 | , '$.001' 1840 | , '$0.001' 1841 | , '12,34.56' 1842 | , '123456,123,123456' 1843 | , '-123456,123,123456' 1844 | , '123,4' 1845 | , ',123' 1846 | , '$-,123' 1847 | , '$' 1848 | , '.' 1849 | , ',' 1850 | , '00' 1851 | , '$-' 1852 | , '$-,.' 1853 | , '-' 1854 | , '-$' 1855 | , '' 1856 | , '- $' 1857 | , '-$10,123.45' 1858 | ] 1859 | }); 1860 | }); 1861 | }); --------------------------------------------------------------------------------