feat(predicates): not
operator
This commit is contained in:
parent
389a765825
commit
ed76fa5141
@ -1,7 +1,7 @@
|
|||||||
`undefined` predicates are ignored and `undefined` is returned if all predicates are `undefined`, this permits the most efficient composition:
|
`undefined` predicates are ignored and `undefined` is returned if all predicates are `undefined`, this permits the most efficient composition:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const compositePredicate = every(undefined, some(predicate2, undefined))
|
const compositePredicate = not(every(undefined, some(not(predicate2), undefined)))
|
||||||
|
|
||||||
// ends up as
|
// ends up as
|
||||||
|
|
||||||
@ -36,6 +36,21 @@ isBetween3And10(10)
|
|||||||
// → false
|
// → false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `not(predicate)`
|
||||||
|
|
||||||
|
> Returns a predicate that returns the negation of the predicate.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const isEven = n => n % 2 === 0
|
||||||
|
const isOdd = not(isEven)
|
||||||
|
|
||||||
|
isOdd(1)
|
||||||
|
// true
|
||||||
|
|
||||||
|
isOdd(2)
|
||||||
|
// false
|
||||||
|
```
|
||||||
|
|
||||||
### `some(predicates)`
|
### `some(predicates)`
|
||||||
|
|
||||||
> Returns a predicate that returns `true` iff some predicate returns `true`.
|
> Returns a predicate that returns `true` iff some predicate returns `true`.
|
||||||
|
@ -19,7 +19,7 @@ Installation of the [npm package](https://npmjs.org/package/@vates/predicates):
|
|||||||
`undefined` predicates are ignored and `undefined` is returned if all predicates are `undefined`, this permits the most efficient composition:
|
`undefined` predicates are ignored and `undefined` is returned if all predicates are `undefined`, this permits the most efficient composition:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const compositePredicate = every(undefined, some(predicate2, undefined))
|
const compositePredicate = not(every(undefined, some(not(predicate2), undefined)))
|
||||||
|
|
||||||
// ends up as
|
// ends up as
|
||||||
|
|
||||||
@ -54,6 +54,21 @@ isBetween3And10(10)
|
|||||||
// → false
|
// → false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `not(predicate)`
|
||||||
|
|
||||||
|
> Returns a predicate that returns the negation of the predicate.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const isEven = n => n % 2 === 0
|
||||||
|
const isOdd = not(isEven)
|
||||||
|
|
||||||
|
isOdd(1)
|
||||||
|
// true
|
||||||
|
|
||||||
|
isOdd(2)
|
||||||
|
// false
|
||||||
|
```
|
||||||
|
|
||||||
### `some(predicates)`
|
### `some(predicates)`
|
||||||
|
|
||||||
> Returns a predicate that returns `true` iff some predicate returns `true`.
|
> Returns a predicate that returns `true` iff some predicate returns `true`.
|
||||||
|
@ -51,6 +51,22 @@ exports.every = function every() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const notPredicateTag = {}
|
||||||
|
exports.not = function not(predicate) {
|
||||||
|
if (isDefinedPredicate(predicate)) {
|
||||||
|
if (predicate.tag === notPredicateTag) {
|
||||||
|
return predicate.predicate
|
||||||
|
}
|
||||||
|
|
||||||
|
function notPredicate() {
|
||||||
|
return !predicate.apply(this, arguments)
|
||||||
|
}
|
||||||
|
notPredicate.predicate = predicate
|
||||||
|
notPredicate.tag = notPredicateTag
|
||||||
|
return notPredicate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exports.some = function some() {
|
exports.some = function some() {
|
||||||
const predicates = handleArgs.apply(this, arguments)
|
const predicates = handleArgs.apply(this, arguments)
|
||||||
const n = predicates.length
|
const n = predicates.length
|
||||||
|
@ -3,20 +3,14 @@
|
|||||||
const assert = require('assert/strict')
|
const assert = require('assert/strict')
|
||||||
const { describe, it } = require('tap').mocha
|
const { describe, it } = require('tap').mocha
|
||||||
|
|
||||||
const { every, some } = require('./')
|
const { every, not, some } = require('./')
|
||||||
|
|
||||||
const T = () => true
|
const T = () => true
|
||||||
const F = () => false
|
const F = () => false
|
||||||
|
|
||||||
const testArgsHandling = fn => {
|
const testArgHandling = fn => {
|
||||||
it('returns undefined if all predicates are undefined', () => {
|
it('returns undefined if predicate is undefined', () => {
|
||||||
assert.equal(fn(undefined), undefined)
|
assert.equal(fn(undefined), undefined)
|
||||||
assert.equal(fn([undefined]), undefined)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('returns the predicate if only a single one is passed', () => {
|
|
||||||
assert.equal(fn(undefined, T), T)
|
|
||||||
assert.equal(fn([undefined, T]), T)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('throws if it receives a non-predicate', () => {
|
it('throws if it receives a non-predicate', () => {
|
||||||
@ -24,6 +18,15 @@ const testArgsHandling = fn => {
|
|||||||
error.value = 3
|
error.value = 3
|
||||||
assert.throws(() => fn(3), error)
|
assert.throws(() => fn(3), error)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const testArgsHandling = fn => {
|
||||||
|
testArgHandling(fn)
|
||||||
|
|
||||||
|
it('returns the predicate if only a single one is passed', () => {
|
||||||
|
assert.equal(fn(undefined, T), T)
|
||||||
|
assert.equal(fn([undefined, T]), T)
|
||||||
|
})
|
||||||
|
|
||||||
it('forwards this and arguments to predicates', () => {
|
it('forwards this and arguments to predicates', () => {
|
||||||
const thisArg = 'qux'
|
const thisArg = 'qux'
|
||||||
@ -36,17 +39,21 @@ const testArgsHandling = fn => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const runTests = (fn, truthTable) =>
|
const runTests = (fn, acceptMultiple, truthTable) =>
|
||||||
it('works', () => {
|
it('works', () => {
|
||||||
truthTable.forEach(([result, ...predicates]) => {
|
truthTable.forEach(([result, ...predicates]) => {
|
||||||
assert.equal(fn(...predicates)(), result)
|
if (acceptMultiple) {
|
||||||
assert.equal(fn(predicates)(), result)
|
assert.equal(fn(predicates)(), result)
|
||||||
|
} else {
|
||||||
|
assert.equal(predicates.length, 1)
|
||||||
|
}
|
||||||
|
assert.equal(fn(...predicates)(), result)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('every', () => {
|
describe('every', () => {
|
||||||
testArgsHandling(every)
|
testArgsHandling(every)
|
||||||
runTests(every, [
|
runTests(every, true, [
|
||||||
[true, T, T],
|
[true, T, T],
|
||||||
[false, T, F],
|
[false, T, F],
|
||||||
[false, F, T],
|
[false, F, T],
|
||||||
@ -54,9 +61,22 @@ describe('every', () => {
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('not', () => {
|
||||||
|
testArgHandling(not)
|
||||||
|
|
||||||
|
it('returns the original predicate if negated twice', () => {
|
||||||
|
assert.equal(not(not(T)), T)
|
||||||
|
})
|
||||||
|
|
||||||
|
runTests(not, false, [
|
||||||
|
[true, F],
|
||||||
|
[false, T],
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
describe('some', () => {
|
describe('some', () => {
|
||||||
testArgsHandling(some)
|
testArgsHandling(some)
|
||||||
runTests(some, [
|
runTests(some, true, [
|
||||||
[true, T, T],
|
[true, T, T],
|
||||||
[true, T, F],
|
[true, T, F],
|
||||||
[true, F, T],
|
[true, F, T],
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
- @vates/nbd-client major
|
- @vates/nbd-client major
|
||||||
- @vates/otp major
|
- @vates/otp major
|
||||||
|
- @vates/predicates minor
|
||||||
- @vates/read-chunk patch
|
- @vates/read-chunk patch
|
||||||
- @xen-orchestra/fs minor
|
- @xen-orchestra/fs minor
|
||||||
- @xen-orchestra/log minor
|
- @xen-orchestra/log minor
|
||||||
|
Loading…
Reference in New Issue
Block a user