Skip to content

Commit 4b75fe9

Browse files
committed
test: migrate TypeScript tests to @typescript/server-harness
- Add new test directory test/ts/ for TypeScript plugin tests - Tests use @typescript/server-harness to test TypeScript features - Migrate hover, definitions, completions, rename, diagnostics, code-action tests - Update language server tests to remove TypeScript-dependent assertions - Keep basic language server functionality tests - Add test-ts script to run TypeScript plugin tests separately
1 parent bcbd2f7 commit 4b75fe9

12 files changed

Lines changed: 538 additions & 14 deletions

packages/language-server/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
],
2929
"scripts": {
3030
"test-api": "node --test 'test/*.test.js'",
31-
"test": "npm run test-api"
31+
"test-ts": "node --test 'test/ts/*.test.js'",
32+
"test": "npm run test-api && npm run test-ts"
3233
},
3334
"dependencies": {
3435
"@mdx-js/language-service": "0.7.2",

packages/language-server/test/code-action.test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ afterEach(() => {
2626

2727
test('return empty code actions for non-existent file', async () => {
2828
const uri = fixtureUri('node16/non-existent.mdx')
29-
3029
const codeActions = await serverHandle.sendCodeActionsRequest(
3130
uri,
3231
{
@@ -39,6 +38,5 @@ test('return empty code actions for non-existent file', async () => {
3938
triggerKind: CodeActionTriggerKind.Invoked
4039
}
4140
)
42-
4341
assert.deepEqual(codeActions, [])
4442
})

packages/language-server/test/definitions.test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ test('does not resolve shadow content', async () => {
4242
line: 0,
4343
character: 37
4444
})
45-
4645
assert.deepEqual(result, [])
4746
})
4847

@@ -52,6 +51,5 @@ test('ignore non-existent mdx files', async () => {
5251
line: 7,
5352
character: 15
5453
})
55-
5654
assert.deepEqual(result, [])
5755
})

packages/language-server/test/diagnostics.test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ test('parse errors', async () => {
3030
'mdx'
3131
)
3232
const diagnostics = await serverHandle.sendDocumentDiagnosticRequest(uri)
33-
3433
assert.deepEqual(diagnostics, {
3534
kind: 'full',
3635
items: [
@@ -78,7 +77,6 @@ test('does not resolve shadow content', async () => {
7877
'mdx'
7978
)
8079
const diagnostics = await serverHandle.sendDocumentDiagnosticRequest(uri)
81-
8280
assert.deepEqual(diagnostics, {
8381
items: [],
8482
kind: 'full'
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @fileoverview TypeScript code action tests for MDX files
3+
*
4+
* These tests verify that code actions (like organize imports)
5+
* work correctly in MDX files through the TypeScript plugin.
6+
*/
7+
import assert from 'node:assert/strict'
8+
import {after, before, test} from 'node:test'
9+
import {fixturePath, getTsServer} from './server.js'
10+
11+
/** @type {Awaited<ReturnType<typeof getTsServer>>} */
12+
let server
13+
14+
before(async () => {
15+
server = await getTsServer()
16+
})
17+
18+
after(() => {
19+
server.shutdown()
20+
})
21+
22+
test('organize imports', async () => {
23+
const filePath = fixturePath('node16/organize-imports.mdx')
24+
await server.openFile(filePath)
25+
26+
try {
27+
const res = await server.tsserver.message({
28+
seq: server.nextSeq(),
29+
type: 'request',
30+
command: 'organizeImports',
31+
arguments: {
32+
scope: {
33+
type: 'file',
34+
args: {file: filePath}
35+
}
36+
}
37+
})
38+
39+
assert.ok(res.success, 'Request should succeed')
40+
assert.ok(res.body, 'Response should have body')
41+
// Organize imports should return file changes
42+
assert.ok(Array.isArray(res.body), 'Response body should be an array')
43+
} finally {
44+
await server.closeFile(filePath)
45+
}
46+
})
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* @fileoverview TypeScript completion tests for MDX files
3+
*
4+
* These tests verify that code completion works correctly
5+
* in MDX files through the TypeScript plugin.
6+
*/
7+
import assert from 'node:assert/strict'
8+
import {after, before, test} from 'node:test'
9+
import {fixturePath, getTsServer} from './server.js'
10+
11+
/** @type {Awaited<ReturnType<typeof getTsServer>>} */
12+
let server
13+
14+
before(async () => {
15+
server = await getTsServer()
16+
})
17+
18+
after(() => {
19+
server.shutdown()
20+
})
21+
22+
test('support completion in ESM', async () => {
23+
const filePath = fixturePath('node16/completion.mdx')
24+
await server.openFile(filePath)
25+
26+
try {
27+
const res = await server.tsserver.message({
28+
seq: server.nextSeq(),
29+
type: 'request',
30+
command: 'completions',
31+
arguments: {
32+
file: filePath,
33+
line: 2,
34+
offset: 1,
35+
includeExternalModuleExports: true
36+
}
37+
})
38+
39+
assert.ok(res.success, 'Request should succeed')
40+
assert.ok(res.body, 'Response should have body')
41+
assert.ok(res.body.length > 0, 'Should have completions')
42+
43+
const booleanCompletion = res.body.find(
44+
(/** @type {{name: string}} */ c) => c.name === 'Boolean'
45+
)
46+
assert.ok(booleanCompletion, 'Should have Boolean completion')
47+
} finally {
48+
await server.closeFile(filePath)
49+
}
50+
})
51+
52+
test('support completion in JSX', async () => {
53+
const filePath = fixturePath('node16/completion.mdx')
54+
await server.openFile(filePath)
55+
56+
try {
57+
const res = await server.tsserver.message({
58+
seq: server.nextSeq(),
59+
type: 'request',
60+
command: 'completions',
61+
arguments: {
62+
file: filePath,
63+
line: 6,
64+
offset: 3,
65+
includeExternalModuleExports: true
66+
}
67+
})
68+
69+
assert.ok(res.success, 'Request should succeed')
70+
assert.ok(res.body, 'Response should have body')
71+
assert.ok(res.body.length > 0, 'Should have completions')
72+
73+
const booleanCompletion = res.body.find(
74+
(/** @type {{name: string}} */ c) => c.name === 'Boolean'
75+
)
76+
assert.ok(booleanCompletion, 'Should have Boolean completion')
77+
} finally {
78+
await server.closeFile(filePath)
79+
}
80+
})
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @fileoverview TypeScript definition tests for MDX files
3+
*
4+
* These tests verify that go-to-definition works correctly
5+
* in MDX files through the TypeScript plugin.
6+
*/
7+
import assert from 'node:assert/strict'
8+
import {after, before, test} from 'node:test'
9+
import {fixturePath, getTsServer} from './server.js'
10+
11+
/** @type {Awaited<ReturnType<typeof getTsServer>>} */
12+
let server
13+
14+
before(async () => {
15+
server = await getTsServer()
16+
})
17+
18+
after(() => {
19+
server.shutdown()
20+
})
21+
22+
test('resolve file-local definitions in ESM', async () => {
23+
const filePath = fixturePath('node16/a.mdx')
24+
await server.openFile(filePath)
25+
26+
try {
27+
const res = await server.tsserver.message({
28+
seq: server.nextSeq(),
29+
type: 'request',
30+
command: 'definition',
31+
arguments: {
32+
file: filePath,
33+
line: 5,
34+
offset: 3
35+
}
36+
})
37+
38+
assert.ok(res.success, 'Request should succeed')
39+
assert.ok(res.body, 'Response should have body')
40+
assert.ok(res.body.length > 0, 'Should have at least one definition')
41+
42+
const def = res.body[0]
43+
assert.ok(def.file.endsWith('a.mdx'), 'Definition should be in a.mdx')
44+
assert.equal(def.start.line, 2, 'Definition should be on line 2')
45+
} finally {
46+
await server.closeFile(filePath)
47+
}
48+
})
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* @fileoverview TypeScript diagnostics tests for MDX files
3+
*
4+
* These tests verify that TypeScript type errors are correctly
5+
* reported in MDX files through the TypeScript plugin.
6+
*/
7+
import assert from 'node:assert/strict'
8+
import {after, before, test} from 'node:test'
9+
import {fixturePath, getTsServer} from './server.js'
10+
11+
/** @type {Awaited<ReturnType<typeof getTsServer>>} */
12+
let server
13+
14+
before(async () => {
15+
server = await getTsServer()
16+
})
17+
18+
after(() => {
19+
server.shutdown()
20+
})
21+
22+
test('type errors', async () => {
23+
const filePath = fixturePath('node16/type-errors.mdx')
24+
await server.openFile(filePath)
25+
26+
try {
27+
const res = await server.tsserver.message({
28+
seq: server.nextSeq(),
29+
type: 'request',
30+
command: 'semanticDiagnosticsSync',
31+
arguments: {
32+
file: filePath
33+
}
34+
})
35+
36+
assert.ok(res.success, 'Request should succeed')
37+
assert.ok(res.body, 'Response should have body')
38+
// Type errors should be reported
39+
assert.ok(res.body.length > 0, 'Should have type errors')
40+
} finally {
41+
await server.closeFile(filePath)
42+
}
43+
})

0 commit comments

Comments
 (0)