test(shared/project-discovery-dirs): cover worktree-path memoization
This commit is contained in:
@@ -1,13 +1,7 @@
|
|||||||
import { afterEach, beforeEach, describe, expect, it } from "bun:test"
|
import { afterEach, beforeEach, describe, expect, it, mock } from "bun:test"
|
||||||
import { mkdirSync, realpathSync, rmSync } from "node:fs"
|
import { mkdirSync, realpathSync, rmSync } from "node:fs"
|
||||||
import { tmpdir } from "node:os"
|
import { tmpdir } from "node:os"
|
||||||
import { join } from "node:path"
|
import { join } from "node:path"
|
||||||
import {
|
|
||||||
findProjectAgentsSkillDirs,
|
|
||||||
findProjectClaudeSkillDirs,
|
|
||||||
findProjectOpencodeCommandDirs,
|
|
||||||
findProjectOpencodeSkillDirs,
|
|
||||||
} from "./project-discovery-dirs"
|
|
||||||
|
|
||||||
const TEST_DIR = join(tmpdir(), `project-discovery-dirs-${Date.now()}`)
|
const TEST_DIR = join(tmpdir(), `project-discovery-dirs-${Date.now()}`)
|
||||||
|
|
||||||
@@ -24,7 +18,7 @@ describe("project-discovery-dirs", () => {
|
|||||||
rmSync(TEST_DIR, { recursive: true, force: true })
|
rmSync(TEST_DIR, { recursive: true, force: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
it("#given nested .opencode skill directories #when finding project opencode skill dirs #then returns nearest-first with aliases", () => {
|
it("#given nested .opencode skill directories #when finding project opencode skill dirs #then returns nearest-first with aliases", async () => {
|
||||||
// given
|
// given
|
||||||
const projectDir = join(TEST_DIR, "project")
|
const projectDir = join(TEST_DIR, "project")
|
||||||
const childDir = join(projectDir, "apps", "cli")
|
const childDir = join(projectDir, "apps", "cli")
|
||||||
@@ -32,6 +26,8 @@ describe("project-discovery-dirs", () => {
|
|||||||
mkdirSync(join(projectDir, ".opencode", "skills"), { recursive: true })
|
mkdirSync(join(projectDir, ".opencode", "skills"), { recursive: true })
|
||||||
mkdirSync(join(TEST_DIR, ".opencode", "skills"), { recursive: true })
|
mkdirSync(join(TEST_DIR, ".opencode", "skills"), { recursive: true })
|
||||||
|
|
||||||
|
const { findProjectOpencodeSkillDirs } = await import("./project-discovery-dirs")
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const directories = findProjectOpencodeSkillDirs(childDir)
|
const directories = findProjectOpencodeSkillDirs(childDir)
|
||||||
|
|
||||||
@@ -43,13 +39,15 @@ describe("project-discovery-dirs", () => {
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("#given nested .opencode command directories #when finding project opencode command dirs #then returns nearest-first with aliases", () => {
|
it("#given nested .opencode command directories #when finding project opencode command dirs #then returns nearest-first with aliases", async () => {
|
||||||
// given
|
// given
|
||||||
const projectDir = join(TEST_DIR, "project")
|
const projectDir = join(TEST_DIR, "project")
|
||||||
const childDir = join(projectDir, "packages", "tool")
|
const childDir = join(projectDir, "packages", "tool")
|
||||||
mkdirSync(join(projectDir, ".opencode", "commands"), { recursive: true })
|
mkdirSync(join(projectDir, ".opencode", "commands"), { recursive: true })
|
||||||
mkdirSync(join(TEST_DIR, ".opencode", "command"), { recursive: true })
|
mkdirSync(join(TEST_DIR, ".opencode", "command"), { recursive: true })
|
||||||
|
|
||||||
|
const { findProjectOpencodeCommandDirs } = await import("./project-discovery-dirs")
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const directories = findProjectOpencodeCommandDirs(childDir)
|
const directories = findProjectOpencodeCommandDirs(childDir)
|
||||||
|
|
||||||
@@ -60,13 +58,15 @@ describe("project-discovery-dirs", () => {
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("#given ancestor claude and agents skill directories #when finding project compatibility dirs #then discovers both scopes", () => {
|
it("#given ancestor claude and agents skill directories #when finding project compatibility dirs #then discovers both scopes", async () => {
|
||||||
// given
|
// given
|
||||||
const projectDir = join(TEST_DIR, "project")
|
const projectDir = join(TEST_DIR, "project")
|
||||||
const childDir = join(projectDir, "src", "nested")
|
const childDir = join(projectDir, "src", "nested")
|
||||||
mkdirSync(join(projectDir, ".claude", "skills"), { recursive: true })
|
mkdirSync(join(projectDir, ".claude", "skills"), { recursive: true })
|
||||||
mkdirSync(join(TEST_DIR, ".agents", "skills"), { recursive: true })
|
mkdirSync(join(TEST_DIR, ".agents", "skills"), { recursive: true })
|
||||||
|
|
||||||
|
const { findProjectAgentsSkillDirs, findProjectClaudeSkillDirs } = await import("./project-discovery-dirs")
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const claudeDirectories = findProjectClaudeSkillDirs(childDir)
|
const claudeDirectories = findProjectClaudeSkillDirs(childDir)
|
||||||
const agentsDirectories = findProjectAgentsSkillDirs(childDir)
|
const agentsDirectories = findProjectAgentsSkillDirs(childDir)
|
||||||
@@ -76,17 +76,64 @@ describe("project-discovery-dirs", () => {
|
|||||||
expect(agentsDirectories).toEqual([canonicalPath(join(TEST_DIR, ".agents", "skills"))])
|
expect(agentsDirectories).toEqual([canonicalPath(join(TEST_DIR, ".agents", "skills"))])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("#given a stop directory #when finding ancestor dirs #then it does not scan beyond the stop boundary", () => {
|
it("#given a stop directory #when finding ancestor dirs #then it does not scan beyond the stop boundary", async () => {
|
||||||
// given
|
// given
|
||||||
const projectDir = join(TEST_DIR, "project")
|
const projectDir = join(TEST_DIR, "project")
|
||||||
const childDir = join(projectDir, "apps", "cli")
|
const childDir = join(projectDir, "apps", "cli")
|
||||||
mkdirSync(join(projectDir, ".opencode", "skills"), { recursive: true })
|
mkdirSync(join(projectDir, ".opencode", "skills"), { recursive: true })
|
||||||
mkdirSync(join(TEST_DIR, ".opencode", "skills"), { recursive: true })
|
mkdirSync(join(TEST_DIR, ".opencode", "skills"), { recursive: true })
|
||||||
|
|
||||||
|
const { findProjectOpencodeSkillDirs } = await import("./project-discovery-dirs")
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const directories = findProjectOpencodeSkillDirs(childDir, projectDir)
|
const directories = findProjectOpencodeSkillDirs(childDir, projectDir)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(directories).toEqual([canonicalPath(join(projectDir, ".opencode", "skills"))])
|
expect(directories).toEqual([canonicalPath(join(projectDir, ".opencode", "skills"))])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("#given repeated worktree detection #when detecting twice #then reuses the cached result", async () => {
|
||||||
|
// given
|
||||||
|
let callCount = 0
|
||||||
|
mock.module("node:child_process", () => ({
|
||||||
|
execFileSync: () => {
|
||||||
|
callCount += 1
|
||||||
|
return TEST_DIR
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
const { clearWorktreeCache, detectWorktreePath } = await import("./project-discovery-dirs")
|
||||||
|
|
||||||
|
clearWorktreeCache()
|
||||||
|
|
||||||
|
// when
|
||||||
|
const firstPath = detectWorktreePath("/some/dir")
|
||||||
|
const secondPath = detectWorktreePath("/some/dir")
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(firstPath).toBe(TEST_DIR)
|
||||||
|
expect(secondPath).toBe(TEST_DIR)
|
||||||
|
expect(callCount).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("#given a cleared worktree cache #when detecting again #then spawns git again", async () => {
|
||||||
|
// given
|
||||||
|
let callCount = 0
|
||||||
|
mock.module("node:child_process", () => ({
|
||||||
|
execFileSync: () => {
|
||||||
|
callCount += 1
|
||||||
|
return TEST_DIR
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
const { clearWorktreeCache, detectWorktreePath } = await import("./project-discovery-dirs")
|
||||||
|
|
||||||
|
// when
|
||||||
|
detectWorktreePath("/some/dir")
|
||||||
|
clearWorktreeCache()
|
||||||
|
detectWorktreePath("/some/dir")
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(execFileSync).toHaveBeenCalledTimes(2)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user