- 前端: 所有界面显示、i18n 文本、组件中的品牌名称 - 后端: 服务层、设置默认值、邮件模板、安装向导 - 数据库: 迁移脚本注释 - 保持功能完全一致,仅更改品牌名称 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
129 lines
3.1 KiB
Go
129 lines
3.1 KiB
Go
package service
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
// TestConvertClaudeToolsToGeminiTools_CustomType 测试custom类型工具转换
|
|
func TestConvertClaudeToolsToGeminiTools_CustomType(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
tools any
|
|
expectedLen int
|
|
description string
|
|
}{
|
|
{
|
|
name: "Standard tools",
|
|
tools: []any{
|
|
map[string]any{
|
|
"name": "get_weather",
|
|
"description": "Get weather info",
|
|
"input_schema": map[string]any{"type": "object"},
|
|
},
|
|
},
|
|
expectedLen: 1,
|
|
description: "标准工具格式应该正常转换",
|
|
},
|
|
{
|
|
name: "Custom type tool (MCP format)",
|
|
tools: []any{
|
|
map[string]any{
|
|
"type": "custom",
|
|
"name": "mcp_tool",
|
|
"custom": map[string]any{
|
|
"description": "MCP tool description",
|
|
"input_schema": map[string]any{"type": "object"},
|
|
},
|
|
},
|
|
},
|
|
expectedLen: 1,
|
|
description: "Custom类型工具应该从custom字段读取",
|
|
},
|
|
{
|
|
name: "Mixed standard and custom tools",
|
|
tools: []any{
|
|
map[string]any{
|
|
"name": "standard_tool",
|
|
"description": "Standard",
|
|
"input_schema": map[string]any{"type": "object"},
|
|
},
|
|
map[string]any{
|
|
"type": "custom",
|
|
"name": "custom_tool",
|
|
"custom": map[string]any{
|
|
"description": "Custom",
|
|
"input_schema": map[string]any{"type": "object"},
|
|
},
|
|
},
|
|
},
|
|
expectedLen: 1,
|
|
description: "混合工具应该都能正确转换",
|
|
},
|
|
{
|
|
name: "Custom tool without custom field",
|
|
tools: []any{
|
|
map[string]any{
|
|
"type": "custom",
|
|
"name": "invalid_custom",
|
|
// 缺少 custom 字段
|
|
},
|
|
},
|
|
expectedLen: 0, // 应该被跳过
|
|
description: "缺少custom字段的custom工具应该被跳过",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := convertClaudeToolsToGeminiTools(tt.tools)
|
|
|
|
if tt.expectedLen == 0 {
|
|
if result != nil {
|
|
t.Errorf("%s: expected nil result, got %v", tt.description, result)
|
|
}
|
|
return
|
|
}
|
|
|
|
if result == nil {
|
|
t.Fatalf("%s: expected non-nil result", tt.description)
|
|
}
|
|
|
|
if len(result) != 1 {
|
|
t.Errorf("%s: expected 1 tool declaration, got %d", tt.description, len(result))
|
|
return
|
|
}
|
|
|
|
toolDecl, ok := result[0].(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("%s: result[0] is not map[string]any", tt.description)
|
|
}
|
|
|
|
funcDecls, ok := toolDecl["functionDeclarations"].([]any)
|
|
if !ok {
|
|
t.Fatalf("%s: functionDeclarations is not []any", tt.description)
|
|
}
|
|
|
|
toolsArr, _ := tt.tools.([]any)
|
|
expectedFuncCount := 0
|
|
for _, tool := range toolsArr {
|
|
toolMap, _ := tool.(map[string]any)
|
|
if toolMap["name"] != "" {
|
|
// 检查是否为有效的custom工具
|
|
if toolMap["type"] == "custom" {
|
|
if toolMap["custom"] != nil {
|
|
expectedFuncCount++
|
|
}
|
|
} else {
|
|
expectedFuncCount++
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(funcDecls) != expectedFuncCount {
|
|
t.Errorf("%s: expected %d function declarations, got %d",
|
|
tt.description, expectedFuncCount, len(funcDecls))
|
|
}
|
|
})
|
|
}
|
|
}
|