135 lines
4.6 KiB
TypeScript
135 lines
4.6 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"
|
|
|
|
const entry = "file:///tmp/kilo-cache/node_modules/@lancedb/lancedb/dist/index.js"
|
|
const add = mock(async () => ({ directory: "/tmp/kilo-cache", entrypoint: entry }))
|
|
const real = await import("@opencode-ai/core/npm")
|
|
|
|
mock.module("@opencode-ai/core/npm", () => ({
|
|
...real,
|
|
Npm: {
|
|
...real.Npm,
|
|
add,
|
|
},
|
|
}))
|
|
|
|
const env = "KILO_LANCEDB_PATH"
|
|
const prev = process.env[env]
|
|
|
|
describe("LanceDBRuntime", () => {
|
|
beforeEach(async () => {
|
|
const { LanceDBRuntime } = await import("../../src/kilocode/lancedb")
|
|
LanceDBRuntime.clear()
|
|
add.mockClear()
|
|
add.mockImplementation(async () => ({ directory: "/tmp/kilo-cache", entrypoint: entry }))
|
|
})
|
|
|
|
afterEach(async () => {
|
|
const { LanceDBRuntime } = await import("../../src/kilocode/lancedb")
|
|
LanceDBRuntime.clear()
|
|
if (prev === undefined) delete process.env[env]
|
|
if (prev !== undefined) process.env[env] = prev
|
|
})
|
|
|
|
test("skips installation for non-lancedb backends", async () => {
|
|
const { LanceDBRuntime } = await import("../../src/kilocode/lancedb")
|
|
|
|
await LanceDBRuntime.ensure("qdrant")
|
|
|
|
expect(add).not.toHaveBeenCalled()
|
|
expect(process.env[env]).toBeUndefined()
|
|
})
|
|
|
|
test("guides Intel Mac users to Qdrant", async () => {
|
|
const { LanceDBRuntime } = await import("../../src/kilocode/lancedb")
|
|
const platform = Object.getOwnPropertyDescriptor(process, "platform")!
|
|
const arch = Object.getOwnPropertyDescriptor(process, "arch")!
|
|
Object.defineProperty(process, "platform", { ...platform, value: "darwin" })
|
|
Object.defineProperty(process, "arch", { ...arch, value: "x64" })
|
|
|
|
try {
|
|
await expect(LanceDBRuntime.ensure("lancedb")).rejects.toThrow(
|
|
'LanceDB is not supported on Intel Macs. Set "indexing.vectorStore" to "qdrant" and configure a Qdrant server.',
|
|
)
|
|
expect(add).not.toHaveBeenCalled()
|
|
} finally {
|
|
Object.defineProperty(process, "platform", platform)
|
|
Object.defineProperty(process, "arch", arch)
|
|
}
|
|
})
|
|
|
|
test("installs the pinned package and exports a file URL for lancedb", async () => {
|
|
const { LanceDBRuntime } = await import("../../src/kilocode/lancedb")
|
|
|
|
await LanceDBRuntime.ensure("lancedb")
|
|
|
|
expect(add).toHaveBeenCalledWith("@lancedb/lancedb@0.26.2")
|
|
expect(process.env[env]).toBe(entry)
|
|
})
|
|
|
|
test("exposes every LanceDB package that must stay external to bun compile", async () => {
|
|
const { LanceDBRuntime } = await import("../../src/kilocode/lancedb")
|
|
|
|
expect(LanceDBRuntime.external).toEqual([
|
|
"@lancedb/lancedb",
|
|
"@lancedb/lancedb-darwin-arm64",
|
|
"@lancedb/lancedb-linux-arm64-gnu",
|
|
"@lancedb/lancedb-linux-arm64-musl",
|
|
"@lancedb/lancedb-linux-x64-gnu",
|
|
"@lancedb/lancedb-linux-x64-musl",
|
|
"@lancedb/lancedb-win32-arm64-msvc",
|
|
"@lancedb/lancedb-win32-x64-msvc",
|
|
])
|
|
})
|
|
|
|
test("skips install when runtime path is already set", async () => {
|
|
const { LanceDBRuntime } = await import("../../src/kilocode/lancedb")
|
|
process.env[env] = "file:///already/set.js"
|
|
|
|
await LanceDBRuntime.ensure("lancedb")
|
|
|
|
expect(add).not.toHaveBeenCalled()
|
|
expect(process.env[env]).toBe("file:///already/set.js")
|
|
})
|
|
|
|
test("dedupes concurrent ensure calls", async () => {
|
|
const { LanceDBRuntime } = await import("../../src/kilocode/lancedb")
|
|
|
|
await Promise.all([
|
|
LanceDBRuntime.ensure("lancedb"),
|
|
LanceDBRuntime.ensure("lancedb"),
|
|
LanceDBRuntime.ensure("lancedb"),
|
|
])
|
|
|
|
expect(add).toHaveBeenCalledTimes(1)
|
|
expect(process.env[env]).toBe(entry)
|
|
})
|
|
|
|
test("surfaces install failures without swallowing them", async () => {
|
|
const { LanceDBRuntime } = await import("../../src/kilocode/lancedb")
|
|
add.mockImplementationOnce(async () => {
|
|
throw new Error("registry unavailable")
|
|
})
|
|
|
|
await expect(LanceDBRuntime.ensure("lancedb")).rejects.toThrow("registry unavailable")
|
|
expect(process.env[env]).toBeUndefined()
|
|
})
|
|
|
|
test("retries after a failed install", async () => {
|
|
const { LanceDBRuntime } = await import("../../src/kilocode/lancedb")
|
|
add
|
|
.mockImplementationOnce(async () => {
|
|
throw new Error("install failed")
|
|
})
|
|
.mockImplementationOnce(async () => ({ directory: "/tmp/kilo-cache", entrypoint: entry }))
|
|
|
|
await expect(LanceDBRuntime.ensure("lancedb")).rejects.toThrow("install failed")
|
|
expect(process.env[env]).toBeUndefined()
|
|
expect(add).toHaveBeenCalledTimes(1)
|
|
|
|
await LanceDBRuntime.ensure("lancedb")
|
|
|
|
expect(add).toHaveBeenCalledTimes(2)
|
|
expect(process.env[env]).toBe(entry)
|
|
})
|
|
})
|