-
Notifications
You must be signed in to change notification settings - Fork 1
/
unpromise.test.ts
157 lines (137 loc) · 4.08 KB
/
unpromise.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* eslint-disable @typescript-eslint/promise-function-async */
import { describe, test, expect } from "vitest";
import { Unpromise } from "../src/unpromise";
function sleep(delayMs: number) {
return new Promise((resolve) => setTimeout(resolve, delayMs));
}
function createComplianceSuite(
wrapper: <T>(promise: Promise<T>) => Promise<T>,
wrapperDescription: string
) {
describe(`${wrapperDescription} Promise<T> compliance`, () => {
test(`${wrapperDescription} resolves (subscribed)`, async () => {
// create Unpromise immediately (don't give promise a chance to settle)
const wrapped = wrapper(sleep(1).then(() => "foo"));
// should resolve like CONTROL
expect(await wrapped).toBe("foo");
});
test(`${wrapperDescription} resolves (settled)`, async () => {
// create promise
const promise = sleep(1).then(() => "foo");
// allow it to settle
await promise;
// create Unpromise from settled promise
const wrapped = wrapper(promise);
// should resolve like CONTROL
expect(await wrapped).toBe("foo");
});
test(`${wrapperDescription} rejects (subscribed)`, async () => {
// create Unpromise immediately (without underlying promise having time to settle)
const unpromise = wrapper(
sleep(1).then(() => {
throw new Error("bar");
})
);
try {
await unpromise;
} catch (error) {
// should reject like CONTROL
expect(error).toEqual(new Error("bar"));
}
});
test(`${wrapperDescription} rejects (settled)`, async () => {
// create promise
const promise = sleep(1).then(() => {
throw new Error("bar");
});
// allow it to settle
try {
await promise;
} catch (error) {
// ignore error
}
// then create Unpromise
const unpromise = wrapper(promise);
try {
await unpromise;
} catch (error) {
// should reject like CONTROL
expect(error).toEqual(new Error("bar"));
}
});
test(`${wrapperDescription} finally - then condition (subscribed)`, async () => {
let finallyCalled = false;
try {
await wrapper(sleep(1));
} catch (error) {
// do nothing - error is expected
} finally {
finallyCalled = true;
}
expect(finallyCalled).toBe(true);
});
test(`${wrapperDescription} finally - catch condition (subscribed)`, async () => {
let finallyCalled = false;
try {
await wrapper(
sleep(1).then(() => {
throw new Error("bar");
})
);
} catch (error) {
// do nothing - error is expected
} finally {
finallyCalled = true;
}
expect(finallyCalled).toBe(true);
});
test(`${wrapperDescription} finally - then condition (settled)`, async () => {
// create promise
const promise = sleep(1);
// allow promise to settle
await promise;
let finallyCalled = false;
try {
await wrapper(promise);
} catch (error) {
// do nothing - error is expected
} finally {
finallyCalled = true;
}
expect(finallyCalled).toBe(true);
});
test(`${wrapperDescription} finally - catch condition (settled)`, async () => {
const promise = sleep(1).then(() => {
throw new Error("bar");
});
try {
await promise;
} catch (error) {
// error is expected
}
let finallyCalled = false;
try {
await wrapper(promise);
} catch (error) {
// do nothing - error is expected
} finally {
finallyCalled = true;
}
expect(finallyCalled).toBe(true);
});
});
}
describe("Unpromise compliance", () => {
createComplianceSuite(
<T>(promise: Promise<T>) => promise,
"Promise (CONTROL)"
);
createComplianceSuite(
<T>(promise: Promise<T>) => Unpromise.get(promise),
"Unpromise.get(promise)"
);
createComplianceSuite(
<T>(promise: Promise<T>) => Unpromise.resolve(promise),
"Unpromise.resolve(promise)"
);
});