Skip to content

Commit 26b3cbe

Browse files
committed
Add everyStrict util
1 parent 25d9113 commit 26b3cbe

File tree

5 files changed

+154
-0
lines changed

5 files changed

+154
-0
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ A collection of array-related async utilities.
1616
### Table of contents
1717

1818
* [`asyncEvery()`](#asyncEvery)
19+
* [`asyncEveryStrict()`](#asyncEveryStrict)
1920
* [`asyncFilter()`](#asyncFilter)
2021
* [`asyncFilterStrict()`](#asyncFilterStrict)
2122
* [`asyncForEach()`](#asyncForEach)
@@ -30,6 +31,8 @@ A collection of array-related async utilities.
3031

3132
Tests whether all elements in the array pass the test implemented by the provided asynchronous function. It returns a Boolean value.
3233

34+
Note: For optimization purposes, all iterations are ran concurrently. If you rely on any side effects, consider `asyncEveryStrict()` instead.
35+
3336
#### Sample usage
3437

3538
```js
@@ -38,6 +41,26 @@ import { asyncEvery } from '@wojtekmaj/async-array-utils';
3841
const largerThanZero = await asyncEvery([1, 2, 3], async (el) => el > 0); // true
3942
```
4043

44+
### `asyncEveryStrict()`
45+
46+
Like `asyncEvery()`, but runs iterations non-concurrently.
47+
48+
#### Sample usage
49+
50+
```js
51+
import { asyncEveryStrict } from '@wojtekmaj/async-array-utils';
52+
53+
const indexes = [];
54+
const largerThanZero = await asyncEveryStrict(
55+
[1, 2, 3],
56+
async (el, index) => {
57+
indexes.push(index);
58+
return el > 0;
59+
},
60+
); // true
61+
console.log(indexes); // [0, 1, 2]
62+
```
63+
4164
### `asyncFilter()`
4265

4366
Creates a new array with all elements that pass the test implemented by the provided asynchronous function.

src/every_strict.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import asyncForEachStrict from './forEach_strict';
2+
3+
export default function asyncEveryStrict(arr, fn) {
4+
return new Promise((resolve) => {
5+
// eslint-disable-next-line no-shadow
6+
asyncForEachStrict(arr, async (cur, idx, arr) => {
7+
const result = await fn(cur, idx, arr);
8+
9+
if (!result) {
10+
resolve(false);
11+
}
12+
}).then(() => {
13+
resolve(true);
14+
});
15+
});
16+
}

src/every_strict.spec.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import asyncEveryStrict from './every_strict';
2+
3+
import {
4+
doubleInputArr,
5+
inputArr,
6+
largerThanOneHundred,
7+
largerThanOneHundredInRandomTime,
8+
makePushDuplicate,
9+
makePushDuplicateInRandomTime,
10+
} from '../test-utils';
11+
12+
function largerOrEqualThanZero(x) {
13+
return x >= 0;
14+
}
15+
16+
function largerOrEqualThanZeroInRandomTime(x) {
17+
return new Promise(
18+
(resolve) => setTimeout(() => {
19+
resolve(x >= 0);
20+
}, Math.random() * 100),
21+
);
22+
}
23+
24+
describe('asyncEvery()', () => {
25+
it.skip('assertions below are valid for synchronous .every()', () => {
26+
const mapper = jest.fn().mockImplementation(largerOrEqualThanZero);
27+
28+
inputArr.every(mapper);
29+
30+
expect.assertions(1 + inputArr.length);
31+
32+
expect(mapper).toHaveBeenCalledTimes(inputArr.length);
33+
inputArr.forEach((el, idx) => {
34+
expect(mapper).toHaveBeenCalledWith(el, idx, inputArr);
35+
});
36+
});
37+
38+
it('iterates over values properly', async () => {
39+
const mapper = jest.fn().mockImplementation(largerOrEqualThanZeroInRandomTime);
40+
41+
await asyncEveryStrict(inputArr, mapper);
42+
43+
expect.assertions(1 + inputArr.length);
44+
45+
expect(mapper).toHaveBeenCalledTimes(inputArr.length);
46+
inputArr.forEach((el, idx) => {
47+
expect(mapper).toHaveBeenCalledWith(el, idx, inputArr);
48+
});
49+
});
50+
51+
it.skip('assertions below are valid for synchronous .every()', () => {
52+
const [arr, pushDuplicate] = makePushDuplicate();
53+
const mapper = jest.fn().mockImplementation((el) => {
54+
pushDuplicate(el);
55+
return largerOrEqualThanZero(el);
56+
});
57+
58+
inputArr.every(mapper);
59+
60+
expect(mapper).toHaveBeenCalledTimes(inputArr.length);
61+
expect(arr).toEqual(doubleInputArr);
62+
});
63+
64+
it('iterates through an array properly with side effects', async () => {
65+
const [arr, pushDuplicate] = makePushDuplicateInRandomTime();
66+
const mapper = jest.fn().mockImplementation(async (el) => {
67+
await pushDuplicate(el);
68+
return largerOrEqualThanZero(el);
69+
});
70+
71+
await asyncEveryStrict(inputArr, mapper);
72+
73+
expect(mapper).toHaveBeenCalledTimes(inputArr.length);
74+
expect(arr).toEqual(doubleInputArr);
75+
});
76+
77+
it.skip('assertions below are valid for synchronous .every()', () => {
78+
const mapper = jest.fn().mockImplementation(largerOrEqualThanZero);
79+
80+
const result = inputArr.every(mapper);
81+
82+
expect(result).toEqual(true);
83+
});
84+
85+
it('returns truthy result properly', async () => {
86+
const mapper = jest.fn().mockImplementation(largerOrEqualThanZeroInRandomTime);
87+
88+
const result = await asyncEveryStrict(inputArr, mapper);
89+
90+
expect(result).toEqual(true);
91+
});
92+
93+
it.skip('assertions below are valid for synchronous .every()', () => {
94+
const mapper = jest.fn().mockImplementation(largerThanOneHundred);
95+
96+
const result = inputArr.every(mapper);
97+
98+
expect(result).toEqual(false);
99+
});
100+
101+
it('returns falsy result properly', async () => {
102+
const mapper = jest.fn().mockImplementation(largerThanOneHundredInRandomTime);
103+
104+
const result = await asyncEveryStrict(inputArr, mapper);
105+
106+
expect(result).toEqual(false);
107+
});
108+
});

src/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import asyncFilterStrict from './filter_strict';
33
import asyncForEach from './forEach';
44
import asyncForEachStrict from './forEach_strict';
55
import asyncEvery from './every';
6+
import asyncEveryStrict from './every_strict';
67
import asyncMap from './map';
78
import asyncMapStrict from './map_strict';
89
import asyncReduce from './reduce';
@@ -15,6 +16,7 @@ export {
1516
asyncForEach,
1617
asyncForEachStrict,
1718
asyncEvery,
19+
asyncEveryStrict,
1820
asyncMap,
1921
asyncMapStrict,
2022
asyncReduce,

src/index.spec.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
asyncForEach,
55
asyncForEachStrict,
66
asyncEvery,
7+
asyncEveryStrict,
78
asyncMap,
89
asyncMapStrict,
910
asyncReduce,
@@ -32,6 +33,10 @@ describe('index', () => {
3233
expect(asyncEvery).toBeInstanceOf(Function);
3334
});
3435

36+
it('has asyncEveryStrict exported properly', () => {
37+
expect(asyncEveryStrict).toBeInstanceOf(Function);
38+
});
39+
3540
it('has asyncMap exported properly', () => {
3641
expect(asyncMap).toBeInstanceOf(Function);
3742
});

0 commit comments

Comments
 (0)