-
Notifications
You must be signed in to change notification settings - Fork 430
Expand file tree
/
Copy pathjavaExtensionAPI.test.ts
More file actions
144 lines (132 loc) · 5.66 KB
/
Copy pathjavaExtensionAPI.test.ts
File metadata and controls
144 lines (132 loc) · 5.66 KB
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
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
import * as assert from "assert";
import * as path from "path";
import * as vscode from "vscode";
import { IProgressReporter } from "../src/progressAPI";
import { getJavaExtensionAPI, getJavaHome } from "../src/utility";
suite("Java extension API activation", () => {
const api = { javaRequirement: { java_home: path.join("test-jdk") } };
let activation: Promise<typeof api>;
let resolveActivation: (value: typeof api) => void;
let rejectActivation: (error: Error) => void;
let activateCalls: number;
let source: vscode.CancellationTokenSource;
let listenerCount: number;
let progress: IProgressReporter;
let restoreExtension: () => void;
setup(() => {
activation = new Promise((resolve, reject) => {
resolveActivation = resolve;
rejectActivation = reject;
});
activateCalls = 0;
source = new vscode.CancellationTokenSource();
listenerCount = 0;
const token: vscode.CancellationToken = {
get isCancellationRequested() { return source.token.isCancellationRequested; },
onCancellationRequested: (listener) => {
listenerCount += 1;
const registration = source.token.onCancellationRequested(listener);
return new vscode.Disposable(() => {
listenerCount -= 1;
registration.dispose();
});
},
};
progress = {
setJobName: () => { },
getId: () => "test",
getProgressLocation: () => vscode.ProgressLocation.Notification,
report: () => { },
show: () => { },
hide: () => { },
isCancelled: () => token.isCancellationRequested,
done: () => source.cancel(),
getCancellationToken: () => token,
observe: () => { },
};
const extensionPath = path.resolve(__dirname, "../..");
const extension: vscode.Extension<typeof api> = {
id: "redhat.java",
extensionPath,
extensionUri: vscode.Uri.file(extensionPath),
isActive: false,
packageJSON: {},
extensionKind: vscode.ExtensionKind.Workspace,
exports: api,
activate() {
activateCalls += 1;
return activation;
},
};
const descriptor = Object.getOwnPropertyDescriptor(vscode.extensions, "getExtension");
assert.ok(descriptor);
Object.defineProperty(vscode.extensions, "getExtension", {
...descriptor,
value: (id: string) => {
assert.strictEqual(id, "redhat.java");
return extension;
},
});
restoreExtension = () => Object.defineProperty(vscode.extensions, "getExtension", descriptor);
});
teardown(async () => {
resolveActivation(api);
await new Promise((resolve) => setImmediate(resolve));
restoreExtension();
source.dispose();
});
test("propagates activation rejection instead of leaving getJavaHome pending", async () => {
const error = new Error("Java activation failed");
const rejected = assert.rejects(getJavaHome(), (actual: unknown) => actual === error);
rejectActivation(error);
await rejected;
assert.strictEqual(activateCalls, 1);
});
test("reads the Java tooling home from the activated API", async () => {
const home = getJavaHome();
resolveActivation(api);
assert.strictEqual(await home, api.javaRequirement.java_home);
});
test("removes the cancellation listener after successful activation", async () => {
const result = Promise.resolve(getJavaExtensionAPI(progress));
assert.strictEqual(listenerCount, 1);
resolveActivation(api);
assert.strictEqual(await result, api);
assert.strictEqual(listenerCount, 0);
});
test("propagates activation failure with progress and removes its listener", async () => {
const error = new Error("Java activation failed with progress");
const rejected = assert.rejects(Promise.resolve(getJavaExtensionAPI(progress)), (actual: unknown) => actual === error);
rejectActivation(error);
await rejected;
assert.strictEqual(listenerCount, 0);
});
test("does not activate Java for an already cancelled caller", async () => {
source.cancel();
assert.strictEqual(await getJavaExtensionAPI(progress), undefined);
assert.strictEqual(activateCalls, 0);
assert.strictEqual(listenerCount, 0);
});
test("cancels one caller without cancelling another caller's activation", async () => {
const cancelled = Promise.resolve(getJavaExtensionAPI(progress));
const other = Promise.resolve(getJavaExtensionAPI());
let otherSettled = false;
void other.then(() => { otherSettled = true; });
source.cancel();
assert.strictEqual(await cancelled, undefined);
assert.strictEqual(otherSettled, false);
assert.strictEqual(listenerCount, 0);
resolveActivation(api);
assert.strictEqual(await other, api);
});
test("handles a late activation rejection after caller cancellation", async () => {
const cancelled = Promise.resolve(getJavaExtensionAPI(progress));
source.cancel();
assert.strictEqual(await cancelled, undefined);
rejectActivation(new Error("Late activation failure"));
await new Promise((resolve) => setImmediate(resolve));
assert.strictEqual(listenerCount, 0);
});
});