Skip to content

Commit ac2aa6a

Browse files
committed
test(shell): strengthen plan-to-git review coverage
1 parent 3341598 commit ac2aa6a

3 files changed

Lines changed: 96 additions & 49 deletions

File tree

packages/app/tests/docker-git/core-templates.test.ts

Lines changed: 73 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { describe, expect, it } from "@effect/vitest"
2+
import * as fc from "fast-check"
23

34
import { defaultTemplateConfig, planFiles, type TemplateConfig } from "../../test-adapters/core-templates.js"
45

@@ -41,6 +42,32 @@ const getGeneratedFile = (files: ReadonlyArray<PlannedFile>, relativePath: strin
4142
const getGeneratedFilePaths = (files: ReadonlyArray<PlannedFile>): ReadonlyArray<string> =>
4243
files.flatMap((file) => file._tag === "File" ? [file.relativePath] : [])
4344

45+
const generatedTemplateConfigArbitrary: fc.Arbitrary<TemplateConfig> = fc
46+
.record({
47+
gpu: fc.constantFrom<TemplateConfig["gpu"]>("none", "all"),
48+
projectIndex: fc.integer({ min: 1, max: 100_000 }),
49+
sshPort: fc.integer({ min: 1024, max: 65_535 }),
50+
sshUserIndex: fc.integer({ min: 1, max: 100_000 })
51+
})
52+
.map(({ gpu, projectIndex, sshPort, sshUserIndex }) => {
53+
const sshUser = `dev${sshUserIndex}`
54+
const projectName = `repo-${projectIndex}`
55+
const home = `/home/${sshUser}`
56+
57+
return makeTemplateConfig({
58+
codexHome: `${home}/.codex`,
59+
containerName: `dg-test-${projectIndex}`,
60+
geminiHome: `${home}/.gemini`,
61+
gpu,
62+
grokHome: `${home}/.grok`,
63+
serviceName: `dg-test-${projectIndex}`,
64+
sshPort,
65+
sshUser,
66+
targetDir: `${home}/org/${projectName}`,
67+
volumeName: `dg-test-${projectIndex}-home`
68+
})
69+
})
70+
4471
describe("app planFiles", () => {
4572
it("includes Grok auth bootstrap wiring in the generated entrypoint", () => {
4673
const files = planFiles(makeTemplateConfig())
@@ -52,49 +79,57 @@ describe("app planFiles", () => {
5279
})
5380

5481
it("uses the Rust browser connection module when Playwright is enabled", () => {
55-
const files = planFiles(makeTemplateConfig({ enableMcpPlaywright: true }))
56-
const filePaths = getGeneratedFilePaths(files)
57-
const dockerfile = getGeneratedFile(files, "Dockerfile")
58-
const entrypoint = getGeneratedFile(files, "entrypoint.sh")
82+
fc.assert(
83+
fc.property(generatedTemplateConfigArbitrary, (generatedConfig) => {
84+
const files = planFiles({ ...generatedConfig, enableMcpPlaywright: true })
85+
const filePaths = getGeneratedFilePaths(files)
86+
const dockerfile = getGeneratedFile(files, "Dockerfile")
87+
const entrypoint = getGeneratedFile(files, "entrypoint.sh")
5988

60-
expect(filePaths).not.toContain("Dockerfile.browser")
61-
expect(filePaths).not.toContain("docker-git-cdp-guard")
62-
expect(filePaths).not.toContain("docker-git-browser-runtime.sh")
63-
expect(dockerfile.contents).toContain(
64-
"cargo install --git https://github.com/ProverCoderAI/rust-browser-connection"
89+
expect(filePaths).not.toContain("Dockerfile.browser")
90+
expect(filePaths).not.toContain("docker-git-cdp-guard")
91+
expect(filePaths).not.toContain("docker-git-browser-runtime.sh")
92+
expect(dockerfile.contents).toContain(
93+
"cargo install --git https://github.com/ProverCoderAI/rust-browser-connection"
94+
)
95+
expect(dockerfile.contents).toContain(
96+
"cargo install --git https://github.com/ProverCoderAI/plan-to-git --rev 06fe8bdf1d2e48a1f5a0218a3bb7af19e63deb5e --locked --bins --root /usr/local"
97+
)
98+
expect(dockerfile.contents).toContain("/usr/local/bin/plan-to-git --help >/dev/null")
99+
expect(dockerfile.contents).toContain("make build-essential docker.io")
100+
expect(dockerfile.contents).toContain("/usr/local/bin/browser-connection --version")
101+
expect(dockerfile.contents).not.toContain("docker-git-playwright-mcp")
102+
expect(entrypoint.contents).not.toContain("docker_git_start_rust_browser_connection")
103+
expect(entrypoint.contents).not.toContain("start --project")
104+
expect(entrypoint.contents).not.toContain("--no-start-browser")
105+
expect(entrypoint.contents).toContain("docker_git_stop_playwright_browser()")
106+
expect(entrypoint.contents).toContain("docker-git-browser-connection")
107+
expect(entrypoint.contents).toContain("stop --project \"$project_container\"")
108+
expect(entrypoint.contents).toContain("command = \"browser-connection\"")
109+
expect(entrypoint.contents).toContain(
110+
"args = [\"--project\", \"$DOCKER_GIT_BROWSER_PROJECT\", \"--network\", \"$DOCKER_GIT_BROWSER_NETWORK\"]"
111+
)
112+
expect(entrypoint.contents).toContain("plan-to-git sync")
113+
expect(entrypoint.contents).toContain("plan-to-git hook --source codex")
114+
expect(entrypoint.contents).toContain("CODEX_REQUIREMENTS_FILE=\"/etc/codex/requirements.toml\"")
115+
expect(entrypoint.contents).toContain("managed_dir = \"/opt/docker-git/hooks\"")
116+
expect(entrypoint.contents).toContain("[[hooks.UserPromptSubmit]]")
117+
expect(entrypoint.contents).toContain("[[hooks.Stop]]")
118+
expect(entrypoint.contents).toContain("command = \"/opt/docker-git/hooks/plan-to-git-codex-hook\"")
119+
})
65120
)
66-
expect(dockerfile.contents).toContain(
67-
"cargo install --git https://github.com/ProverCoderAI/plan-to-git --rev 06fe8bdf1d2e48a1f5a0218a3bb7af19e63deb5e --locked --bins --root /usr/local"
68-
)
69-
expect(dockerfile.contents).toContain("/usr/local/bin/plan-to-git --help >/dev/null")
70-
expect(dockerfile.contents).toContain("make build-essential docker.io")
71-
expect(dockerfile.contents).toContain("/usr/local/bin/browser-connection --version")
72-
expect(dockerfile.contents).not.toContain("docker-git-playwright-mcp")
73-
expect(entrypoint.contents).not.toContain("docker_git_start_rust_browser_connection")
74-
expect(entrypoint.contents).not.toContain("start --project")
75-
expect(entrypoint.contents).not.toContain("--no-start-browser")
76-
expect(entrypoint.contents).toContain("docker_git_stop_playwright_browser()")
77-
expect(entrypoint.contents).toContain("docker-git-browser-connection")
78-
expect(entrypoint.contents).toContain("stop --project \"$project_container\"")
79-
expect(entrypoint.contents).toContain("command = \"browser-connection\"")
80-
expect(entrypoint.contents).toContain(
81-
"args = [\"--project\", \"$DOCKER_GIT_BROWSER_PROJECT\", \"--network\", \"$DOCKER_GIT_BROWSER_NETWORK\"]"
82-
)
83-
expect(entrypoint.contents).toContain("plan-to-git sync")
84-
expect(entrypoint.contents).toContain("plan-to-git hook --source codex")
85-
expect(entrypoint.contents).toContain("CODEX_REQUIREMENTS_FILE=\"/etc/codex/requirements.toml\"")
86-
expect(entrypoint.contents).toContain("managed_dir = \"/opt/docker-git/hooks\"")
87-
expect(entrypoint.contents).toContain("[[hooks.UserPromptSubmit]]")
88-
expect(entrypoint.contents).toContain("[[hooks.Stop]]")
89-
expect(entrypoint.contents).toContain("command = \"/opt/docker-git/hooks/plan-to-git-codex-hook\"")
90121
})
91122

92123
it("keeps plan-to-git state out of generated git and docker contexts", () => {
93-
const files = planFiles(makeTemplateConfig())
94-
const gitignore = getGeneratedFile(files, ".gitignore")
95-
const dockerignore = getGeneratedFile(files, ".dockerignore")
124+
fc.assert(
125+
fc.property(generatedTemplateConfigArbitrary, (config) => {
126+
const files = planFiles(config)
127+
const gitignore = getGeneratedFile(files, ".gitignore")
128+
const dockerignore = getGeneratedFile(files, ".dockerignore")
96129

97-
expect(gitignore.contents).toContain(".agent-plan.json")
98-
expect(dockerignore.contents).toContain(".agent-plan.json")
130+
expect(gitignore.contents).toContain(".agent-plan.json")
131+
expect(dockerignore.contents).toContain(".agent-plan.json")
132+
})
133+
)
99134
})
100135
})

packages/lib/tests/core/git-post-push-wrapper.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ if [[ -n "\${FAKE_PLAN_TO_GIT_LOG_PATH:-}" ]]; then
117117
printf '%s\\t%s\\n' "$PWD" "$*" >> "$FAKE_PLAN_TO_GIT_LOG_PATH"
118118
fi
119119
120+
if [[ "\${1:-}" != "sync" ]]; then
121+
if [[ -n "\${FAKE_PLAN_TO_GIT_LOG_PATH:-}" ]]; then
122+
printf '%s\\tunexpected-command:%s\\n' "$PWD" "\${1:-<empty>}" >> "$FAKE_PLAN_TO_GIT_LOG_PATH"
123+
fi
124+
echo "fakePlanToGit: expected sync command, got: \${1:-<empty>}" >&2
125+
exit 127
126+
fi
127+
120128
if [[ -n "\${FAKE_PLAN_TO_GIT_EXIT_CODE:-}" ]]; then
121129
exit "$FAKE_PLAN_TO_GIT_EXIT_CODE"
122130
fi

packages/lib/tests/core/templates.test.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -512,18 +512,22 @@ describe("renderEntrypointGitHooks", () => {
512512

513513
describe("planFiles generated ignores", () => {
514514
it("keeps plan-to-git state out of git and docker build contexts", () => {
515-
const files = planFiles(makeTemplateConfig())
516-
const gitignore = files.find(
517-
(file): file is Extract<(typeof files)[number], { readonly _tag: "File" }> =>
518-
file._tag === "File" && file.relativePath === ".gitignore"
519-
)
520-
const dockerignore = files.find(
521-
(file): file is Extract<(typeof files)[number], { readonly _tag: "File" }> =>
522-
file._tag === "File" && file.relativePath === ".dockerignore"
515+
fc.assert(
516+
fc.property(generatedTemplateConfigArbitrary, (config) => {
517+
const files = planFiles(config)
518+
const gitignore = files.find(
519+
(file): file is Extract<(typeof files)[number], { readonly _tag: "File" }> =>
520+
file._tag === "File" && file.relativePath === ".gitignore"
521+
)
522+
const dockerignore = files.find(
523+
(file): file is Extract<(typeof files)[number], { readonly _tag: "File" }> =>
524+
file._tag === "File" && file.relativePath === ".dockerignore"
525+
)
526+
527+
expect(gitignore?.contents).toContain(".agent-plan.json")
528+
expect(dockerignore?.contents).toContain(".agent-plan.json")
529+
})
523530
)
524-
525-
expect(gitignore?.contents).toContain(".agent-plan.json")
526-
expect(dockerignore?.contents).toContain(".agent-plan.json")
527531
})
528532
})
529533

0 commit comments

Comments
 (0)