//! Memory smoke test — full lifecycle: store → retrieve → dedup //! //! Uses in-memory SqliteStorage with real FTS5. use std::sync::Arc; use zclaw_growth::{ ExperienceStore, Experience, VikingAdapter, storage::SqliteStorage, }; #[tokio::test] async fn smoke_memory_full_lifecycle() { let sqlite = SqliteStorage::in_memory().await; let viking = Arc::new(VikingAdapter::new(Arc::new(sqlite))); let store = ExperienceStore::new(viking); // 1. Store first experience let exp1 = Experience::new( "agent-smoke", "用户反馈页面加载缓慢", "前端性能问题,首屏加载超 5 秒", vec![ "分析 Network 瀑布图".to_string(), "启用代码分割".to_string(), "配置 CDN".to_string(), ], "首屏加载降至 1.2 秒", ); store.store_experience(&exp1).await.expect("store exp1"); // 2. Store second experience (different topic) let exp2 = Experience::new( "agent-smoke", "数据库查询缓慢", "订单列表查询超时", vec!["添加复合索引".to_string()], "查询时间从 3s 降至 50ms", ); store.store_experience(&exp2).await.expect("store exp2"); // 3. Retrieve by agent — should find both let all = store.find_by_agent("agent-smoke").await.expect("find by agent"); assert_eq!(all.len(), 2, "should have 2 experiences"); // 4. Search by pattern — should find relevant one let db_results = store.find_by_pattern("agent-smoke", "数据库 查询 缓慢").await.expect("search"); assert!(!db_results.is_empty(), "FTS5 should find database experience"); assert!( db_results.iter().any(|e| e.pain_pattern.contains("数据库")), "should match database experience" ); // 5. Dedup — store same experience again store.store_experience(&exp1).await.expect("dedup store"); let all_after_dedup = store.find_by_agent("agent-smoke").await.expect("find after dedup"); assert_eq!(all_after_dedup.len(), 2, "should still have 2 after dedup"); let deduped = all_after_dedup.iter().find(|e| e.pain_pattern.contains("页面加载")).unwrap(); assert!(deduped.reuse_count >= 1, "reuse_count should be incremented"); }