Skip to content

Commit

Permalink
feat: implement none
Browse files Browse the repository at this point in the history
  • Loading branch information
customcommander committed Oct 27, 2021
1 parent 28cc3a4 commit 0530a94
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module.exports = {
* @param {function(?): boolean} pred Predicate
* @param {Array|Object|string} xs List of values
* @returns {boolean}
* @see none
*/
all: curry((pred, xs) => {
for (let [_, v] of iter(xs)) if (pred(v) !== true) return false;
Expand Down
44 changes: 44 additions & 0 deletions src/none.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* @license MIT
* @copyright (c) 2021 Julien Gonzalez <hello@spinjs.com>
*/

const iter = require('./_iterable');
const {curry} = require('./curry');

/**
* @namespace
* @alias ROOT
*/
module.exports = {
/**
* True if all elements of `xs` didn't satisfy predicate `pred`.
* Otherwise returns false as soon as one did.
*
* @example
* > Check that a list does not contain any 'x'
*
* ```javascript
* const no_x = none(x => x === 'x');
*
* no_x(['a','b','c']); //=> true
* no_x(['a','x','c']); //=> false
*
* no_x('abc'); //=> true
* no_x('axc'); //=> false
*
* no_x({m: 'a', n: 'b', o: 'c'}); //=> true
* no_x({m: 'a', n: 'x', o: 'c'}); //=> false
* ```
*
* @public
* @param {function(?): boolean} pred Predicate
* @param {Array|Object|string} xs List of values
* @returns {boolean}
* @see all
*/
none: curry((pred, xs) => {
for (let [_, v] of iter(xs)) if (pred(v) === true) return false;
return true;
})
};
66 changes: 66 additions & 0 deletions test/none.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const td = require('testdouble');
const test = require('tape');
const {none: sut} = require('..');

test('none(pred)(xs) -> true when xs is empty', t => {
const f = td.func();
t.same(sut(f)([]), true);
t.same(sut(f)(""), true);
t.same(sut(f)({}), true);
td.verify(f(), {times: 0, ignoreExtraArgs: true});
t.end();
});

test('none(pred)(xs) -> true if pred(x) returned false for all x', t => {
const f = td.func();
const g = td.func();
const h = td.func();
td.when(f(1)).thenReturn(false);
td.when(f(2)).thenReturn(false);
td.when(g(4)).thenReturn(false);
td.when(g(5)).thenReturn(false);
td.when(h("🥑")).thenReturn(false);
td.when(h("🌯")).thenReturn(false);
t.same(sut(f)([1, 2]), true);
t.same(sut(g)({a: 4, b: 5}), true);
t.same(sut(h)("🥑🌯"), true);
td.verify(f(), {times: 2, ignoreExtraArgs: true});
td.verify(g(), {times: 2, ignoreExtraArgs: true});
td.verify(h(), {times: 2, ignoreExtraArgs: true});
t.end();
});

test('none(pred)(xs) -> false if pred(x) returned true (not truthy) for any x', t => {
const f = td.func();
const g = td.func();
const h = td.func();
td.when(f(1)).thenReturn(true);
td.when(g(4)).thenReturn(true);
td.when(h("🥑")).thenReturn(true);
t.same(sut(f)([1, 2]), false);
t.same(sut(g)({a: 4, b: 5}), false);
t.same(sut(h)("🥑🌯"), false);
td.verify(f(), {times: 1, ignoreExtraArgs: true});
td.verify(g(), {times: 1, ignoreExtraArgs: true});
td.verify(h(), {times: 1, ignoreExtraArgs: true});
t.end();
});

test('none(pred)(xs) -> true even if pred(x) returned truthy for all x', t => {
const f = td.func();
const g = td.func();
const h = td.func();
td.when(f(1)).thenReturn(1);
td.when(f(2)).thenReturn([]);
td.when(g(4)).thenReturn('true');
td.when(g(5)).thenReturn({});
td.when(h("🥑")).thenReturn(10);
td.when(h("🌯")).thenReturn(20);
t.same(sut(f)([1, 2]), true);
t.same(sut(g)({a: 4, b: 5}), true);
t.same(sut(h)("🥑🌯"), true);
td.verify(f(), {times: 2, ignoreExtraArgs: true});
td.verify(g(), {times: 2, ignoreExtraArgs: true});
td.verify(h(), {times: 2, ignoreExtraArgs: true});
t.end();
});

0 comments on commit 0530a94

Please sign in to comment.