初始化仓库
This commit is contained in:
@@ -0,0 +1,257 @@
|
||||
package config_matrix
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/chenhg5/cc-connect/config"
|
||||
)
|
||||
|
||||
func writeConfig(t *testing.T, body string) string {
|
||||
t.Helper()
|
||||
path := filepath.Join(t.TempDir(), "config.toml")
|
||||
if err := os.WriteFile(path, []byte(body), 0o644); err != nil {
|
||||
t.Fatalf("write config: %v", err)
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func baseProjectTOML(extra string) string {
|
||||
return `
|
||||
data_dir = "` + filepath.ToSlash(os.TempDir()) + `/cc-connect-release-test"
|
||||
` + extra + `
|
||||
|
||||
[[projects]]
|
||||
name = "release"
|
||||
|
||||
[projects.agent]
|
||||
type = "claudecode"
|
||||
work_dir = "/tmp/cc-connect-release-work"
|
||||
|
||||
[[projects.platforms]]
|
||||
type = "feishu"
|
||||
app_id = "cli_release"
|
||||
app_secret = "secret"
|
||||
`
|
||||
}
|
||||
|
||||
func TestReleaseConfig_ProjectDisplayOverridesGlobalFromLoadedConfig(t *testing.T) {
|
||||
path := writeConfig(t, `
|
||||
attachment_send = "off"
|
||||
|
||||
[display]
|
||||
mode = "quiet"
|
||||
card_mode = "rich"
|
||||
thinking_messages = true
|
||||
tool_messages = false
|
||||
|
||||
[[projects]]
|
||||
name = "release"
|
||||
reset_on_idle_mins = 0
|
||||
|
||||
[projects.display]
|
||||
mode = "full"
|
||||
card_mode = "legacy"
|
||||
thinking_messages = false
|
||||
tool_messages = true
|
||||
thinking_max_len = 111
|
||||
tool_max_len = 222
|
||||
|
||||
[projects.agent]
|
||||
type = "claudecode"
|
||||
work_dir = "/tmp/cc-connect-release-work"
|
||||
|
||||
[[projects.platforms]]
|
||||
type = "feishu"
|
||||
app_id = "cli_release"
|
||||
app_secret = "secret"
|
||||
`)
|
||||
|
||||
cfg, err := config.Load(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Load() error = %v", err)
|
||||
}
|
||||
if cfg.AttachmentSend != "off" {
|
||||
t.Fatalf("AttachmentSend = %q, want off", cfg.AttachmentSend)
|
||||
}
|
||||
if len(cfg.Projects) != 1 {
|
||||
t.Fatalf("projects = %d, want 1", len(cfg.Projects))
|
||||
}
|
||||
proj := &cfg.Projects[0]
|
||||
if proj.ResetOnIdleMins == nil || *proj.ResetOnIdleMins != 0 {
|
||||
t.Fatalf("ResetOnIdleMins = %#v, want explicit 0", proj.ResetOnIdleMins)
|
||||
}
|
||||
|
||||
mode, thinking, tools, thinkingMax, toolMax, _, _ := config.EffectiveDisplay(cfg, proj)
|
||||
if mode != config.DisplayModeFull {
|
||||
t.Fatalf("mode = %q, want project full override", mode)
|
||||
}
|
||||
if thinking {
|
||||
t.Fatal("thinking_messages = true, want project override false")
|
||||
}
|
||||
if !tools {
|
||||
t.Fatal("tool_messages = false, want project override true")
|
||||
}
|
||||
if thinkingMax != 111 || toolMax != 222 {
|
||||
t.Fatalf("max lens = %d/%d, want 111/222", thinkingMax, toolMax)
|
||||
}
|
||||
if got := config.EffectiveCardMode(cfg, proj); got != "legacy" {
|
||||
t.Fatalf("card mode = %q, want project legacy override", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleaseConfig_DefaultsKeepAttachmentsAndFullDisplayEnabled(t *testing.T) {
|
||||
path := writeConfig(t, baseProjectTOML(""))
|
||||
cfg, err := config.Load(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Load() error = %v", err)
|
||||
}
|
||||
if cfg.AttachmentSend != "on" {
|
||||
t.Fatalf("AttachmentSend = %q, want default on", cfg.AttachmentSend)
|
||||
}
|
||||
mode, thinking, tools, _, _, _, _ := config.EffectiveDisplay(cfg, &cfg.Projects[0])
|
||||
if mode != config.DisplayModeFull || !thinking || !tools {
|
||||
t.Fatalf("display = mode:%s thinking:%v tools:%v, want full/true/true", mode, thinking, tools)
|
||||
}
|
||||
if got := config.EffectiveCardMode(cfg, &cfg.Projects[0]); got != "legacy" {
|
||||
t.Fatalf("card mode = %q, want default legacy", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleaseConfig_BehaviorControlSwitchesParseFromLoadedConfig(t *testing.T) {
|
||||
path := writeConfig(t, `
|
||||
[stream_preview]
|
||||
enabled = false
|
||||
disabled_platforms = ["feishu", "telegram"]
|
||||
interval_ms = 250
|
||||
min_delta_chars = 12
|
||||
max_chars = 777
|
||||
|
||||
[[projects]]
|
||||
name = "release"
|
||||
show_context_indicator = false
|
||||
reply_footer = false
|
||||
disabled_commands = ["restart", "shell"]
|
||||
|
||||
[projects.display]
|
||||
mode = "quiet"
|
||||
card_mode = "rich"
|
||||
thinking_messages = false
|
||||
tool_messages = false
|
||||
|
||||
[projects.agent]
|
||||
type = "claudecode"
|
||||
work_dir = "/tmp/cc-connect-release-work"
|
||||
|
||||
[[projects.platforms]]
|
||||
type = "feishu"
|
||||
app_id = "cli_release"
|
||||
app_secret = "secret"
|
||||
`)
|
||||
|
||||
cfg, err := config.Load(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Load() error = %v", err)
|
||||
}
|
||||
if cfg.StreamPreview.Enabled == nil || *cfg.StreamPreview.Enabled {
|
||||
t.Fatalf("stream_preview.enabled = %#v, want false", cfg.StreamPreview.Enabled)
|
||||
}
|
||||
if got := strings.Join(cfg.StreamPreview.DisabledPlatforms, ","); got != "feishu,telegram" {
|
||||
t.Fatalf("stream_preview.disabled_platforms = %#v", cfg.StreamPreview.DisabledPlatforms)
|
||||
}
|
||||
if cfg.StreamPreview.IntervalMs == nil || *cfg.StreamPreview.IntervalMs != 250 {
|
||||
t.Fatalf("stream_preview.interval_ms = %#v, want 250", cfg.StreamPreview.IntervalMs)
|
||||
}
|
||||
if cfg.StreamPreview.MinDeltaChars == nil || *cfg.StreamPreview.MinDeltaChars != 12 {
|
||||
t.Fatalf("stream_preview.min_delta_chars = %#v, want 12", cfg.StreamPreview.MinDeltaChars)
|
||||
}
|
||||
if cfg.StreamPreview.MaxChars == nil || *cfg.StreamPreview.MaxChars != 777 {
|
||||
t.Fatalf("stream_preview.max_chars = %#v, want 777", cfg.StreamPreview.MaxChars)
|
||||
}
|
||||
|
||||
proj := &cfg.Projects[0]
|
||||
if proj.ShowContextIndicator == nil || *proj.ShowContextIndicator {
|
||||
t.Fatalf("show_context_indicator = %#v, want false", proj.ShowContextIndicator)
|
||||
}
|
||||
if proj.ReplyFooter == nil || *proj.ReplyFooter {
|
||||
t.Fatalf("reply_footer = %#v, want false", proj.ReplyFooter)
|
||||
}
|
||||
if strings.Join(proj.DisabledCommands, ",") != "restart,shell" {
|
||||
t.Fatalf("disabled_commands = %#v", proj.DisabledCommands)
|
||||
}
|
||||
mode, thinking, tools, _, _, _, _ := config.EffectiveDisplay(cfg, proj)
|
||||
if mode != config.DisplayModeQuiet || thinking || tools {
|
||||
t.Fatalf("display = mode:%s thinking:%v tools:%v, want quiet/false/false", mode, thinking, tools)
|
||||
}
|
||||
if got := config.EffectiveCardMode(cfg, proj); got != "rich" {
|
||||
t.Fatalf("card mode = %q, want rich", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReleaseConfig_InvalidCriticalOptionsFailFast(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
toml string
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "invalid attachment send",
|
||||
toml: baseProjectTOML(`
|
||||
attachment_send = "maybe"
|
||||
`),
|
||||
wantErr: `attachment_send must be "on" or "off"`,
|
||||
},
|
||||
{
|
||||
name: "invalid project display mode",
|
||||
toml: `
|
||||
[[projects]]
|
||||
name = "release"
|
||||
|
||||
[projects.display]
|
||||
mode = "verbose"
|
||||
|
||||
[projects.agent]
|
||||
type = "claudecode"
|
||||
work_dir = "/tmp/cc-connect-release-work"
|
||||
|
||||
[[projects.platforms]]
|
||||
type = "feishu"
|
||||
app_id = "cli_release"
|
||||
app_secret = "secret"
|
||||
`,
|
||||
wantErr: `projects[0].display.mode must be "full", "compact", or "quiet"`,
|
||||
},
|
||||
{
|
||||
name: "negative reset on idle",
|
||||
toml: `
|
||||
[[projects]]
|
||||
name = "release"
|
||||
reset_on_idle_mins = -1
|
||||
|
||||
[projects.agent]
|
||||
type = "claudecode"
|
||||
work_dir = "/tmp/cc-connect-release-work"
|
||||
|
||||
[[projects.platforms]]
|
||||
type = "feishu"
|
||||
app_id = "cli_release"
|
||||
app_secret = "secret"
|
||||
`,
|
||||
wantErr: "reset_on_idle_mins must be >= 0",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, err := config.Load(writeConfig(t, tt.toml))
|
||||
if err == nil {
|
||||
t.Fatal("Load() error = nil, want validation error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), tt.wantErr) {
|
||||
t.Fatalf("Load() error = %q, want contains %q", err.Error(), tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user