-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsmoke.js
More file actions
87 lines (81 loc) · 3.29 KB
/
smoke.js
File metadata and controls
87 lines (81 loc) · 3.29 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
// Smoke-test for the bundled extension. Stubs the `vscode` module
// (which is supplied by the editor at runtime and isn't installable
// from npm), loads `dist/extension.js`, and asserts the bundle exposes
// the activate/deactivate contract VS Code requires.
//
// This is what would have caught the "missing vscode-languageclient at
// runtime" regression: a successful `vsce package` is not the same as
// a loadable extension. Run as `npm run smoke`.
const Module = require("module");
// Just enough surface for vscode-languageclient + our activate path to
// load. We don't actually exercise it — loading is the test, since
// load-time failures are how a missing dep would surface in production.
// Anything we didn't enumerate falls through to a generic class stub so
// `class X extends vscode.CompletionItem` etc. don't throw.
//
// Constructible classes that the SUT calls at *module load time* — not
// just inside a function — must be declared here, because esbuild's
// `__toESM` namespace wrapper enumerates own keys at load time and a
// Proxy's dynamic get is invisible to that enumeration. The two below
// come from findingsView.ts's top-level SEVERITY_ICON table; the
// CodeActionKind constant is consumed by codeActions.ts's static
// `providedCodeActionKinds = [vscode.CodeActionKind.QuickFix]` field
// initializer — the Proxy default of "return a class" would resolve
// `vscode.CodeActionKind` to a class with no `.QuickFix` property and
// crash the load.
class StubThemeIcon {}
class StubThemeColor {}
const known = {
ThemeIcon: StubThemeIcon,
ThemeColor: StubThemeColor,
CodeActionKind: {
QuickFix: { value: "quickfix" },
Empty: { value: "" },
Refactor: { value: "refactor" },
RefactorExtract: { value: "refactor.extract" },
RefactorInline: { value: "refactor.inline" },
RefactorRewrite: { value: "refactor.rewrite" },
Source: { value: "source" },
SourceOrganizeImports: { value: "source.organizeImports" },
},
commands: {
registerCommand: () => ({ dispose: () => undefined }),
},
window: {
showErrorMessage: async () => undefined,
showInformationMessage: async () => undefined,
createOutputChannel: () => ({ show: () => undefined, dispose: () => undefined }),
},
workspace: {
getConfiguration: () => ({ get: (_key, fallback) => fallback }),
},
env: {
clipboard: { writeText: async () => undefined },
},
};
const vscodeStub = new Proxy(known, {
get(target, prop) {
if (prop in target) return target[prop];
// Default: a class so `class X extends vscode.Y` works for the
// languageclient's deep imports (CompletionItem, Diagnostic, etc.).
target[prop] = class StubVSCodeMember {};
return target[prop];
},
});
const originalLoad = Module._load;
Module._load = function patchedLoad(request, ...rest) {
if (request === "vscode") {
return vscodeStub;
}
return originalLoad.call(this, request, ...rest);
};
const bundle = require("../dist/extension.js");
if (typeof bundle.activate !== "function") {
console.error("Bundle smoke FAILED: activate() not exported");
process.exit(1);
}
if (typeof bundle.deactivate !== "function") {
console.error("Bundle smoke FAILED: deactivate() not exported");
process.exit(1);
}
console.log("Bundle smoke OK: activate/deactivate exported, vscode-languageclient bundled");