Kaynağa Gözat

Migrate custom provider tests to instance fixtures

Migrate the next custom provider/model config tests to Effect-aware instance fixtures while keeping timing neutral and behavior unchanged.
Kit Langton 3 ay önce
ebeveyn
işleme
ae2ecd1ed3

+ 99 - 123
packages/opencode/test/provider/provider.test.ts

@@ -228,81 +228,65 @@ it.instance(
   },
   },
 )
 )
 
 
-test("custom model alias via config", async () => {
-  await using tmp = await tmpdir({
-    init: async (dir) => {
-      await Bun.write(
-        path.join(dir, "opencode.json"),
-        JSON.stringify({
-          $schema: "https://opencode.ai/config.json",
-          provider: {
-            anthropic: {
-              models: {
-                "my-alias": {
-                  id: "claude-sonnet-4-20250514",
-                  name: "My Custom Alias",
-                },
-              },
+it.instance(
+  "custom model alias via config",
+  Effect.gen(function* () {
+    yield* setProcessEnv("ANTHROPIC_API_KEY", "test-api-key")
+    const providers = yield* Provider.Service.use((provider) => provider.list())
+    expect(providers[ProviderID.anthropic]).toBeDefined()
+    expect(providers[ProviderID.anthropic].models["my-alias"]).toBeDefined()
+    expect(providers[ProviderID.anthropic].models["my-alias"].name).toBe("My Custom Alias")
+  }),
+  {
+    config: {
+      provider: {
+        anthropic: {
+          models: {
+            "my-alias": {
+              id: "claude-sonnet-4-20250514",
+              name: "My Custom Alias",
             },
             },
           },
           },
-        }),
-      )
-    },
-  })
-  await withTestInstance({
-    directory: tmp.path,
-    fn: async (ctx) => {
-      await set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
-      const providers = await list(ctx)
-      expect(providers[ProviderID.anthropic]).toBeDefined()
-      expect(providers[ProviderID.anthropic].models["my-alias"]).toBeDefined()
-      expect(providers[ProviderID.anthropic].models["my-alias"].name).toBe("My Custom Alias")
+        },
+      },
     },
     },
-  })
-})
+  },
+)
 
 
-test("custom provider with npm package", async () => {
-  await using tmp = await tmpdir({
-    init: async (dir) => {
-      await Bun.write(
-        path.join(dir, "opencode.json"),
-        JSON.stringify({
-          $schema: "https://opencode.ai/config.json",
-          provider: {
-            "custom-provider": {
-              name: "Custom Provider",
-              npm: "@ai-sdk/openai-compatible",
-              api: "https://api.custom.com/v1",
-              env: ["CUSTOM_API_KEY"],
-              models: {
-                "custom-model": {
-                  name: "Custom Model",
-                  tool_call: true,
-                  limit: {
-                    context: 128000,
-                    output: 4096,
-                  },
-                },
-              },
-              options: {
-                apiKey: "custom-key",
+it.instance(
+  "custom provider with npm package",
+  Effect.gen(function* () {
+    const providers = yield* Provider.Service.use((provider) => provider.list())
+    expect(providers[ProviderID.make("custom-provider")]).toBeDefined()
+    expect(providers[ProviderID.make("custom-provider")].name).toBe("Custom Provider")
+    expect(providers[ProviderID.make("custom-provider")].models["custom-model"]).toBeDefined()
+  }),
+  {
+    config: {
+      provider: {
+        "custom-provider": {
+          name: "Custom Provider",
+          npm: "@ai-sdk/openai-compatible",
+          api: "https://api.custom.com/v1",
+          env: ["CUSTOM_API_KEY"],
+          models: {
+            "custom-model": {
+              name: "Custom Model",
+              tool_call: true,
+              limit: {
+                context: 128000,
+                output: 4096,
               },
               },
             },
             },
           },
           },
-        }),
-      )
-    },
-  })
-  await withTestInstance({
-    directory: tmp.path,
-    fn: async (ctx) => {
-      const providers = await list(ctx)
-      expect(providers[ProviderID.make("custom-provider")]).toBeDefined()
-      expect(providers[ProviderID.make("custom-provider")].name).toBe("Custom Provider")
-      expect(providers[ProviderID.make("custom-provider")].models["custom-model"]).toBeDefined()
+          options: {
+            apiKey: "custom-key",
+          },
+        },
+      },
     },
     },
-  })
-})
+  },
+)
 
 
 it.instance(
 it.instance(
   "filters alpha provider models by default",
   "filters alpha provider models by default",
@@ -324,66 +308,58 @@ experimentalModels.instance(
   { config: alphaProviderConfig },
   { config: alphaProviderConfig },
 )
 )
 
 
-test("custom DeepSeek openai-compatible model defaults interleaved reasoning field", async () => {
-  await using tmp = await tmpdir({
-    init: async (dir) => {
-      await Bun.write(
-        path.join(dir, "opencode.json"),
-        JSON.stringify({
-          $schema: "https://opencode.ai/config.json",
-          provider: {
-            "custom-provider": {
-              name: "Custom Provider",
-              npm: "@ai-sdk/openai-compatible",
-              api: "https://api.custom.com/v1",
-              models: {
-                "deepseek-r1": {
-                  name: "DeepSeek R1",
-                },
-                "deepseek-details": {
-                  name: "DeepSeek Details",
-                  interleaved: { field: "reasoning_details" },
-                },
-                "custom-model": {
-                  name: "Custom Model",
-                },
-              },
-              options: {
-                apiKey: "custom-key",
-              },
+it.instance(
+  "custom DeepSeek openai-compatible model defaults interleaved reasoning field",
+  Effect.gen(function* () {
+    const providers = yield* Provider.Service.use((provider) => provider.list())
+    const provider = providers[ProviderID.make("custom-provider")]
+    expect(provider.models["deepseek-r1"].capabilities.interleaved).toEqual({ field: "reasoning_content" })
+    expect(provider.models["deepseek-details"].capabilities.interleaved).toEqual({ field: "reasoning_details" })
+    expect(provider.models["custom-model"].capabilities.interleaved).toBe(false)
+    expect(providers[ProviderID.make("custom-anthropic-provider")].models["deepseek-r1"].capabilities.interleaved).toBe(
+      false,
+    )
+  }),
+  {
+    config: {
+      provider: {
+        "custom-provider": {
+          name: "Custom Provider",
+          npm: "@ai-sdk/openai-compatible",
+          api: "https://api.custom.com/v1",
+          models: {
+            "deepseek-r1": {
+              name: "DeepSeek R1",
             },
             },
-            "custom-anthropic-provider": {
-              name: "Custom Anthropic Provider",
-              npm: "@ai-sdk/anthropic",
-              api: "https://api.custom.com/v1",
-              models: {
-                "deepseek-r1": {
-                  name: "DeepSeek R1",
-                },
-              },
-              options: {
-                apiKey: "custom-key",
-              },
+            "deepseek-details": {
+              name: "DeepSeek Details",
+              interleaved: { field: "reasoning_details" },
+            },
+            "custom-model": {
+              name: "Custom Model",
             },
             },
           },
           },
-        }),
-      )
-    },
-  })
-  await withTestInstance({
-    directory: tmp.path,
-    fn: async (ctx) => {
-      const providers = await list(ctx)
-      const provider = providers[ProviderID.make("custom-provider")]
-      expect(provider.models["deepseek-r1"].capabilities.interleaved).toEqual({ field: "reasoning_content" })
-      expect(provider.models["deepseek-details"].capabilities.interleaved).toEqual({ field: "reasoning_details" })
-      expect(provider.models["custom-model"].capabilities.interleaved).toBe(false)
-      expect(
-        providers[ProviderID.make("custom-anthropic-provider")].models["deepseek-r1"].capabilities.interleaved,
-      ).toBe(false)
+          options: {
+            apiKey: "custom-key",
+          },
+        },
+        "custom-anthropic-provider": {
+          name: "Custom Anthropic Provider",
+          npm: "@ai-sdk/anthropic",
+          api: "https://api.custom.com/v1",
+          models: {
+            "deepseek-r1": {
+              name: "DeepSeek R1",
+            },
+          },
+          options: {
+            apiKey: "custom-key",
+          },
+        },
+      },
     },
     },
-  })
-})
+  },
+)
 
 
 test("env variable takes precedence, config merges options", async () => {
 test("env variable takes precedence, config merges options", async () => {
   await using tmp = await tmpdir({
   await using tmp = await tmpdir({

+ 1 - 0
perf/test-suite.md

@@ -69,6 +69,7 @@ Repeated setup work, long sleeps/timeouts, serial integration tests, filesystem/
 | HTTP listen PTY ticket tests restart the same listener topology twice                                     | Folded directory-scoped ticket regression into the broader unsafe-ticket test                  | 7.051s    | 6.170s  | keep     | Two targeted reruns passed after the change: 6.76s, 6.17s; still covers mint failure and successful same-directory upgrade. |
 | HTTP listen PTY ticket tests restart the same listener topology twice                                     | Folded directory-scoped ticket regression into the broader unsafe-ticket test                  | 7.051s    | 6.170s  | keep     | Two targeted reruns passed after the change: 6.76s, 6.17s; still covers mint failure and successful same-directory upgrade. |
 | File watcher readiness can write before async native subscriptions are active                             | Retried short readiness writes and accepted symlink-realpath HEAD events                       | failed    | 4.62s   | keep     | Three sequential focused watcher runs passed: 4.62s, 4.57s, 4.64s; full suite no longer failed in `watcher.test.ts`.        |
 | File watcher readiness can write before async native subscriptions are active                             | Retried short readiness writes and accepted symlink-realpath HEAD events                       | failed    | 4.62s   | keep     | Three sequential focused watcher runs passed: 4.62s, 4.57s, 4.64s; full suite no longer failed in `watcher.test.ts`.        |
 | First provider config/env/filtering block can use Effect-aware instance fixtures                          | Migrated six `tmpdir` + `withTestInstance` cases to `it.instance`                              | 6.06s     | 6.07s   | keep     | Neutral timing, but removes manual config file writes and instance plumbing; use as the pattern for later provider slices.  |
 | First provider config/env/filtering block can use Effect-aware instance fixtures                          | Migrated six `tmpdir` + `withTestInstance` cases to `it.instance`                              | 6.06s     | 6.07s   | keep     | Neutral timing, but removes manual config file writes and instance plumbing; use as the pattern for later provider slices.  |
+| Custom provider/model config cases can use Effect-aware instance fixtures                                 | Migrated three more config-heavy provider cases to `it.instance`                               | 6.07s     | 6.12s   | keep     | Neutral timing within noise, but continues removing manual config file writes on top of the first provider fixture PR.      |
 
 
 ## Profiling Results
 ## Profiling Results