-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.js
106 lines (84 loc) · 2.61 KB
/
test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import test from 'ava';
import delay from 'delay';
import inRange from 'in-range';
import timeSpan from 'time-span';
import randomInt from 'random-int';
import m from '.';
test('keys: 2, concurrency: 1', async t => {
const input = [
['a', 'a1', 300],
['a', 'a2', 200],
['a', 'a3', 100],
['b', 'b1', 310],
['b', 'b2', 210],
['b', 'b3', 110]
];
const resultEvaluationOrder = [];
const end = timeSpan();
const limit = m(1);
const mapper = ([key, val, ms]) => limit(key, () => delay(ms).then(() => {
resultEvaluationOrder.push(val);
return val;
}));
t.deepEqual(await Promise.all(input.map(mapper)), ['a1', 'a2', 'a3', 'b1', 'b2', 'b3']);
t.deepEqual(resultEvaluationOrder, ['a1', 'b1', 'a2', 'b2', 'a3', 'b3']);
t.true(inRange(end(), 620, 690));
});
test('keys: 4, concurrency: 5', async t => {
const concurrency = 5;
const runnings = [0, 0, 0, 0];
const limit = m(concurrency);
const input = Array.from({length: 100}, (_ignore, index) => limit(index % 4, async () => {
runnings[index % 4]++;
t.true(runnings[index % 4] <= concurrency);
await delay(randomInt(30, 200));
runnings[index % 4]--;
}));
await Promise.all(input);
});
test('non-promise returning function', async t => {
await t.notThrows(async () => {
const limit = m(1);
await limit('mykey', () => null);
});
});
test('continues after sync throw', async t => {
const limit = m(1);
let ranSameKey = false;
let ranOtherKey = false;
const promises = [
limit('mykey', () => {
throw new Error('err');
}),
limit('mykey', () => {
ranSameKey = true;
}),
limit('myotherkey', () => {
ranOtherKey = true;
})
];
await Promise.all(promises).catch(() => {});
t.is(ranSameKey && ranOtherKey, true);
});
test('accepts additional arguments', async t => {
const limit = m(1);
const symbol = Symbol('test');
await limit('mykey', a => t.is(a, symbol), symbol);
});
test('tests value of getSize', async t => {
const limit = m(5);
await Promise.all(['key1', 'key2', 'key3'].map(async key => {
t.is(limit.getSize(key), 0);
const runningPromise1 = limit(key, () => delay(1000));
t.is(limit.getSize(key), 1);
await runningPromise1;
t.is(limit.getSize(key), 0);
const immediatePromises = Array.from({length: 5}, () => limit(key, () => delay(1000)));
const delayedPromises = Array.from({length: 3}, () => limit(key, () => delay(1000)));
t.is(limit.getSize(key), 5 + 3);
await Promise.all(immediatePromises);
t.is(limit.getSize(key), 3);
await Promise.all(delayedPromises);
t.is(limit.getSize(key), 0);
}));
});