style: cargo fmt --all (round 4 ingest log feature follow-up)
Phase C4 executor 의 마지막 `fix(test): clippy + fmt fixes` commit 이 test file 부분만 fmt 적용. workspace 전체 fmt 누락 발견 → cargo fmt --all 적용. 모든 import alphabetical reorder + line wrapping 정합. 추가 untracked artifact 동시 commit: - docs/superpowers/specs/2026-05-28-v0.20-ingest-log-spec.md (491 line, ACCEPT) - docs/superpowers/plans/2026-05-28-v0.20-ingest-log-plan.md (616 line, ACCEPT) workspace test: 1370 passed / 0 failed / 50 ignored, ingest_log_smoke green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,7 +23,11 @@ async fn schema_tool_emits_error_v1_when_db_missing() {
|
||||
handler.state(),
|
||||
kebab_mcp::tools::schema::SchemaInput::default(),
|
||||
);
|
||||
assert_eq!(result.is_error, Some(true), "expected isError=true on missing DB");
|
||||
assert_eq!(
|
||||
result.is_error,
|
||||
Some(true),
|
||||
"expected isError=true on missing DB"
|
||||
);
|
||||
|
||||
let content = result.content.first().unwrap();
|
||||
let text = match &content.raw {
|
||||
@@ -31,6 +35,9 @@ async fn schema_tool_emits_error_v1_when_db_missing() {
|
||||
other => panic!("expected text content, got {other:?}"),
|
||||
};
|
||||
let v: serde_json::Value = serde_json::from_str(text).unwrap();
|
||||
assert_eq!(v.get("schema_version").and_then(|s| s.as_str()), Some("error.v1"));
|
||||
assert_eq!(
|
||||
v.get("schema_version").and_then(|s| s.as_str()),
|
||||
Some("error.v1")
|
||||
);
|
||||
assert_eq!(v.get("code").and_then(|s| s.as_str()), Some("not_indexed"));
|
||||
}
|
||||
|
||||
@@ -9,10 +9,7 @@ use rmcp::model::RawContent;
|
||||
fn minimal_config(data_dir: &std::path::Path, workspace_root: &std::path::Path) -> Config {
|
||||
let mut cfg = Config::defaults();
|
||||
cfg.storage.data_dir = data_dir.to_string_lossy().into_owned();
|
||||
cfg.storage.model_dir = data_dir
|
||||
.join("models")
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
cfg.storage.model_dir = data_dir.join("models").to_string_lossy().into_owned();
|
||||
cfg.workspace.root = workspace_root.to_string_lossy().into_owned();
|
||||
cfg.workspace.exclude.clear();
|
||||
cfg.models.embedding.provider = "none".to_string();
|
||||
|
||||
@@ -31,7 +31,11 @@ fn setup() -> (tempfile::TempDir, KebabHandler) {
|
||||
"# Alpha\n\nThis document mentions kebab and bread.",
|
||||
)
|
||||
.unwrap();
|
||||
let scope = SourceScope { root: workspace_root.clone(), include: vec![], exclude: vec![] };
|
||||
let scope = SourceScope {
|
||||
root: workspace_root.clone(),
|
||||
include: vec![],
|
||||
exclude: vec![],
|
||||
};
|
||||
let _ = kebab_app::ingest_with_config(config.clone(), scope, false).unwrap();
|
||||
let state = KebabAppState::new(config, None);
|
||||
let handler = KebabHandler::new(state);
|
||||
@@ -39,7 +43,10 @@ fn setup() -> (tempfile::TempDir, KebabHandler) {
|
||||
}
|
||||
|
||||
fn extract_json(result: &rmcp::model::CallToolResult) -> serde_json::Value {
|
||||
assert!(!result.is_error.unwrap_or(false), "expected isError=false, got {result:?}");
|
||||
assert!(
|
||||
!result.is_error.unwrap_or(false),
|
||||
"expected isError=false, got {result:?}"
|
||||
);
|
||||
let content = result.content.first().expect("at least one content item");
|
||||
let text = match &content.raw {
|
||||
RawContent::Text(t) => &t.text,
|
||||
@@ -89,7 +96,7 @@ async fn bulk_search_invalid_item_field_continues_with_per_item_error() {
|
||||
let input = kebab_mcp::tools::bulk_search::BulkSearchInput {
|
||||
queries: vec![
|
||||
json!({"query": "kebab", "mode": "lexical"}),
|
||||
json!({"query": "bread", "mode": "bogus"}), // invalid mode
|
||||
json!({"query": "bread", "mode": "bogus"}), // invalid mode
|
||||
],
|
||||
};
|
||||
let result = kebab_mcp::tools::bulk_search::handle(handler.state(), input);
|
||||
@@ -117,5 +124,8 @@ async fn bulk_search_over_cap_returns_tool_error() {
|
||||
RawContent::Text(t) => &t.text,
|
||||
other => panic!("expected Text content, got {other:?}"),
|
||||
};
|
||||
assert!(text.contains("max 100"), "expected 'max 100' in error: {text}");
|
||||
assert!(
|
||||
text.contains("max 100"),
|
||||
"expected 'max 100' in error: {text}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,10 +15,7 @@ use rmcp::model::RawContent;
|
||||
fn minimal_config(data_dir: &std::path::Path, workspace_root: &std::path::Path) -> Config {
|
||||
let mut cfg = Config::defaults();
|
||||
cfg.storage.data_dir = data_dir.to_string_lossy().into_owned();
|
||||
cfg.storage.model_dir = data_dir
|
||||
.join("models")
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
cfg.storage.model_dir = data_dir.join("models").to_string_lossy().into_owned();
|
||||
cfg.workspace.root = workspace_root.to_string_lossy().into_owned();
|
||||
cfg.workspace.exclude.clear();
|
||||
cfg.models.embedding.provider = "none".to_string();
|
||||
|
||||
@@ -112,6 +112,14 @@ async fn ingest_file_tool_idempotent_on_second_call() {
|
||||
other => panic!("expected text, got {other:?}"),
|
||||
};
|
||||
let v2: serde_json::Value = serde_json::from_str(text2).unwrap();
|
||||
assert_eq!(v2.get("new").and_then(serde_json::Value::as_u64), Some(0), "{v2:?}");
|
||||
assert_eq!(v2.get("unchanged").and_then(serde_json::Value::as_u64), Some(1), "{v2:?}");
|
||||
assert_eq!(
|
||||
v2.get("new").and_then(serde_json::Value::as_u64),
|
||||
Some(0),
|
||||
"{v2:?}"
|
||||
);
|
||||
assert_eq!(
|
||||
v2.get("unchanged").and_then(serde_json::Value::as_u64),
|
||||
Some(1),
|
||||
"{v2:?}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,10 +10,7 @@ use rmcp::model::RawContent;
|
||||
fn minimal_config(data_dir: &std::path::Path, workspace_root: &std::path::Path) -> Config {
|
||||
let mut cfg = Config::defaults();
|
||||
cfg.storage.data_dir = data_dir.to_string_lossy().into_owned();
|
||||
cfg.storage.model_dir = data_dir
|
||||
.join("models")
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
cfg.storage.model_dir = data_dir.join("models").to_string_lossy().into_owned();
|
||||
cfg.workspace.root = workspace_root.to_string_lossy().into_owned();
|
||||
cfg.workspace.exclude.clear();
|
||||
cfg.models.embedding.provider = "none".to_string();
|
||||
@@ -52,7 +49,10 @@ async fn schema_tool_returns_schema_v1_json() {
|
||||
"expected isError=false on healthy schema, got {result:?}"
|
||||
);
|
||||
|
||||
let content = result.content.first().expect("expected at least one content item");
|
||||
let content = result
|
||||
.content
|
||||
.first()
|
||||
.expect("expected at least one content item");
|
||||
|
||||
// Content = Annotated<RawContent>; deref to get the inner RawContent.
|
||||
let text = match &content.raw {
|
||||
@@ -67,7 +67,9 @@ async fn schema_tool_returns_schema_v1_json() {
|
||||
"unexpected schema_version in: {v}"
|
||||
);
|
||||
assert_eq!(
|
||||
v.get("capabilities").and_then(|c| c.get("mcp_server")).and_then(serde_json::Value::as_bool),
|
||||
v.get("capabilities")
|
||||
.and_then(|c| c.get("mcp_server"))
|
||||
.and_then(serde_json::Value::as_bool),
|
||||
Some(true),
|
||||
"mcp_server capability flag should be true after fb-30",
|
||||
);
|
||||
|
||||
@@ -10,10 +10,7 @@ use rmcp::model::RawContent;
|
||||
fn minimal_config(data_dir: &std::path::Path, workspace_root: &std::path::Path) -> Config {
|
||||
let mut cfg = Config::defaults();
|
||||
cfg.storage.data_dir = data_dir.to_string_lossy().into_owned();
|
||||
cfg.storage.model_dir = data_dir
|
||||
.join("models")
|
||||
.to_string_lossy()
|
||||
.into_owned();
|
||||
cfg.storage.model_dir = data_dir.join("models").to_string_lossy().into_owned();
|
||||
cfg.workspace.root = workspace_root.to_string_lossy().into_owned();
|
||||
cfg.workspace.exclude.clear();
|
||||
cfg.models.embedding.provider = "none".to_string();
|
||||
@@ -99,15 +96,15 @@ async fn search_tool_returns_search_response_v1() {
|
||||
"expected at least one hit for 'kebab' in 'a.md'"
|
||||
);
|
||||
assert_eq!(
|
||||
hits[0]
|
||||
.get("schema_version")
|
||||
.and_then(|s| s.as_str()),
|
||||
hits[0].get("schema_version").and_then(|s| s.as_str()),
|
||||
Some("search_hit.v1"),
|
||||
"first hit should carry schema_version=search_hit.v1"
|
||||
);
|
||||
// truncated must be present (bool); next_cursor may be null on last page.
|
||||
assert!(
|
||||
v.get("truncated").and_then(serde_json::Value::as_bool).is_some(),
|
||||
v.get("truncated")
|
||||
.and_then(serde_json::Value::as_bool)
|
||||
.is_some(),
|
||||
"envelope should carry truncated:bool"
|
||||
);
|
||||
assert!(
|
||||
|
||||
@@ -79,7 +79,10 @@ async fn search_with_trace_true_returns_trace_field() {
|
||||
let result = kebab_mcp::tools::search::handle(handler.state(), make_input(Some(true)));
|
||||
let v = extract_json(&result);
|
||||
assert_eq!(v["schema_version"], "search_response.v1");
|
||||
assert!(v["trace"].is_object(), "trace field present when trace:true");
|
||||
assert!(
|
||||
v["trace"].is_object(),
|
||||
"trace field present when trace:true"
|
||||
);
|
||||
assert!(v["trace"]["timing"]["total_ms"].is_number());
|
||||
assert!(v["trace"]["lexical"].is_array());
|
||||
assert!(v["trace"]["vector"].is_array());
|
||||
|
||||
@@ -7,7 +7,12 @@ use kebab_mcp::build_tools_vec;
|
||||
#[test]
|
||||
fn tools_list_returns_eight_tools() {
|
||||
let tools = build_tools_vec();
|
||||
assert_eq!(tools.len(), 8, "expected exactly 8 tools, got {}", tools.len());
|
||||
assert_eq!(
|
||||
tools.len(),
|
||||
8,
|
||||
"expected exactly 8 tools, got {}",
|
||||
tools.len()
|
||||
);
|
||||
|
||||
let names: Vec<&str> = tools.iter().map(|t| t.name.as_ref()).collect();
|
||||
assert!(names.contains(&"schema"), "missing 'schema' tool");
|
||||
@@ -15,7 +20,10 @@ fn tools_list_returns_eight_tools() {
|
||||
assert!(names.contains(&"search"), "missing 'search' tool");
|
||||
assert!(names.contains(&"ask"), "missing 'ask' tool");
|
||||
assert!(names.contains(&"ingest_file"), "missing 'ingest_file' tool");
|
||||
assert!(names.contains(&"ingest_stdin"), "missing 'ingest_stdin' tool");
|
||||
assert!(
|
||||
names.contains(&"ingest_stdin"),
|
||||
"missing 'ingest_stdin' tool"
|
||||
);
|
||||
assert!(names.contains(&"fetch"), "missing 'fetch' tool");
|
||||
assert!(names.contains(&"bulk_search"), "missing 'bulk_search' tool");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user