test(ci): register omitted V2 unit suites (#45970)

This commit is contained in:
Kit Langton
2026-08-28 17:58:54 -04:00
committed by GitHub
parent f779b2748a
commit 51d53f45c1
6 changed files with 63 additions and 39 deletions
+1
View File
@@ -2,3 +2,4 @@ packages/core/migration/**/snapshot.json linguist-generated
packages/core/src/database/migration.gen.ts linguist-generated
packages/core/src/models-dev/snapshot.txt linguist-generated
packages/core/src/**/*.txt text eol=lf
packages/httpapi-codegen/test/generated/*.ts text eol=lf
@@ -2,6 +2,7 @@ import { describe, expect, test } from "bun:test"
import { mkdtemp, rm } from "node:fs/promises"
import { tmpdir } from "node:os"
import { join } from "node:path"
import { fileURLToPath } from "node:url"
import { Effect, FileSystem, Schema, SchemaAST, SchemaGetter } from "effect"
import {
HttpApi,
@@ -1096,7 +1097,7 @@ describe("HttpApiCodegen.generate", () => {
Effect.gen(function* () {
const output = compile(FixtureApi)
const actual = yield* Effect.promise(() =>
Array.fromAsync(new Bun.Glob("*.ts").scan(new URL("generated", import.meta.url).pathname)),
Array.fromAsync(new Bun.Glob("*.ts").scan(fileURLToPath(new URL("generated", import.meta.url)))),
)
expect(actual.sort((a, b) => a.localeCompare(b))).toEqual(
output.files.map((file) => file.path).sort((a, b) => a.localeCompare(b)),
+4 -3
View File
@@ -1,4 +1,5 @@
import { describe, expect } from "bun:test"
import { join } from "node:path"
import { Effect, FileSystem, Option } from "effect"
import { write, type Output } from "../src"
import { it } from "./effect"
@@ -15,8 +16,8 @@ describe("HttpApiCodegen.write", () => {
yield* write(output, "/generated")
expect(writes).toEqual([
{ path: "/generated/session.ts", content: "export const session = {}\n" },
{ path: "/generated/.httpapi-codegen.json", content: '["session.ts"]\n' },
{ path: join("/generated", "session.ts"), content: "export const session = {}\n" },
{ path: join("/generated", ".httpapi-codegen.json"), content: '["session.ts"]\n' },
])
}).pipe(
Effect.provideService(
@@ -55,7 +56,7 @@ describe("HttpApiCodegen.write", () => {
writeFileString: () => Effect.void,
}),
),
Effect.tap(() => Effect.sync(() => expect(removed).toEqual(["/generated/old.ts"]))),
Effect.tap(() => Effect.sync(() => expect(removed).toEqual([join("/generated", "old.ts")]))),
)
})
+27 -17
View File
@@ -11,6 +11,7 @@ import { ServerFetch } from "../src/fetch"
const options = {
app: { version: "test-version" },
database: { path: ":memory:" },
config: { project: false },
models: { fetch: false },
fs: { filewatcher: false },
} as const
@@ -26,15 +27,20 @@ function occupy(port: number, cancel = false) {
server: createServer((request, response) => {
requests.push(request.url ?? "")
response.end(cancel ? "cancelled" : "still running", () => {
if (cancel) servers.forEach((item) => item.server.close())
if (cancel)
servers.forEach((item) => {
// Bun clears its native handle in close(), so force-close connections first.
item.server.closeAllConnections()
item.server.close()
})
})
}),
}))
yield* Effect.addFinalizer(() =>
Effect.forEach(servers, (item) =>
Effect.callback<void>((resume) => {
item.server.close(() => resume(Effect.void))
item.server.closeAllConnections()
item.server.close(() => resume(Effect.void))
}),
),
)
@@ -154,22 +160,26 @@ it.live("falls back to port 1457 when OpenAI OAuth port 1455 remains busy", () =
}),
)
it.live("explains how to recover when both OpenAI OAuth callback ports are busy", () =>
Effect.gen(function* () {
yield* occupy(1455)
yield* occupy(1457)
const handler = yield* ServerFetch.make(options)
yield* ready(handler)
const response = yield* connectOpenAI(handler)
it.live(
"explains how to recover when both OpenAI OAuth callback ports are busy",
() =>
Effect.gen(function* () {
yield* occupy(1455)
yield* occupy(1457)
const handler = yield* ServerFetch.make(options)
yield* ready(handler)
const response = yield* connectOpenAI(handler)
expect(response.status).toBe(400)
expect(yield* Effect.promise(() => response.json())).toEqual({
_tag: "InvalidRequestError",
message:
"OpenAI browser login needs local port 1455 or 1457, but both are already in use. Stop the processes using those ports or choose ChatGPT Pro/Plus (headless), then try again.",
kind: "integration_authorization",
})
}),
expect(response.status).toBe(400)
expect(yield* Effect.promise(() => response.json())).toEqual({
_tag: "InvalidRequestError",
message:
"OpenAI browser login needs local port 1455 or 1457, but both are already in use. Stop the processes using those ports or choose ChatGPT Pro/Plus (headless), then try again.",
kind: "integration_authorization",
})
}),
// Real retries wait 18 * 200 ms; startup and scoped cleanup also count toward the deadline.
{ timeout: 10_000 },
)
it.live("treats destroying a missing workspace as success", () =>
@@ -1,19 +1,12 @@
import { describe, expect, test } from "bun:test"
import { Effect } from "effect"
const forbidden = /["']@opencode-ai\/(?:core|sdk|server)(?:\/[^"']*)?["']/
const oldSession = /(?:SessionV1|session-v1|legacy-message|legacy-message-values)/
describe("Session UI package boundaries", () => {
test("does not import server runtime packages", async () => {
const files = new Bun.Glob("**/*.{ts,tsx}")
const violations: string[] = []
for await (const path of files.scan({ cwd: import.meta.dir, absolute: true })) {
if (path === import.meta.path) continue
if (forbidden.test(await Bun.file(path).text())) violations.push(path.slice(import.meta.dir.length + 1))
}
expect(violations).toEqual([])
expect(await findViolations(forbidden)).toEqual([])
})
test("does not declare server runtime dependencies", async () => {
@@ -26,15 +19,7 @@ describe("Session UI package boundaries", () => {
})
test("does not contain old Session message boundaries", async () => {
const files = new Bun.Glob("**/*.{ts,tsx}")
const violations: string[] = []
for await (const path of files.scan({ cwd: import.meta.dir, absolute: true })) {
if (path === import.meta.path) continue
if (oldSession.test(await Bun.file(path).text())) violations.push(path.slice(import.meta.dir.length + 1))
}
expect(violations).toEqual([])
expect(await findViolations(oldSession)).toEqual([])
})
test("exports the current Session document surface", async () => {
@@ -49,3 +34,18 @@ describe("Session UI package boundaries", () => {
expect(exports["./timeline/projection"]).toBe("./src/timeline/projection.ts")
})
})
async function findViolations(pattern: RegExp) {
const files = await Array.fromAsync(new Bun.Glob("**/*.{ts,tsx}").scan({ cwd: import.meta.dir, absolute: true }))
const matches = await Effect.runPromise(
Effect.forEach(
files.filter((path) => path !== import.meta.path),
(path) =>
Effect.promise(async () =>
pattern.test(await Bun.file(path).text()) ? path.slice(import.meta.dir.length + 1) : undefined,
),
{ concurrency: 8 },
),
)
return matches.filter((path) => path !== undefined)
}
+11
View File
@@ -34,6 +34,10 @@
"dependsOn": [],
"outputs": ["dist/**"]
},
"@opencode-ai/ai#test": {
"dependsOn": ["^build"],
"outputs": []
},
"@opencode-ai/codemode#test": {
"dependsOn": ["^build"],
"outputs": []
@@ -45,6 +49,13 @@
"@opencode-ai/function#test": {
"outputs": []
},
"@opencode-ai/httpapi-codegen#test": {
"outputs": []
},
"@opencode-ai/server#test": {
"dependsOn": ["^build"],
"outputs": []
},
"@opencode-ai/cli#test": {
"dependsOn": ["^build"],
"outputs": []