├── .babelrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── package.json ├── snapshot └── async_predicate_just_fun.png ├── src ├── allPass.js ├── alpha.js ├── alphaDash.js ├── always.js ├── assert.js ├── compact.js ├── decimal.js ├── equals.js ├── exactLength.js ├── failed.js ├── imageMatchP.js ├── index.js ├── integer.js ├── internal │ ├── _alpha.js │ ├── _alphaDash.js │ ├── _identity.js │ ├── _imageInfoP.js │ ├── _integer.js │ ├── _isFailedByRuleValue.js │ ├── _isThenable.js │ ├── _nature.js │ ├── _natureNoZero.js │ ├── _path.js │ ├── _required.js │ └── _validUrl.js ├── itShould.js ├── itShouldPath.js ├── itShouldProp.js ├── large.js ├── largeOrEqual.js ├── less.js ├── lessOrEqual.js ├── matchs.js ├── maxLength.js ├── minLength.js ├── nature.js ├── natureNoZero.js ├── normal.js ├── normalP.js ├── numeric.js ├── of.js ├── oneOf.js ├── required.js ├── validIP.js ├── validUrl.js └── validate.js └── test ├── allPass.spec.js ├── alpha.spec.js ├── alphaDash.spec.js ├── assert.spec.js ├── compact.spec.js ├── decimal.spec.js ├── exactLength.spec.js ├── imageMatch.spec.js ├── integer.js ├── itShould.spec.js ├── itShouldPath.js ├── itShouldProp.js ├── large.spec.js ├── largeOrEqual.spec.js ├── less.spec.js ├── lessOrEqual.js ├── matchs.spec.js ├── maxLength.spec.js ├── minLength.spec.js ├── nature.spec.js ├── natureNoZero.spec.js ├── normalP.js ├── numeric.spec.js ├── oneOf.spec.js ├── required.spec.js ├── validIP.spec.js ├── validUrl.spec.js └── validate.spec.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ['@babel/preset-env', { 4 | 'targets': { 5 | 'browsers': ['last 2 versions'] 6 | }, 7 | 'debug': true 8 | }] 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json 3 | .nyc_output/ 4 | coverage* 5 | lib/ -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | snapshot/ 3 | src/ 4 | .travis.yml 5 | coverage* 6 | .nyc* -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "7" 4 | - "6" 5 | 6 | before_script: 7 | - npm install 8 | 9 | cache: 10 | directories: 11 | - "node_modules" 12 | 13 | script: 14 | - npm run coverage 15 | - npm run test -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OverAssert 2 | 3 | [![Build Status](https://travis-ci.com/Qquanwei/OverAssert.svg?token=ywJP6ZbPxtsNYQ2GidVL&branch=master)](https://travis-ci.com/Qquanwei/OverAssert) 4 | [![codecov](https://codecov.io/gh/Qquanwei/OverAssert/branch/master/graph/badge.svg?token=oJbeN3S4cq)](https://codecov.io/gh/Qquanwei/OverAssert) 5 | [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FQquanwei%2FOverAssert.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FQquanwei%2FOverAssert?ref=badge_shield) 6 | [![npm version](https://badge.fury.io/js/overassert.svg)](https://badge.fury.io/js/overassert) 7 | 8 | 校验,规则,可组合,可复用,同步&异步, 函数式. 9 | 10 | OverAssert 提供一种 DSL 让断言规则更加语意化, 规则即是文档. 同时设计本身为函数式风格,很容易与其他库结合使用。OverAssert 提供了大量的内置断言,覆盖多种复杂场景,对同步、异步都有非常良好的支持. 11 | 12 | ## 使用 13 | ```javascript 14 | import { of, itShould, itShouldProp, always } from 'overassert'; 15 | 16 | of(x) 17 | .map(itShould(large(10), always('应该大于10'))) 18 | .map(itShould(large(20), always('应该大于20') 19 | .validate((success, reason) => { 20 | if (success) { 21 | } else { 22 | } 23 | }) 24 | 25 | of(x) 26 | .map(itShouldProp('name', A.required(), A.always('require name'))) 27 | .map(itShouldProp('age', A.required(), A.always('require age'))) 28 | .validate((success, reason) => { 29 | return success; 30 | }) 31 | 32 | ``` 33 | 34 | 35 | > OverAssert 没有包含 Promise 的 Polyfill,如果用到了内置的异步断言例如imageMatchP,需要确保外部打入 Promise 的 polyfill。 36 | 37 | ![async predicate just fun](./snapshot/async_predicate_just_fun.png) 38 | 39 | 40 | #### React Demo online 41 | 42 | https://stackblitz.com/edit/overassert-react-test?file=index.js 43 | 44 | ## API 45 | 46 | * 建立描述 47 | * [of](#of) 48 | * [itShould](#itShould) 49 | * [itShouldProp](#itShouldProp) 50 | * [itShouldPath](#itShouldPath) 51 | * [always](#always) 52 | * [validate](#validate) 53 | 54 | * 断言 55 | * [required](#required) 该字段为必传 56 | * [large](#large) 该字段大于x 57 | * [largeE](#largeOrEqual) largeOrEqual别名 58 | * [largeOrEqual](#largeOrEqual) 该字段大于等于x 59 | * [less](#less) 该字段小于x 60 | * [lessE](#lessOrEqual) lessOrEqual别名 61 | * [lessOrEqual](#lessOrEqual) 该字段小于等于x 62 | * [equals](#equals) 该字段等于x 63 | * [integer](#integer) 该字段为整数,包含正整数,负整数和0 64 | * [nature](#nature) 该字段为自然数, 包含正整数和0 65 | * [natureNoZero](#natureNoZero) 该字段仅包含正整数 66 | * [imageMatchP](#imageMatchP) 该字段所表示的图片满足条件x 67 | * [validUrl](#validUrl) 该字段是一个有效的url 68 | * [validIP](#validIP) 该字段是一个有效的ip 69 | * [alpha](#alpha) 该字段是字母组成的 70 | * [alphaDash](#alphaDash) 该字段是字母,下划线,中划线 71 | * [numeric](#numeric) 该字段由数字组成 72 | * [decimal](#decimal) 该字段是十进制的数字 73 | * [minLength](#minLength) 该字段最小长度>=x 74 | * [maxLength](#maxLength) 该字段最大长度<=x 75 | * [exactLength](#exactLength) 该字段长度==x 76 | * [matchs](#matchs) 正则匹配 77 | * [oneOf](#oneOf) 枚举匹配 78 | 79 | * 组合规则 80 | 81 | * [compact](#compact) 82 | 83 | * 组合断言 84 | 85 | * [allPass](#allPass) 86 | * 高级 87 | * [异步校验](#异步校验) 88 | * [自定义断言函数](#自定义断言函数) 89 | * [自定义规则函数](#自定义规则函数) 90 | * [创建复合断言](#创建复合断言) 91 | * [创建复合规则](#创建复合规则) 92 | 93 | 94 | of(data: any) => Assert(#of) 95 | -------------------- 96 | #### 创建一个Assert对象 97 | 98 | ```javascript 99 | assert = of(1) 100 | assert = of([1, 2, 3]) 101 | assert = of({ name: 'Alice', age: 20}) 102 | ``` 103 | 104 | * assert.map(rule) 105 | 106 | > rule: (value: any) => Assert|Promise|string|undefined 107 | 108 | * assert.validate(callback) 109 | 110 | > callback: (success: boolean, reason: string) => void 111 | 112 | itShould(predicate: Function, failedReason: Function) => rule 113 | ------------------------- 114 | #### 通过断言函数,错误信息函数生成一个规则函数. 115 | 116 | ```javascript 117 | rule1 = itShould(Array.isArray, item => `${item} is not array`); 118 | ``` 119 | 120 | equal 121 | 122 | ```javascript 123 | rule1 = (value) => { 124 | if (Array.isArray(value)) { 125 | return undefined; 126 | } 127 | return `${value} is not array` 128 | } 129 | ``` 130 | 131 | 132 | ```javascript 133 | of(1) 134 | .map(itShould(Array.isArray, item => `${item} is not array`)) 135 | .map(itShould(Number.isInteger, item => `${item} should be integer`)) 136 | .validate((success, value) => { 137 | console.log(success, value); 138 | }) 139 | ``` 140 | 141 | output: 142 | 143 | ``` 144 | false `1 is not array` 145 | ``` 146 | 147 | itShouldProp(propName: string, predicate: Function, failedReason: Function) => rule 148 | -------------------------- 149 | #### 通过断言某个属性生成一个规则函数 150 | 151 | 152 | ```javascript 153 | of({ name: 'Alice' }) 154 | .map(itShouldProp('name', Array.isArray, item => `${item} is not array`)) 155 | .validate((success, value) => { 156 | console.log(success, value); 157 | }) 158 | ``` 159 | 160 | output 161 | 162 | ``` 163 | false Alice is not array 164 | ``` 165 | 166 | itShouldPath(pathArray: Array, predicate: Function, failedReason: Function) => rule 167 | --------------------------- 168 | ### 通过断言深层属性生成一个规则函数. 如果该路径不存在,则直接断言失败 169 | 170 | ```javascript 171 | of({ first: { name: 'Alice'}}) 172 | .map(itShouldPath(['first', 'name'], Array.isArray, item => `${item} is not array`)) 173 | .validate((success, value) => { 174 | console.log(success, value); 175 | }) 176 | ``` 177 | 178 | output 179 | 180 | ``` 181 | false Alice is not array 182 | ``` 183 | 184 | always(reason: string) => Function 185 | ---------------------------- 186 | #### 生成一个返回固定信息的函数. 187 | 188 | ```javascript 189 | of(1) 190 | .map(itShould(Array.isArray, always('该属性不是Array'))) 191 | .validate((success, value) => { 192 | console.log(success, value); 193 | }) 194 | ``` 195 | 196 | output 197 | 198 | ``` 199 | false 该属性不是Array 200 | ``` 201 | 202 | validate(v1: Assert,v2: Assert,..., callback: Function) => void 203 | -------------------------- 204 | #### validate是assert.validate的函数形式,可以同时校验多个assert 205 | 206 | ```javascript 207 | validate( 208 | of(1).map(itShould(large(10), always('应该大于10'))), 209 | (success, value) => { 210 | console.log(success, value) 211 | } 212 | ); 213 | 214 | validate( 215 | of(11).map(itShould(large(10), always('应该大于10'))), 216 | of(12).map(itShould(large(20), always('应该大于20'))), 217 | (success, value) => { 218 | console.log(success, value); 219 | } 220 | ) 221 | ``` 222 | 223 | output 224 | 225 | ``` 226 | false 应该大于10 227 | false 应该大于20 228 | ``` 229 | 230 | 231 | required() = PredicateFunction 232 | ------------------- 233 | #### 要求必须有值 234 | 235 | ``` 236 | true -> true 237 | false -> true 238 | 123 -> true 239 | 'hello' -> true 240 | 0 -> true 241 | 242 | '' -> false 243 | null -> false 244 | undefined -> false 245 | ``` 246 | 247 | large(value: number) => Predicate Function 248 | ---------------------------- 249 | ### 生成一个判断是否大于指定数字的断言函数 250 | 251 | large10 = large(10); 252 | 253 | * large10(1) -> false 254 | * large10(11) -> true 255 | 256 | ```javascript 257 | of(1) 258 | .map(itShould(large(10), always('数字应该大于10'))) 259 | .validate((success, value) => { 260 | console.log(success, value) 261 | }) 262 | ``` 263 | 264 | output 265 | 266 | ``` 267 | false 数字应该大于10 268 | ``` 269 | 270 | largeOrEqual(value: number) => PredicateFunction 271 | ---------------- 272 | ##### 判断是否大于或等于 273 | 274 | less(value: number) => PredicateFunction 275 | ------------------------------- 276 | #### 生成一个判断是否小于指定数字的断言函数 277 | 278 | ```javascript 279 | of(12) 280 | .map(itShould(large(5), always('数字应该大于5'))) 281 | .map(itShould(less(10),always('数字应该小于10'))) 282 | .validate((success, value) => { 283 | console.log(success, value) 284 | }) 285 | ``` 286 | 287 | output 288 | 289 | ``` 290 | false 数字应该小于10 291 | ``` 292 | 293 | lessOrEqual(value: number) => PredicateFunction 294 | -------------- 295 | #### 判断是否小于等于 296 | 297 | equals(value: any) => PredicateFunction 298 | ---------------------------------- 299 | #### 判断是否严格相等 300 | 301 | ``` 302 | 1 , 1 -> true 303 | 1 , "1" -> false 304 | ``` 305 | 306 | integer() => PredicateFunction 307 | ------------------------------ 308 | #### 判断是否是整数 309 | 310 | ``` 311 | 123 -> true 312 | -123 -> true 313 | 0 -> true 314 | 315 | 12.3 -> false 316 | "12.3" -> false 317 | "12ac" -> false 318 | null -> false 319 | undefined -> false 320 | object -> false 321 | ``` 322 | 323 | nature() => PredicateFunction 324 | ----------------------- 325 | #### 判断是否是自然数 326 | 327 | ``` 328 | 0 -> true 329 | 1 -> true 330 | 100 -> false 331 | -1 -> false 332 | null -> false 333 | undefined -> false 334 | ``` 335 | 336 | natureNoZero() => PredicateFunction 337 | --------------- 338 | #### 判断是否是不为0的自然数 339 | 340 | ``` 341 | 1 -> true 342 | 100 -> true 343 | 344 | 0 -> false 345 | -1 -> false 346 | -100 -> false 347 | ``` 348 | 349 | imageMatchP(rule1: Function, rule2: Function, ...) => PredicateFunction 350 | -------------- 351 | #### 判断本地图片对象是否合法 352 | 353 | ```javascript 354 | 355 | const imageSizeRule = itShouldProp('width', large(10), always('width should large 10')); 356 | 357 | of(imageFile) 358 | .map(itShould(imageMatchP(imageSizeRule), always('file not exists'))) 359 | .validate((success, reason) => { 360 | }) 361 | ``` 362 | 363 | imageMatchP是一个普通的异步断言. 可以和itShould结合使用。 364 | 365 | validUrl() => PredicateFunction 366 | ---------------------- 367 | #### 是否是合法的url 368 | 369 | ``` 370 | http://google.com -> true 371 | http://google.com?a=1&b=1 -> true 372 | http://gogole.com/index.html -> true 373 | 374 | 127.0.0.1 -> false 375 | undefined/null/number -> false 376 | helloworld.com -> false 377 | worldismine/ccc -> false 378 | ``` 379 | 380 | validIP() => PredicateFunction 381 | -------------- 382 | #### 是否是合法的ip 383 | 384 | ``` 385 | 255.255.255.255 -> true 386 | 0.0.0.0 -> true 387 | 192.168.0.1 -> true 388 | 389 | 256.0.0.1 -> false 390 | abcde -> false 391 | ``` 392 | 393 | alpha()=> PredicateFunction 394 | --------------------- 395 | #### 是否是是字母表中的字母 396 | 397 | ``` 398 | abc -> true 399 | 123 -> false 400 | abc!@# -> false 401 | null -> false 402 | undefined -> false 403 | ``` 404 | 405 | alphaDash() => PredicateFunction 406 | -------- 407 | #### 是否仅仅为字母,下划线,中划线 408 | 409 | ``` 410 | abc -> true 411 | abc_bcd -> true 412 | abc-bcd -> true 413 | 414 | 123 -> false 415 | abc123 -> false 416 | null -> false 417 | undefined -> false 418 | ``` 419 | 420 | 421 | numeric() => PredicateFunction 422 | --------- 423 | #### 是否是数字 424 | 425 | ``` 426 | 123 -> true 427 | abc -> false 428 | null -> false 429 | undefined -> false 430 | ``` 431 | 432 | decimal() => PredicateFunction 433 | ------- 434 | #### 是否是十进制的数字 435 | 436 | ``` 437 | 123.123 -> true 438 | 12 -> true 439 | .123 -> true 440 | 441 | null -> false 442 | undefined -> false 443 | abc -> false 444 | ``` 445 | 446 | 447 | minLength(value: number 448 | -------- 449 | #### 判断输入最小长度 450 | 451 | ``` 452 | minLength(3) => 最小长度为3 453 | 454 | 123 -> true 455 | 1234 -> true 456 | abcd -> true 457 | 458 | 12 -> false 459 | null -> false 460 | undefined -> false 461 | ab -> false 462 | 463 | ``` 464 | 465 | maxLength(value: number 466 | ---------- 467 | #### 判断输入最大长度 468 | 469 | ``` 470 | maxLength(3) => 最大长度为3 471 | 472 | 123 -> true 473 | 12 -> true 474 | ab -> true 475 | c -> true 476 | 477 | 1234 -> false 478 | abcd -> false 479 | null -> false 480 | undefined -> false 481 | ``` 482 | 483 | 484 | 485 | exactLength(value: number) => PredicateFunction 486 | -------------------- 487 | #### 输入长度是否等于 488 | 489 | ``` 490 | exactLength(3) => 长度为3 491 | 492 | 123 -> true 493 | abc -> true 494 | 000 -> true 495 | 496 | -123 -> false 497 | ab -> false 498 | null -> false 499 | undefined -> false 500 | ``` 501 | 502 | matchs(re: RegExp|string) => PredicateFunction 503 | -------------- 504 | #### 输入是否匹配指定正则或字符串 505 | 506 | ``` 507 | matchs(/123/) => 输入是否能够匹配123 508 | 509 | 12345 -> true 510 | '12345' -> true 511 | 512 | otherwise -> false 513 | ``` 514 | 515 | oneOf(list: Array) => PredicateFunction 516 | ------ 517 | #### 是否为其中之一 518 | 519 | ``` 520 | oneOf(['1', 2, {}]) 521 | 522 | '1' -> true 523 | 2 -> true 524 | 525 | {} -> false 526 | 1 -> false 527 | '2' -> false 528 | null -> false 529 | undefined -> false 530 | ``` 531 | 532 | compact(rule1: Function, rule2: Function, ...) => Rule 533 | -------------------------------- 534 | #### 组合多个规则函数生成一个规则 535 | 536 | allPass(predicate1: Function, predicate2: Function, ...) => PredicateFunction 537 | ---------------------------------- 538 | #### 返回一个新的断言,当所有条件满足即满足条件时为真 539 | 540 | ```javascript 541 | of(15) 542 | .map(itShould( 543 | allPass(large(10), less(20)), 544 | always('数字不在区间内') 545 | )) 546 | .validate((success, value) => { 547 | console.log(success, value); 548 | }) 549 | ``` 550 | 551 | output 552 | 553 | ``` 554 | false 数字不在区间内 555 | ``` 556 | 557 | 558 | ### 一点点概念: 559 | 560 | 断言函数: 指仅仅提供断言功能,返回是否满足条件的函数. (x) => bool 561 | 562 | 规则函数: 指自定义,或者用itShould创建,里面包含断言与错误信息的函数 563 | 564 | ## 异步校验 565 | 566 | 如果有一个断言函数是 `x => Promise`, 那么就是一个异步校验. OverAssert天然支持异步校验. 567 | 568 | 异步校验会将Promise::fulfilled当作成功的条件, 对应的Promise::rejected会执行失败逻辑. 569 | 570 | 571 | ```javascript 572 | import { of, always } from 'overassert'; 573 | 574 | function asyncLarge10(value) { 575 | return new Promise((resolve, reject) => { 576 | setTimeout(() => { 577 | if (value > 10) { 578 | resolve(); 579 | } else { 580 | reject(); 581 | } 582 | }, 300); 583 | }); 584 | } 585 | 586 | of(x) 587 | .map(itShould(asyncLarge10, always('emm!')) 588 | .validate((success, value) => { 589 | if (success) { 590 | // value === x 591 | } else { 592 | // value === 'emm!' 593 | } 594 | }) 595 | ``` 596 | 597 | ## 自定义断言函数 598 | 599 | ```javascript 600 | function isShouldLarge10(value) { 601 | return value > 10; 602 | } 603 | ``` 604 | 605 | ## 自定义规则函数 606 | 607 | ```javascript 608 | function customP(value) { 609 | if (value > 10) { 610 | return value + ' should not large than 10'; 611 | } 612 | } 613 | 614 | of(x) 615 | .map(customP) 616 | ``` 617 | 618 | 619 | ## 创建复合断言 620 | 621 | 借住内置的方法,或者其他库函数创建出复合的断言函数. 622 | 623 | 例如: allPass 624 | ``` 625 | of(10) 626 | .map(itShould( 627 | allPass(large(10), less(20)), 628 | always('数据不在区间内') 629 | )) 630 | ``` 631 | 632 | ## 创建复合规则 633 | 634 | 借助 compact 可以帮我们组合规则函数. 635 | 636 | ```javascript 637 | 638 | const myCustomCompact = compact( 639 | itShould(large(10), always('should large than 10')), 640 | itShould(less(20), always('should less than 20')) 641 | ); 642 | 643 | of(15) 644 | .map(myCustomCompact) 645 | .map(customP) 646 | .map(itShould(isInteger(), always('should is a integer'))); 647 | ``` 648 | 649 | 650 | 651 | 652 | ## Normal and Failed 653 | 654 | > import { Normal, Failed } from './src'; 655 | 656 | Normal用来表示一个正常的值, Failed用来表示一个失败的值. 657 | 658 | ## About Maybe Monad 659 | https://en.wikibooks.org/wiki/Haskell/Understanding_monads/Maybe 660 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "overassert", 3 | "version": "1.0.5", 4 | "description": "校验,规则,可组合,可复用,函数式。", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "clean": "rm -rf lib", 8 | "build": "npm run clean && babel src --out-dir lib", 9 | "coverage": "nyc --reporter=text-lcov mocha --require @babel/register > coverage.lcov && codecov", 10 | "test": "mocha --require @babel/register" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/Qquanwei/OverAssert.git" 15 | }, 16 | "keywords": ["validation", "assert", "functional", "form"], 17 | "author": "Qquanwei", 18 | "license": "ISC", 19 | "bugs": { 20 | "url": "https://github.com/Qquanwei/OverAssert/issues" 21 | }, 22 | "homepage": "https://github.com/Qquanwei/OverAssert#readme", 23 | "devDependencies": { 24 | "@babel/cli": "^7.2.3", 25 | "@babel/core": "^7.3.4", 26 | "@babel/preset-env": "^7.3.4", 27 | "@babel/register": "^7.0.0", 28 | "chai": "^4.2.0", 29 | "codecov": "^3.2.0", 30 | "jsdom": "^14.0.0", 31 | "jsdom-global": "^3.0.2", 32 | "mocha": "^6.0.2", 33 | "nyc": "^13.3.0", 34 | "sinon": "^7.2.7" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /snapshot/async_predicate_just_fun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Qquanwei/OverAssert/a153d07de7ec5841ce2a19afa5a741c9b6cd36a9/snapshot/async_predicate_just_fun.png -------------------------------------------------------------------------------- /src/allPass.js: -------------------------------------------------------------------------------- 1 | import _identity from './internal/_identity'; 2 | 3 | function allPass(...fnArgs) { 4 | const fns = fnArgs.length ? fnArgs : [_identity]; 5 | 6 | return value => { 7 | return fns.reduce((ans, fn) => { 8 | return ans && fn(value); 9 | }, true); 10 | } 11 | } 12 | 13 | export default allPass; 14 | -------------------------------------------------------------------------------- /src/alpha.js: -------------------------------------------------------------------------------- 1 | import _alpha from './internal/_alpha'; 2 | 3 | function alpha() { 4 | return _alpha; 5 | } 6 | 7 | 8 | export default alpha; 9 | -------------------------------------------------------------------------------- /src/alphaDash.js: -------------------------------------------------------------------------------- 1 | import _alphaDash from './internal/_alphaDash'; 2 | 3 | // only contains alpha-numeric, underscore, dashs 4 | function alphaDash() { 5 | return _alphaDash; 6 | } 7 | 8 | export default alphaDash; 9 | -------------------------------------------------------------------------------- /src/always.js: -------------------------------------------------------------------------------- 1 | function always(x) { 2 | return () => { 3 | return x; 4 | } 5 | } 6 | 7 | export default always; 8 | -------------------------------------------------------------------------------- /src/assert.js: -------------------------------------------------------------------------------- 1 | // Nomal 2 | function Assert () { 3 | if (!(this instanceof Assert)) { 4 | throw new Error('Maybe you should initialize by Assert.of(value)'); 5 | } 6 | } 7 | 8 | Assert.prototype.map = function (fn) { 9 | throw new Error('map not implement'); 10 | } 11 | 12 | Assert.prototype.validate = function (callback) { 13 | if (callback) { 14 | return callback(this.success, this.value); 15 | } 16 | } 17 | 18 | export default Assert; 19 | -------------------------------------------------------------------------------- /src/compact.js: -------------------------------------------------------------------------------- 1 | import _identity from './internal/_identity'; 2 | import of from './of'; 3 | 4 | function compact(...FnArgs) { 5 | const fns = FnArgs.length ? FnArgs : [_identity]; 6 | 7 | return value => { 8 | return fns.reduce((v, fn) => { 9 | return v.map(fn); 10 | }, of(value)); 11 | } 12 | } 13 | 14 | 15 | export default compact; 16 | -------------------------------------------------------------------------------- /src/decimal.js: -------------------------------------------------------------------------------- 1 | function decimal() { 2 | return value => { 3 | if (value && value[0] === '.') { 4 | return decimal()('0' + value); 5 | } 6 | return ('' + value) === ('' + Number.parseFloat(value)); 7 | } 8 | } 9 | 10 | export default decimal; 11 | -------------------------------------------------------------------------------- /src/equals.js: -------------------------------------------------------------------------------- 1 | function equals(x) { 2 | return value => { 3 | return value === x; 4 | } 5 | } 6 | 7 | export default equals; 8 | -------------------------------------------------------------------------------- /src/exactLength.js: -------------------------------------------------------------------------------- 1 | import _nature from './internal/_nature'; 2 | 3 | function exactLength(length) { 4 | if (!_nature(length)) { 5 | throw new Error('exactLength: length should be large than 0 and integer'); 6 | } 7 | 8 | return (value) => { 9 | if (value === null || value === undefined) { 10 | return false; 11 | } 12 | 13 | return `${value}`.length === length; 14 | } 15 | } 16 | 17 | export default exactLength; 18 | -------------------------------------------------------------------------------- /src/failed.js: -------------------------------------------------------------------------------- 1 | import Assert from './assert'; 2 | // Failed 3 | 4 | function Failed(valueOrAssert) { 5 | Assert.call(this, valueOrAssert); 6 | this.success = false; 7 | this.value = valueOrAssert; 8 | } 9 | 10 | Failed.prototype = new Assert(); 11 | Failed.prototype.constructor = Failed; 12 | 13 | Failed.prototype.map = function (fn) { 14 | return this; 15 | } 16 | 17 | 18 | export default Failed; 19 | -------------------------------------------------------------------------------- /src/imageMatchP.js: -------------------------------------------------------------------------------- 1 | import _imageInfoP from './internal/_imageInfoP'; 2 | import compact from './compact'; 3 | 4 | // itShould(imageSizeMatch( 5 | // itShouldProp('width', large(100), always('weight should large 100')) 6 | // )) 7 | function imageMatchP(...assertFunction) { 8 | return file => { 9 | return _imageInfoP(file) 10 | .then(compact.apply(this, assertFunction)); 11 | } 12 | } 13 | 14 | export default imageMatchP; 15 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Assert from './assert'; 2 | import Normal from './normal'; 3 | import Failed from './failed'; 4 | import always from './always'; 5 | import large from './large'; 6 | import largeOrEqual from './largeOrEqual'; 7 | import less from './less'; 8 | import allPass from './allPass'; 9 | import itShould from './itShould'; 10 | import itShouldProp from './itShouldProp'; 11 | import itShouldPath from './itShouldPath'; 12 | import equals from './equals'; 13 | import validate from './validate'; 14 | import lessOrEqual from './lessOrEqual'; 15 | import integer from './integer'; 16 | import nature from './nature'; 17 | import natureNoZero from './natureNoZero'; 18 | import imageMatchP from './imageMatchP'; 19 | import of from './of'; 20 | import validUrl from './validUrl'; 21 | import alpha from './alpha'; 22 | import numeric from './numeric'; 23 | import validIP from './validIP'; 24 | import decimal from './decimal'; 25 | import minLength from './minLength'; 26 | import maxLength from './maxLength'; 27 | import required from './required'; 28 | import exactLength from './exactLength'; 29 | import matchs from './matchs'; 30 | import alphaDash from './alphaDash'; 31 | import compact from './compact'; 32 | import oneOf from './oneOf'; 33 | 34 | const largeE = largeOrEqual; 35 | const lessE = lessOrEqual; 36 | 37 | export { 38 | Assert, 39 | Normal, 40 | Failed, 41 | always, 42 | large, 43 | less, 44 | allPass, 45 | itShould, 46 | itShouldProp, 47 | equals, 48 | itShouldPath, 49 | validate, 50 | integer, 51 | nature, 52 | natureNoZero, 53 | imageMatchP, 54 | of, 55 | validUrl, 56 | alpha, 57 | numeric, 58 | validIP, 59 | decimal, 60 | minLength, 61 | maxLength, 62 | required, 63 | exactLength, 64 | matchs, 65 | alphaDash, 66 | compact, 67 | oneOf, 68 | largeOrEqual, 69 | largeE, 70 | lessOrEqual, 71 | lessE 72 | } 73 | -------------------------------------------------------------------------------- /src/integer.js: -------------------------------------------------------------------------------- 1 | import _integer from './internal/_integer'; 2 | 3 | function integer() { 4 | return _integer; 5 | } 6 | 7 | export default integer; 8 | -------------------------------------------------------------------------------- /src/internal/_alpha.js: -------------------------------------------------------------------------------- 1 | function alpha(value) { 2 | if (value === null || value === undefined) { 3 | return false; 4 | } 5 | 6 | return /^[a-zA-Z]{1,}$/.test(value); 7 | } 8 | 9 | export default alpha; 10 | -------------------------------------------------------------------------------- /src/internal/_alphaDash.js: -------------------------------------------------------------------------------- 1 | function alphaDash(value) { 2 | if (value === null || value === undefined) { 3 | return false; 4 | } 5 | 6 | return /^[\-\_a-zA-Z]{1,}$/.test(value); 7 | } 8 | 9 | export default alphaDash; 10 | -------------------------------------------------------------------------------- /src/internal/_identity.js: -------------------------------------------------------------------------------- 1 | function identity(x) { 2 | return x; 3 | } 4 | 5 | 6 | export default identity; 7 | -------------------------------------------------------------------------------- /src/internal/_imageInfoP.js: -------------------------------------------------------------------------------- 1 | // only for browser 2 | 3 | function getImage(src) { 4 | return new Promise((done, reject) => { 5 | const img = new Image(); 6 | img.src = src; 7 | img.onload = () => { 8 | done(img); 9 | }; 10 | img.onerror = reject; 11 | }); 12 | } 13 | 14 | function imageInfoP(imageFile) { 15 | // src 16 | if (typeof imageFile === 'string') { 17 | return getImage(imageFile); 18 | } 19 | 20 | // blob 21 | return new Promise((done) => { 22 | const reader = new FileReader(); 23 | reader.addEventListener('load', () => { 24 | done(getImage(reader.result)); 25 | }); 26 | reader.readAsDataURL(imageFile); 27 | }) 28 | } 29 | 30 | 31 | export default imageInfoP; 32 | -------------------------------------------------------------------------------- /src/internal/_integer.js: -------------------------------------------------------------------------------- 1 | function _integer(value) { 2 | return /^-?[0-9]+$/.test(`${value}`); 3 | } 4 | 5 | export default _integer; 6 | -------------------------------------------------------------------------------- /src/internal/_isFailedByRuleValue.js: -------------------------------------------------------------------------------- 1 | function isFailedByRuleValue(value) { 2 | return value && typeof value === 'string'; 3 | } 4 | 5 | export default isFailedByRuleValue; 6 | -------------------------------------------------------------------------------- /src/internal/_isThenable.js: -------------------------------------------------------------------------------- 1 | function isThenable(p) { 2 | return p && p.then && typeof p.then === 'function'; 3 | } 4 | 5 | export default isThenable; 6 | -------------------------------------------------------------------------------- /src/internal/_nature.js: -------------------------------------------------------------------------------- 1 | import _integer from './_integer'; 2 | 3 | function _nature(value) { 4 | return _integer(value) && Number(value) >= 0; 5 | } 6 | 7 | export default _nature; 8 | -------------------------------------------------------------------------------- /src/internal/_natureNoZero.js: -------------------------------------------------------------------------------- 1 | import _nature from './_nature'; 2 | 3 | function _natureNoZero(value) { 4 | return `${value}` !== '0' && _nature(value); 5 | } 6 | 7 | export default _natureNoZero; 8 | -------------------------------------------------------------------------------- /src/internal/_path.js: -------------------------------------------------------------------------------- 1 | function path(pathArray, obj) { 2 | return pathArray.reduce((root, prop) => { 3 | return root && root[prop]; 4 | }, Object.assign({}, obj)); 5 | } 6 | 7 | export default path; 8 | -------------------------------------------------------------------------------- /src/internal/_required.js: -------------------------------------------------------------------------------- 1 | function required(value) { 2 | if (value === null || value === undefined) { 3 | return false; 4 | } 5 | 6 | return !!`${value}`.trim(); 7 | } 8 | 9 | export default required; 10 | -------------------------------------------------------------------------------- /src/internal/_validUrl.js: -------------------------------------------------------------------------------- 1 | function validUrl(url) { 2 | return /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(url); 3 | } 4 | 5 | export default validUrl; 6 | -------------------------------------------------------------------------------- /src/itShould.js: -------------------------------------------------------------------------------- 1 | import _isThenable from './internal/_isThenable'; 2 | import always from './always'; 3 | import Failed from './failed'; 4 | 5 | function itShould(predicate, failed) { 6 | return value => { 7 | const returnValue = predicate(value); 8 | 9 | if (_isThenable(returnValue)) { 10 | // there is 2 situation will consider be failed. 11 | return returnValue 12 | .then(result => { 13 | // situation 1 14 | if (result instanceof Failed) { 15 | return result; 16 | } 17 | return value 18 | }) 19 | .catch(e => { 20 | // situation 2 21 | return new Failed(failed(e)); 22 | }); 23 | } 24 | 25 | if (!returnValue) { 26 | return new Failed(failed(value)); 27 | } 28 | 29 | return false; 30 | } 31 | } 32 | 33 | export default itShould; 34 | -------------------------------------------------------------------------------- /src/itShouldPath.js: -------------------------------------------------------------------------------- 1 | import _path from './internal/_path'; 2 | import itShould from './itShould'; 3 | 4 | function itShouldPath(path, predicate, failed) { 5 | if (!predicate || typeof predicate !== 'function') { 6 | throw new Error(`itShouldPath ${path} require second parameter is function`); 7 | } 8 | if (!failed || typeof failed !== 'function') { 9 | throw new Error(`itShouldPath ${path} require third parameter is function`); 10 | } 11 | 12 | return value => { 13 | const ans = _path(path, value); 14 | if (ans === undefined) { 15 | return failed(undefined); 16 | } 17 | 18 | return itShould(predicate, failed)(ans); 19 | } 20 | } 21 | 22 | export default itShouldPath; 23 | -------------------------------------------------------------------------------- /src/itShouldProp.js: -------------------------------------------------------------------------------- 1 | import itShould from './itShould'; 2 | 3 | function itShouldProp(prop, predicate, failed) { 4 | if (!predicate || typeof predicate !== 'function') { 5 | throw new Error(`itShouldProp ${prop} require second parameter is function`); 6 | } 7 | if (!failed || typeof failed !== 'function') { 8 | throw new Error(`itShouldProp ${prop} require third parameter is function`); 9 | } 10 | 11 | return (value) => { 12 | if (value) { 13 | return itShould(predicate, failed)(value[prop]); 14 | } 15 | 16 | return failed(undefined); 17 | } 18 | } 19 | 20 | export default itShouldProp; 21 | -------------------------------------------------------------------------------- /src/large.js: -------------------------------------------------------------------------------- 1 | import _required from './internal/_required'; 2 | 3 | function Large(x) { 4 | return (value) => { 5 | return _required(value) && value > x; 6 | } 7 | } 8 | 9 | export default Large; 10 | -------------------------------------------------------------------------------- /src/largeOrEqual.js: -------------------------------------------------------------------------------- 1 | import _required from './internal/_required'; 2 | 3 | function largeOrEqual(x) { 4 | return value => { 5 | return _required(value) && value >= x; 6 | } 7 | } 8 | 9 | export default largeOrEqual; 10 | -------------------------------------------------------------------------------- /src/less.js: -------------------------------------------------------------------------------- 1 | import _required from './internal/_required'; 2 | 3 | function less(x) { 4 | return value => { 5 | return _required(value) && x > value; 6 | } 7 | } 8 | 9 | export default less; 10 | -------------------------------------------------------------------------------- /src/lessOrEqual.js: -------------------------------------------------------------------------------- 1 | import _required from './internal/_required'; 2 | 3 | function lessOrEqual(x) { 4 | return (value) => { 5 | return _required(value) && value <= x; 6 | } 7 | } 8 | 9 | export default lessOrEqual; 10 | -------------------------------------------------------------------------------- /src/matchs.js: -------------------------------------------------------------------------------- 1 | function matchs(re) { 2 | if (re === null || re === undefined) { 3 | throw new Error('matchs: required regexp or string'); 4 | } 5 | 6 | return value => { 7 | if (typeof value === 'string' || typeof value === 'number') { 8 | const m = `${value}`.match(re); 9 | return !!(m && m.length); 10 | } 11 | return false; 12 | } 13 | } 14 | 15 | export default matchs; 16 | -------------------------------------------------------------------------------- /src/maxLength.js: -------------------------------------------------------------------------------- 1 | import _natureNoZero from './internal/_natureNoZero'; 2 | 3 | function maxLength(length) { 4 | if (!_natureNoZero(length)) { 5 | throw new Error('maxLength: legth should be large than 0 and integer'); 6 | } 7 | 8 | return (value) => { 9 | if (value === null || value === undefined) { 10 | return false; 11 | } 12 | 13 | if (!(typeof value === 'string' || typeof value === 'number')) { 14 | return false; 15 | } 16 | 17 | return `${value}`.length <= length; 18 | } 19 | } 20 | 21 | export default maxLength; 22 | -------------------------------------------------------------------------------- /src/minLength.js: -------------------------------------------------------------------------------- 1 | import _natureNoZero from './internal/_natureNoZero'; 2 | 3 | function minLength(length) { 4 | if (!_natureNoZero(length)) { 5 | throw new Error('minLength: length should be large than 0 and integer '); 6 | } 7 | 8 | return (value) => { 9 | if (value === null || value === undefined) { 10 | return false; 11 | } 12 | 13 | if (!(typeof value === 'string' || typeof value === 'number')) { 14 | return false; 15 | } 16 | 17 | return `${value}`.length >= length; 18 | } 19 | } 20 | 21 | export default minLength; 22 | -------------------------------------------------------------------------------- /src/nature.js: -------------------------------------------------------------------------------- 1 | import _nature from './internal/_nature'; 2 | 3 | function nature() { 4 | return _nature; 5 | } 6 | 7 | export default nature; 8 | -------------------------------------------------------------------------------- /src/natureNoZero.js: -------------------------------------------------------------------------------- 1 | import _natureNoZero from './internal/_natureNoZero'; 2 | 3 | function natureNoZero() { 4 | return _natureNoZero; 5 | } 6 | 7 | export default natureNoZero; 8 | -------------------------------------------------------------------------------- /src/normal.js: -------------------------------------------------------------------------------- 1 | import Assert from './assert'; 2 | import NormalP from './normalP'; 3 | import Failed from './failed'; 4 | import _isFailedByRuleValue from './internal/_isFailedByRuleValue'; 5 | import _isThenable from './internal/_isThenable'; 6 | 7 | function Normal(valueOrAssert) { 8 | Assert.call(this, valueOrAssert); 9 | 10 | this.success = true; 11 | this.value = valueOrAssert; 12 | } 13 | Normal.prototype = new Assert(); 14 | Normal.prototype.constructor = Normal; 15 | 16 | /* 17 | fn :: value => Assert|message|undefined 18 | */ 19 | Normal.prototype.map = function (fn) { 20 | const value = fn(this.value); 21 | 22 | if (value instanceof Assert) { 23 | return value; 24 | } 25 | 26 | if (_isFailedByRuleValue(value)) { 27 | return new Failed(value); 28 | } 29 | 30 | if (_isThenable(value)) { 31 | return new NormalP(value); 32 | } 33 | 34 | return this; 35 | } 36 | 37 | export default Normal; 38 | -------------------------------------------------------------------------------- /src/normalP.js: -------------------------------------------------------------------------------- 1 | import Assert from './assert'; 2 | import of from './of'; 3 | import _isFailedByRuleValue from './internal/_isFailedByRuleValue'; 4 | 5 | function NormalP(x) { 6 | Assert.call(this, x); 7 | this.value = Promise.resolve(x); 8 | } 9 | 10 | NormalP.prototype = new Assert(); 11 | NormalP.prototype.constructor = NormalP; 12 | 13 | NormalP.prototype.validate = function validate(callback) { 14 | if (callback) { 15 | return this.value 16 | .then((v) => { 17 | return of(v).validate(callback); 18 | }); 19 | } 20 | } 21 | 22 | NormalP.prototype.map = function map(rule) { 23 | return new NormalP( 24 | this.value.then((realValue) => of(realValue).map(rule)) 25 | ); 26 | } 27 | 28 | export default NormalP; 29 | -------------------------------------------------------------------------------- /src/numeric.js: -------------------------------------------------------------------------------- 1 | function numeric() { 2 | return (value) => { 3 | if (value === null || value === undefined) { 4 | return false; 5 | } 6 | 7 | return /^-?[0-9]{1,}$/.test(value); 8 | } 9 | } 10 | 11 | export default numeric; 12 | -------------------------------------------------------------------------------- /src/of.js: -------------------------------------------------------------------------------- 1 | import Normal from './normal'; 2 | import Assert from './assert'; 3 | 4 | function of(x) { 5 | if (x instanceof Assert) { 6 | return x; 7 | } 8 | 9 | return new Normal(x); 10 | } 11 | 12 | export default of; 13 | -------------------------------------------------------------------------------- /src/oneOf.js: -------------------------------------------------------------------------------- 1 | function oneOf(array) { 2 | return value => { 3 | return Array.isArray(array) && (array.find(itm => itm === value) !== undefined); 4 | } 5 | } 6 | 7 | export default oneOf; -------------------------------------------------------------------------------- /src/required.js: -------------------------------------------------------------------------------- 1 | import _required from './internal/_required'; 2 | 3 | function required() { 4 | return _required; 5 | } 6 | 7 | export default required; 8 | -------------------------------------------------------------------------------- /src/validIP.js: -------------------------------------------------------------------------------- 1 | // https://www.w3resource.com/javascript/form/ip-address-validation.php 2 | 3 | function validIP() { 4 | return (value) => { 5 | if (value === null || value === undefined) { 6 | return false; 7 | } 8 | return /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(value); 9 | } 10 | } 11 | 12 | export default validIP; 13 | -------------------------------------------------------------------------------- /src/validUrl.js: -------------------------------------------------------------------------------- 1 | import _validUrl from './internal/_validUrl'; 2 | 3 | function validUrl() { 4 | return _validUrl; 5 | } 6 | 7 | export default validUrl; 8 | -------------------------------------------------------------------------------- /src/validate.js: -------------------------------------------------------------------------------- 1 | import compact from './compact'; 2 | import of from './of'; 3 | 4 | function validate(...args) { 5 | const callback = args[args.length - 1]; 6 | 7 | if (!args.length || !(typeof callback === 'function')) { 8 | throw new Error('validate: the last parameter not a function'); 9 | } 10 | 11 | 12 | 13 | const asserts = args.slice(0, -1); 14 | 15 | const rules = asserts.map(assert => { 16 | return () => of(assert) 17 | }); 18 | 19 | return compact.apply(this, rules)().validate(callback); 20 | } 21 | 22 | export default validate; 23 | -------------------------------------------------------------------------------- /test/allPass.spec.js: -------------------------------------------------------------------------------- 1 | import { allPass, large, less } from '../src'; 2 | import { expect } from 'chai'; 3 | 4 | describe('allPass Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(allPass).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should be return a function when apply', () => { 11 | expect(allPass()).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should not throw when there\'s no predicate function', () => { 15 | expect(allPass()).to.not.throw(); 16 | }) 17 | 18 | it ('should return true when allPass', () => { 19 | const p = allPass(large(10), less(20)); 20 | 21 | expect(p(15)).to.be.equals(true); 22 | expect(p(11)).to.be.equals(true); 23 | expect(p('15')).to.be.equals(true); 24 | expect(p('11')).to.be.equals(true); 25 | }) 26 | 27 | it ('should return false when not allPass', () => { 28 | const p = allPass(large(-10), less(10)); 29 | 30 | expect(p('')).to.be.equals(false); 31 | expect(p(null)).to.be.equals(false); 32 | expect(p(undefined)).to.be.equals(false); 33 | 34 | expect(p(-10)).to.be.equals(false); 35 | expect(p(20)).to.be.equals(false); 36 | expect(p('-10')).to.be.equals(false); 37 | }) 38 | 39 | }) 40 | -------------------------------------------------------------------------------- /test/alpha.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { alpha } from '../src'; 3 | 4 | describe('alpha spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(alpha).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should return a function when apply', () => { 11 | expect(alpha()).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should be return true when value is alpha', () => { 15 | const alp = alpha(); 16 | 17 | expect(alp('a')).to.be.equals(true); 18 | expect(alp('abc')).to.be.equals(true); 19 | expect(alp('AuiZ')).to.be.equals(true); 20 | expect(alp('Z')).to.be.equals(true); 21 | expect(alp('AA')).to.be.equals(true); 22 | }) 23 | 24 | it ('should be return false when value isn\'t alpha', () => { 25 | const alp = alpha(); 26 | 27 | expect(alp('1')).to.be.equals(false); 28 | expect(alp(1)).to.be.equals(false); 29 | expect(alp('a1')).to.be.equals(false); 30 | expect(alp(null)).to.be.equals(false) 31 | expect(alp(undefined)).to.be.equals(false) 32 | expect(alp('A12c')).to.be.equals(false) 33 | expect(alp('a!@#')).to.be.equals(false) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /test/alphaDash.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { alphaDash } from '../src'; 3 | 4 | describe('alphaDash Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(alphaDash).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should be return a function when apply', () => { 11 | expect(alphaDash()).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should return true when only contains alphaDash', () => { 15 | const adash = alphaDash(); 16 | 17 | expect(adash('abc')).to.be.equals(true); 18 | expect(adash('abc_d')).to.be.equals(true); 19 | expect(adash('-')).to.be.equals(true); 20 | expect(adash('_-ca')).to.be.equals(true); 21 | }) 22 | 23 | it ('should return false when value is not alphaDash', () => { 24 | const adash = alphaDash(); 25 | 26 | expect(adash('789')).to.be.equals(false); 27 | expect(adash('abc789')).to.be.equals(false); 28 | expect(adash(123)).to.be.equals(false); 29 | expect(adash('_abc78')).to.be.equals(false); 30 | expect(adash(null)).to.be.equals(false); 31 | expect(adash(undefined)).to.be.equals(false); 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /test/assert.spec.js: -------------------------------------------------------------------------------- 1 | import Assert from '../src/assert'; 2 | import { expect } from 'chai'; 3 | 4 | describe('Assert', () => { 5 | it ('should Assert has not implement method', () => { 6 | const assert = new Assert(); 7 | expect(() => assert.map(a => a)).to.have.throw(); 8 | }) 9 | }) 10 | -------------------------------------------------------------------------------- /test/compact.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import Normal from '../src/normal'; 3 | import Failed from '../src/failed'; 4 | import large from '../src/large'; 5 | import less from '../src/less'; 6 | import itShould from '../src/itShould'; 7 | import always from '../src/always'; 8 | import _identity from '../src/internal/_identity'; 9 | import { compact } from '../src'; 10 | 11 | describe('Compact Spec', () => { 12 | it ('should be a function', () => { 13 | expect(compact).to.have.instanceOf(Function); 14 | }) 15 | 16 | it ('should return a function when apply a function', () => { 17 | expect(compact(_identity)).to.have.instanceOf(Function); 18 | }) 19 | 20 | it ('should return function can as a assertFunction', () => { 21 | const fn = compact( 22 | itShould(large(20), always('A')), 23 | itShould(less(30), always('B')) 24 | ); 25 | 26 | expect(fn(10)).to.have.instanceOf(Failed); 27 | expect(fn(20)).to.have.instanceOf(Failed); 28 | expect(fn(25)).to.have.instanceOf(Normal); 29 | expect(fn(30)).to.have.instanceOf(Failed); 30 | }); 31 | }) 32 | -------------------------------------------------------------------------------- /test/decimal.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { decimal } from '../src'; 3 | 4 | describe('decimal Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(decimal).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should return a function when apply', () => { 11 | expect(decimal()).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should return true when value is decimal', () => { 15 | const dec = decimal(); 16 | expect(dec('0.1')).to.be.equals(true); 17 | expect(dec(0.1)).to.be.equals(true); 18 | expect(dec('123.1212')).to.be.equals(true); 19 | expect(dec(123.2173823812)).to.be.equals(true); 20 | expect(dec(123)).to.be.equals(true); 21 | expect(dec('123')).to.be.equals(true); 22 | expect(dec('.123')).to.be.equals(true); 23 | }) 24 | 25 | it ('should return false when value is not decimal', () => { 26 | const dec = decimal(); 27 | 28 | expect(dec(null)).to.be.equals(false); 29 | expect(dec(undefined)).to.be.equals(false); 30 | expect(dec('123.a')).to.be.equals(false); 31 | expect(dec('abc.123')).to.be.equals(false); 32 | expect(dec('abc')).to.be.equals(false); 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /test/exactLength.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { exactLength } from '../src'; 3 | 4 | describe('exactLength Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(exactLength).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should be return a function when apply', () => { 11 | expect(exactLength(0)).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should be return true when exact length', () => { 15 | const exa = exactLength(2); 16 | 17 | expect(exa(12)).to.be.equals(true); 18 | expect(exa('ab')).to.be.equals(true); 19 | }) 20 | 21 | it ('should be return false when not exact length', () => { 22 | const exa = exactLength(2); 23 | 24 | expect(exa(-12)).to.be.equals(false); 25 | expect(exa(0)).to.be.equals(false); 26 | expect(exa('')).to.be.equals(false); 27 | expect(exa('abc')).to.be.equals(false); 28 | expect(exa(null)).to.be.equals(false); 29 | expect(exa(undefined)).to.be.equals(false); 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /test/imageMatch.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import sinon from 'sinon'; 3 | import jsdom from 'jsdom-global'; 4 | import { itShould, validate, of, always, imageMatchP, itShouldProp, large, less } from '../src'; 5 | 6 | describe('imageMatchP Spec', () => { 7 | jsdom(); 8 | /* jsdom(``, { 9 | * url: 'http://localhost' 10 | * }); */ 11 | 12 | it ('should be a function', () => { 13 | expect(imageMatchP).to.be.instanceOf(Function); 14 | }) 15 | 16 | it ('should return a function when apply', () => { 17 | expect(imageMatchP()).to.be.instanceOf(Function); 18 | }) 19 | 20 | it ('should return true when sizeMatch', (testDone) => { 21 | global.Image = function () { 22 | const img = { 23 | width: 100, 24 | height: 200 25 | }; 26 | 27 | Object.defineProperty(img, 'onload', { 28 | configurable: true, 29 | enumerable: true, 30 | get () { 31 | return null; 32 | }, 33 | set (callback) { 34 | setTimeout(callback, 100); 35 | } 36 | }); 37 | return img; 38 | } 39 | global.FileReader = function () { 40 | return { 41 | result: null, 42 | readAsDataURL: () => {}, 43 | addEventListener: (type, callback) => { 44 | callback(); 45 | } 46 | } 47 | } 48 | 49 | 50 | of(1) 51 | .map( 52 | imageMatchP( 53 | itShouldProp('width', large(50), always('A')), 54 | itShouldProp('height', less(100), always('B')) 55 | )) 56 | .validate((success, reason) => { 57 | expect(success).to.be.equals(false); 58 | expect(reason).to.be.equals('B'); 59 | testDone(); 60 | }); 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /test/integer.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { integer, of, always } from '../src'; 3 | 4 | describe('integer spec', () => { 5 | it ('should integer is a function', () => { 6 | expect(integer).to.be.instanceOf(Function); 7 | }) 8 | 9 | it ('should integer return a function when apply', () => { 10 | expect(integer()).to.be.instanceOf(Function); 11 | }) 12 | 13 | it ('should return true when value is a integer', () => { 14 | const int = integer(); 15 | expect(int(1)).to.be.equals(true); 16 | expect(int('1')).to.be.equals(true); 17 | expect(int(123)).to.be.equals(true); 18 | expect(int(-123)).to.be.equals(true); 19 | expect(int('-123')).to.be.equals(true); 20 | }) 21 | 22 | it ('should return false when value invalid or not integer', () => { 23 | const int = integer(); 24 | expect(int(1.2)).to.be.equals(false); 25 | expect(int(-1.2)).to.be.equals(false); 26 | expect(int(null)).to.be.equals(false); 27 | expect(int(undefined)).to.be.equals(false); 28 | expect(int('ab')).to.be.equals(false); 29 | expect(int('123.1')).to.be.equals(false); 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /test/itShould.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { of, itShould, always } from '../src'; 3 | 4 | describe('itShould Spec', () => { 5 | it ('should itShould can take a Promise predicate', (done) => { 6 | of(3).map(itShould(() => Promise.resolve(true), always('A'))) 7 | .validate((success) => { 8 | expect(success).to.be.equals(true); 9 | }); 10 | 11 | of(3).map(itShould(() => Promise.reject(true), always('A'))) 12 | .validate((success, reason) => { 13 | expect(success).to.be.equals(false); 14 | expect(reason).to.be.equals('A'); 15 | done(); 16 | }) 17 | 18 | }) 19 | 20 | it ('should itShould can take a Promise predicate', (done) => { 21 | of(3).map(itShould(() => Promise.resolve(of(1)), always('A'))) 22 | .validate((success) => { 23 | expect(success).to.be.equals(true); 24 | }); 25 | 26 | of(3).map(itShould(() => Promise.resolve(of(1).map(() => 'B')), always('A'))) 27 | .validate((success, reason) => { 28 | expect(success).to.be.equals(false); 29 | expect(reason).to.be.equals('B'); 30 | done(); 31 | }) 32 | 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /test/itShouldPath.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import Normal from '../src/normal'; 3 | import Failed from '../src/failed'; 4 | import always from '../src/always'; 5 | import equals from '../src/equals'; 6 | import itShouldPath from '../src/itShouldPath'; 7 | import of from '../src/of'; 8 | 9 | describe('itShouldPath Spec', () => { 10 | 11 | it ('should itShouldPath is a assert function', () => { 12 | expect(itShouldPath).to.be.instanceof(Function); 13 | }) 14 | 15 | it ('should itShouldPath have three params', () => { 16 | expect(itShouldPath.length).to.be.equal(3); 17 | }) 18 | 19 | it ('should itShouldPatc create a rule ', () => { 20 | const propEq3 = itShouldPath(['a'], equals(3), always('A')); 21 | 22 | expect(of({a: 3}).map(propEq3)).to.be.instanceof(Normal); 23 | expect(of({a: 4}).map(propEq3)).to.be.instanceof(Failed); 24 | expect(of(3).map(propEq3)).to.be.instanceof(Failed); 25 | 26 | of(3) 27 | .map(propEq3) 28 | .validate((success, value) => { 29 | expect(success).to.be.equal(false); 30 | expect(value).to.be.equal('A'); 31 | }); 32 | }) 33 | 34 | it ('should itShouldPatch create a rule for deep prop', () => { 35 | const propEq3 = itShouldPath(['a', 'b'], equals(3), always('A')); 36 | 37 | expect(of({ 38 | a: {b: 3}}).map(propEq3)).to.be.instanceof(Normal); 39 | expect(of({a: 4}).map(propEq3)).to.be.instanceof(Failed); 40 | expect(of(3).map(propEq3)).to.be.instanceof(Failed); 41 | 42 | of(3) 43 | .map(propEq3) 44 | .validate((success, value) => { 45 | expect(success).to.be.equal(false); 46 | expect(value).to.be.equal('A'); 47 | }); 48 | }) 49 | }) 50 | -------------------------------------------------------------------------------- /test/itShouldProp.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import Normal from '../src/normal'; 3 | import Failed from '../src/failed'; 4 | import always from '../src/always'; 5 | import equals from '../src/equals'; 6 | import itShouldProp from '../src/itShouldProp'; 7 | import of from '../src/of'; 8 | 9 | describe('itShouldProp Spec', () => { 10 | 11 | it ('should itShouldProp is a assert function', () => { 12 | expect(itShouldProp).to.be.instanceof(Function); 13 | }) 14 | 15 | it ('should itShouldProp have three params', () => { 16 | expect(itShouldProp.length).to.be.equal(3); 17 | }) 18 | 19 | it ('should itShouldProp create a rule ', () => { 20 | const propEq3 = itShouldProp('a', equals(3), always('A')); 21 | 22 | expect(of({a: 3}).map(propEq3)).to.be.instanceof(Normal); 23 | expect(of({a: 4}).map(propEq3)).to.be.instanceof(Failed); 24 | expect(of(3).map(propEq3)).to.be.instanceof(Failed); 25 | 26 | of(3) 27 | .map(propEq3) 28 | .validate((success, value) => { 29 | expect(success).to.be.equal(false); 30 | expect(value).to.be.equal('A'); 31 | }); 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /test/large.spec.js: -------------------------------------------------------------------------------- 1 | import { large } from '../src'; 2 | import { expect } from 'chai'; 3 | 4 | describe('large Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(large).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should be return a function when apply', () => { 11 | expect(large()).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should be return true when large', () => { 15 | const l = large(0); 16 | expect(l('1')).to.be.equals(true); 17 | expect(l(1)).to.be.equals(true); 18 | expect(l(10)).to.be.equals(true); 19 | expect(l('100')).to.be.equals(true); 20 | }) 21 | 22 | it ('should be return false when not large', () => { 23 | const l = large(-1); 24 | expect(l(-1)).to.be.equals(false); 25 | expect(l('-1')).to.be.equals(false); 26 | expect(l('-2')).to.be.equals(false); 27 | expect(l(-2)).to.be.equals(false); 28 | expect(l('')).to.be.equals(false); 29 | expect(l(null)).to.be.equals(false); 30 | expect(l(undefined)).to.be.equals(false); 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /test/largeOrEqual.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { largeOrEqual } from '../src'; 3 | 4 | describe('largeOrEqual Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(largeOrEqual).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should be return function when apply', () => { 11 | expect(largeOrEqual()).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should be return true when largeEqual', () => { 15 | const p = largeOrEqual(10); 16 | 17 | expect(p(10)).to.be.equals(true); 18 | expect(p(11)).to.be.equals(true); 19 | }) 20 | 21 | it ('should be return false when not largeOrEqual', () => { 22 | const p = largeOrEqual(10); 23 | 24 | expect(p(9)).to.be.equals(false); 25 | expect(p(0)).to.be.equals(false); 26 | expect(p(null)).to.be.equals(false); 27 | expect(p(undefined)).to.be.equals(false); 28 | expect(p('')).to.be.equals(false); 29 | }) 30 | 31 | it ('should be correct with not input', () => { 32 | const p = largeOrEqual(0); 33 | expect(p('')).to.be.equals(false); 34 | expect(p(null)).to.be.equals(false); 35 | expect(p(undefined)).to.be.equals(false); 36 | }) 37 | }) 38 | -------------------------------------------------------------------------------- /test/less.spec.js: -------------------------------------------------------------------------------- 1 | import { less } from '../src'; 2 | import { expect } from 'chai'; 3 | 4 | describe('less Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(less).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should be return a function when apply', () => { 11 | expect(less()).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should return true when less', () => { 15 | const l = less(10); 16 | expect(l(1)).to.be.equals(true); 17 | expect(l(-1)).to.be.equals(true); 18 | expect(l(9)).to.be.equals(true); 19 | expect(l('8')).to.be.equals(true); 20 | expect(l('-1')).to.be.equals(true); 21 | }) 22 | 23 | it ('should return false when not less', () => { 24 | const l = less(-1); 25 | expect(l(1)).to.be.equals(false); 26 | expect(l(-1)).to.be.equals(false); 27 | expect(l('-1')).to.be.equals(false); 28 | expect(l(19)).to.be.equals(false); 29 | expect(l(null)).to.be.equals(false); 30 | expect(l(undefined)).to.be.equals(false); 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /test/lessOrEqual.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { 3 | lessOrEqual, 4 | of, 5 | itShould 6 | } from '../src'; 7 | 8 | describe('lessOrEqual Spec', () => { 9 | it ('should be a function', () => { 10 | expect(lessOrEqual).to.be.instanceOf(Function); 11 | }) 12 | 13 | it ('should return a function when apply number', () => { 14 | expect(lessOrEqual(1)).to.be.instanceOf(Function); 15 | }) 16 | 17 | it ('should assert less or equal', () => { 18 | expect(lessOrEqual(1)(2)).to.be.equals(false); 19 | expect(lessOrEqual(1)(1)).to.be.equals(true); 20 | expect(lessOrEqual(1)(0)).to.be.equals(true); 21 | }) 22 | 23 | it ('should return true when less or equal', () => { 24 | const less = lessOrEqual(1); 25 | expect(less('0')).to.be.equals(true); 26 | }) 27 | it ('should return false when not less', () => { 28 | const less = lessOrEqual(1); 29 | expect(less('')).to.be.equals(false); 30 | expect(less(null)).to.be.equals(false); 31 | expect(less(undefined)).to.be.equals(false); 32 | 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /test/matchs.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { matchs } from '../src'; 3 | 4 | 5 | describe('matchs Spec', () => { 6 | it ('should be a function', () => { 7 | expect(matchs).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should be return a function when apply', () => { 11 | expect(matchs('')).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should return true when match reg', () => { 15 | const match = matchs(/abc/); 16 | 17 | expect(match('abcd')).to.be.equals(true); 18 | expect(match('%^&*abjlabc&*s')).to.be.equals(true); 19 | }) 20 | 21 | it ('should return true when match string', () => { 22 | const match = matchs(/123/); 23 | 24 | expect(match(12345)).to.be.equals(true); 25 | expect(match('561234')).to.be.equals(true); 26 | }) 27 | 28 | it ('should be return false when not match', () => { 29 | const match = matchs(/123/); 30 | 31 | expect(match(undefined)).to.be.equals(false); 32 | expect(match(null)).to.be.equals(false); 33 | expect(match('')).to.be.equals(false); 34 | expect(match(5678)).to.be.equals(false); 35 | expect(match('abcd')).to.be.equals(false); 36 | }) 37 | }) 38 | -------------------------------------------------------------------------------- /test/maxLength.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { maxLength } from '../src'; 3 | 4 | describe('maxLength Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(maxLength).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should return a function when apply', () => { 11 | expect(maxLength(2)).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should return true when length <= maxLength', () => { 15 | const max = maxLength(2); 16 | 17 | expect(max('ab')).to.be.equals(true); 18 | expect(max(12)).to.be.equals(true); 19 | expect(max('1')).to.be.equals(true); 20 | }) 21 | 22 | it ('should return false when length > maxLength', () => { 23 | const max = maxLength(2); 24 | 25 | expect(max('abc')).to.be.equals(false); 26 | expect(max(123)).to.be.equals(false); 27 | expect(max(null)).to.be.equals(false); 28 | expect(max(undefined)).to.be.equals(false); 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /test/minLength.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { minLength } from '../src'; 3 | 4 | describe('minLength Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(minLength).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should return a function when apply', () => { 11 | expect(minLength(10)).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should return true when length > minLength', () => { 15 | const min = minLength(3); 16 | 17 | expect(min('abc')).to.be.equals(true); 18 | expect(min('abcd')).to.be.equals(true); 19 | expect(min(1234)).to.be.equals(true); 20 | expect(min(123)).to.be.equals(true); 21 | }) 22 | 23 | it ('should be return false when length < minLength', () => { 24 | const min = minLength(3); 25 | 26 | expect(min('ab')).to.be.equals(false); 27 | expect(min(12)).to.be.equals(false); 28 | expect(min(null)).to.be.equals(false); 29 | expect(min(undefined)).to.be.equals(false); 30 | expect(min({})).to.be.equals(false); 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /test/nature.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { nature } from '../src'; 3 | 4 | describe('nature Spec', () => { 5 | it ('should be a function', () => { 6 | expect(nature).to.be.instanceOf(Function); 7 | }) 8 | 9 | it ('should return a function when apply', () => { 10 | expect(nature()).to.be.instanceOf(Function); 11 | }) 12 | 13 | it ('should return true when value is nature', () => { 14 | const nat = nature(); 15 | expect(nat(0)).to.be.equals(true); 16 | expect(nat('0')).to.be.equals(true); 17 | expect(nat(1)).to.be.equals(true); 18 | expect(nat(100)).to.be.equals(true) 19 | expect(nat('100')).to.be.equals(true) 20 | expect(nat('18782178')).to.be.equals(true) 21 | }) 22 | 23 | it ('should return false when value is not nature', () => { 24 | const nat = nature(); 25 | expect(nat(-1)).to.be.equals(false); 26 | expect(nat(-100)).to.be.equals(false); 27 | expect(nat(1.2)).to.be.equals(false); 28 | expect(nat(null)).to.be.equals(false); 29 | expect(nat(undefined)).to.be.equals(false); 30 | expect(nat('1.2')).to.be.equals(false); 31 | expect(nat('abc')).to.be.equals(false); 32 | expect(nat({})).to.be.equals(false); 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /test/natureNoZero.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { natureNoZero } from '../src'; 3 | 4 | describe('natureNoZero Spec', () => { 5 | it ('should be a function', () => { 6 | expect(natureNoZero).to.be.instanceOf(Function); 7 | }) 8 | 9 | it ('should return a function when apply', () => { 10 | expect(natureNoZero()).to.be.instanceOf(Function); 11 | }) 12 | 13 | it ('should return true when nature no zero', () => { 14 | const nat = natureNoZero(); 15 | expect(nat(1)).to.be.equals(true); 16 | expect(nat(2)).to.be.equals(true); 17 | expect(nat('123')).to.be.equals(true); 18 | }) 19 | 20 | 21 | it ('should return false when not naturenozero ', () => { 22 | const nat = natureNoZero(); 23 | expect(nat(0)).to.be.equals(false); 24 | expect(nat(-1)).to.be.equals(false); 25 | expect(nat(1.2)).to.be.equals(false); 26 | expect(nat(-1.2)).to.be.equals(false); 27 | expect(nat('-1')).to.be.equals(false); 28 | expect(nat('abc')).to.be.equals(false); 29 | expect(nat('1.1')).to.be.equals(false); 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /test/normalP.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import always from '../src/always'; 3 | import of from '../src/of'; 4 | import large from '../src/large'; 5 | import itShould from '../src/itShould'; 6 | 7 | function delay(ms) { 8 | return () => { 9 | return new Promise((d) => { 10 | setTimeout(d, ms); 11 | }); 12 | }; 13 | } 14 | 15 | describe('normalP Spec', () => { 16 | it ('should create a async assert', (resolve) => { 17 | of(1) 18 | .map(itShould(delay(30), always('not'))) 19 | .validate((success, value) => { 20 | expect(success).to.be.equals(true); 21 | expect(value).to.be.equals(1); 22 | resolve(); 23 | }); 24 | }) 25 | 26 | it ('should catch async error', (resolve) => { 27 | function delayAndThrow(ms) { 28 | return () => { 29 | return new Promise((_1, reject) => { 30 | setTimeout(reject, ms); 31 | }); 32 | }; 33 | } 34 | 35 | of(1) 36 | .map(itShould(delayAndThrow(30), always('yes'))) 37 | .validate((success, value) => { 38 | expect(success).to.be.equals(false); 39 | expect(value).to.be.equals('yes'); 40 | resolve(); 41 | }); 42 | }) 43 | 44 | it ('should mixin other rule', (resolve) => { 45 | of(1) 46 | .map(itShould(large(-1), always('yes'))) 47 | .map(itShould(delay(30), always('not'))) 48 | .map(itShould(large(0), always('yes'))) 49 | .validate((success, value) => { 50 | expect(success).to.be.equals(true); 51 | expect(value).to.be.equals(1); 52 | resolve(); 53 | }); 54 | }) 55 | 56 | it ('should return transparent', (resolve) => { 57 | of(1) 58 | .map(itShould(large(-1), always('yes'))) 59 | .map(itShould(delay(30), always('not'))) 60 | .map(itShould(large(0), always('yes'))) 61 | .validate((success, value) => { 62 | return 'A'; 63 | }) 64 | .then((value) => { 65 | expect(value).to.be.equals('A'); 66 | resolve(); 67 | }) 68 | }) 69 | 70 | it ('should can reserve Promise', (done) => { 71 | of(1) 72 | .map(itShould(delay(30)), always('A')) 73 | .map(item => { 74 | expect(item).to.be.equals(1); 75 | done(); 76 | }) 77 | }) 78 | 79 | it ('should can reserve Promise', (done) => { 80 | of(1).map(itShould(() => { 81 | return new Promise(resolve => { 82 | resolve(of(2)) 83 | }); 84 | }, always('A'))) 85 | .map(item => { 86 | expect(item).to.be.equals(1); 87 | done(); 88 | }) 89 | }) 90 | }) 91 | -------------------------------------------------------------------------------- /test/numeric.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { numeric } from '../src'; 3 | 4 | describe('numberic Spec', () => { 5 | 6 | it('should be a function', () => { 7 | expect(numeric).to.be.instanceOf(Function); 8 | }) 9 | 10 | it('should return function when apply', () => { 11 | expect(numeric()).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should return true when value is numeric', () => { 15 | const num = numeric(); 16 | 17 | expect(num(1)).to.be.equals(true); 18 | expect(num(-1)).to.be.equals(true); 19 | expect(num(0)).to.be.equals(true); 20 | expect(num('1')).to.be.equals(true); 21 | expect(num('-1')).to.be.equals(true); 22 | expect(num('0')).to.be.equals(true); 23 | 24 | }) 25 | 26 | it ('should return false when value is\'t numeric', () => { 27 | const num = numeric(); 28 | expect(num(NaN)).to.be.equals(false); 29 | expect(num(null)).to.be.equals(false); 30 | expect(num(undefined)).to.be.equals(false); 31 | expect(num('-')).to.be.equals(false); 32 | expect(num('false')).to.be.equals(false); 33 | }) 34 | }) 35 | -------------------------------------------------------------------------------- /test/oneOf.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { oneOf } from '../src'; 3 | 4 | describe('oneOf Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(oneOf).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should be return a function when apply', () => { 11 | expect(oneOf([])).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should return true when oneOf item', () => { 15 | const item = {}; 16 | const one = oneOf(['a', 1, item]); 17 | 18 | expect(one('a')).to.be.equals(true); 19 | expect(one(1)).to.be.equals(true); 20 | expect(one(item)).to.be.equals(true); 21 | }) 22 | 23 | it ('should return false when not exists', () => { 24 | const item = {}; 25 | const one = oneOf(['a', 1, item]); 26 | 27 | expect(one('ab')).to.be.equals(false); 28 | expect(one('1')).to.be.equals(false); 29 | expect(one({})).to.be.equals(false); 30 | expect(one(null)).to.be.equals(false); 31 | expect(one(undefined)).to.be.equals(false); 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /test/required.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { required } from '../src'; 3 | 4 | describe('required Spec', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(required).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should be return a function when apply', () => { 11 | expect(required()).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should be return true when value is truthy ', () => { 15 | const req = required(); 16 | 17 | expect(req('1')).to.be.equals(true); 18 | expect(req({})).to.be.equals(true); 19 | expect(req(123)).to.be.equals(true); 20 | expect(req(0)).to.be.equals(true); 21 | expect(req('0')).to.be.equals(true); 22 | expect(req(false)).to.be.equals(true); 23 | }) 24 | 25 | it ('should be return false when value is falsy', () => { 26 | const req = required(); 27 | 28 | expect(req()).to.be.equals(false); 29 | expect(req(null)).to.be.equals(false); 30 | expect(req(undefined)).to.be.equals(false); 31 | expect(req('')).to.be.equals(false); 32 | }) 33 | }) 34 | -------------------------------------------------------------------------------- /test/validIP.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { validIP } from '../src'; 3 | 4 | describe('validIP Spec ', () => { 5 | 6 | it ('should be a function', () => { 7 | expect(validIP).to.be.instanceOf(Function); 8 | }) 9 | 10 | it ('should return a function when apply', () => { 11 | expect(validIP()).to.be.instanceOf(Function); 12 | }) 13 | 14 | it ('should return true when ip valid ', () => { 15 | const ip = validIP(); 16 | expect(ip('192.168.0.1')).to.be.equals(true); 17 | expect(ip('255.255.255.255')).to.be.equals(true); 18 | expect(ip('0.0.0.0')).to.be.equals(true); 19 | }) 20 | 21 | it ('should return false when ip invalid', () => { 22 | const ip = validIP(); 23 | expect(ip('1.1.1.1.1')).to.be.equals(false); 24 | expect(ip(null)).to.be.equals(false); 25 | expect(ip(undefined)).to.be.equals(false); 26 | expect(ip('')).to.be.equals(false); 27 | expect(ip(12345)).to.be.equals(false); 28 | expect(ip('256.0.0.1')).to.be.equals(false); 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /test/validUrl.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import { validUrl } from '../src'; 3 | 4 | describe('validUrl Spec', () => { 5 | it ('should be a function', () => { 6 | expect(validUrl).to.be.instanceOf(Function); 7 | }) 8 | 9 | it ('should be return a function when apply', () => { 10 | expect(validUrl()).to.be.instanceOf(Function); 11 | }) 12 | 13 | it ('should be return true when url is valid', () => { 14 | const url = validUrl(); 15 | 16 | expect(url('http://google.com')).to.be.equals(true); 17 | expect(url('http://localhost')).to.be.equals(true); 18 | expect(url('http://localhost/a/b/c')).to.be.equals(true); 19 | expect(url('http://localhost/a/b/c/index.html')).to.be.equals(true); 20 | expect(url('http://localhost/a/b/c/index.html?worldismine')).to.be.equals(true); 21 | expect(url('http://localhost/a/b/c?a=1&b=2')).to.be.equals(true); 22 | expect(url('http://127.0.0.1')).to.be.equals(true); 23 | }) 24 | 25 | it ('should be return false when url is inalid', () => { 26 | const url = validUrl(); 27 | expect(url('abc')).to.be.equals(false); 28 | expect(url(123)).to.be.equals(false); 29 | expect(url('')).to.be.equals(false); 30 | expect(url(undefined)).to.be.equals(false); 31 | expect(url(null)).to.be.equals(false); 32 | expect(url('helloworld.com')).to.be.equals(false); 33 | expect(url('worldismine/ccc')).to.be.equals(false); 34 | expect(url('127.0.0.1')).to.be.equals(false); 35 | }) 36 | }) 37 | -------------------------------------------------------------------------------- /test/validate.spec.js: -------------------------------------------------------------------------------- 1 | import { expect } from 'chai'; 2 | import of from '../src/of'; 3 | import itShould from '../src/itShould'; 4 | import always from '../src/always'; 5 | import large from '../src/large'; 6 | import validate from '../src/validate'; 7 | 8 | describe('Validate Spec', () => { 9 | it ('should is a function', () => { 10 | expect(validate).to.be.instanceOf(Function); 11 | }) 12 | 13 | it ('should can take multi assert to one', () => { 14 | validate( 15 | of(1), 16 | of(2), 17 | (success, value) => { 18 | expect(success).to.be.equals(true); 19 | expect(value).to.be.equals(2) 20 | } 21 | ); 22 | }) 23 | 24 | it ('should can take multi assert to one even failed', () => { 25 | validate( 26 | of(1), 27 | of(2).map(itShould(large(10), always('A'))), 28 | of(3), 29 | (success, value) => { 30 | expect(success).to.be.equals(false); 31 | expect(value).to.be.equals('A'); 32 | } 33 | ) 34 | }) 35 | 36 | it ('should can take multi assert to one event async', (done) => { 37 | function delayAndThrow(ms) { 38 | return () => { 39 | return new Promise((_1, reject) => { 40 | setTimeout(reject, ms); 41 | }); 42 | } 43 | } 44 | 45 | validate( 46 | of(1), 47 | of(2).map(itShould(delayAndThrow(100), always('A'))), 48 | of(3), 49 | of(4), 50 | of(5).map(itShould(delayAndThrow(200), always('B'))), 51 | (success, value) => { 52 | expect(success).to.be.equals(false); 53 | expect(value).to.be.equals('A'); 54 | done(); 55 | } 56 | ) 57 | }) 58 | 59 | it ('should return transparent', () => { 60 | expect(validate(of(1), (success, reason) => { 61 | return 'A'; 62 | })).to.be.equals('A'); 63 | }) 64 | }) 65 | --------------------------------------------------------------------------------