Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/gitpod-protocol/src/util/queue.spec.ts
2500 views
1
/* eslint-disable @typescript-eslint/no-unsafe-argument */
2
/* eslint-disable @typescript-eslint/no-floating-promises */
3
/**
4
* Copyright (c) 2020 Gitpod GmbH. All rights reserved.
5
* Licensed under the GNU Affero General Public License (AGPL).
6
* See License.AGPL.txt in the project root for license information.
7
*/
8
9
import { suite, test, slow, timeout } from "@testdeck/mocha";
10
import * as chai from "chai";
11
const chaiSubset = require("chai-subset");
12
chai.use(chaiSubset);
13
14
import { Queue } from "..";
15
import { fail } from "assert";
16
import { Deferred } from "./deferred";
17
18
const expect = chai.expect;
19
20
@suite
21
class QueueSpec {
22
queue: Queue;
23
seq: number[];
24
25
before() {
26
this.queue = new Queue();
27
this.seq = [];
28
}
29
30
async exec(seqNr: number, nextTick: boolean = false, sleep: number = 0) {
31
return this.queue.enqueue(async () => {
32
const push = async () => {
33
if (sleep > 0)
34
return new Promise((resolve) => {
35
setTimeout(() => {
36
this.seq.push(seqNr);
37
resolve(undefined);
38
}, sleep);
39
});
40
else this.seq.push(seqNr);
41
};
42
43
if (nextTick)
44
return new Promise((resolve) => {
45
process.nextTick(() => {
46
push().then(resolve);
47
});
48
});
49
else await push();
50
});
51
}
52
execError(seqNr: number): Deferred<boolean> {
53
const deferred = new Deferred<boolean>();
54
this.queue
55
.enqueue(async () => {
56
this.seq.push(seqNr);
57
throw new Error("test error");
58
})
59
.then(() => {
60
deferred.reject(false);
61
})
62
.catch(() => {
63
deferred.resolve(true);
64
});
65
66
return deferred;
67
}
68
69
protected expectArray<T>(actual: T[], expected: T[]) {
70
expect(actual).to.have.lengthOf(expected.length);
71
const expIt = expected.entries();
72
for (const act of actual) {
73
const {
74
value: [, exp],
75
} = expIt.next();
76
expect(act).to.deep.equal(exp);
77
}
78
}
79
80
@test public async isExecutedInOrder() {
81
this.exec(1);
82
await this.exec(2);
83
84
this.expectArray(this.seq, [1, 2]);
85
}
86
87
@test public async isExecutedInOrderSkipTick() {
88
this.exec(1, true);
89
await this.exec(2);
90
91
this.expectArray(this.seq, [1, 2]);
92
}
93
94
@test @timeout(3000) @slow(3000) public async isExecutedInOrderSleep() {
95
this.exec(1, false, 2000);
96
await this.exec(2);
97
98
this.expectArray(this.seq, [1, 2]);
99
}
100
101
@test public async continueDespiteError() {
102
this.exec(1);
103
const receivedError = this.execError(2);
104
await this.exec(3);
105
106
expect(receivedError.isResolved).to.equal(true);
107
expect(await receivedError.promise).to.equal(true);
108
this.expectArray(this.seq, [1, 2, 3]);
109
}
110
111
@test public async mustCatchError() {
112
const f = async () => {
113
throw new Error();
114
};
115
try {
116
const p = this.queue.enqueue(async () => {
117
return f();
118
});
119
120
p.catch((err) => {
121
// Silence unhandled promise rejection messages
122
});
123
} catch (err) {
124
fail("We expect to catch no error");
125
}
126
}
127
128
@test public async expectUncaughtError() {
129
const f = async () => {
130
throw new Error();
131
};
132
const p = this.queue.enqueue(async () => {
133
return f();
134
});
135
p.then((r) => {
136
fail("Expected to catch error!");
137
}).catch((err) => {
138
// Silence unhandled promise rejection messages
139
});
140
}
141
}
142
module.exports = new QueueSpec();
143
144