-
Notifications
You must be signed in to change notification settings - Fork 1.5k
test: add package-level Vitest examples for web-cluster and shared packages #1826
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,8 @@ | |
| "scripts": { | ||
| "dev_": "pnpm dotenv -e ../../.env -- concurrently \"deno run --allow-all --watch ./src/runner/index.ts\" \"deno run --allow-all --watch ./src/shard-manager.ts\"", | ||
| "build": "pnpm run --filter @cap/web-cluster^... build", | ||
| "build:docker": "cd ../.. && docker build -f apps/web-cluster/Dockerfile -t ghcr.io/brendonovich/cap-web-cluster:latest ." | ||
| "build:docker": "cd ../.. && docker build -f apps/web-cluster/Dockerfile -t ghcr.io/brendonovich/cap-web-cluster:latest .", | ||
| "test": "pnpm exec vitest run" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
None of the four new workspaces ship a Prompt To Fix With AIThis is a comment left during a code review.
Path: apps/web-cluster/package.json
Line: 8
Comment:
**No `vitest.config` file for the new test suites**
None of the four new workspaces ship a `vitest.config.ts`, while every existing workspace that has a `test` script (`apps/desktop`, `apps/discord-bot`, `apps/web`) provides one. Without a config, Vitest uses default settings — no TypeScript path-alias resolution, no custom environment, and no `globals` injection. Adding at least a minimal config file per package aligns with the project's existing pattern.
How can I resolve this? If you propose a fix, please make it concise. |
||
| }, | ||
| "dependencies": { | ||
| "@cap/web-backend": "workspace:*", | ||
|
|
@@ -26,6 +27,7 @@ | |
| }, | ||
| "devDependencies": { | ||
| "concurrently": "^9.2.1", | ||
| "dotenv-cli": "^10.0.0" | ||
| "dotenv-cli": "^10.0.0", | ||
| "vitest": "~2.1.9" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import { Effect } from "effect"; | ||
| import { afterEach, describe, expect, it, vi } from "vitest"; | ||
|
|
||
| import { ContainerMetadata } from "./container-metadata"; | ||
|
|
||
| afterEach(() => { | ||
| delete process.env.ECS_CONTAINER_METADATA_URI_V4; | ||
| vi.unstubAllGlobals(); | ||
| vi.restoreAllMocks(); | ||
| }); | ||
|
|
||
| describe("container metadata", () => { | ||
| it("falls back to 0.0.0.0 when metadata URI is not configured", async () => { | ||
| delete process.env.ECS_CONTAINER_METADATA_URI_V4; | ||
|
|
||
| const ip = await Effect.runPromise( | ||
| Effect.gen(function* () { | ||
| const metadata = yield* ContainerMetadata; | ||
| return metadata.ipAddress; | ||
| }).pipe(Effect.provide(ContainerMetadata.Default)), | ||
| ); | ||
| expect(ip).toBe("0.0.0.0"); | ||
| }); | ||
|
|
||
| it("uses ECS metadata endpoint when URI is configured", async () => { | ||
| process.env.ECS_CONTAINER_METADATA_URI_V4 = "http://metadata"; | ||
|
|
||
| const fetchMock = vi.fn().mockResolvedValue({ | ||
| json: async () => ({ | ||
| Containers: [{ Networks: [{ IPv4Addresses: ["10.0.0.7"] }] }], | ||
| }), | ||
| }); | ||
| vi.stubGlobal("fetch", fetchMock); | ||
|
|
||
| const ip = await Effect.runPromise( | ||
| Effect.gen(function* () { | ||
| const metadata = yield* ContainerMetadata; | ||
| return metadata.ipAddress; | ||
| }).pipe(Effect.provide(ContainerMetadata.Default)), | ||
| ); | ||
|
|
||
| expect(fetchMock).toHaveBeenCalledWith("http://metadata/task"); | ||
| expect(ip).toBe("10.0.0.7"); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { defineConfig } from "vitest/config"; | ||
|
|
||
| export default defineConfig({ | ||
| test: { | ||
| environment: "node", | ||
| }, | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { describe, expect, it, vi } from "vitest"; | ||
|
|
||
| import { getSupportedMimeType } from "./mime-types"; | ||
|
|
||
| describe("sdk-recorder mime type selection", () => { | ||
| it("prioritizes higher quality preferred codecs first", () => { | ||
| const isTypeSupported = vi.fn((mimeType: string) => | ||
| [ | ||
| "video/webm;codecs=vp9,opus", | ||
| "video/webm;codecs=vp8,opus", | ||
| "video/webm", | ||
| ].includes(mimeType), | ||
| ); | ||
| vi.stubGlobal("MediaRecorder", { isTypeSupported }); | ||
|
|
||
| expect(getSupportedMimeType()).toBe("video/webm;codecs=vp9,opus"); | ||
| expect(isTypeSupported).toHaveBeenCalledTimes(1); | ||
| expect(isTypeSupported).toHaveBeenCalledWith("video/webm;codecs=vp9,opus"); | ||
|
|
||
| vi.unstubAllGlobals(); | ||
| }); | ||
|
|
||
| it("returns empty string when no preferred mime type is supported", () => { | ||
| vi.stubGlobal("MediaRecorder", { isTypeSupported: vi.fn(() => false) }); | ||
|
|
||
| expect(getSupportedMimeType()).toBe(""); | ||
|
|
||
| vi.unstubAllGlobals(); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { defineConfig } from "vitest/config"; | ||
|
|
||
| export default defineConfig({ | ||
| test: { | ||
| environment: "node", | ||
| }, | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { describe, expect, it } from "vitest"; | ||
|
|
||
| import { OrganizationHexColor, OrganizationLogoUpdate } from "./desktop"; | ||
|
|
||
| describe("desktop API contract schemas", () => { | ||
| it("accepts valid org brand hex colors", () => { | ||
| expect(OrganizationHexColor.parse("#A1b2C3")).toBe("#A1b2C3"); | ||
| }); | ||
|
|
||
| it("rejects invalid org brand hex colors", () => { | ||
| expect(() => OrganizationHexColor.parse("#GGGGGG")).toThrow(); | ||
| expect(() => OrganizationHexColor.parse("123456")).toThrow(); | ||
| }); | ||
|
|
||
| it("validates logo update variants", () => { | ||
| expect(OrganizationLogoUpdate.parse({ action: "keep" }).action).toBe("keep"); | ||
| expect(() => | ||
| OrganizationLogoUpdate.parse({ | ||
| action: "upload", | ||
| contentType: "image/png", | ||
| data: "", | ||
| }), | ||
| ).toThrow(); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { defineConfig } from "vitest/config"; | ||
|
|
||
| export default defineConfig({ | ||
| test: { | ||
| environment: "node", | ||
| }, | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| import { Option, Schema } from "effect"; | ||
| import { describe, expect, it } from "vitest"; | ||
|
|
||
| import { optional } from "./utils"; | ||
|
|
||
| describe("web-domain optional schema helper", () => { | ||
| it("maps nullish values to Option.none and concrete values to Option.some", () => { | ||
| const schema = Schema.Struct({ | ||
| value: optional(Schema.String), | ||
| }); | ||
| const decode = Schema.decodeUnknownSync(schema); | ||
|
|
||
| const someValue = decode({ value: "cap" }).value; | ||
| const missingValue = decode({}).value; | ||
| const noneFromNull = decode({ value: null }).value; | ||
|
|
||
| expect(Option.isSome(someValue)).toBe(true); | ||
| if (Option.isSome(someValue)) { | ||
| expect(someValue.value).toBe("cap"); | ||
| } | ||
| expect(missingValue).toBeUndefined(); | ||
| expect(Option.isNone(noneFromNull)).toBe(true); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { defineConfig } from "vitest/config"; | ||
|
|
||
| export default defineConfig({ | ||
| test: { | ||
| environment: "node", | ||
| }, | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vitestmissing from devDependenciespnpm exec vitest runresolves the binary from the localnode_modules/.bin. Sincevitestis not declared as adevDependencyhere (or in any of the other three affected packages), the command will fail on a clean install or in CI. It likely passes locally only because vitest is hoisted from another workspace package (e.g.apps/web), which is an implicit, unreliable dependency. The same gap affectspackages/sdk-recorder,packages/web-api-contract, andpackages/web-domain.Prompt To Fix With AI