//! Integration test for the `cases:` dataset.
//!
//! Runs a mocked composition that references `${var.query}` and
//! `${var.limit}` against three cases. Each case produces its own
//! [`CaseTrace`]; the test asserts that the per-case `var` binding
//! threaded through into the recorded inputs.

use std::sync::Arc;

use mcptest_core::composition::{self, CompositionSpec, ResolvedComposition};
use mcptest_core::connector::ServerPool;
use serde_json::json;

#[tokio::test]
async fn cases_iterate_with_per_row_vars() {
    let yaml = r##"
name: parametric
nodes:
  - id: search
    tool: search_packages
    args:
      q: "${var.query}"
      limit: "${var.limit}"
    mock:
      result: { hits: [] }
output: search
cases:
  - name: short
    vars: { query: "mcp", limit: 1 }
  - name: long
    vars: { query: "test framework", limit: 10 }
  - name: golden
    vars: { query: "rubric", limit: 5 }
    golden: { hits: [] }
    expect:
      - target: "nodes.search.output.hits"
        matcher: { exact: [] }
"##;
    let spec: CompositionSpec = serde_yaml::from_str(yaml).unwrap();
    let (resolved, _) = ResolvedComposition::resolve(&spec).unwrap();
    assert_eq!(resolved.cases.len(), 3);
    let pool = Arc::new(ServerPool::new());
    let traces = composition::run_cases(&resolved, pool.as_ref(), None).await;
    assert_eq!(traces.len(), 3);

    let short = &traces[0];
    assert_eq!(short.name, "short");
    let short_search = short.trace.nodes.get("search").unwrap();
    assert_eq!(short_search.inputs, json!({"q": "mcp", "limit": 1}));

    let long = &traces[1];
    assert_eq!(long.name, "long");
    let long_search = long.trace.nodes.get("search").unwrap();
    assert_eq!(
        long_search.inputs,
        json!({"q": "test framework", "limit": 10})
    );

    let golden = &traces[2];
    assert_eq!(golden.name, "golden");
    assert!(golden.golden.is_some());
    assert_eq!(golden.expect.len(), 1);
}
