first commit

This commit is contained in:
2026-08-14 23:41:57 +08:00
commit 086803a8dd
471 changed files with 91938 additions and 0 deletions
+164
View File
@@ -0,0 +1,164 @@
package provider
import (
"sort"
"testing"
)
func TestLookupProviderSpec_Hit(t *testing.T) {
spec, ok := LookupProviderSpec("deepseek")
if !ok {
t.Fatalf("LookupProviderSpec(deepseek): expected hit, got miss")
}
if spec.Name != "deepseek" {
t.Errorf("Name = %q, want deepseek", spec.Name)
}
if spec.DefaultBaseURL != "https://api.deepseek.com" {
t.Errorf("DefaultBaseURL = %q, want https://api.deepseek.com", spec.DefaultBaseURL)
}
if spec.Protocol != ProtocolOpenAIResponses {
t.Errorf("Protocol = %q, want %q", spec.Protocol, ProtocolOpenAIResponses)
}
if len(spec.EnvVars) != 1 || spec.EnvVars[0] != "DEEPSEEK_API_KEY" {
t.Errorf("EnvVars = %v, want [DEEPSEEK_API_KEY]", spec.EnvVars)
}
}
func TestLookupProviderSpec_Miss(t *testing.T) {
if _, ok := LookupProviderSpec("does-not-exist"); ok {
t.Errorf("LookupProviderSpec(does-not-exist): expected miss, got hit")
}
}
func TestAnthropicEnvVarOrder(t *testing.T) {
spec, ok := LookupProviderSpec("anthropic")
if !ok {
t.Fatal("LookupProviderSpec(anthropic): expected hit")
}
want := []string{"ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY", "CLAUDE_API_KEY"}
if len(spec.EnvVars) != len(want) {
t.Fatalf("EnvVars = %v, want %v", spec.EnvVars, want)
}
for i := range want {
if spec.EnvVars[i] != want[i] {
t.Errorf("EnvVars[%d] = %q, want %q (OAuth must be first)", i, spec.EnvVars[i], want[i])
}
}
if spec.Protocol != ProtocolAnthropic {
t.Errorf("Protocol = %q, want %q", spec.Protocol, ProtocolAnthropic)
}
}
func TestHuggingfaceEnvVar(t *testing.T) {
spec, ok := LookupProviderSpec("huggingface")
if !ok {
t.Fatal("LookupProviderSpec(huggingface): expected hit")
}
if len(spec.EnvVars) != 1 || spec.EnvVars[0] != "HF_TOKEN" {
t.Errorf("EnvVars = %v, want [HF_TOKEN]", spec.EnvVars)
}
}
func TestChineseCloudProviders(t *testing.T) {
cases := []struct {
name string
envVars []string
baseURL string
}{
{"qianfan", []string{"QIANFAN_API_KEY"}, "https://qianfan.baidubce.com/v2"},
{"volcengine", []string{"ARK_API_KEY", "VOLCENGINE_API_KEY"}, "https://ark.cn-beijing.volces.com/api/v3"},
{"dashscope", []string{"DASHSCOPE_API_KEY"}, "https://dashscope.aliyuncs.com/compatible-mode/v1"},
{"hunyuan", []string{"HUNYUAN_API_KEY"}, "https://api.hunyuan.cloud.tencent.com/v1"},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
spec, ok := LookupProviderSpec(tc.name)
if !ok {
t.Fatalf("LookupProviderSpec(%q): expected hit", tc.name)
}
if spec.Name != tc.name {
t.Errorf("Name = %q, want %q", spec.Name, tc.name)
}
if spec.DefaultBaseURL != tc.baseURL {
t.Errorf("DefaultBaseURL = %q, want %q", spec.DefaultBaseURL, tc.baseURL)
}
if spec.Protocol != ProtocolOpenAI {
t.Errorf("Protocol = %q, want %q", spec.Protocol, ProtocolOpenAI)
}
if spec.AuthScheme != AuthBearer {
t.Errorf("AuthScheme = %q, want %q", spec.AuthScheme, AuthBearer)
}
if len(spec.EnvVars) != len(tc.envVars) {
t.Fatalf("EnvVars = %v, want %v", spec.EnvVars, tc.envVars)
}
for i := range tc.envVars {
if spec.EnvVars[i] != tc.envVars[i] {
t.Errorf("EnvVars[%d] = %q, want %q", i, spec.EnvVars[i], tc.envVars[i])
}
}
})
}
}
func TestAzureBaseURLEnvVars(t *testing.T) {
spec, ok := LookupProviderSpec("azure-openai-responses")
if !ok {
t.Fatal("LookupProviderSpec(azure-openai-responses): expected hit")
}
found := false
for _, v := range spec.BaseURLEnvVars {
if v == "AZURE_OPENAI_BASE_URL" {
found = true
}
}
if !found {
t.Errorf("BaseURLEnvVars = %v, want to contain AZURE_OPENAI_BASE_URL", spec.BaseURLEnvVars)
}
}
func TestRegistryContainsAllExpectedProviders(t *testing.T) {
expected := []string{
"anthropic", "openai", "ant-ling", "deepseek", "nvidia", "google",
"groq", "cerebras", "xai", "openrouter", "vercel-ai-gateway", "zai",
"zai-coding-cn", "mistral", "minimax", "minimax-cn", "moonshotai",
"moonshotai-cn", "huggingface", "fireworks", "together", "opencode",
"opencode-go", "kimi-coding", "xiaomi", "xiaomi-token-plan-cn",
"xiaomi-token-plan-ams", "xiaomi-token-plan-sgp",
"qianfan", "volcengine", "dashscope", "hunyuan",
"azure-openai-responses", "amazon-bedrock", "google-vertex",
"cloudflare-workers-ai", "cloudflare-ai-gateway",
}
for _, name := range expected {
if _, ok := LookupProviderSpec(name); !ok {
t.Errorf("registry missing expected provider %q", name)
}
}
names := ProviderNames()
if len(names) != len(expected) {
t.Errorf("registry has %d providers, want %d", len(names), len(expected))
}
// Every spec must have a name, at least one env var, and a valid protocol.
for _, spec := range ProviderSpecs() {
if spec.Name == "" {
t.Error("found spec with empty Name")
}
if len(spec.EnvVars) == 0 {
t.Errorf("provider %q has no EnvVars", spec.Name)
}
if spec.Protocol != ProtocolOpenAI && spec.Protocol != ProtocolAnthropic && spec.Protocol != ProtocolOpenAIResponses {
t.Errorf("provider %q has invalid Protocol %q", spec.Name, spec.Protocol)
}
}
// No duplicate provider names.
seen := make(map[string]bool, len(names))
dupSorted := append([]string(nil), names...)
sort.Strings(dupSorted)
for _, n := range dupSorted {
if seen[n] {
t.Errorf("duplicate provider name %q in registry", n)
}
seen[n] = true
}
}