Skip to content

Commit bac7e2e

Browse files
committed
Add tests
1 parent 0964dbf commit bac7e2e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+7924
-11
lines changed

package-lock.json

Lines changed: 1989 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/tailwindcss-language-server/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
"clean": "rimraf bin",
1919
"hashbang": "node scripts/hashbang.mjs",
2020
"create-notices-file": "node scripts/createNoticesFile.mjs",
21-
"prepublishOnly": "npm run build"
21+
"prepublishOnly": "npm run build",
22+
"test": "vitest",
23+
"test:prepare": "node tests/prepare.js"
2224
},
2325
"bin": {
2426
"tailwindcss-language-server": "./bin/tailwindcss-language-server"
@@ -65,7 +67,9 @@
6567
"stack-trace": "0.0.10",
6668
"tailwindcss": "3.3.0",
6769
"typescript": "4.6.4",
70+
"vitest": "0.34.2",
6871
"vscode-css-languageservice": "5.4.1",
72+
"vscode-jsonrpc": "8.1.0",
6973
"vscode-languageserver": "8.0.2",
7074
"vscode-languageserver-textdocument": "1.0.7",
7175
"vscode-uri": "3.0.2"

packages/tailwindcss-language-server/src/server.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,10 +1200,13 @@ async function createProjectService(
12001200
URI.file(path.resolve(path.dirname(URI.parse(document.uri).fsPath), linkPath)).toString()
12011201
)
12021202
},
1203-
provideDiagnostics: debounce((document: TextDocument) => {
1204-
if (!state.enabled) return
1205-
provideDiagnostics(state, document)
1206-
}, 500),
1203+
provideDiagnostics: debounce(
1204+
(document: TextDocument) => {
1205+
if (!state.enabled) return
1206+
provideDiagnostics(state, document)
1207+
},
1208+
params.initializationOptions?.testMode ? 0 : 500
1209+
),
12071210
provideDiagnosticsForce: (document: TextDocument) => {
12081211
if (!state.enabled) return
12091212
provideDiagnostics(state, document)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { test, expect } from 'vitest'
2+
import * as fs from 'node:fs/promises'
3+
import { withFixture } from '../common'
4+
5+
withFixture('basic', (c) => {
6+
function testFixture(fixture) {
7+
test(fixture, async () => {
8+
fixture = await fs.readFile(`tests/code-actions/${fixture}.json`, 'utf8')
9+
10+
let { code, expected, language = 'html' } = JSON.parse(fixture)
11+
12+
let promise = new Promise((resolve) => {
13+
c.onNotification('textDocument/publishDiagnostics', ({ diagnostics }) => {
14+
resolve(diagnostics)
15+
})
16+
})
17+
18+
let textDocument = await c.openDocument({ text: code, lang: language })
19+
let diagnostics = await promise
20+
21+
let res = await c.sendRequest('textDocument/codeAction', {
22+
textDocument,
23+
context: {
24+
diagnostics,
25+
},
26+
})
27+
// console.log(JSON.stringify(res))
28+
29+
expected = JSON.parse(JSON.stringify(expected).replaceAll('{{URI}}', textDocument.uri))
30+
31+
expect(res).toEqual(expected)
32+
})
33+
}
34+
35+
testFixture('conflict')
36+
testFixture('invalid-theme')
37+
testFixture('invalid-screen')
38+
})
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { test, expect } from 'vitest'
2+
import { withFixture } from '../common'
3+
import * as fs from 'node:fs/promises'
4+
5+
withFixture('v2-jit', (c) => {
6+
function testFixture(fixture) {
7+
test(fixture, async () => {
8+
fixture = await fs.readFile(`tests/code-actions/${fixture}.json`, 'utf8')
9+
10+
let { code, expected, language = 'html' } = JSON.parse(fixture)
11+
12+
let promise = new Promise((resolve) => {
13+
c.onNotification('textDocument/publishDiagnostics', ({ diagnostics }) => {
14+
resolve(diagnostics)
15+
})
16+
})
17+
18+
let textDocument = await c.openDocument({ text: code, lang: language })
19+
let diagnostics = await promise
20+
21+
let res = await c.sendRequest('textDocument/codeAction', {
22+
textDocument,
23+
context: {
24+
diagnostics,
25+
},
26+
})
27+
// console.log(JSON.stringify(res))
28+
29+
expected = JSON.parse(JSON.stringify(expected).replaceAll('{{URI}}', textDocument.uri))
30+
31+
expect(res).toEqual(expected)
32+
})
33+
}
34+
35+
testFixture('variant-order')
36+
})
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { test, expect } from 'vitest'
2+
import { withFixture } from '../common'
3+
import * as fs from 'node:fs/promises'
4+
5+
withFixture('v2', (c) => {
6+
function testFixture(fixture) {
7+
test(fixture, async () => {
8+
fixture = await fs.readFile(`tests/code-actions/${fixture}.json`, 'utf8')
9+
10+
let { code, expected, language = 'html' } = JSON.parse(fixture)
11+
12+
let promise = new Promise((resolve) => {
13+
c.onNotification('textDocument/publishDiagnostics', ({ diagnostics }) => {
14+
resolve(diagnostics)
15+
})
16+
})
17+
18+
let textDocument = await c.openDocument({ text: code, lang: language })
19+
let diagnostics = await promise
20+
21+
let res = await c.sendRequest('textDocument/codeAction', {
22+
textDocument,
23+
context: {
24+
diagnostics,
25+
},
26+
})
27+
// console.log(JSON.stringify(res))
28+
29+
expected = JSON.parse(JSON.stringify(expected).replaceAll('{{URI}}', textDocument.uri))
30+
31+
expect(res).toEqual(expected)
32+
})
33+
}
34+
35+
// testFixture('conflict')
36+
testFixture('invalid-theme')
37+
testFixture('invalid-screen')
38+
testFixture('invalid-variant')
39+
})
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
{
2+
"code": "<div class=\"lowercase uppercase\">",
3+
"expected": [
4+
{
5+
"title": "Delete 'uppercase'",
6+
"kind": "quickfix",
7+
"diagnostics": [
8+
{
9+
"code": "cssConflict",
10+
"className": {
11+
"className": "lowercase",
12+
"classList": {
13+
"classList": "lowercase uppercase",
14+
"range": {
15+
"start": { "line": 0, "character": 12 },
16+
"end": { "line": 0, "character": 31 }
17+
}
18+
},
19+
"relativeRange": {
20+
"start": { "line": 0, "character": 0 },
21+
"end": { "line": 0, "character": 9 }
22+
},
23+
"range": {
24+
"start": { "line": 0, "character": 12 },
25+
"end": { "line": 0, "character": 21 }
26+
}
27+
},
28+
"otherClassNames": [
29+
{
30+
"className": "uppercase",
31+
"classList": {
32+
"classList": "lowercase uppercase",
33+
"range": {
34+
"start": { "line": 0, "character": 12 },
35+
"end": { "line": 0, "character": 31 }
36+
}
37+
},
38+
"relativeRange": {
39+
"start": { "line": 0, "character": 10 },
40+
"end": { "line": 0, "character": 19 }
41+
},
42+
"range": {
43+
"start": { "line": 0, "character": 22 },
44+
"end": { "line": 0, "character": 31 }
45+
}
46+
}
47+
],
48+
"range": {
49+
"start": { "line": 0, "character": 12 },
50+
"end": { "line": 0, "character": 21 }
51+
},
52+
"severity": 2,
53+
"message": "'lowercase' applies the same CSS properties as 'uppercase'.",
54+
"relatedInformation": [
55+
{
56+
"message": "uppercase",
57+
"location": {
58+
"uri": "{{URI}}",
59+
"range": {
60+
"start": { "line": 0, "character": 22 },
61+
"end": { "line": 0, "character": 31 }
62+
}
63+
}
64+
}
65+
]
66+
}
67+
],
68+
"edit": {
69+
"changes": {
70+
"{{URI}}": [
71+
{
72+
"range": {
73+
"start": { "line": 0, "character": 12 },
74+
"end": { "line": 0, "character": 31 }
75+
},
76+
"newText": "lowercase"
77+
}
78+
]
79+
}
80+
}
81+
},
82+
{
83+
"title": "Delete 'lowercase'",
84+
"kind": "quickfix",
85+
"diagnostics": [
86+
{
87+
"code": "cssConflict",
88+
"className": {
89+
"className": "uppercase",
90+
"classList": {
91+
"classList": "lowercase uppercase",
92+
"range": {
93+
"start": { "line": 0, "character": 12 },
94+
"end": { "line": 0, "character": 31 }
95+
}
96+
},
97+
"relativeRange": {
98+
"start": { "line": 0, "character": 10 },
99+
"end": { "line": 0, "character": 19 }
100+
},
101+
"range": {
102+
"start": { "line": 0, "character": 22 },
103+
"end": { "line": 0, "character": 31 }
104+
}
105+
},
106+
"otherClassNames": [
107+
{
108+
"className": "lowercase",
109+
"classList": {
110+
"classList": "lowercase uppercase",
111+
"range": {
112+
"start": { "line": 0, "character": 12 },
113+
"end": { "line": 0, "character": 31 }
114+
}
115+
},
116+
"relativeRange": {
117+
"start": { "line": 0, "character": 0 },
118+
"end": { "line": 0, "character": 9 }
119+
},
120+
"range": {
121+
"start": { "line": 0, "character": 12 },
122+
"end": { "line": 0, "character": 21 }
123+
}
124+
}
125+
],
126+
"range": {
127+
"start": { "line": 0, "character": 22 },
128+
"end": { "line": 0, "character": 31 }
129+
},
130+
"severity": 2,
131+
"message": "'uppercase' applies the same CSS properties as 'lowercase'.",
132+
"relatedInformation": [
133+
{
134+
"message": "lowercase",
135+
"location": {
136+
"uri": "{{URI}}",
137+
"range": {
138+
"start": { "line": 0, "character": 12 },
139+
"end": { "line": 0, "character": 21 }
140+
}
141+
}
142+
}
143+
]
144+
}
145+
],
146+
"edit": {
147+
"changes": {
148+
"{{URI}}": [
149+
{
150+
"range": {
151+
"start": { "line": 0, "character": 12 },
152+
"end": { "line": 0, "character": 31 }
153+
},
154+
"newText": "uppercase"
155+
}
156+
]
157+
}
158+
}
159+
}
160+
]
161+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"code": "@screen small",
3+
"language": "css",
4+
"expected": [
5+
{
6+
"title": "Replace with 'sm'",
7+
"kind": "quickfix",
8+
"diagnostics": [
9+
{
10+
"code": "invalidScreen",
11+
"range": {
12+
"start": { "line": 0, "character": 8 },
13+
"end": { "line": 0, "character": 13 }
14+
},
15+
"severity": 1,
16+
"message": "The screen 'small' does not exist in your theme config. Did you mean 'sm'?",
17+
"suggestions": ["sm"]
18+
}
19+
],
20+
"edit": {
21+
"changes": {
22+
"{{URI}}": [
23+
{
24+
"range": {
25+
"start": { "line": 0, "character": 8 },
26+
"end": { "line": 0, "character": 13 }
27+
},
28+
"newText": "sm"
29+
}
30+
]
31+
}
32+
}
33+
}
34+
]
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"code": ".test { color: theme(colors.red.901) }",
3+
"language": "css",
4+
"expected": [
5+
{
6+
"title": "Replace with 'colors.red.900'",
7+
"kind": "quickfix",
8+
"diagnostics": [
9+
{
10+
"code": "invalidConfigPath",
11+
"range": {
12+
"start": { "line": 0, "character": 21 },
13+
"end": { "line": 0, "character": 35 }
14+
},
15+
"severity": 1,
16+
"message": "'colors.red.901' does not exist in your theme config. Did you mean 'colors.red.900'?",
17+
"suggestions": ["colors.red.900"]
18+
}
19+
],
20+
"edit": {
21+
"changes": {
22+
"{{URI}}": [
23+
{
24+
"range": {
25+
"start": { "line": 0, "character": 21 },
26+
"end": { "line": 0, "character": 35 }
27+
},
28+
"newText": "colors.red.900"
29+
}
30+
]
31+
}
32+
}
33+
}
34+
]
35+
}

0 commit comments

Comments
 (0)