//! TuiConfig 的 JSON 编解码与默认值测试。 //! Tests for TuiConfig JSON codec and defaults. use focus_json::JsonValue; use focus_tui::config::{ProviderKind, TuiConfig}; #[test] fn defaults() { let cfg = TuiConfig::default(); assert_eq!(cfg.provider, ProviderKind::Anthropic); assert_eq!(cfg.api_key, ""); assert_eq!(cfg.model, "claude-sonnet-4"); assert_eq!(cfg.base_url, None); assert_eq!(cfg.context_window, None); assert!(!cfg.is_ready()); } #[test] fn roundtrip_json() { let cfg = TuiConfig { provider: ProviderKind::OpenAI, openai_protocol: focus_providers::openai::OpenAiProtocol::ChatCompletions, base_url: Some("https://localhost:8080/v1".into()), api_key: "sk-abc".into(), model: "gpt-4o".into(), context_window: Some(128_000), }; let json = cfg.to_json(); let restored = TuiConfig::from_json(&json); assert_eq!(restored.provider, ProviderKind::OpenAI); assert_eq!( restored.openai_protocol, focus_providers::openai::OpenAiProtocol::ChatCompletions ); assert_eq!( restored.base_url.as_deref(), Some("https://localhost:8080/v1") ); assert_eq!(restored.api_key, "sk-abc"); assert_eq!(restored.model, "gpt-4o"); assert_eq!(restored.context_window, Some(128_000)); assert!(restored.is_ready()); } #[test] fn tolerates_missing_and_invalid_fields() { // 空对象 → 全默认。 // Empty object → all defaults. let cfg = TuiConfig::from_json(&JsonValue::obj()); assert_eq!(cfg.provider, ProviderKind::Anthropic); // 非法字段回落默认。 // Invalid fields fall back to defaults. let mut o = JsonValue::obj(); o.insert("provider", "bogus".into()).ok(); o.insert("contextWindow", JsonValue::Num(-5.0)).ok(); o.insert("model", "".into()).ok(); let cfg = TuiConfig::from_json(&o); assert_eq!(cfg.provider, ProviderKind::Anthropic); assert_eq!(cfg.context_window, None); assert_eq!(cfg.model, "claude-sonnet-4"); }