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>
81 lines
2.7 KiB
Rust
81 lines
2.7 KiB
Rust
//! Integration: `build_tools_vec` returns 8 tools with correct names and
|
|
//! inputSchema. Uses the extracted `pub fn build_tools_vec()` helper — no
|
|
//! transport or RequestContext needed.
|
|
|
|
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()
|
|
);
|
|
|
|
let names: Vec<&str> = tools.iter().map(|t| t.name.as_ref()).collect();
|
|
assert!(names.contains(&"schema"), "missing 'schema' tool");
|
|
assert!(names.contains(&"doctor"), "missing 'doctor' tool");
|
|
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(&"fetch"), "missing 'fetch' tool");
|
|
assert!(names.contains(&"bulk_search"), "missing 'bulk_search' tool");
|
|
}
|
|
|
|
#[test]
|
|
fn search_tool_input_schema_has_required_query() {
|
|
let tools = build_tools_vec();
|
|
let search = tools
|
|
.iter()
|
|
.find(|t| t.name.as_ref() == "search")
|
|
.expect("search tool must be present");
|
|
|
|
// input_schema is Arc<JsonObject> (serde_json::Map<String, Value>).
|
|
let schema_val = serde_json::Value::Object(search.input_schema.as_ref().clone());
|
|
|
|
let required = schema_val
|
|
.get("required")
|
|
.and_then(|v| v.as_array())
|
|
.expect("search inputSchema must have a 'required' array");
|
|
|
|
assert!(
|
|
required.iter().any(|v| v.as_str() == Some("query")),
|
|
"search inputSchema 'required' must contain 'query', got: {required:?}"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn schema_and_doctor_tools_accept_empty_input() {
|
|
let tools = build_tools_vec();
|
|
|
|
for name in &["schema", "doctor"] {
|
|
let tool = tools
|
|
.iter()
|
|
.find(|t| t.name.as_ref() == *name)
|
|
.unwrap_or_else(|| panic!("{name} tool must be present"));
|
|
|
|
let schema_val = serde_json::Value::Object(tool.input_schema.as_ref().clone());
|
|
// An empty-input schema has type "object" and no required fields
|
|
// (or no 'required' key at all).
|
|
let ty = schema_val.get("type").and_then(|v| v.as_str());
|
|
assert_eq!(
|
|
ty,
|
|
Some("object"),
|
|
"{name} inputSchema 'type' must be 'object', got {ty:?}"
|
|
);
|
|
|
|
if let Some(required) = schema_val.get("required").and_then(|v| v.as_array()) {
|
|
assert!(
|
|
required.is_empty(),
|
|
"{name} inputSchema 'required' must be empty, got: {required:?}"
|
|
);
|
|
}
|
|
}
|
|
}
|