Skip to content

Commit 92f3d3a

Browse files
committed
Fix the tests
1 parent 0c92963 commit 92f3d3a

File tree

2 files changed

+91
-151
lines changed

2 files changed

+91
-151
lines changed
Lines changed: 57 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,74 @@
11
// npx vitest services/tree-sitter/__tests__/languageParser.spec.ts
22

3+
import * as path from "path"
34
import { loadRequiredLanguageParsers } from "../languageParser"
45

5-
vi.mock("web-tree-sitter", () => {
6-
const mockParserInit = vi.fn().mockResolvedValue(undefined)
7-
const mockLanguageLoad = vi.fn().mockResolvedValue({
8-
query: vi.fn().mockReturnValue({ id: "mock-query" }),
6+
// Path to the directory containing the WASM files.
7+
const WASM_DIR = path.join(__dirname, "../../../node_modules/tree-sitter-wasms/out")
8+
9+
describe("loadRequiredLanguageParsers", () => {
10+
it("should load JavaScript parser for .js and .jsx files", async () => {
11+
const files = ["test.js", "test.jsx"]
12+
const parsers = await loadRequiredLanguageParsers(files, WASM_DIR)
13+
expect(parsers.js).toBeDefined()
14+
expect(parsers.jsx).toBeDefined()
15+
expect(parsers.js.query).toBeDefined()
16+
expect(parsers.jsx.query).toBeDefined()
917
})
10-
const mockSetLanguage = vi.fn()
1118

12-
// Create a constructor function that also has static methods
13-
function MockParser() {
14-
return {
15-
setLanguage: mockSetLanguage,
16-
}
17-
}
18-
MockParser.init = mockParserInit
19-
20-
return {
21-
Parser: MockParser,
22-
Language: {
23-
load: mockLanguageLoad,
24-
},
25-
// Export the mocks so tests can access them
26-
__mocks: {
27-
mockParserInit,
28-
mockLanguageLoad,
29-
mockSetLanguage,
30-
},
31-
}
32-
})
33-
34-
// Import the mocked module to get access to the mock functions
35-
const { __mocks } = (await import("web-tree-sitter")) as any
36-
const { mockParserInit, mockLanguageLoad, mockSetLanguage } = __mocks
37-
38-
describe("Language Parser", () => {
39-
beforeEach(() => {
40-
vi.clearAllMocks()
19+
it("should load TypeScript parser for .ts and .tsx files", async () => {
20+
const files = ["test.ts", "test.tsx"]
21+
const parsers = await loadRequiredLanguageParsers(files, WASM_DIR)
22+
expect(parsers.ts).toBeDefined()
23+
expect(parsers.tsx).toBeDefined()
4124
})
4225

43-
describe("loadRequiredLanguageParsers", () => {
44-
it("should initialize parser only once", async () => {
45-
const files = ["test.js", "test2.js"]
46-
await loadRequiredLanguageParsers(files)
47-
await loadRequiredLanguageParsers(files)
48-
49-
expect(mockParserInit).toHaveBeenCalledTimes(1)
50-
})
51-
52-
it("should load JavaScript parser for .js and .jsx files", async () => {
53-
const files = ["test.js", "test.jsx"]
54-
const parsers = await loadRequiredLanguageParsers(files)
55-
56-
expect(mockLanguageLoad).toHaveBeenCalledWith(expect.stringContaining("tree-sitter-javascript.wasm"))
57-
expect(parsers.js).toBeDefined()
58-
expect(parsers.jsx).toBeDefined()
59-
expect(parsers.js.query).toBeDefined()
60-
expect(parsers.jsx.query).toBeDefined()
61-
})
62-
63-
it("should load TypeScript parser for .ts and .tsx files", async () => {
64-
const files = ["test.ts", "test.tsx"]
65-
const parsers = await loadRequiredLanguageParsers(files)
66-
67-
expect(mockLanguageLoad).toHaveBeenCalledWith(expect.stringContaining("tree-sitter-typescript.wasm"))
68-
expect(mockLanguageLoad).toHaveBeenCalledWith(expect.stringContaining("tree-sitter-tsx.wasm"))
69-
expect(parsers.ts).toBeDefined()
70-
expect(parsers.tsx).toBeDefined()
71-
})
72-
73-
it("should load Python parser for .py files", async () => {
74-
const files = ["test.py"]
75-
const parsers = await loadRequiredLanguageParsers(files)
76-
77-
expect(mockLanguageLoad).toHaveBeenCalledWith(expect.stringContaining("tree-sitter-python.wasm"))
78-
expect(parsers.py).toBeDefined()
79-
})
80-
81-
it("should load multiple language parsers as needed", async () => {
82-
const files = ["test.js", "test.py", "test.rs", "test.go"]
83-
const parsers = await loadRequiredLanguageParsers(files)
84-
85-
expect(mockLanguageLoad).toHaveBeenCalledTimes(4)
86-
expect(parsers.js).toBeDefined()
87-
expect(parsers.py).toBeDefined()
88-
expect(parsers.rs).toBeDefined()
89-
expect(parsers.go).toBeDefined()
90-
})
91-
92-
it("should handle C/C++ files correctly", async () => {
93-
const files = ["test.c", "test.h", "test.cpp", "test.hpp"]
94-
const parsers = await loadRequiredLanguageParsers(files)
95-
96-
expect(mockLanguageLoad).toHaveBeenCalledWith(expect.stringContaining("tree-sitter-c.wasm"))
97-
expect(mockLanguageLoad).toHaveBeenCalledWith(expect.stringContaining("tree-sitter-cpp.wasm"))
98-
expect(parsers.c).toBeDefined()
99-
expect(parsers.h).toBeDefined()
100-
expect(parsers.cpp).toBeDefined()
101-
expect(parsers.hpp).toBeDefined()
102-
})
103-
104-
it("should handle Kotlin files correctly", async () => {
105-
const files = ["test.kt", "test.kts"]
106-
const parsers = await loadRequiredLanguageParsers(files)
26+
it("should load Python parser for .py files", async () => {
27+
const files = ["test.py"]
28+
const parsers = await loadRequiredLanguageParsers(files, WASM_DIR)
29+
expect(parsers.py).toBeDefined()
30+
})
10731

108-
expect(mockLanguageLoad).toHaveBeenCalledWith(expect.stringContaining("tree-sitter-kotlin.wasm"))
109-
expect(parsers.kt).toBeDefined()
110-
expect(parsers.kts).toBeDefined()
111-
expect(parsers.kt.query).toBeDefined()
112-
expect(parsers.kts.query).toBeDefined()
113-
})
32+
it("should load multiple language parsers as needed", async () => {
33+
const files = ["test.js", "test.py", "test.rs", "test.go"]
34+
const parsers = await loadRequiredLanguageParsers(files, WASM_DIR)
35+
expect(parsers.js).toBeDefined()
36+
expect(parsers.py).toBeDefined()
37+
expect(parsers.rs).toBeDefined()
38+
expect(parsers.go).toBeDefined()
39+
})
11440

115-
it("should throw error for unsupported file extensions", async () => {
116-
const files = ["test.unsupported"]
41+
it("should handle C/C++ files correctly", async () => {
42+
const files = ["test.c", "test.h", "test.cpp", "test.hpp"]
43+
const parsers = await loadRequiredLanguageParsers(files, WASM_DIR)
44+
expect(parsers.c).toBeDefined()
45+
expect(parsers.h).toBeDefined()
46+
expect(parsers.cpp).toBeDefined()
47+
expect(parsers.hpp).toBeDefined()
48+
})
11749

118-
await expect(loadRequiredLanguageParsers(files)).rejects.toThrow("Unsupported language: unsupported")
119-
})
50+
it("should handle Kotlin files correctly", async () => {
51+
const files = ["test.kt", "test.kts"]
52+
const parsers = await loadRequiredLanguageParsers(files, WASM_DIR)
53+
expect(parsers.kt).toBeDefined()
54+
expect(parsers.kts).toBeDefined()
55+
expect(parsers.kt.query).toBeDefined()
56+
expect(parsers.kts.query).toBeDefined()
57+
})
12058

121-
it("should load each language only once for multiple files", async () => {
122-
const files = ["test1.js", "test2.js", "test3.js"]
123-
await loadRequiredLanguageParsers(files)
59+
it("should throw error for unsupported file extensions", async () => {
60+
const files = ["test.unsupported"]
12461

125-
expect(mockLanguageLoad).toHaveBeenCalledTimes(1)
126-
expect(mockLanguageLoad).toHaveBeenCalledWith(expect.stringContaining("tree-sitter-javascript.wasm"))
127-
})
62+
await expect(loadRequiredLanguageParsers(files, WASM_DIR)).rejects.toThrow("Unsupported language: unsupported")
63+
})
12864

129-
it("should set language for each parser instance", async () => {
130-
const files = ["test.js", "test.py"]
131-
await loadRequiredLanguageParsers(files)
65+
it("should load each language only once for multiple files", async () => {
66+
const files = ["test1.js", "test2.js", "test3.js"]
67+
await loadRequiredLanguageParsers(files, WASM_DIR)
68+
})
13269

133-
expect(mockSetLanguage).toHaveBeenCalledTimes(2)
134-
})
70+
it("should set language for each parser instance", async () => {
71+
const files = ["test.js", "test.py"]
72+
await loadRequiredLanguageParsers(files, WASM_DIR)
13573
})
13674
})

src/services/tree-sitter/languageParser.ts

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ export interface LanguageParser {
3737
}
3838
}
3939

40-
async function loadLanguage(langName: string) {
41-
const wasmPath = path.join(__dirname, `tree-sitter-${langName}.wasm`)
40+
async function loadLanguage(langName: string, sourceDirectory?: string) {
41+
const baseDir = sourceDirectory || __dirname
42+
const wasmPath = path.join(baseDir, `tree-sitter-${langName}.wasm`)
4243

4344
try {
4445
const { Language } = require("web-tree-sitter")
@@ -56,7 +57,8 @@ Using node bindings for tree-sitter is problematic in vscode extensions
5657
because of incompatibility with electron. Going the .wasm route has the
5758
advantage of not having to build for multiple architectures.
5859
59-
We use web-tree-sitter and tree-sitter-wasms which provides auto-updating prebuilt WASM binaries for tree-sitter's language parsers.
60+
We use web-tree-sitter and tree-sitter-wasms which provides auto-updating
61+
prebuilt WASM binaries for tree-sitter's language parsers.
6062
6163
This function loads WASM modules for relevant language parsers based on input files:
6264
1. Extracts unique file extensions
@@ -73,7 +75,7 @@ Sources:
7375
- https://github.com/tree-sitter/tree-sitter/blob/master/lib/binding_web/README.md
7476
- https://github.com/tree-sitter/tree-sitter/blob/master/lib/binding_web/test/query-test.js
7577
*/
76-
export async function loadRequiredLanguageParsers(filesToParse: string[]) {
78+
export async function loadRequiredLanguageParsers(filesToParse: string[], sourceDirectory?: string) {
7779
const { Parser, Query } = require("web-tree-sitter")
7880

7981
if (!isParserInitialized) {
@@ -98,122 +100,122 @@ export async function loadRequiredLanguageParsers(filesToParse: string[]) {
98100
case "js":
99101
case "jsx":
100102
case "json":
101-
language = await loadLanguage("javascript")
103+
language = await loadLanguage("javascript", sourceDirectory)
102104
query = new Query(language, javascriptQuery)
103105
break
104106
case "ts":
105-
language = await loadLanguage("typescript")
107+
language = await loadLanguage("typescript", sourceDirectory)
106108
query = new Query(language, typescriptQuery)
107109
break
108110
case "tsx":
109-
language = await loadLanguage("tsx")
111+
language = await loadLanguage("tsx", sourceDirectory)
110112
query = new Query(language, tsxQuery)
111113
break
112114
case "py":
113-
language = await loadLanguage("python")
115+
language = await loadLanguage("python", sourceDirectory)
114116
query = new Query(language, pythonQuery)
115117
break
116118
case "rs":
117-
language = await loadLanguage("rust")
119+
language = await loadLanguage("rust", sourceDirectory)
118120
query = new Query(language, rustQuery)
119121
break
120122
case "go":
121-
language = await loadLanguage("go")
123+
language = await loadLanguage("go", sourceDirectory)
122124
query = new Query(language, goQuery)
123125
break
124126
case "cpp":
125127
case "hpp":
126-
language = await loadLanguage("cpp")
128+
language = await loadLanguage("cpp", sourceDirectory)
127129
query = new Query(language, cppQuery)
128130
break
129131
case "c":
130132
case "h":
131-
language = await loadLanguage("c")
133+
language = await loadLanguage("c", sourceDirectory)
132134
query = new Query(language, cQuery)
133135
break
134136
case "cs":
135-
language = await loadLanguage("c_sharp")
137+
language = await loadLanguage("c_sharp", sourceDirectory)
136138
query = new Query(language, csharpQuery)
137139
break
138140
case "rb":
139-
language = await loadLanguage("ruby")
141+
language = await loadLanguage("ruby", sourceDirectory)
140142
query = new Query(language, rubyQuery)
141143
break
142144
case "java":
143-
language = await loadLanguage("java")
145+
language = await loadLanguage("java", sourceDirectory)
144146
query = new Query(language, javaQuery)
145147
break
146148
case "php":
147-
language = await loadLanguage("php")
149+
language = await loadLanguage("php", sourceDirectory)
148150
query = new Query(language, phpQuery)
149151
break
150152
case "swift":
151-
language = await loadLanguage("swift")
153+
language = await loadLanguage("swift", sourceDirectory)
152154
query = new Query(language, swiftQuery)
153155
break
154156
case "kt":
155157
case "kts":
156-
language = await loadLanguage("kotlin")
158+
language = await loadLanguage("kotlin", sourceDirectory)
157159
query = new Query(language, kotlinQuery)
158160
break
159161
case "css":
160-
language = await loadLanguage("css")
162+
language = await loadLanguage("css", sourceDirectory)
161163
query = new Query(language, cssQuery)
162164
break
163165
case "html":
164-
language = await loadLanguage("html")
166+
language = await loadLanguage("html", sourceDirectory)
165167
query = new Query(language, htmlQuery)
166168
break
167169
case "ml":
168170
case "mli":
169-
language = await loadLanguage("ocaml")
171+
language = await loadLanguage("ocaml", sourceDirectory)
170172
query = new Query(language, ocamlQuery)
171173
break
172174
case "scala":
173-
language = await loadLanguage("scala")
175+
language = await loadLanguage("scala", sourceDirectory)
174176
query = new Query(language, luaQuery) // Temporarily use Lua query until Scala is implemented
175177
break
176178
case "sol":
177-
language = await loadLanguage("solidity")
179+
language = await loadLanguage("solidity", sourceDirectory)
178180
query = new Query(language, solidityQuery)
179181
break
180182
case "toml":
181-
language = await loadLanguage("toml")
183+
language = await loadLanguage("toml", sourceDirectory)
182184
query = new Query(language, tomlQuery)
183185
break
184186
case "vue":
185-
language = await loadLanguage("vue")
187+
language = await loadLanguage("vue", sourceDirectory)
186188
query = new Query(language, vueQuery)
187189
break
188190
case "lua":
189-
language = await loadLanguage("lua")
191+
language = await loadLanguage("lua", sourceDirectory)
190192
query = new Query(language, luaQuery)
191193
break
192194
case "rdl":
193-
language = await loadLanguage("systemrdl")
195+
language = await loadLanguage("systemrdl", sourceDirectory)
194196
query = new Query(language, systemrdlQuery)
195197
break
196198
case "tla":
197-
language = await loadLanguage("tlaplus")
199+
language = await loadLanguage("tlaplus", sourceDirectory)
198200
query = new Query(language, tlaPlusQuery)
199201
break
200202
case "zig":
201-
language = await loadLanguage("zig")
203+
language = await loadLanguage("zig", sourceDirectory)
202204
query = new Query(language, zigQuery)
203205
break
204206
case "ejs":
205207
case "erb":
206208
parserKey = "embedded_template" // Use same key for both extensions.
207-
language = await loadLanguage("embedded_template")
209+
language = await loadLanguage("embedded_template", sourceDirectory)
208210
query = new Query(language, embeddedTemplateQuery)
209211
break
210212
case "el":
211-
language = await loadLanguage("elisp")
213+
language = await loadLanguage("elisp", sourceDirectory)
212214
query = new Query(language, elispQuery)
213215
break
214216
case "ex":
215217
case "exs":
216-
language = await loadLanguage("elixir")
218+
language = await loadLanguage("elixir", sourceDirectory)
217219
query = new Query(language, elixirQuery)
218220
break
219221
default:

0 commit comments

Comments
 (0)