Skip to content
Source
Sign inSign up
Open History to see the last commit

instanceEnvironment.test.ts

115 lines4.2 KB

1import * as NodeServices from "@effect/platform-node/NodeServices";
2import { describe, expect, it } from "@effect/vitest";
3import { SecretProviderId } from "@t3tools/contracts";
4import * as Effect from "effect/Effect";
5import * as Path from "effect/Path";
6import * as HostProcess from "@t3tools/shared/HostProcess";
7​
8import { mergeProviderInstanceEnvironment } from "./instanceEnvironment.ts";
9​
10describe("mergeProviderInstanceEnvironment", () => {
11 it.effect.each([
12 { value: "~/.account", tail: ".account" },
13 { value: "~\\.account\\work", tail: ".account\\work" },
14 ])("expands configured provider homes set to $value", ({ value, tail }) =>
15 Effect.gen(function* () {
16 const path = yield* Path.Path;
17 const baseEnv = {
18 CODEX_HOME: "~/.inherited-codex",
19 CLAUDE_CONFIG_DIR: "~/.inherited-claude",
20 GROK_HOME: "~/.inherited-grok",
21 };
22 const environment = yield* mergeProviderInstanceEnvironment(
23 [
24 { name: "CODEX_HOME", value, sensitive: false },
25 { name: "CLAUDE_CONFIG_DIR", value, sensitive: false },
26 { name: "GROK_HOME", value, sensitive: false },
27 { name: "CUSTOM_VALUE", value, sensitive: false },
28 ],
29 baseEnv,
30 );
31​
32 expect(environment).toEqual({
33 CODEX_HOME: path.join("/home/ada", tail),
34 CLAUDE_CONFIG_DIR: path.join("/home/ada", tail),
35 GROK_HOME: path.join("/home/ada", tail),
36 CUSTOM_VALUE: value,
37 });
38 expect(baseEnv).toEqual({
39 CODEX_HOME: "~/.inherited-codex",
40 CLAUDE_CONFIG_DIR: "~/.inherited-claude",
41 GROK_HOME: "~/.inherited-grok",
42 });
43 }).pipe(
44 Effect.provideService(HostProcess.HomeDirectory, "/home/ada"),
45 Effect.provide(NodeServices.layer),
46 ),
47 );
48​
49 it.effect("leaves inherited provider homes unchanged", () =>
50 Effect.gen(function* () {
51 const baseEnv = { CODEX_HOME: "~/.codex", CLAUDE_CONFIG_DIR: "~\\.claude" };
52​
53 expect(
54 yield* mergeProviderInstanceEnvironment(
55 [{ name: "CUSTOM_VALUE", value: "~/.custom", sensitive: false }],
56 baseEnv,
57 ),
58 ).toEqual({ ...baseEnv, CUSTOM_VALUE: "~/.custom" });
59 }),
60 );
61​
62 it.effect("overrides inherited environment values and preserves empty strings", () =>
63 Effect.gen(function* () {
64 expect(
65 yield* mergeProviderInstanceEnvironment(
66 [
67 { name: "OPENROUTER_API_KEY", value: "sk-or-test", sensitive: true },
68 { name: "ANTHROPIC_API_KEY", value: "", sensitive: false },
69 {
70 name: "OPENAI_API_KEY",
71 value: {
72 provider: SecretProviderId.make("personal"),
73 reference: "op://Private/OpenAI/credential",
74 },
75 sensitive: true,
76 },
77 ],
78 { ANTHROPIC_API_KEY: "inherited", OPENAI_API_KEY: "inherited", PATH: "/bin" },
79 ),
80 ).toMatchObject({
81 OPENROUTER_API_KEY: "sk-or-test",
82 ANTHROPIC_API_KEY: "",
83 OPENAI_API_KEY: "inherited",
84 PATH: "/bin",
85 });
86 }),
87 );
88​
89 it.effect("replaces every inherited spelling of a name on Windows, and only there", () =>
90 Effect.gen(function* () {
91 const merge = (platform: NodeJS.Platform) =>
92 mergeProviderInstanceEnvironment(
93 [{ name: "Https_Proxy", value: "http://gateway", sensitive: false }],
94 { HTTPS_PROXY: "http://mine", PATH: "/bin" },
95 ).pipe(Effect.provideService(HostProcess.Platform, platform));
96 // A home variable in another spelling is still expanded.
97 expect(
98 yield* mergeProviderInstanceEnvironment(
99 [{ name: "Codex_Home", value: "~/corp", sensitive: false }],
100 {},
101 ).pipe(
102 Effect.provideService(HostProcess.Platform, "win32"),
103 Effect.provideService(HostProcess.HomeDirectory, "/home/ada"),
104 ),
105 ).toEqual({ CODEX_HOME: "/home/ada/corp" });
106 // Upper case sorts first, so it also wins where a spawn merges the parent environment back.
107 expect(yield* merge("win32")).toEqual({ HTTPS_PROXY: "http://gateway", PATH: "/bin" });
108 expect(yield* merge("linux")).toEqual({
109 HTTPS_PROXY: "http://mine",
110 Https_Proxy: "http://gateway",
111 PATH: "/bin",
112 });
113 }),
114 );
115});