test(omo-codex): batch 42 (4 files)
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./telemetry"
|
||||||
|
export * from "./install"
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
import { describe, expect, it } from "bun:test"
|
||||||
|
import { readFileSync } from "node:fs"
|
||||||
|
import { join } from "node:path"
|
||||||
|
|
||||||
|
import { runUserPromptSubmitHook } from "../plugin/components/ultrawork/src/codex-hook"
|
||||||
|
|
||||||
|
const repoRoot = join(import.meta.dir, "..", "..", "..")
|
||||||
|
|
||||||
|
describe("omo-codex Python migration cross-platform behavior", () => {
|
||||||
|
it("handles empty inventory, malformed input, and Windows paths without Python", () => {
|
||||||
|
// given
|
||||||
|
const aggregateHooks = readJson(join(repoRoot, "packages/omo-codex/plugin/hooks/hooks.json"))
|
||||||
|
const componentHooks = readJson(join(repoRoot, "packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json"))
|
||||||
|
const hookCommands = collectHookCommands([aggregateHooks, componentHooks])
|
||||||
|
|
||||||
|
// when
|
||||||
|
const outputs = [
|
||||||
|
runUserPromptSubmitHook(undefined),
|
||||||
|
runUserPromptSubmitHook({ hook_event_name: "UserPromptSubmit", prompt: "" }),
|
||||||
|
runUserPromptSubmitHook({ hook_event_name: "UserPromptSubmit", prompt: "refactor ulw_helper.ts" }),
|
||||||
|
runUserPromptSubmitHook({
|
||||||
|
cwd: "C:\\Users\\codex\\project",
|
||||||
|
hook_event_name: "UserPromptSubmit",
|
||||||
|
model: "gpt-5.5",
|
||||||
|
permission_mode: "default",
|
||||||
|
prompt: "please ulw this",
|
||||||
|
session_id: "s",
|
||||||
|
transcript_path: null,
|
||||||
|
turn_id: "t",
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
const ultraworkOutput = parseHookOutput(outputs[3])
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(hookCommands).not.toContainEqual(expect.stringMatching(/\bpython3?\b/i))
|
||||||
|
expect(hookCommands).toContain('node "${PLUGIN_ROOT}/components/ultrawork/dist/cli.js" hook user-prompt-submit')
|
||||||
|
expect(hookCommands).toContain('node "${PLUGIN_ROOT}/dist/cli.js" hook user-prompt-submit')
|
||||||
|
expect(outputs[0]).toBe("")
|
||||||
|
expect(outputs[1]).toBe("")
|
||||||
|
expect(outputs[2]).toBe("")
|
||||||
|
expect(ultraworkOutput.hookSpecificOutput.hookEventName).toBe("UserPromptSubmit")
|
||||||
|
expect(ultraworkOutput.hookSpecificOutput.additionalContext).toStartWith("<ultrawork-mode>")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function readJson(path: string): unknown {
|
||||||
|
return JSON.parse(readFileSync(path, "utf8"))
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectHookCommands(values: readonly unknown[]): readonly string[] {
|
||||||
|
return values.flatMap(collectHookCommandsFromValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectHookCommandsFromValue(value: unknown): readonly string[] {
|
||||||
|
if (typeof value === "string") return []
|
||||||
|
if (Array.isArray(value)) return value.flatMap(collectHookCommandsFromValue)
|
||||||
|
if (!isRecord(value)) return []
|
||||||
|
const ownCommand = typeof value["command"] === "string" ? [value["command"]] : []
|
||||||
|
return [...ownCommand, ...Object.values(value).flatMap(collectHookCommandsFromValue)]
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
return typeof value === "object" && value !== null && !Array.isArray(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UserPromptSubmitHookOutput {
|
||||||
|
readonly hookSpecificOutput: {
|
||||||
|
readonly hookEventName: "UserPromptSubmit"
|
||||||
|
readonly additionalContext: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseHookOutput(output: string): UserPromptSubmitHookOutput {
|
||||||
|
const parsed: unknown = JSON.parse(output)
|
||||||
|
if (!isUserPromptSubmitHookOutput(parsed)) throw new TypeError("Expected UserPromptSubmit hook output")
|
||||||
|
return parsed
|
||||||
|
}
|
||||||
|
|
||||||
|
function isUserPromptSubmitHookOutput(value: unknown): value is UserPromptSubmitHookOutput {
|
||||||
|
if (!isRecord(value)) return false
|
||||||
|
const hookSpecificOutput = value["hookSpecificOutput"]
|
||||||
|
return (
|
||||||
|
isRecord(hookSpecificOutput) &&
|
||||||
|
hookSpecificOutput["hookEventName"] === "UserPromptSubmit" &&
|
||||||
|
typeof hookSpecificOutput["additionalContext"] === "string"
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
import { describe, expect, it } from "bun:test"
|
||||||
|
import { readdirSync, statSync } from "node:fs"
|
||||||
|
import { join, relative, sep } from "node:path"
|
||||||
|
|
||||||
|
const repoRoot = join(import.meta.dir, "..", "..", "..")
|
||||||
|
const packageRoot = join(repoRoot, "packages", "omo-codex")
|
||||||
|
|
||||||
|
const retainedPythonFiles = [
|
||||||
|
"packages/omo-codex/plugin/components/lsp/test/fixtures/broken.py",
|
||||||
|
"packages/omo-codex/plugin/skills/programming/scripts/go/new-project.py",
|
||||||
|
"packages/omo-codex/plugin/skills/programming/scripts/python/check-no-excuse-rules.py",
|
||||||
|
"packages/omo-codex/plugin/skills/programming/scripts/python/new-project.py",
|
||||||
|
"packages/omo-codex/plugin/skills/programming/scripts/python/new-script.py",
|
||||||
|
"packages/omo-codex/plugin/skills/programming/scripts/rust/check-no-excuse-rules.py",
|
||||||
|
"packages/omo-codex/plugin/skills/programming/scripts/rust/new-project.py",
|
||||||
|
] as const
|
||||||
|
const retainedPythonFileSet = new Set<string>(retainedPythonFiles)
|
||||||
|
|
||||||
|
describe("omo-codex Python migration inventory", () => {
|
||||||
|
it("classifies every Python file under packages/omo-codex", () => {
|
||||||
|
// given
|
||||||
|
const pythonFiles = listPythonFiles(packageRoot)
|
||||||
|
|
||||||
|
// when
|
||||||
|
const unclassified = pythonFiles.filter((path) => !retainedPythonFileSet.has(path))
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(unclassified).toEqual([])
|
||||||
|
expect(pythonFiles).toEqual([...retainedPythonFiles].sort())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function listPythonFiles(root: string): readonly string[] {
|
||||||
|
const files: string[] = []
|
||||||
|
collectPythonFiles(root, files)
|
||||||
|
return files.sort()
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectPythonFiles(directory: string, files: string[]): void {
|
||||||
|
for (const entry of readdirSync(directory)) {
|
||||||
|
if (entry === "node_modules" || entry === "dist") continue
|
||||||
|
|
||||||
|
const absolutePath = join(directory, entry)
|
||||||
|
const stats = statSync(absolutePath)
|
||||||
|
if (stats.isDirectory()) {
|
||||||
|
collectPythonFiles(absolutePath, files)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.endsWith(".py") || entry.endsWith(".pyi")) {
|
||||||
|
files.push(relative(repoRoot, absolutePath).split(sep).join("/"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { describe, expect, it } from "bun:test"
|
||||||
|
import { readFileSync } from "node:fs"
|
||||||
|
import { join } from "node:path"
|
||||||
|
|
||||||
|
const repoRoot = join(import.meta.dir, "..", "..", "..")
|
||||||
|
const ultraworkRoot = join(repoRoot, "packages/omo-codex/plugin/components/ultrawork")
|
||||||
|
|
||||||
|
describe("omo-codex Python migration regression", () => {
|
||||||
|
it("keeps package scripts and plugin packaging Python-free", () => {
|
||||||
|
// given
|
||||||
|
const componentPackage = readJson(join(ultraworkRoot, "package.json"))
|
||||||
|
const aggregateHooks = readFileSync(join(repoRoot, "packages/omo-codex/plugin/hooks/hooks.json"), "utf8")
|
||||||
|
const componentHooks = readFileSync(join(ultraworkRoot, "hooks/hooks.json"), "utf8")
|
||||||
|
const aggregateTest = readFileSync(join(repoRoot, "packages/omo-codex/plugin/test/aggregate.test.mjs"), "utf8")
|
||||||
|
|
||||||
|
// when
|
||||||
|
const packagedFiles = isRecord(componentPackage) && Array.isArray(componentPackage["files"])
|
||||||
|
? componentPackage["files"]
|
||||||
|
: []
|
||||||
|
const scripts = isRecord(componentPackage) && isRecord(componentPackage["scripts"]) ? componentPackage["scripts"] : {}
|
||||||
|
const bin = isRecord(componentPackage) && isRecord(componentPackage["bin"]) ? componentPackage["bin"] : {}
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(scripts["build"]).toBe("tsc -p tsconfig.build.json")
|
||||||
|
expect(scripts["test"]).toBe("vitest --run")
|
||||||
|
expect(bin["omo-ultrawork"]).toBe("./dist/cli.js")
|
||||||
|
expect(packagedFiles).toContain("dist")
|
||||||
|
expect(packagedFiles).not.toContain("hooks/ultrawork-detector.py")
|
||||||
|
expect(`${aggregateHooks}\n${componentHooks}\n${aggregateTest}`).not.toMatch(/\bpython3?\b|ultrawork-detector\.py/)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function readJson(path: string): unknown {
|
||||||
|
return JSON.parse(readFileSync(path, "utf8"))
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
return typeof value === "object" && value !== null && !Array.isArray(value)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user