Skip to content

Commit fab82a0

Browse files
authored
Introduce smoke test for TS Plugin + Loose Mode (#807)
* start building out smoke test * test that basic loose mode diagnostic shows up
1 parent 0cf6210 commit fab82a0

File tree

2 files changed

+112
-4
lines changed

2 files changed

+112
-4
lines changed

packages/vscode/__tests__/support/launch-from-cli.mts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@ const emptyUserDataDir = path.join(os.tmpdir(), `user-data-${Math.random()}`);
1010
const settingsDir = path.join(emptyUserDataDir, 'User');
1111
fs.mkdirSync(settingsDir, { recursive: true });
1212

13-
const userPreferences = {
13+
const userPreferences: Record<string, any> = {
1414
// When testing TS Plugin, it can be useful to look at tsserver logs within
1515
// the test runner VSCode instance. To do this, uncomment the following line,
1616
// and then check the logs for TypeScript
17-
// "typescript.tsserver.log": "verbose",
17+
// 'typescript.tsserver.log': 'verbose',
1818
};
1919

20-
fs.writeFileSync(path.join(settingsDir, 'settings.json'), JSON.stringify(userPreferences, null, 2));
21-
2220
const testType = process.argv[2];
2321

2422
let disableExtensionArgs: string[] = [];
@@ -34,13 +32,17 @@ switch (testType) {
3432
case 'ts-plugin':
3533
testRunner = 'lib/__tests__/support/vscode-runner-ts-plugin.js';
3634

35+
userPreferences['glint.server.hybridMode'] = true;
36+
3737
// Note: here, we WANT vanilla TS to be enabled since we're testing the TS Plugin.
3838
break;
3939
default:
4040
console.error('Test type must be either "language-server" or "ts-plugin"');
4141
process.exit(1);
4242
}
4343

44+
fs.writeFileSync(path.join(settingsDir, 'settings.json'), JSON.stringify(userPreferences, null, 2));
45+
4446
try {
4547
runTests({
4648
extensionDevelopmentPath: packageRoot,
@@ -60,6 +62,7 @@ try {
6062
`${packageRoot}/__fixtures__/ember-app`,
6163
`${packageRoot}/__fixtures__/template-imports-app`,
6264
`${packageRoot}/__fixtures__/template-imports-app-ts-plugin`,
65+
`${packageRoot}/__fixtures__/ember-app-loose-and-gts`,
6366
],
6467
});
6568
} catch (error) {
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import {
2+
commands,
3+
languages,
4+
ViewColumn,
5+
window,
6+
Uri,
7+
Range,
8+
Position,
9+
CodeAction,
10+
workspace,
11+
TextEditor,
12+
} from 'vscode';
13+
import * as path from 'path';
14+
import { describe, afterEach, test } from 'mocha';
15+
import { expect } from 'expect';
16+
import { waitUntil } from '../helpers/async';
17+
18+
describe('Smoke test: Loose Mode + GTS with TS Plugin Mode', () => {
19+
const rootDir = path.resolve(__dirname, '../../../__fixtures__/ember-app-loose-and-gts');
20+
21+
afterEach(async () => {
22+
while (window.activeTextEditor) {
23+
await commands.executeCommand('workbench.action.files.revert');
24+
await commands.executeCommand('workbench.action.closeActiveEditor');
25+
}
26+
});
27+
28+
describe.only('loose mode aka ts + hbs two-file components', () => {
29+
describe('diagnostics', () => {
30+
test('adds missing args from template into Args type', async () => {
31+
let scriptURI = Uri.file(`${rootDir}/app/components/colocated-layout-with-errors.hbs`);
32+
33+
// Open the script and the template
34+
let scriptEditor = await window.showTextDocument(scriptURI, { viewColumn: ViewColumn.One });
35+
36+
// Wait for a diagnostic to appear in the template
37+
await waitUntil(() => languages.getDiagnostics(scriptURI).length);
38+
39+
expect(languages.getDiagnostics(scriptURI)).toMatchObject([
40+
{
41+
message:
42+
"Property 'messageeee' does not exist on type 'ColocatedLayoutComponent'. Did you mean 'message'?",
43+
source: 'ts-plugin',
44+
code: 2551,
45+
},
46+
]);
47+
});
48+
});
49+
});
50+
});
51+
52+
/**
53+
* It takes a little while for the TS Plugin to fully activate, and unfortunately
54+
* VSCode won't automatically re-trigger/re-calculate diagnostics for a file after
55+
* a TS Plugin kicks in, so we need some way to know that the TS Plugin is activated
56+
* before we edit the file.
57+
*
58+
* To accomplish this, this function inserts invalid TS into the .gts file and waits
59+
* for diagnostics to show up.
60+
*/
61+
async function hackishlyWaitForTypescriptPluginToActivate(
62+
scriptEditor: TextEditor,
63+
scriptURI: Uri,
64+
): Promise<void> {
65+
let invalidAssignment = 'let s: string = 123;';
66+
await scriptEditor.edit((edit) => {
67+
edit.insert(new Position(0, 0), invalidAssignment);
68+
});
69+
70+
let numSpacesAdded = 0;
71+
const startTime = Date.now();
72+
73+
// eslint-disable-next-line no-constant-condition
74+
while (true) {
75+
await scriptEditor.edit((edit) => {
76+
edit.insert(new Position(0, 0), ' ');
77+
});
78+
numSpacesAdded++;
79+
80+
if (languages.getDiagnostics(scriptURI).length) {
81+
break;
82+
}
83+
84+
if (Date.now() - startTime > 5000) {
85+
throw new Error(
86+
'Timed out waiting for TS Plugin to activate (i.e. waiting for diagnostics to show up)',
87+
);
88+
}
89+
90+
// We'd love to wait for a smaller increment than 1000 but the editor
91+
// debounces before triggering diagnostics so we need a large enough time.
92+
await new Promise((resolve) => setTimeout(resolve, 1000));
93+
}
94+
95+
// Remove our invalid assignment
96+
await scriptEditor.edit((edit) => {
97+
edit.replace(new Range(0, 0, 0, invalidAssignment.length + numSpacesAdded), '');
98+
});
99+
100+
await new Promise((resolve) => setTimeout(resolve, 1000));
101+
102+
if (languages.getDiagnostics(scriptURI).length) {
103+
throw new Error('Diagnostics still showing up after removing invalid assignment');
104+
}
105+
}

0 commit comments

Comments
 (0)