1import * as Cloudflare from "@/Cloudflare/index.ts";
2import { Interaction } from "@/Interaction.ts";
3import { RpcProviderProxy } from "@/Local/RpcProviderProxy";
4import * as Test from "@/Test/Alchemy";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7
8/**
9 * Contract tests for the test harness's sidecar topology (see
10 * MakeOptions.sidecar in Test/Core.ts): `dev: true` runs local providers
11 * behind the RPC proxy used by the real `alchemy dev` command BY DEFAULT,
12 * and `sidecar: false` opts back into the in-process topology.
13 *
14 * The dev-mode resource tests (KV/R2/Queue/D1 `*.local.test.ts`) would
15 * still pass in-process if the default silently stopped installing the
16 * proxy — the whole point of the topology is that missing main-process
17 * dependencies only surface under it (#1007). These tests pin the harness
18 * contract directly so a refactor of Test.make can't quietly demote every
19 * dev test back to in-process.
20 */
21
22const dev = Test.make({
23 providers: Cloudflare.providers(),
24 dev: true,
25});
26
27const inProcess = Test.make({
28 providers: Cloudflare.providers(),
29 dev: true,
30 sidecar: false,
31});
32
33const live = Test.make({
34 providers: Cloudflare.providers(),
35});
36
37dev.test(
38 "dev: true installs the RpcProviderProxy by default",
39 Effect.gen(function* () {
40 const proxy = yield* Effect.serviceOption(RpcProviderProxy);
41 expect(proxy._tag).toBe("Some");
42 }),
43 { tags: ["provider:cloudflare", "local"] },
44);
45
46inProcess.test(
47 "sidecar: false opts a dev test out of the RpcProviderProxy",
48 Effect.gen(function* () {
49 const proxy = yield* Effect.serviceOption(RpcProviderProxy);
50 expect(proxy._tag).toBe("None");
51 }),
52 { tags: ["provider:cloudflare", "local"] },
53);
54
55live.test(
56 "non-dev tests do not install the RpcProviderProxy",
57 Effect.gen(function* () {
58 const proxy = yield* Effect.serviceOption(RpcProviderProxy);
59 expect(proxy._tag).toBe("None");
60 }),
61 { tags: ["provider:cloudflare", "local"] },
62);
63
64live.test(
65 "test runtimes provide a non-interactive Interaction",
66 Effect.gen(function* () {
67 const interaction = yield* Interaction;
68 const failure = yield* Effect.flip(
69 interaction.prompt.confirm({ message: "?" }),
70 );
71 expect(failure._tag).toBe("NonInteractiveTerminal");
72 }),
73 { tags: ["provider:cloudflare", "local"] },
74);