chushihua
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
||||
Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Phil Booth
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
# History
|
||||
|
||||
## 7.4.0
|
||||
|
||||
### New features
|
||||
|
||||
* docs: add note about typescript definitions to readme (13c7a90)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* docs: remove errant semicolon from example code (9053f95)
|
||||
* docs: clarify the behaviour of between and inRange (88a2f61)
|
||||
* tests: ensure tests run in non-es6 environments (4bae637)
|
||||
|
||||
### Other changes
|
||||
|
||||
* deps: update please-release-me (72377bf)
|
||||
* project: migrate to gitlab (19919b5)
|
||||
* package: update authors (9848df0)
|
||||
|
||||
## 7.3.0
|
||||
|
||||
* feature: add primitive predicate (3114d7f)
|
||||
|
||||
## 7.2.1
|
||||
|
||||
* fix: perf tweaks for tight loops (8a9919d)
|
||||
* chore: update ci config (136f185)
|
||||
|
||||
## 7.2.0
|
||||
|
||||
* feature: return the target value from assertions (73da792)
|
||||
* chore: add release script dependency (cacc348)
|
||||
* fix: make assert throw for any falsy value (4f15c73)
|
||||
|
||||
## 7.1
|
||||
|
||||
* Implement `nonEmptyObject`. Thanks to [Victor Bakke][gipphe].
|
||||
* Implement `nonEmptyArray`. Thanks to [Victor Bakke][gipphe].
|
||||
* Fix error messages on assertions that take a string as their last argument.
|
||||
* Add support for custom error types in assertions.
|
||||
* Throw TypeErrors by default.
|
||||
|
||||
## 7.0
|
||||
|
||||
* Breaking changes:
|
||||
* Rename `instance` to `instanceStrict`.
|
||||
* Combine `builtIn` and `userDefined` to form new `instance` predicate.
|
||||
* Exclude non-src files from npm package
|
||||
|
||||
## 6.0
|
||||
|
||||
* Breaking change:
|
||||
* `either` modifier removed.
|
||||
* Eliminated some string duplication.
|
||||
|
||||
## 5.1
|
||||
|
||||
* Fix broken implementation of `maybe.array.of`.
|
||||
|
||||
## 5.0
|
||||
|
||||
* Breaking changes:
|
||||
* `isMap` predicate removed (see `builtIn`).
|
||||
* `error` predicate removed (see `builtIn`).
|
||||
* Implement `builtIn` predicate.
|
||||
* Implement `userDefined` predicate.
|
||||
* Implement `emptyString` predicate.
|
||||
* Implement `infinity` predicate.
|
||||
|
||||
## 4.3
|
||||
|
||||
* Implement `isMap`. Thanks to [Ryan Temple][ryantemple].
|
||||
|
||||
## 4.2
|
||||
|
||||
* Implement `includes`.
|
||||
|
||||
## 4.1
|
||||
|
||||
* Implement `equal`.
|
||||
|
||||
## 4.0
|
||||
|
||||
* Breaking changes:
|
||||
* Rename `unemptyString` => `nonEmptyString`.
|
||||
* Support derived error objects in `error`.
|
||||
* Fix HTMLElement instance predicate bug in Safari.
|
||||
|
||||
## 3.3
|
||||
|
||||
* Implement `greaterOrEqual`.
|
||||
* Implement `lessOrEqual`.
|
||||
* Implement `inRange`.
|
||||
* Fix default error message for `function`. Thanks to [Paul Jolly][myitcv].
|
||||
|
||||
## 3.2
|
||||
|
||||
* Implement `arrayLike`
|
||||
* Implement `iterable`
|
||||
* Implement `array.of`
|
||||
* Implement `arrayLike.of`
|
||||
* Implement `iterable.of`
|
||||
* Implement `object.of`
|
||||
* Fix unhandled exception when dereferencing undefined data inside `map`.
|
||||
|
||||
## 3.1
|
||||
|
||||
* Accept a single predicate in `map`.
|
||||
* Remove assertions from `hasLength` and `like`.
|
||||
|
||||
## 3.0
|
||||
|
||||
* Breaking changes:
|
||||
* Rename `length` => `hasLength`.
|
||||
* Drop `webUrl`. (sorry @bahmutov!)
|
||||
* Turn `assert`, `not` and `maybe` into standalone functions as well as modifiers.
|
||||
* Implement `match` for general regex-matching. Possibly of interest to former users of `webUrl`, `gitUrl` and `email`.
|
||||
* Implement `contains`.
|
||||
* Implement `between`.
|
||||
* Implement `greater`.
|
||||
* Implement `less`.
|
||||
* Implement `zero`.
|
||||
* Implement `emptyArray`.
|
||||
* Implement `error`.
|
||||
* Fix errant check that property counts match in `map`.
|
||||
|
||||
## 2.2
|
||||
|
||||
* Ensure `date` predicate returns `false` for invalid dates.
|
||||
|
||||
## 2.1
|
||||
|
||||
* Add `either`.
|
||||
|
||||
## 2.0
|
||||
|
||||
* Breaking changes:
|
||||
* Drop ES3 support.
|
||||
* Rename `verify` => `assert`.
|
||||
* Remame `nulled` => `null`.
|
||||
* Switch `defined` to `undefined` for consistency with `null`.
|
||||
* Tightened implementation of `webUrl` to reject more cases.
|
||||
* Drop `gitUrl`. (sorry @galniv!)
|
||||
* Drop `email`. (sorry @rodrigo!)
|
||||
* Drop `floatNumber`. (sorry @rodrigo!)
|
||||
* Rename `oddNumber`, `evenNumber`, `positiveNumber`, `negativeNumber`, `intNumber` => `odd`, `even`, `positive`, `negative`, `integer`.
|
||||
* Rename `bool` => `boolean`.
|
||||
* Rename `every` => `all`.
|
||||
* Add predicate `assigned`.
|
||||
* Add `apply` batch operation.
|
||||
* Delete superfluous unit tests.
|
||||
|
||||
## 1.4
|
||||
|
||||
* Implement `bool` predicate. Thanks to [Clinton Skakun][clintonskakun].
|
||||
|
||||
## 1.3
|
||||
|
||||
* Implement `email`, `intNumber` and `floatNumber` predicates. Thanks to [Rodrigo González][rodrigo].
|
||||
* Infinity is not a number.
|
||||
* Implement `defined` and `nulled`. Thanks to [Alejandro Villanueva][ialex].
|
||||
* Speculatively fix conflict with angular-mocks.
|
||||
|
||||
## 1.2
|
||||
|
||||
* Implement `not` modifier.
|
||||
* Implement `gitUrl` predicate. Thanks to [Gal Niv][galniv].
|
||||
|
||||
## 1.1
|
||||
|
||||
* Replace `check.maybe.verify.xxx` with `check.verify.maybe.xxx`.
|
||||
|
||||
## 1.0
|
||||
|
||||
* API overhaul:
|
||||
* Predicates exported as `check.xxx` rather than `check.isXxx`.
|
||||
* Verifiers exported as `check.verify.xxx` rather than `check.verifyXxx`. Thanks to [Marc-Olivier Ricard][marcolivier].
|
||||
* Unit tests added for error messages.
|
||||
|
||||
## 0.8
|
||||
|
||||
* Added `isWebUrl` and `verifyWebUrl`. Thanks to [Gleb Bahmutov][gleb].
|
||||
|
||||
## 0.7
|
||||
|
||||
* Added `check.maybe` modifier. Thanks to [Marc-Olivier Ricard][marcolivier].
|
||||
* Added `check.map`, `check.every` and `check.any` batch operations. Thanks to [Marc-Olivier Ricard][marcolivier].
|
||||
* Harmonised the node and browser unit tests.
|
||||
|
||||
[marcolivier]: https://github.com/ricardmo
|
||||
[gleb]: https://github.com/bahmutov
|
||||
[galniv]: https://github.com/galniv
|
||||
[rodrigo]: https://github.com/roro89
|
||||
[ialex]: https://github.com/ialex
|
||||
[clintonskakun]: https://github.com/clintonskakun
|
||||
[myitcv]: https://github.com/myitcv
|
||||
[ryantemple]: https://github.com/ryantemple
|
||||
[gipphe]: https://github.com/Gipphe
|
||||
|
||||
+823
@@ -0,0 +1,823 @@
|
||||
# check-types.js
|
||||
|
||||
[](https://gitlab.com/philbooth/check-types.js/pipelines)
|
||||
[](https://www.npmjs.com/package/check-types)
|
||||
[](https://www.npmjs.com/package/check-types)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
A little JavaScript library
|
||||
for asserting types
|
||||
and values.
|
||||
|
||||
* [Why would I want that?](#why-would-i-want-that)
|
||||
* [How little is it?](#how-little-is-it)
|
||||
* [How do I install it?](#how-do-i-install-it)
|
||||
* [How do I use it?](#how-do-i-use-it)
|
||||
* [Loading the library](#loading-the-library)
|
||||
* [Calling the exported functions](#calling-the-exported-functions)
|
||||
* [General predicates](#general-predicates)
|
||||
* [String predicates](#string-predicates)
|
||||
* [Number predicates](#number-predicates)
|
||||
* [Boolean predicates](#boolean-predicates)
|
||||
* [Object predicates](#object-predicates)
|
||||
* [Array predicates](#array-predicates)
|
||||
* [Date predicates](#date-predicates)
|
||||
* [Error predicates](#error-predicates)
|
||||
* [Function predicates](#function-predicates)
|
||||
* [Modifiers](#modifiers)
|
||||
* [Batch operations](#batch-operations)
|
||||
* [Some examples](#some-examples)
|
||||
* [Are there TypeScript definitions?](#are-there-typescript-definitions)
|
||||
* [Where can I use it?](#where-can-i-use-it)
|
||||
* [What changed from 6.x to 7.x?](#what-changed-from-6x-to-7x)
|
||||
* [What changed from 5.x to 6.x?](#what-changed-from-5x-to-6x)
|
||||
* [What changed from 4.x to 5.x?](#what-changed-from-4x-to-5x)
|
||||
* [What changed from 3.x to 4.x?](#what-changed-from-3x-to-4x)
|
||||
* [What changed from 2.x to 3.x?](#what-changed-from-2x-to-3x)
|
||||
* [What changed from 1.x to 2.x?](#what-changed-from-1x-to-2x)
|
||||
* [What changed from 0.x to 1.x?](#what-changed-from-0x-to-1x)
|
||||
* [How do I set up the build environment?](#how-do-i-set-up-the-build-environment)
|
||||
* [What license is it released under?](#what-license-is-it-released-under)
|
||||
|
||||
## Why would I want that?
|
||||
|
||||
Writing explicit conditions
|
||||
in your functions
|
||||
to check arguments
|
||||
and throw exceptions
|
||||
is a task that
|
||||
swiftly becomes tiresome
|
||||
and adds complexity
|
||||
to your codebase.
|
||||
|
||||
The purpose of check-types.js
|
||||
is to remove this burden
|
||||
from JavaScript application developers
|
||||
in an efficient and robust manner,
|
||||
abstracted by a simple API.
|
||||
|
||||
## How little is it?
|
||||
|
||||
21 kb unminified with comments, 6.1 kb minified, 2.2 kb minified + gzipped.
|
||||
|
||||
## How do I install it?
|
||||
|
||||
Via npm:
|
||||
|
||||
```
|
||||
npm i check-types --save
|
||||
```
|
||||
|
||||
Or if you just want the git repo:
|
||||
|
||||
```
|
||||
git clone git@gitlab.com:philbooth/check-types.js.git
|
||||
```
|
||||
|
||||
If you're into
|
||||
other package managers,
|
||||
it is also available
|
||||
from Bower, Component and Jam.
|
||||
|
||||
## How do I use it?
|
||||
|
||||
### Loading the library
|
||||
|
||||
If you are running in
|
||||
Node.js,
|
||||
Browserify
|
||||
or another CommonJS-style
|
||||
environment,
|
||||
you can `require`
|
||||
check-types like so:
|
||||
|
||||
```javascript
|
||||
var check = require('check-types');
|
||||
```
|
||||
|
||||
It also the supports
|
||||
the AMD-style format
|
||||
preferred by Require.js.
|
||||
|
||||
If you are
|
||||
including check-types.js
|
||||
with an HTML `<script>` tag,
|
||||
or neither of the above environments
|
||||
are detected,
|
||||
it will export the interface globally as `check`.
|
||||
|
||||
### Calling the exported functions
|
||||
|
||||
Once you've loaded the library
|
||||
in your application,
|
||||
a whole bunch of functions are available
|
||||
to call.
|
||||
|
||||
Most of the functions
|
||||
are predicates,
|
||||
which can be executed
|
||||
in a number of different contexts:
|
||||
|
||||
* `check.xxx(thing)`:
|
||||
These functions are basic predicates,
|
||||
returning true or false
|
||||
depending on the type and value of `thing`.
|
||||
|
||||
* `check.not.xxx(thing)`:
|
||||
The `not` modifier
|
||||
negates predicates,
|
||||
returning `true` if the predicate returns `false`
|
||||
and `false` if the predicate returns `true`.
|
||||
It is also itself a function,
|
||||
which simply returns
|
||||
the negation of
|
||||
its argument.
|
||||
|
||||
* `check.maybe.xxx(thing)`:
|
||||
The `maybe` modifier
|
||||
tweaks predicates to
|
||||
return `true` if `thing` is `null` or `undefined`,
|
||||
otherwise their normal result
|
||||
is returned.
|
||||
It is also itself a function,
|
||||
which returns `true`
|
||||
when its argument is `null` or `undefined`,
|
||||
otherwise it returns its argument.
|
||||
|
||||
* `check.assert.xxx(thing, message)`:
|
||||
The `assert` modifier
|
||||
changes predicates
|
||||
to throw when their result is `false`,
|
||||
otherwise it returns `thing`.
|
||||
It can be applied
|
||||
to the `not` and `maybe` modifiers
|
||||
using the forms
|
||||
`check.assert.not.xxx(thing, message)` and
|
||||
`check.assert.maybe.xxx(thing, message)`.
|
||||
It is also itself a function,
|
||||
which simply throws
|
||||
when its argument is false.
|
||||
|
||||
* `check.array.of.xxx(thing)`:
|
||||
The `array.of` modifier
|
||||
first checks that
|
||||
it is operating on an array
|
||||
and then applies
|
||||
the modified predicate
|
||||
to each item
|
||||
of the array.
|
||||
If the predicate fails
|
||||
for any item,
|
||||
it returns `false`,
|
||||
otherwise it returns `true`.
|
||||
It can also be prefixed
|
||||
by other modifiers,
|
||||
so `check.maybe.array.of`,
|
||||
`check.not.array.of`,
|
||||
`check.assert.array.of`,
|
||||
`check.assert.maybe.array.of` and
|
||||
`check.assert.not.array.of`
|
||||
all work
|
||||
as you would expect
|
||||
them to.
|
||||
|
||||
* `check.arrayLike.of.xxx(thing)`:
|
||||
The `arrayLike.of` modifier
|
||||
is synonymous with `array.of`,
|
||||
except it operates on array-like objects.
|
||||
|
||||
* `check.iterable.of.xxx(thing)`:
|
||||
The `iterable.of` modifier
|
||||
is synonymous with `array.of`,
|
||||
except it operates on iterables.
|
||||
|
||||
* `check.object.of.xxx(thing)`:
|
||||
The `object.of` modifier
|
||||
is synonymous with `array.of`,
|
||||
except it operates on an object's properties.
|
||||
|
||||
Additionally, there are some batch operations
|
||||
that allow you to apply different predicates
|
||||
to each value
|
||||
in an array or object.
|
||||
These are implemented by
|
||||
`check.apply`,
|
||||
`check.map`,
|
||||
`check.any` and
|
||||
`check.all`.
|
||||
|
||||
#### General predicates
|
||||
|
||||
* `check.equal(thing, thang)`:
|
||||
Returns `true`
|
||||
if `thing === thang`,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.null(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is `null`,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.undefined(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is `undefined`,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.assigned(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is not
|
||||
`null` or `undefined`,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.primitive(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a primitive type,
|
||||
`false` otherwise.
|
||||
Primitive types are
|
||||
`null`, `undefined`, booleans, numbers, strings and symbols.
|
||||
|
||||
* `check.hasLength(thing, value)`:
|
||||
Returns `true`
|
||||
if `thing` has a length property
|
||||
that equals `value`,
|
||||
`false` otherwise.
|
||||
|
||||
#### String predicates
|
||||
|
||||
* `check.string(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a string,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.emptyString(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is the empty string,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.nonEmptyString(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a non-empty string,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.contains(thing, substring)`:
|
||||
Returns `true`
|
||||
if `thing` is a string
|
||||
that contains `substring`,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.match(thing, regex)`:
|
||||
Returns `true`
|
||||
if `thing` is a string
|
||||
that matches `regex`,
|
||||
`false` otherwise.
|
||||
|
||||
#### Number predicates
|
||||
|
||||
* `check.number(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a number,
|
||||
`false` otherwise.
|
||||
Note that
|
||||
`NaN`,
|
||||
`Number.POSITIVE_INFINITY` and
|
||||
`Number.NEGATIVE_INFINITY`
|
||||
are not considered numbers here.
|
||||
|
||||
* `check.integer(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is an integer,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.zero(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is zero,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.infinity(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is positive or negative infinity,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.greater(thing, value)`:
|
||||
Returns `true` if `thing` is a number
|
||||
greater than `value`,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.greaterOrEqual(thing, value)`:
|
||||
Returns `true` if `thing` is a number
|
||||
greater than or equal to `value`,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.less(thing, value)`:
|
||||
Returns `true` if `thing` is a number
|
||||
less than `value`,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.lessOrEqual(thing, value)`:
|
||||
Returns `true` if `thing` is a number
|
||||
less than or equal to `value`,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.between(thing, a, b)`:
|
||||
Returns `true` if `thing` is a number
|
||||
between `a` and `b`
|
||||
(excluding `a` and `b`),
|
||||
`false` otherwise.
|
||||
The arguments `a` and `b`
|
||||
may be in any order,
|
||||
it doesn't matter
|
||||
which is greater.
|
||||
|
||||
* `check.inRange(thing, a, b)`:
|
||||
Returns `true` if `thing` is a number
|
||||
in the range `a` .. `b`
|
||||
(including `a` and `b`),
|
||||
`false` otherwise.
|
||||
The arguments `a` and `b`
|
||||
may be in any order,
|
||||
it doesn't matter
|
||||
which is greater.
|
||||
|
||||
* `check.positive(thing)`:
|
||||
Returns `true` if `thing` is a number
|
||||
greater than zero,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.negative(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a number
|
||||
less than zero,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.odd(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is an odd number,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.even(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is an even number,
|
||||
`false` otherwise.
|
||||
|
||||
#### Boolean predicates
|
||||
|
||||
* `check.boolean(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a boolean,
|
||||
`false` otherwise.
|
||||
|
||||
#### Object predicates
|
||||
|
||||
* `check.object(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a plain-old JavaScript object,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.emptyObject(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is an empty object,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.nonEmptyObject(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a non-empty object,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.instanceStrict(thing, prototype)`:
|
||||
Returns `true`
|
||||
if `thing` is an instance of `prototype`,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.instance(thing, prototype)`:
|
||||
Returns `true`
|
||||
if `thing` is an instance of `prototype`,
|
||||
`false` otherwise.
|
||||
Falls back to testing
|
||||
`constructor.name` and `Object.prototype.toString`
|
||||
if the `instanceof` test fails.
|
||||
|
||||
* `check.like(thing, duck)`:
|
||||
Duck-typing checker.
|
||||
Returns `true`
|
||||
if `thing` has all of the properties of `duck`,
|
||||
`false` otherwise.
|
||||
|
||||
#### Array predicates
|
||||
|
||||
* `check.array(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is an array,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.emptyArray(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is an empty array,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.nonEmptyArray(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a non-empty array,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.arrayLike(thing)`:
|
||||
Returns `true`
|
||||
if `thing` has a numeric length property,
|
||||
`false` otherwise.
|
||||
|
||||
* `check.iterable(thing)`:
|
||||
Returns `true`
|
||||
if `thing` implements the iterable protocol,
|
||||
`false` otherwise.
|
||||
In pre-ES6 environments,
|
||||
this predicate falls back
|
||||
to `arrayLike` behaviour.
|
||||
|
||||
* `check.includes(thing, value)`:
|
||||
Returns `true`
|
||||
if `thing` includes `value`,
|
||||
`false` otherwise.
|
||||
|
||||
#### Date predicates
|
||||
|
||||
* `check.date(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a valid date,
|
||||
`false` otherwise.
|
||||
|
||||
#### Function predicates
|
||||
|
||||
* `check.function(thing)`:
|
||||
Returns `true`
|
||||
if `thing` is a function,
|
||||
`false` otherwise.
|
||||
|
||||
#### Modifiers
|
||||
|
||||
* `check.not(value)`:
|
||||
Returns the negation
|
||||
of `value`.
|
||||
|
||||
* `check.not.xxx(...)`:
|
||||
Returns the negation
|
||||
of the predicate.
|
||||
|
||||
* `check.maybe(value)`:
|
||||
Returns `true`
|
||||
if `value` is `null` or `undefined`,
|
||||
otherwise it returns `value`.
|
||||
|
||||
* `check.maybe.xxx(...)`:
|
||||
Returns `true`
|
||||
if `thing` is `null` or `undefined`,
|
||||
otherwise it propagates
|
||||
the return value
|
||||
from its predicate.
|
||||
|
||||
* `check.array.of.xxx(value)`:
|
||||
Returns `true`
|
||||
if `value` is an array
|
||||
and the predicate is true
|
||||
for every item.
|
||||
Also works with the `not` and `maybe` modifiers.
|
||||
|
||||
* `check.arrayLike.of.xxx(thing)`:
|
||||
The `arrayLike.of` modifier
|
||||
is synonymous with `array.of`,
|
||||
except it operates on array-like objects.
|
||||
|
||||
* `check.iterable.of.xxx(thing)`:
|
||||
The `iterable.of` modifier
|
||||
is synonymous with `array.of`,
|
||||
except it operates on iterables.
|
||||
|
||||
* `check.object.of.xxx(thing)`:
|
||||
The `object.of` modifier
|
||||
is synonymous with `array.of`,
|
||||
except it operates on an object's properties.
|
||||
|
||||
* `check.assert(value, message, ErrorType)`:
|
||||
Throws a `TypeError`
|
||||
if `value` is *falsy*,
|
||||
otherwise it returns `value`.
|
||||
`message` and `ErrorType`
|
||||
are optional arguments
|
||||
that control
|
||||
the message and type
|
||||
of the thrown error object.
|
||||
|
||||
* `check.assert.xxx(...)`:
|
||||
Throws a `TypeError`
|
||||
if the predicate returns false,
|
||||
otherwise it returns the subject value.
|
||||
The last two arguments
|
||||
are an optional message and error type
|
||||
that control
|
||||
the message and type
|
||||
of the thrown error object.
|
||||
Also works with the `not`, `maybe` and `...of` modifiers.
|
||||
|
||||
#### Batch operations
|
||||
|
||||
* `check.apply(things, predicates)`:
|
||||
Applies each value from the `things` array
|
||||
to the corresponding predicate
|
||||
and returns the array of results.
|
||||
Passing a single predicate
|
||||
instead of an array
|
||||
applies all of the values
|
||||
to the same predicate.
|
||||
|
||||
* `check.map(things, predicates)`:
|
||||
Maps each value from the `things` object
|
||||
to the corresponding predicate
|
||||
and returns an object
|
||||
containing the results.
|
||||
Supports nested objects.
|
||||
Passing a single predicate
|
||||
instead of an object
|
||||
applies all of the values
|
||||
to the same predicate,
|
||||
ignoring nested objects.
|
||||
|
||||
* `check.all(results)`:
|
||||
Returns `true`
|
||||
if all the result values are true
|
||||
in an array (returned from `apply`)
|
||||
or object (returned from `map`).
|
||||
|
||||
* `check.any(predicateResults)`:
|
||||
Returns `true`
|
||||
if any result value is true
|
||||
in an array (returned from `apply`)
|
||||
or object (returned from `map`).
|
||||
|
||||
#### Some examples
|
||||
|
||||
```javascript
|
||||
check.even(3);
|
||||
// Returns false
|
||||
```
|
||||
|
||||
```javascript
|
||||
check.not.even(3);
|
||||
// Returns true
|
||||
```
|
||||
|
||||
```javascript
|
||||
check.maybe.even(null);
|
||||
// Returns true
|
||||
```
|
||||
|
||||
```javascript
|
||||
check.assert.like({ foo: 'bar' }, { baz: 'qux' });
|
||||
// Throws `new TypeError('Invalid type')`
|
||||
```
|
||||
|
||||
```javascript
|
||||
check.assert.not.like({ foo: 'bar' }, { baz: 'qux' });
|
||||
// Doesn't throw, returns `{ foo: 'bar' }`
|
||||
```
|
||||
|
||||
```javascript
|
||||
check.assert.maybe.like(undefined, { foo: 'bar' });
|
||||
// Doesn't throw, returns `undefined`
|
||||
```
|
||||
|
||||
```javascript
|
||||
check.assert(myFunction(), 'Something went wrong', CustomError);
|
||||
// Throws `new CustomError('Something went wrong')` if myFunction returns `false`
|
||||
```
|
||||
|
||||
```javascript
|
||||
check.apply([ 'foo', 'bar', '' ], check.nonEmptyString);
|
||||
// Returns [ true, true, false ]
|
||||
```
|
||||
|
||||
```javascript
|
||||
check.map({
|
||||
foo: 2,
|
||||
bar: { baz: 'qux' }
|
||||
}, {
|
||||
foo: check.odd,
|
||||
bar: { baz: check.nonEmptyString }
|
||||
});
|
||||
// Returns { foo: false, bar: { baz: true } }
|
||||
```
|
||||
|
||||
```javascript
|
||||
check.all(
|
||||
check.map(
|
||||
{ foo: 0, bar: '' },
|
||||
{ foo: check.number, bar: check.string }
|
||||
)
|
||||
);
|
||||
// Returns true
|
||||
```
|
||||
|
||||
```javascript
|
||||
check.any(
|
||||
check.apply(
|
||||
[ 1, 2, 3, '' ],
|
||||
check.string
|
||||
)
|
||||
);
|
||||
// Returns true
|
||||
```
|
||||
|
||||
## Are there TypeScript definitions?
|
||||
|
||||
[Yes](https://www.npmjs.com/package/@types/check-types)!
|
||||
|
||||
Thanks to [@idchlife](https://github.com/idchlife),
|
||||
type definitions [were added](https://github.com/DefinitelyTyped/DefinitelyTyped/commit/d19ddb855dea08105a3d7450a98696c7bcd62f60)
|
||||
to [DefinitelyTyped].
|
||||
You can add them to your project
|
||||
via npm:
|
||||
|
||||
```
|
||||
npm i @types/check-types --save-dev
|
||||
```
|
||||
|
||||
## Where can I use it?
|
||||
|
||||
As of version 2.0,
|
||||
this library no longer supports ES3.
|
||||
That means you can't use it
|
||||
in IE 7 or 8.
|
||||
|
||||
Everywhere else should be fine.
|
||||
|
||||
If those versions of IE
|
||||
are important to you,
|
||||
worry not!
|
||||
The 1.x versions
|
||||
all support old IE
|
||||
and any future 1.x versions
|
||||
will adhere to that too.
|
||||
|
||||
See the [releases]
|
||||
for more information.
|
||||
|
||||
## What changed from 6.x to 7.x?
|
||||
|
||||
Breaking changes
|
||||
were made to the API
|
||||
in version 7.0.0.
|
||||
|
||||
Specifically,
|
||||
the `instance` predicate
|
||||
was renamed to `instanceStrict`
|
||||
and the `builtIn` and `userDefined` predicates
|
||||
were combined to form
|
||||
a new `instance` predicate.
|
||||
|
||||
See the [history][history7]
|
||||
for more details.
|
||||
|
||||
## What changed from 5.x to 6.x?
|
||||
|
||||
Breaking changes
|
||||
were made to the API
|
||||
in version 6.0.0.
|
||||
|
||||
Specifically,
|
||||
the `either` modifier was removed.
|
||||
Instead,
|
||||
calling code can use
|
||||
the `any` function,
|
||||
or simply express the boolean logic
|
||||
in JS.
|
||||
|
||||
See the [history][history6]
|
||||
for more details.
|
||||
|
||||
## What changed from 4.x to 5.x?
|
||||
|
||||
Breaking changes
|
||||
were made to the API
|
||||
in version 5.0.0.
|
||||
|
||||
Specifically,
|
||||
the predicates `isMap` and `error` were removed
|
||||
in favour of the new predicate `builtIn`,
|
||||
which can be used to test for
|
||||
all built-in objects.
|
||||
|
||||
See the [history][history5]
|
||||
for more details.
|
||||
|
||||
## What changed from 3.x to 4.x?
|
||||
|
||||
Breaking changes
|
||||
were made to the API
|
||||
in version 4.0.0.
|
||||
|
||||
Specifically,
|
||||
the predicate `unemptyString`
|
||||
was renamed to `nonEmptyString`
|
||||
and the predicate `error`
|
||||
was changed to support
|
||||
derived Error objects.
|
||||
|
||||
See the [history][history4]
|
||||
for more details.
|
||||
|
||||
## What changed from 2.x to 3.x?
|
||||
|
||||
Breaking changes
|
||||
were made to the API
|
||||
in version 3.0.0.
|
||||
|
||||
Specifically,
|
||||
the predicate `length`
|
||||
was renamed to `hasLength`
|
||||
and the predicate `webUrl`
|
||||
was removed.
|
||||
|
||||
See the [history][history3]
|
||||
for more details.
|
||||
|
||||
## What changed from 1.x to 2.x?
|
||||
|
||||
Breaking changes
|
||||
were made to the API
|
||||
in version 2.0.0.
|
||||
|
||||
Specifically:
|
||||
|
||||
* Support for ES3 was dropped
|
||||
* The predicates `gitUrl`, `email` and `floatNumber` were removed.
|
||||
* `verify` was renamed to `assert`.
|
||||
* `nulled` was renamed to `null`.
|
||||
* `oddNumber` was renamed to `odd`.
|
||||
* `evenNumber` was renamed to `even`.
|
||||
* `positiveNumber` was renamed to `positive`.
|
||||
* `negativeNumber` was renamed to `negative`.
|
||||
* `intNumber` was renamed to `integer`.
|
||||
* `bool` was renamed to `boolean`.
|
||||
* `defined` was swapped to become `undefined`.
|
||||
* `webUrl` was tightened to reject more cases.
|
||||
|
||||
See the [history][history2]
|
||||
for more details.
|
||||
|
||||
## What changed from 0.x to 1.x?
|
||||
|
||||
Breaking changes
|
||||
were made to the API
|
||||
in version 1.0.0.
|
||||
|
||||
Specifically,
|
||||
all of the predicates
|
||||
were renamed
|
||||
from `check.isXxxx`
|
||||
to `check.xxx` and
|
||||
all of the verifiers
|
||||
were renamed
|
||||
from `check.verifyXxxx`
|
||||
to `check.verify.xxx`.
|
||||
|
||||
See the [history][history1]
|
||||
for more details.
|
||||
|
||||
## How do I set up the build environment?
|
||||
|
||||
The build environment relies on
|
||||
[Node.js][node],
|
||||
[NPM],
|
||||
[JSHint],
|
||||
[Mocha],
|
||||
[Chai],
|
||||
[UglifyJS] and
|
||||
[please-release-me].
|
||||
Assuming that you already have Node.js and NPM set up,
|
||||
you just need to run `npm install` to
|
||||
install all of the dependencies as listed in `package.json`.
|
||||
|
||||
The unit tests are in `test/check-types.js`.
|
||||
You can run them with the command `npm test`.
|
||||
To run the tests in a web browser,
|
||||
open `test/check-types.html`.
|
||||
|
||||
## What license is it released under?
|
||||
|
||||
[MIT][license]
|
||||
|
||||
[definitelytyped]: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
[releases]: https://gitlab.com/philbooth/check-types.js/tags
|
||||
[history7]: HISTORY.md#70
|
||||
[history6]: HISTORY.md#60
|
||||
[history5]: HISTORY.md#50
|
||||
[history4]: HISTORY.md#40
|
||||
[history3]: HISTORY.md#30
|
||||
[history2]: HISTORY.md#20
|
||||
[history1]: HISTORY.md#10
|
||||
[node]: http://nodejs.org/
|
||||
[npm]: https://npmjs.org/
|
||||
[jshint]: https://github.com/jshint/node-jshint
|
||||
[mocha]: http://mochajs.org/
|
||||
[chai]: http://chaijs.com/
|
||||
[uglifyjs]: https://github.com/mishoo/UglifyJS
|
||||
[please-release-me]: https://gitlab.com/philbooth/please-release-me
|
||||
[license]: https://gitlab.com/philbooth/check-types.js/blob/master/COPYING
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "check-types",
|
||||
"version": "7.4.0",
|
||||
"description": "A little library for asserting types and values.",
|
||||
"homepage": "https://gitlab.com/philbooth/check-types.js",
|
||||
"bugs": "https://gitlab.com/philbooth/check-types.js/issues",
|
||||
"license": "MIT",
|
||||
"author": "Phil Booth <pmbooth@gmail.com> (https://philbooth.me/)",
|
||||
"main": "./src/check-types",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitlab.com/philbooth/check-types.js.git"
|
||||
},
|
||||
"keywords": [
|
||||
"type",
|
||||
"types",
|
||||
"type-check",
|
||||
"type-checking",
|
||||
"duck-typing",
|
||||
"arguments",
|
||||
"parameters",
|
||||
"values",
|
||||
"data",
|
||||
"contract",
|
||||
"assert",
|
||||
"check",
|
||||
"verify",
|
||||
"safe",
|
||||
"safety"
|
||||
],
|
||||
"devDependencies": {
|
||||
"jshint": "2.9.x",
|
||||
"mocha": "3.2.x",
|
||||
"chai": "3.5.x",
|
||||
"uglify-js": "2.7.x",
|
||||
"please-release-me": "2.0.x"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "jshint ./src/check-types.js",
|
||||
"test": "mocha --ui tdd --reporter spec --colors ./test/check-types.js",
|
||||
"minify": "uglifyjs ./src/check-types.js --compress --mangle --output ./src/check-types.min.js"
|
||||
},
|
||||
"files": [
|
||||
"COPYING",
|
||||
"HISTORY.md",
|
||||
"src"
|
||||
]
|
||||
}
|
||||
+898
@@ -0,0 +1,898 @@
|
||||
/*globals define, module, Symbol */
|
||||
/*jshint -W056 */
|
||||
|
||||
(function (globals) {
|
||||
'use strict';
|
||||
|
||||
var strings, messages, predicates, functions, assert, not, maybe,
|
||||
collections, slice, neginf, posinf, isArray, haveSymbols;
|
||||
|
||||
strings = {
|
||||
v: 'value',
|
||||
n: 'number',
|
||||
s: 'string',
|
||||
b: 'boolean',
|
||||
o: 'object',
|
||||
t: 'type',
|
||||
a: 'array',
|
||||
al: 'array-like',
|
||||
i: 'iterable',
|
||||
d: 'date',
|
||||
f: 'function',
|
||||
l: 'length'
|
||||
};
|
||||
|
||||
messages = {};
|
||||
predicates = {};
|
||||
|
||||
[
|
||||
{ n: 'equal', f: equal, s: 'v' },
|
||||
{ n: 'undefined', f: isUndefined, s: 'v' },
|
||||
{ n: 'null', f: isNull, s: 'v' },
|
||||
{ n: 'assigned', f: assigned, s: 'v' },
|
||||
{ n: 'primitive', f: primitive, s: 'v' },
|
||||
{ n: 'includes', f: includes, s: 'v' },
|
||||
{ n: 'zero', f: zero },
|
||||
{ n: 'infinity', f: infinity },
|
||||
{ n: 'number', f: number },
|
||||
{ n: 'integer', f: integer },
|
||||
{ n: 'even', f: even },
|
||||
{ n: 'odd', f: odd },
|
||||
{ n: 'greater', f: greater },
|
||||
{ n: 'less', f: less },
|
||||
{ n: 'between', f: between },
|
||||
{ n: 'greaterOrEqual', f: greaterOrEqual },
|
||||
{ n: 'lessOrEqual', f: lessOrEqual },
|
||||
{ n: 'inRange', f: inRange },
|
||||
{ n: 'positive', f: positive },
|
||||
{ n: 'negative', f: negative },
|
||||
{ n: 'string', f: string, s: 's' },
|
||||
{ n: 'emptyString', f: emptyString, s: 's' },
|
||||
{ n: 'nonEmptyString', f: nonEmptyString, s: 's' },
|
||||
{ n: 'contains', f: contains, s: 's' },
|
||||
{ n: 'match', f: match, s: 's' },
|
||||
{ n: 'boolean', f: boolean, s: 'b' },
|
||||
{ n: 'object', f: object, s: 'o' },
|
||||
{ n: 'emptyObject', f: emptyObject, s: 'o' },
|
||||
{ n: 'nonEmptyObject', f: nonEmptyObject, s: 'o' },
|
||||
{ n: 'instanceStrict', f: instanceStrict, s: 't' },
|
||||
{ n: 'instance', f: instance, s: 't' },
|
||||
{ n: 'like', f: like, s: 't' },
|
||||
{ n: 'array', f: array, s: 'a' },
|
||||
{ n: 'emptyArray', f: emptyArray, s: 'a' },
|
||||
{ n: 'nonEmptyArray', f: nonEmptyArray, s: 'a' },
|
||||
{ n: 'arrayLike', f: arrayLike, s: 'al' },
|
||||
{ n: 'iterable', f: iterable, s: 'i' },
|
||||
{ n: 'date', f: date, s: 'd' },
|
||||
{ n: 'function', f: isFunction, s: 'f' },
|
||||
{ n: 'hasLength', f: hasLength, s: 'l' },
|
||||
].map(function (data) {
|
||||
var n = data.n;
|
||||
messages[n] = 'Invalid ' + strings[data.s || 'n'];
|
||||
predicates[n] = data.f;
|
||||
});
|
||||
|
||||
functions = {
|
||||
apply: apply,
|
||||
map: map,
|
||||
all: all,
|
||||
any: any
|
||||
};
|
||||
|
||||
collections = [ 'array', 'arrayLike', 'iterable', 'object' ];
|
||||
slice = Array.prototype.slice;
|
||||
neginf = Number.NEGATIVE_INFINITY;
|
||||
posinf = Number.POSITIVE_INFINITY;
|
||||
isArray = Array.isArray;
|
||||
haveSymbols = typeof Symbol === 'function';
|
||||
|
||||
functions = mixin(functions, predicates);
|
||||
assert = createModifiedPredicates(assertModifier, assertImpl);
|
||||
not = createModifiedPredicates(notModifier, notImpl);
|
||||
maybe = createModifiedPredicates(maybeModifier, maybeImpl);
|
||||
assert.not = createModifiedModifier(assertModifier, not);
|
||||
assert.maybe = createModifiedModifier(assertModifier, maybe);
|
||||
|
||||
collections.forEach(createOfPredicates);
|
||||
createOfModifiers(assert, assertModifier);
|
||||
createOfModifiers(not, notModifier);
|
||||
collections.forEach(createMaybeOfModifiers);
|
||||
|
||||
exportFunctions(mixin(functions, {
|
||||
assert: assert,
|
||||
not: not,
|
||||
maybe: maybe
|
||||
}));
|
||||
|
||||
/**
|
||||
* Public function `equal`.
|
||||
*
|
||||
* Returns true if `lhs` and `rhs` are strictly equal, without coercion.
|
||||
* Returns false otherwise.
|
||||
*/
|
||||
function equal (lhs, rhs) {
|
||||
return lhs === rhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `undefined`.
|
||||
*
|
||||
* Returns true if `data` is undefined, false otherwise.
|
||||
*/
|
||||
function isUndefined (data) {
|
||||
return data === undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `null`.
|
||||
*
|
||||
* Returns true if `data` is null, false otherwise.
|
||||
*/
|
||||
function isNull (data) {
|
||||
return data === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `assigned`.
|
||||
*
|
||||
* Returns true if `data` is not null or undefined, false otherwise.
|
||||
*/
|
||||
function assigned (data) {
|
||||
return data !== undefined && data !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `primitive`.
|
||||
*
|
||||
* Returns true if `data` is a primitive type, false otherwise.
|
||||
*/
|
||||
function primitive (data) {
|
||||
var type;
|
||||
|
||||
switch (data) {
|
||||
case null:
|
||||
case undefined:
|
||||
case false:
|
||||
case true:
|
||||
return true;
|
||||
}
|
||||
|
||||
type = typeof data;
|
||||
return type === 'string' || type === 'number' || (haveSymbols && type === 'symbol');
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `zero`.
|
||||
*
|
||||
* Returns true if `data` is zero, false otherwise.
|
||||
*/
|
||||
function zero (data) {
|
||||
return data === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `infinity`.
|
||||
*
|
||||
* Returns true if `data` is positive or negative infinity, false otherwise.
|
||||
*/
|
||||
function infinity (data) {
|
||||
return data === neginf || data === posinf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `number`.
|
||||
*
|
||||
* Returns true if `data` is a number, false otherwise.
|
||||
*/
|
||||
function number (data) {
|
||||
return typeof data === 'number' && data > neginf && data < posinf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `integer`.
|
||||
*
|
||||
* Returns true if `data` is an integer, false otherwise.
|
||||
*/
|
||||
function integer (data) {
|
||||
return typeof data === 'number' && data % 1 === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `even`.
|
||||
*
|
||||
* Returns true if `data` is an even number, false otherwise.
|
||||
*/
|
||||
function even (data) {
|
||||
return typeof data === 'number' && data % 2 === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `odd`.
|
||||
*
|
||||
* Returns true if `data` is an odd number, false otherwise.
|
||||
*/
|
||||
function odd (data) {
|
||||
return integer(data) && data % 2 !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `greater`.
|
||||
*
|
||||
* Returns true if `lhs` is a number greater than `rhs`, false otherwise.
|
||||
*/
|
||||
function greater (lhs, rhs) {
|
||||
return number(lhs) && lhs > rhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `less`.
|
||||
*
|
||||
* Returns true if `lhs` is a number less than `rhs`, false otherwise.
|
||||
*/
|
||||
function less (lhs, rhs) {
|
||||
return number(lhs) && lhs < rhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `between`.
|
||||
*
|
||||
* Returns true if `data` is a number between `x` and `y`, false otherwise.
|
||||
*/
|
||||
function between (data, x, y) {
|
||||
if (x < y) {
|
||||
return greater(data, x) && data < y;
|
||||
}
|
||||
|
||||
return less(data, x) && data > y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `greaterOrEqual`.
|
||||
*
|
||||
* Returns true if `lhs` is a number greater than or equal to `rhs`, false
|
||||
* otherwise.
|
||||
*/
|
||||
function greaterOrEqual (lhs, rhs) {
|
||||
return number(lhs) && lhs >= rhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `lessOrEqual`.
|
||||
*
|
||||
* Returns true if `lhs` is a number less than or equal to `rhs`, false
|
||||
* otherwise.
|
||||
*/
|
||||
function lessOrEqual (lhs, rhs) {
|
||||
return number(lhs) && lhs <= rhs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `inRange`.
|
||||
*
|
||||
* Returns true if `data` is a number in the range `x..y`, false otherwise.
|
||||
*/
|
||||
function inRange (data, x, y) {
|
||||
if (x < y) {
|
||||
return greaterOrEqual(data, x) && data <= y;
|
||||
}
|
||||
|
||||
return lessOrEqual(data, x) && data >= y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `positive`.
|
||||
*
|
||||
* Returns true if `data` is a positive number, false otherwise.
|
||||
*/
|
||||
function positive (data) {
|
||||
return greater(data, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `negative`.
|
||||
*
|
||||
* Returns true if `data` is a negative number, false otherwise.
|
||||
*/
|
||||
function negative (data) {
|
||||
return less(data, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `string`.
|
||||
*
|
||||
* Returns true if `data` is a string, false otherwise.
|
||||
*/
|
||||
function string (data) {
|
||||
return typeof data === 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `emptyString`.
|
||||
*
|
||||
* Returns true if `data` is the empty string, false otherwise.
|
||||
*/
|
||||
function emptyString (data) {
|
||||
return data === '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `nonEmptyString`.
|
||||
*
|
||||
* Returns true if `data` is a non-empty string, false otherwise.
|
||||
*/
|
||||
function nonEmptyString (data) {
|
||||
return string(data) && data !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `contains`.
|
||||
*
|
||||
* Returns true if `data` is a string that contains `substring`, false
|
||||
* otherwise.
|
||||
*/
|
||||
function contains (data, substring) {
|
||||
return string(data) && data.indexOf(substring) !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `match`.
|
||||
*
|
||||
* Returns true if `data` is a string that matches `regex`, false otherwise.
|
||||
*/
|
||||
function match (data, regex) {
|
||||
return string(data) && !! data.match(regex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `boolean`.
|
||||
*
|
||||
* Returns true if `data` is a boolean value, false otherwise.
|
||||
*/
|
||||
function boolean (data) {
|
||||
return data === false || data === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `object`.
|
||||
*
|
||||
* Returns true if `data` is a plain-old JS object, false otherwise.
|
||||
*/
|
||||
function object (data) {
|
||||
return Object.prototype.toString.call(data) === '[object Object]';
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `emptyObject`.
|
||||
*
|
||||
* Returns true if `data` is an empty object, false otherwise.
|
||||
*/
|
||||
function emptyObject (data) {
|
||||
return object(data) && Object.keys(data).length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `nonEmptyObject`.
|
||||
*
|
||||
* Returns true if `data` is a non-empty object, false otherwise.
|
||||
*/
|
||||
function nonEmptyObject (data) {
|
||||
return object(data) && Object.keys(data).length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `instanceStrict`.
|
||||
*
|
||||
* Returns true if `data` is an instance of `prototype`, false otherwise.
|
||||
*/
|
||||
function instanceStrict (data, prototype) {
|
||||
try {
|
||||
return data instanceof prototype;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `instance`.
|
||||
*
|
||||
* Returns true if `data` is an instance of `prototype`, false otherwise.
|
||||
* Falls back to testing constructor.name and Object.prototype.toString
|
||||
* if the initial instanceof test fails.
|
||||
*/
|
||||
function instance (data, prototype) {
|
||||
try {
|
||||
return instanceStrict(data, prototype) ||
|
||||
data.constructor.name === prototype.name ||
|
||||
Object.prototype.toString.call(data) === '[object ' + prototype.name + ']';
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `like`.
|
||||
*
|
||||
* Tests whether `data` 'quacks like a duck'. Returns true if `data` has all
|
||||
* of the properties of `archetype` (the 'duck'), false otherwise.
|
||||
*/
|
||||
function like (data, archetype) {
|
||||
var name;
|
||||
|
||||
for (name in archetype) {
|
||||
if (archetype.hasOwnProperty(name)) {
|
||||
if (data.hasOwnProperty(name) === false || typeof data[name] !== typeof archetype[name]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object(data[name]) && like(data[name], archetype[name]) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `array`.
|
||||
*
|
||||
* Returns true if `data` is an array, false otherwise.
|
||||
*/
|
||||
function array (data) {
|
||||
return isArray(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `emptyArray`.
|
||||
*
|
||||
* Returns true if `data` is an empty array, false otherwise.
|
||||
*/
|
||||
function emptyArray (data) {
|
||||
return array(data) && data.length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `nonEmptyArray`.
|
||||
*
|
||||
* Returns true if `data` is a non-empty array, false otherwise.
|
||||
*/
|
||||
function nonEmptyArray (data) {
|
||||
return array(data) && greater(data.length, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `arrayLike`.
|
||||
*
|
||||
* Returns true if `data` is an array-like object, false otherwise.
|
||||
*/
|
||||
function arrayLike (data) {
|
||||
return assigned(data) && greaterOrEqual(data.length, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `iterable`.
|
||||
*
|
||||
* Returns true if `data` is an iterable, false otherwise.
|
||||
*/
|
||||
function iterable (data) {
|
||||
if (! haveSymbols) {
|
||||
// Fall back to `arrayLike` predicate in pre-ES6 environments.
|
||||
return arrayLike(data);
|
||||
}
|
||||
|
||||
return assigned(data) && isFunction(data[Symbol.iterator]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `includes`.
|
||||
*
|
||||
* Returns true if `data` contains `value`, false otherwise.
|
||||
*/
|
||||
function includes (data, value) {
|
||||
var iterator, iteration, keys, length, i;
|
||||
|
||||
if (! assigned(data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (haveSymbols && data[Symbol.iterator] && isFunction(data.values)) {
|
||||
iterator = data.values();
|
||||
|
||||
do {
|
||||
iteration = iterator.next();
|
||||
|
||||
if (iteration.value === value) {
|
||||
return true;
|
||||
}
|
||||
} while (! iteration.done);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
keys = Object.keys(data);
|
||||
length = keys.length;
|
||||
for (i = 0; i < length; ++i) {
|
||||
if (data[keys[i]] === value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `hasLength`.
|
||||
*
|
||||
* Returns true if `data` has a length property that equals `length`, false
|
||||
* otherwise.
|
||||
*/
|
||||
function hasLength (data, length) {
|
||||
return assigned(data) && data.length === length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `date`.
|
||||
*
|
||||
* Returns true if `data` is a valid date, false otherwise.
|
||||
*/
|
||||
function date (data) {
|
||||
return instanceStrict(data, Date) && integer(data.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `function`.
|
||||
*
|
||||
* Returns true if `data` is a function, false otherwise.
|
||||
*/
|
||||
function isFunction (data) {
|
||||
return typeof data === 'function';
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `apply`.
|
||||
*
|
||||
* Maps each value from the `data` to the corresponding predicate and returns
|
||||
* the result array. If the same function is to be applied across all of the
|
||||
* data, a single predicate function may be passed in.
|
||||
*
|
||||
*/
|
||||
function apply (data, predicates) {
|
||||
assert.array(data);
|
||||
|
||||
if (isFunction(predicates)) {
|
||||
return data.map(function (value) {
|
||||
return predicates(value);
|
||||
});
|
||||
}
|
||||
|
||||
assert.array(predicates);
|
||||
assert.hasLength(data, predicates.length);
|
||||
|
||||
return data.map(function (value, index) {
|
||||
return predicates[index](value);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `map`.
|
||||
*
|
||||
* Maps each value from the `data` to the corresponding predicate and returns
|
||||
* the result object. Supports nested objects. If the `data` is not nested and
|
||||
* the same function is to be applied across all of it, a single predicate
|
||||
* function may be passed in.
|
||||
*
|
||||
*/
|
||||
function map (data, predicates) {
|
||||
assert.object(data);
|
||||
|
||||
if (isFunction(predicates)) {
|
||||
return mapSimple(data, predicates);
|
||||
}
|
||||
|
||||
assert.object(predicates);
|
||||
|
||||
return mapComplex(data, predicates);
|
||||
}
|
||||
|
||||
function mapSimple (data, predicate) {
|
||||
var result = {};
|
||||
|
||||
Object.keys(data).forEach(function (key) {
|
||||
result[key] = predicate(data[key]);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function mapComplex (data, predicates) {
|
||||
var result = {};
|
||||
|
||||
Object.keys(predicates).forEach(function (key) {
|
||||
var predicate = predicates[key];
|
||||
|
||||
if (isFunction(predicate)) {
|
||||
if (not.assigned(data)) {
|
||||
result[key] = !!predicate.m;
|
||||
} else {
|
||||
result[key] = predicate(data[key]);
|
||||
}
|
||||
} else if (object(predicate)) {
|
||||
result[key] = mapComplex(data[key], predicate);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `all`
|
||||
*
|
||||
* Check that all boolean values are true
|
||||
* in an array (returned from `apply`)
|
||||
* or object (returned from `map`).
|
||||
*
|
||||
*/
|
||||
function all (data) {
|
||||
if (array(data)) {
|
||||
return testArray(data, false);
|
||||
}
|
||||
|
||||
assert.object(data);
|
||||
|
||||
return testObject(data, false);
|
||||
}
|
||||
|
||||
function testArray (data, result) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < data.length; i += 1) {
|
||||
if (data[i] === result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return !result;
|
||||
}
|
||||
|
||||
function testObject (data, result) {
|
||||
var key, value;
|
||||
|
||||
for (key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
value = data[key];
|
||||
|
||||
if (object(value) && testObject(value, result) === result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (value === result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public function `any`
|
||||
*
|
||||
* Check that at least one boolean value is true
|
||||
* in an array (returned from `apply`)
|
||||
* or object (returned from `map`).
|
||||
*
|
||||
*/
|
||||
function any (data) {
|
||||
if (array(data)) {
|
||||
return testArray(data, true);
|
||||
}
|
||||
|
||||
assert.object(data);
|
||||
|
||||
return testObject(data, true);
|
||||
}
|
||||
|
||||
function mixin (target, source) {
|
||||
Object.keys(source).forEach(function (key) {
|
||||
target[key] = source[key];
|
||||
});
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public modifier `assert`.
|
||||
*
|
||||
* Throws if `predicate` returns false.
|
||||
*/
|
||||
function assertModifier (predicate, defaultMessage) {
|
||||
return function () {
|
||||
return assertPredicate(predicate, arguments, defaultMessage);
|
||||
};
|
||||
}
|
||||
|
||||
function assertPredicate (predicate, args, defaultMessage) {
|
||||
var argCount = predicate.l || predicate.length;
|
||||
var message = args[argCount];
|
||||
var ErrorType = args[argCount + 1];
|
||||
assertImpl(
|
||||
predicate.apply(null, args),
|
||||
nonEmptyString(message) ? message : defaultMessage,
|
||||
isFunction(ErrorType) ? ErrorType : TypeError
|
||||
);
|
||||
return args[0];
|
||||
}
|
||||
|
||||
function assertImpl (value, message, ErrorType) {
|
||||
if (value) {
|
||||
return value;
|
||||
}
|
||||
throw new (ErrorType || Error)(message || 'Assertion failed');
|
||||
}
|
||||
|
||||
/**
|
||||
* Public modifier `not`.
|
||||
*
|
||||
* Negates `predicate`.
|
||||
*/
|
||||
function notModifier (predicate) {
|
||||
var modifiedPredicate = function () {
|
||||
return notImpl(predicate.apply(null, arguments));
|
||||
};
|
||||
modifiedPredicate.l = predicate.length;
|
||||
return modifiedPredicate;
|
||||
}
|
||||
|
||||
function notImpl (value) {
|
||||
return !value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public modifier `maybe`.
|
||||
*
|
||||
* Returns true if predicate argument is null or undefined,
|
||||
* otherwise propagates the return value from `predicate`.
|
||||
*/
|
||||
function maybeModifier (predicate) {
|
||||
var modifiedPredicate = function () {
|
||||
if (not.assigned(arguments[0])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return predicate.apply(null, arguments);
|
||||
};
|
||||
modifiedPredicate.l = predicate.length;
|
||||
|
||||
// Hackishly indicate that this is a maybe.xxx predicate.
|
||||
// Without this flag, the alternative would be to iterate
|
||||
// through the maybe predicates or use indexOf to check,
|
||||
// which would be time-consuming.
|
||||
modifiedPredicate.m = true;
|
||||
|
||||
return modifiedPredicate;
|
||||
}
|
||||
|
||||
function maybeImpl (value) {
|
||||
if (assigned(value) === false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public modifier `of`.
|
||||
*
|
||||
* Applies the chained predicate to members of the collection.
|
||||
*/
|
||||
function ofModifier (target, type, predicate) {
|
||||
var modifiedPredicate = function () {
|
||||
var collection, args;
|
||||
|
||||
collection = arguments[0];
|
||||
|
||||
if (target === 'maybe' && not.assigned(collection)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!type(collection)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
collection = coerceCollection(type, collection);
|
||||
args = slice.call(arguments, 1);
|
||||
|
||||
try {
|
||||
collection.forEach(function (item) {
|
||||
if (
|
||||
(target !== 'maybe' || assigned(item)) &&
|
||||
!predicate.apply(null, [ item ].concat(args))
|
||||
) {
|
||||
// TODO: Replace with for...of when ES6 is required.
|
||||
throw 0;
|
||||
}
|
||||
});
|
||||
} catch (ignore) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
modifiedPredicate.l = predicate.length;
|
||||
return modifiedPredicate;
|
||||
}
|
||||
|
||||
function coerceCollection (type, collection) {
|
||||
switch (type) {
|
||||
case arrayLike:
|
||||
return slice.call(collection);
|
||||
case object:
|
||||
return Object.keys(collection).map(function (key) {
|
||||
return collection[key];
|
||||
});
|
||||
default:
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
|
||||
function createModifiedPredicates (modifier, object) {
|
||||
return createModifiedFunctions([ modifier, predicates, object ]);
|
||||
}
|
||||
|
||||
function createModifiedFunctions (args) {
|
||||
var modifier, object, functions, result;
|
||||
|
||||
modifier = args.shift();
|
||||
object = args.pop();
|
||||
functions = args.pop();
|
||||
|
||||
result = object || {};
|
||||
|
||||
Object.keys(functions).forEach(function (key) {
|
||||
Object.defineProperty(result, key, {
|
||||
configurable: false,
|
||||
enumerable: true,
|
||||
writable: false,
|
||||
value: modifier.apply(null, args.concat(functions[key], messages[key]))
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function createModifiedModifier (modifier, modified) {
|
||||
return createModifiedFunctions([ modifier, modified, null ]);
|
||||
}
|
||||
|
||||
function createOfPredicates (key) {
|
||||
predicates[key].of = createModifiedFunctions(
|
||||
[ ofModifier.bind(null, null), predicates[key], predicates, null ]
|
||||
);
|
||||
}
|
||||
|
||||
function createOfModifiers (base, modifier) {
|
||||
collections.forEach(function (key) {
|
||||
base[key].of = createModifiedModifier(modifier, predicates[key].of);
|
||||
});
|
||||
}
|
||||
|
||||
function createMaybeOfModifiers (key) {
|
||||
maybe[key].of = createModifiedFunctions(
|
||||
[ ofModifier.bind(null, 'maybe'), predicates[key], predicates, null ]
|
||||
);
|
||||
assert.maybe[key].of = createModifiedModifier(assertModifier, maybe[key].of);
|
||||
assert.not[key].of = createModifiedModifier(assertModifier, not[key].of);
|
||||
}
|
||||
|
||||
function exportFunctions (functions) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(function () {
|
||||
return functions;
|
||||
});
|
||||
} else if (typeof module !== 'undefined' && module !== null && module.exports) {
|
||||
module.exports = functions;
|
||||
} else {
|
||||
globals.check = functions;
|
||||
}
|
||||
}
|
||||
}(this));
|
||||
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user