Skip to content

Commit b50534b

Browse files
authored
feat(nxls): add clickable links for projects (#2901)
1 parent 4f464d2 commit b50534b

File tree

4 files changed

+455
-7
lines changed

4 files changed

+455
-7
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import {
2+
e2eCwd,
3+
modifyJsonFile,
4+
newWorkspace,
5+
simpleReactWorkspaceOptions,
6+
uniq,
7+
} from '@nx-console/shared-e2e-utils';
8+
import { readFileSync, writeFileSync } from 'fs';
9+
import { join } from 'path';
10+
import { Position } from 'vscode-languageserver';
11+
import { URI } from 'vscode-uri';
12+
import { NxlsWrapper } from '../nxls-wrapper';
13+
14+
let nxlsWrapper: NxlsWrapper;
15+
const workspaceName = uniq('workspace');
16+
const e2eProjectName = 'e2e';
17+
18+
const projectJsonPath = join(e2eCwd, workspaceName, 'project.json');
19+
const e2eProjectJsonPath = join(e2eCwd, workspaceName, 'e2e', 'project.json');
20+
21+
describe('document link completion - project links', () => {
22+
beforeAll(async () => {
23+
newWorkspace({
24+
name: workspaceName,
25+
options: simpleReactWorkspaceOptions,
26+
});
27+
28+
writeFileSync(
29+
e2eProjectJsonPath,
30+
JSON.stringify(
31+
{
32+
implicitDependencies: [workspaceName],
33+
},
34+
null,
35+
2,
36+
),
37+
);
38+
39+
nxlsWrapper = new NxlsWrapper(true);
40+
await nxlsWrapper.startNxls(join(e2eCwd, workspaceName));
41+
42+
nxlsWrapper.sendNotification({
43+
method: 'textDocument/didOpen',
44+
params: {
45+
textDocument: {
46+
uri: URI.file(e2eProjectJsonPath).toString(),
47+
languageId: 'JSON',
48+
version: 1,
49+
text: readFileSync(e2eProjectJsonPath, 'utf-8'),
50+
},
51+
},
52+
});
53+
});
54+
55+
afterAll(async () => {
56+
await nxlsWrapper.stopNxls();
57+
});
58+
59+
describe('project links', () => {
60+
it('should return correct link for valid project in implicitDependencies', async () => {
61+
modifyJsonFile(e2eProjectJsonPath, (data) => ({
62+
...data,
63+
implicitDependencies: [workspaceName],
64+
}));
65+
66+
nxlsWrapper.sendNotification({
67+
method: 'textDocument/didChange',
68+
params: {
69+
textDocument: {
70+
uri: URI.file(e2eProjectJsonPath).toString(),
71+
languageId: 'JSON',
72+
version: 2,
73+
},
74+
contentChanges: [
75+
{
76+
text: readFileSync(e2eProjectJsonPath, 'utf-8'),
77+
},
78+
],
79+
},
80+
});
81+
82+
const linkResponse = await nxlsWrapper.sendRequest({
83+
method: 'textDocument/documentLink',
84+
params: {
85+
textDocument: {
86+
uri: URI.file(e2eProjectJsonPath).toString(),
87+
},
88+
position: Position.create(1, 4),
89+
},
90+
});
91+
92+
const projectLink = (linkResponse.result as any[])[0]?.target;
93+
expect(projectLink).toBeDefined();
94+
expect(decodeURI(projectLink)).toContain(projectJsonPath);
95+
expect(projectLink).toMatch(/#1$/);
96+
});
97+
98+
it('should return correct link for project with ! prefix in implicitDependencies', async () => {
99+
modifyJsonFile(e2eProjectJsonPath, (data) => ({
100+
...data,
101+
implicitDependencies: [`!${workspaceName}`],
102+
}));
103+
104+
nxlsWrapper.sendNotification({
105+
method: 'textDocument/didChange',
106+
params: {
107+
textDocument: {
108+
uri: URI.file(e2eProjectJsonPath).toString(),
109+
languageId: 'JSON',
110+
version: 3,
111+
},
112+
contentChanges: [
113+
{
114+
text: readFileSync(e2eProjectJsonPath, 'utf-8'),
115+
},
116+
],
117+
},
118+
});
119+
120+
const linkResponse = await nxlsWrapper.sendRequest({
121+
method: 'textDocument/documentLink',
122+
params: {
123+
textDocument: {
124+
uri: URI.file(e2eProjectJsonPath).toString(),
125+
},
126+
position: Position.create(1, 4),
127+
},
128+
});
129+
130+
const projectLink = (linkResponse.result as any[])[0]?.target;
131+
expect(projectLink).toBeDefined();
132+
expect(decodeURI(projectLink)).toContain(projectJsonPath);
133+
expect(projectLink).toMatch(/#1$/);
134+
});
135+
136+
it('should not return link for non-existent project in implicitDependencies', async () => {
137+
modifyJsonFile(e2eProjectJsonPath, (data) => ({
138+
...data,
139+
implicitDependencies: ['non-existent-project'],
140+
}));
141+
142+
nxlsWrapper.sendNotification({
143+
method: 'textDocument/didChange',
144+
params: {
145+
textDocument: {
146+
uri: URI.file(e2eProjectJsonPath).toString(),
147+
languageId: 'JSON',
148+
version: 4,
149+
},
150+
contentChanges: [
151+
{
152+
text: readFileSync(e2eProjectJsonPath, 'utf-8'),
153+
},
154+
],
155+
},
156+
});
157+
158+
const linkResponse = await nxlsWrapper.sendRequest({
159+
method: 'textDocument/documentLink',
160+
params: {
161+
textDocument: {
162+
uri: URI.file(e2eProjectJsonPath).toString(),
163+
},
164+
position: Position.create(1, 4),
165+
},
166+
});
167+
168+
const links = linkResponse.result as any[];
169+
expect(links).toEqual([]);
170+
});
171+
});
172+
});

0 commit comments

Comments
 (0)