-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
_rate_limitter_test.ts
103 lines (96 loc) · 2.92 KB
/
_rate_limitter_test.ts
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
import {
assertAlmostEquals,
assertEquals,
assertRejects,
assertThrows,
} from "@std/assert";
import { RateLimitter } from "./_rate_limitter.ts";
Deno.test("RateLimitter", async (t) => {
await t.step("fromResponse returns a new RateLimitter instance", () => {
const reset = Date.now() + 1000;
const resp = new Response("", {
headers: {
"X-RateLimit-Limit": "100",
"X-RateLimit-Remaining": "99",
"X-RateLimit-Reset": reset.toString(),
},
});
const rateLimitter = RateLimitter.fromResponse(resp);
assertEquals(rateLimitter.reset, reset);
});
await t.step(
"fromResponse throws Error when X-RateLimit-Reset header is missing",
() => {
const resp = new Response("", {
headers: {
"X-RateLimit-Limit": "100",
"X-RateLimit-Remaining": "99",
},
});
assertThrows(() => RateLimitter.fromResponse(resp), Error);
},
);
await t.step(
"fromResponse throws Error when X-RateLimit-Reset header is invalid",
() => {
const resp = new Response("", {
headers: {
"X-RateLimit-Limit": "100",
"X-RateLimit-Remaining": "99",
"X-RateLimit-Reset": "invalid",
},
});
assertThrows(() => RateLimitter.fromResponse(resp), Error);
},
);
await t.step(
"wait waits until the reset time has passed",
async () => {
const rateLimitter = new RateLimitter(Date.now() + 100);
const start = performance.now();
await rateLimitter.wait();
const diff = performance.now() - start;
assertAlmostEquals(diff, 100, 10);
},
);
await t.step(
"wait immediately return when the reset time is past",
async () => {
const rateLimitter = new RateLimitter(Date.now() - 100);
const start = performance.now();
await rateLimitter.wait();
const diff = performance.now() - start;
assertAlmostEquals(diff, 0, 10);
},
);
await t.step(
"wait immediately rejects an error when the signal is already aborted",
async () => {
const controller = new AbortController();
controller.abort();
const rateLimitter = new RateLimitter(Date.now() + 500);
const start = performance.now();
await assertRejects(
() => rateLimitter.wait({ signal: controller.signal }),
DOMException,
);
const diff = performance.now() - start;
assertAlmostEquals(diff, 0, 10);
},
);
await t.step(
"wait rejects an error when the signal is aborted",
async () => {
const controller = new AbortController();
const rateLimitter = new RateLimitter(Date.now() + 500);
const start = performance.now();
setTimeout(() => controller.abort(), 100);
await assertRejects(
() => rateLimitter.wait({ signal: controller.signal }),
DOMException,
);
const diff = performance.now() - start;
assertAlmostEquals(diff, 100, 10);
},
);
});