Files

127 lines
3.4 KiB
Rust

//! Integration tests for the `jsonshape` command.
use std::path::PathBuf;
use assert_cmd::Command;
use predicates::prelude::*;
use serde_json::Value;
use tempfile::tempdir;
fn cargo_command() -> Command {
Command::cargo_bin("jsonshape").expect("binary")
}
fn fixture(path: &str) -> PathBuf {
let fixture = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("..")
.join("fixtures")
.join(path);
assert!(
fixture.exists(),
"missing fixture `{path}` at {}",
fixture.display()
);
fixture
}
fn json_stdout(output: &[u8]) -> Value {
serde_json::from_slice(output).unwrap_or_else(|error| {
panic!(
"stdout should be valid JSON: {error}\n{}",
String::from_utf8_lossy(output)
)
})
}
#[test]
fn accepts_stdin_path_streams_in_auto_mode() {
let output = cargo_command()
.arg("--json")
.write_stdin(format!(
"{}\n{}\n",
fixture("reading/config.json").display(),
fixture("toon/config.json").display()
))
.assert()
.success()
.get_output()
.stdout
.clone();
let payload = json_stdout(&output);
assert_eq!(
payload["documents"],
2,
"stdout={}",
String::from_utf8_lossy(&output)
);
let paths = payload["paths"].as_array().unwrap_or_else(|| {
panic!(
"paths should be an array: {}",
String::from_utf8_lossy(&output)
)
});
assert!(
paths.iter().any(|entry| entry["path"] == "$.app.name"),
"stdout={}",
String::from_utf8_lossy(&output)
);
assert!(
paths.iter().any(|entry| entry["path"] == "$.context.task"),
"stdout={}",
String::from_utf8_lossy(&output)
);
}
#[test]
fn help_mentions_repo_safe_examples() {
cargo_command()
.arg("--help")
.assert()
.success()
.stdout(predicate::str::contains(
"bat --style=plain --paging=never .\\fixtures\\jsonshape\\events.jsonl",
))
.stdout(predicate::str::contains(
"fd -g config.json . .\\fixtures | jsonshape --json",
));
}
#[test]
fn diff_compares_paths_hidden_by_display_limit() {
let temp = tempdir().expect("tempdir");
let before = temp.path().join("before.json");
let after = temp.path().join("after.json");
std::fs::write(&before, r#"{"a":1,"z":1}"#).expect("before fixture");
std::fs::write(&after, r#"{"a":1,"z":"changed"}"#).expect("after fixture");
cargo_command()
.arg("diff")
.arg(&before)
.arg(&after)
.arg("--limit")
.arg("1")
.assert()
.success()
.stdout(predicate::str::contains("change=changed"))
.stdout(predicate::str::contains("$.z"));
}
#[test]
fn auto_mode_rejects_pretty_json_in_explicit_jsonl_and_ndjson_paths() {
let temp = tempdir().expect("tempdir");
let jsonl = temp.path().join("pretty.jsonl");
let ndjson = temp.path().join("pretty.ndjson");
std::fs::write(&jsonl, "{\n \"ok\": true\n}\n").expect("jsonl fixture");
std::fs::write(&ndjson, "{\n \"ok\": true\n}\n").expect("ndjson fixture");
for path in [&jsonl, &ndjson] {
cargo_command()
.arg(path)
.assert()
.failure()
.stderr(predicate::str::contains("invalid JSONL at line 1"));
}
}