Skip to content

Commit 6c91772

Browse files
committed
add command to insert theme-check disable comments and tests
1 parent 089d8c0 commit 6c91772

File tree

4 files changed

+584
-1
lines changed

4 files changed

+584
-1
lines changed

packages/theme-language-server-common/src/commands/ExecuteCommandProvider.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@ import { ClientCapabilities } from '../ClientCapabilities';
33
import { DiagnosticsManager } from '../diagnostics';
44
import { DocumentManager } from '../documents';
55
import { BaseExecuteCommandProvider } from './BaseExecuteCommandProvider';
6-
import { ApplyFixesProvider, ApplySuggestionProvider, RunChecksProvider } from './providers';
6+
import {
7+
ApplyDisableCheckProvider,
8+
ApplyFixesProvider,
9+
ApplySuggestionProvider,
10+
RunChecksProvider,
11+
} from './providers';
712

813
export const Commands = [
14+
ApplyDisableCheckProvider.command,
915
ApplyFixesProvider.command,
1016
ApplySuggestionProvider.command,
1117
RunChecksProvider.command,
@@ -28,6 +34,12 @@ export class ExecuteCommandProvider {
2834
connection: Connection,
2935
) {
3036
this.commands = {
37+
[ApplyDisableCheckProvider.command]: new ApplyDisableCheckProvider(
38+
documentManager,
39+
diagnosticsManager,
40+
clientCapabilities,
41+
connection,
42+
),
3143
[ApplyFixesProvider.command]: new ApplyFixesProvider(
3244
documentManager,
3345
diagnosticsManager,
Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
import { path } from '@shopify/theme-check-common';
2+
import { beforeEach, describe, expect, it, Mock, vi } from 'vitest';
3+
import { URI } from 'vscode-uri';
4+
import { DiagnosticsManager } from '../../diagnostics';
5+
import { DocumentManager } from '../../documents';
6+
import { ApplyDisableCheckProvider } from './ApplyDisableCheckProvider';
7+
8+
describe('Unit: ApplyDisableCheckProvider', () => {
9+
const liquidUri = path.normalize(URI.file('/path/to/file.liquid'));
10+
const liquidContents = `
11+
{% assign x = 1 %}
12+
<script src="2.js"></script>
13+
<script src="3.js"></script>
14+
`;
15+
let connection: { sendRequest: Mock; sendDiagnostics: Mock };
16+
let documentManager: DocumentManager;
17+
let diagnosticsManager: DiagnosticsManager;
18+
let applyDisableCheckProvider: ApplyDisableCheckProvider;
19+
20+
beforeEach(() => {
21+
connection = { sendRequest: vi.fn(), sendDiagnostics: vi.fn() };
22+
documentManager = new DocumentManager();
23+
diagnosticsManager = new DiagnosticsManager(connection as any);
24+
const capabilities = { hasApplyEditSupport: true };
25+
applyDisableCheckProvider = new ApplyDisableCheckProvider(
26+
documentManager,
27+
diagnosticsManager,
28+
capabilities as any,
29+
connection as any,
30+
);
31+
});
32+
33+
describe('execute - Liquid files', () => {
34+
beforeEach(() => {
35+
documentManager.open(liquidUri, liquidContents, 1);
36+
diagnosticsManager.set(liquidUri, 1, []);
37+
});
38+
39+
it('adds disable-next-line comment with proper indentation', async () => {
40+
await applyDisableCheckProvider.execute(liquidUri, 1, 'next-line', 'UnusedAssign', 1);
41+
42+
expect(connection.sendRequest).toHaveBeenCalledWith(expect.anything(), {
43+
edit: {
44+
documentChanges: [
45+
{
46+
textDocument: { uri: liquidUri, version: 1 },
47+
edits: [
48+
{
49+
newText: ' {% # theme-check-disable-next-line UnusedAssign %}\n',
50+
range: {
51+
start: { line: 1, character: 0 },
52+
end: { line: 1, character: 0 },
53+
},
54+
},
55+
],
56+
},
57+
],
58+
},
59+
});
60+
});
61+
62+
it('adds disable comment at top of file for file-level disable', async () => {
63+
await applyDisableCheckProvider.execute(liquidUri, 1, 'file', 'ParserBlockingScript', 0);
64+
65+
expect(connection.sendRequest).toHaveBeenCalledWith(expect.anything(), {
66+
edit: {
67+
documentChanges: [
68+
{
69+
textDocument: { uri: liquidUri, version: 1 },
70+
edits: [
71+
{
72+
newText: '{% # theme-check-disable ParserBlockingScript %}\n',
73+
range: {
74+
start: { line: 0, character: 0 },
75+
end: { line: 0, character: 0 },
76+
},
77+
},
78+
],
79+
},
80+
],
81+
},
82+
});
83+
});
84+
85+
it('handles lines with no indentation', async () => {
86+
const noIndentContents = `{% assign x = 1 %}
87+
<script src="2.js"></script>`;
88+
documentManager.open(liquidUri, noIndentContents, 2);
89+
diagnosticsManager.set(liquidUri, 2, []);
90+
91+
await applyDisableCheckProvider.execute(liquidUri, 2, 'next-line', 'UnusedAssign', 0);
92+
93+
expect(connection.sendRequest).toHaveBeenCalledWith(expect.anything(), {
94+
edit: {
95+
documentChanges: [
96+
{
97+
textDocument: { uri: liquidUri, version: 2 },
98+
edits: [
99+
{
100+
newText: '{% # theme-check-disable-next-line UnusedAssign %}\n',
101+
range: {
102+
start: { line: 0, character: 0 },
103+
end: { line: 0, character: 0 },
104+
},
105+
},
106+
],
107+
},
108+
],
109+
},
110+
});
111+
});
112+
113+
it('preserves tabs in indentation', async () => {
114+
const tabContents = `\t\t{% assign x = 1 %}`;
115+
documentManager.open(liquidUri, tabContents, 3);
116+
diagnosticsManager.set(liquidUri, 3, []);
117+
118+
await applyDisableCheckProvider.execute(liquidUri, 3, 'next-line', 'UnusedAssign', 0);
119+
120+
expect(connection.sendRequest).toHaveBeenCalledWith(expect.anything(), {
121+
edit: {
122+
documentChanges: [
123+
{
124+
textDocument: { uri: liquidUri, version: 3 },
125+
edits: [
126+
{
127+
newText: '\t\t{% # theme-check-disable-next-line UnusedAssign %}\n',
128+
range: {
129+
start: { line: 0, character: 0 },
130+
end: { line: 0, character: 0 },
131+
},
132+
},
133+
],
134+
},
135+
],
136+
},
137+
});
138+
});
139+
140+
it('uses plain comment format inside liquid tags', async () => {
141+
const liquidTagContents = `
142+
{% liquid
143+
assign x = 1
144+
echo x
145+
%}`;
146+
documentManager.open(liquidUri, liquidTagContents, 1);
147+
diagnosticsManager.set(liquidUri, 1, []);
148+
149+
await applyDisableCheckProvider.execute(liquidUri, 1, 'next-line', 'UnusedAssign', 2);
150+
151+
expect(connection.sendRequest).toHaveBeenCalledWith(expect.anything(), {
152+
edit: {
153+
documentChanges: [
154+
{
155+
textDocument: { uri: liquidUri, version: 1 },
156+
edits: [
157+
{
158+
newText: ' # theme-check-disable-next-line UnusedAssign\n',
159+
range: {
160+
start: { line: 2, character: 0 },
161+
end: { line: 2, character: 0 },
162+
},
163+
},
164+
],
165+
},
166+
],
167+
},
168+
});
169+
});
170+
171+
it('uses regular comment format for file-level disable even inside liquid tags', async () => {
172+
const liquidTagContents = `
173+
{% liquid
174+
assign x = 1
175+
echo x
176+
%}`;
177+
documentManager.open(liquidUri, liquidTagContents, 1);
178+
diagnosticsManager.set(liquidUri, 1, []);
179+
180+
// File-level disable should always use regular format
181+
await applyDisableCheckProvider.execute(liquidUri, 1, 'file', 'UnusedAssign', 2);
182+
183+
expect(connection.sendRequest).toHaveBeenCalledWith(expect.anything(), {
184+
edit: {
185+
documentChanges: [
186+
{
187+
textDocument: { uri: liquidUri, version: 1 },
188+
edits: [
189+
{
190+
newText: '{% # theme-check-disable UnusedAssign %}\n',
191+
range: {
192+
start: { line: 0, character: 0 },
193+
end: { line: 0, character: 0 },
194+
},
195+
},
196+
],
197+
},
198+
],
199+
},
200+
});
201+
});
202+
203+
it('appends to existing disable-next-line comment', async () => {
204+
const contentsWithComment = `
205+
{% assign x = 1 %}
206+
{% # theme-check-disable-next-line UnusedAssign %}
207+
<script src="2.js"></script>`;
208+
documentManager.open(liquidUri, contentsWithComment, 1);
209+
diagnosticsManager.set(liquidUri, 1, []);
210+
211+
await applyDisableCheckProvider.execute(liquidUri, 1, 'next-line', 'ParserBlockingScript', 3);
212+
213+
expect(connection.sendRequest).toHaveBeenCalledWith(expect.anything(), {
214+
edit: {
215+
documentChanges: [
216+
{
217+
textDocument: { uri: liquidUri, version: 1 },
218+
edits: [
219+
{
220+
newText:
221+
'{% # theme-check-disable-next-line UnusedAssign, ParserBlockingScript %}',
222+
range: {
223+
start: { line: 2, character: 4 },
224+
end: { line: 2, character: 54 },
225+
},
226+
},
227+
],
228+
},
229+
],
230+
},
231+
});
232+
});
233+
234+
it('appends to existing file-level disable comment', async () => {
235+
const contentsWithComment = `{% # theme-check-disable UnusedAssign %}
236+
{% assign x = 1 %}
237+
<script src="2.js"></script>`;
238+
documentManager.open(liquidUri, contentsWithComment, 1);
239+
diagnosticsManager.set(liquidUri, 1, []);
240+
241+
await applyDisableCheckProvider.execute(liquidUri, 1, 'file', 'ParserBlockingScript', 2);
242+
243+
expect(connection.sendRequest).toHaveBeenCalledWith(expect.anything(), {
244+
edit: {
245+
documentChanges: [
246+
{
247+
textDocument: { uri: liquidUri, version: 1 },
248+
edits: [
249+
{
250+
newText: '{% # theme-check-disable UnusedAssign, ParserBlockingScript %}',
251+
range: {
252+
start: { line: 0, character: 0 },
253+
end: { line: 0, character: 40 },
254+
},
255+
},
256+
],
257+
},
258+
],
259+
},
260+
});
261+
});
262+
263+
it('appends to existing liquid tag disable comment', async () => {
264+
const liquidTagContents = `
265+
{% liquid
266+
# theme-check-disable-next-line UnusedAssign
267+
assign x = 1
268+
echo x
269+
%}`;
270+
documentManager.open(liquidUri, liquidTagContents, 1);
271+
diagnosticsManager.set(liquidUri, 1, []);
272+
273+
await applyDisableCheckProvider.execute(liquidUri, 1, 'next-line', 'LiquidFilter', 3);
274+
275+
expect(connection.sendRequest).toHaveBeenCalledWith(expect.anything(), {
276+
edit: {
277+
documentChanges: [
278+
{
279+
textDocument: { uri: liquidUri, version: 1 },
280+
edits: [
281+
{
282+
newText: '# theme-check-disable-next-line UnusedAssign, LiquidFilter',
283+
range: {
284+
start: { line: 2, character: 2 },
285+
end: { line: 2, character: 46 },
286+
},
287+
},
288+
],
289+
},
290+
],
291+
},
292+
});
293+
});
294+
295+
it('appends to existing disable comment even with blank lines in between', async () => {
296+
const contentsWithBlankLine = `
297+
{% # theme-check-disable-next-line MissingTemplate %}
298+
299+
{% render 'test' %}`;
300+
documentManager.open(liquidUri, contentsWithBlankLine, 1);
301+
diagnosticsManager.set(liquidUri, 1, []);
302+
303+
// Try to disable SyntaxError on line 3
304+
await applyDisableCheckProvider.execute(liquidUri, 1, 'next-line', 'SyntaxError', 3);
305+
306+
expect(connection.sendRequest).toHaveBeenCalledWith(expect.anything(), {
307+
edit: {
308+
documentChanges: [
309+
{
310+
textDocument: { uri: liquidUri, version: 1 },
311+
edits: [
312+
{
313+
newText: '{% # theme-check-disable-next-line MissingTemplate, SyntaxError %}',
314+
range: {
315+
start: { line: 1, character: 4 },
316+
end: { line: 1, character: 57 },
317+
},
318+
},
319+
],
320+
},
321+
],
322+
},
323+
});
324+
});
325+
});
326+
});

0 commit comments

Comments
 (0)