forked from Crockan/MercuryToolbox
121 lines
3.6 KiB
Rust
121 lines
3.6 KiB
Rust
//! Integration tests for the `ison` command.
|
|
//!
|
|
//! The table block expectations track public examples on <https://ison.dev> and
|
|
//! <https://ison.dev/spec.html>. The v1 CLI tests a deterministic JSON-family
|
|
//! subset that is stable enough for local conversion workflows.
|
|
|
|
use std::fs;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
use assert_cmd::Command;
|
|
use predicates::prelude::*;
|
|
use tempfile::tempdir;
|
|
|
|
fn cargo_command() -> Command {
|
|
Command::cargo_bin("ison").expect("binary")
|
|
}
|
|
|
|
fn fixture_path(relative: &str) -> PathBuf {
|
|
let fixture = Path::new(env!("CARGO_MANIFEST_DIR"))
|
|
.parent()
|
|
.and_then(Path::parent)
|
|
.expect("workspace root")
|
|
.join(relative);
|
|
assert!(
|
|
fixture.exists(),
|
|
"missing fixture `{relative}` at {}",
|
|
fixture.display()
|
|
);
|
|
fixture
|
|
}
|
|
|
|
#[test]
|
|
fn help_mentions_ison_examples_and_interop() {
|
|
cargo_command()
|
|
.arg("--help")
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("Convert between JSON and ISON"))
|
|
.stdout(predicate::str::contains("ISON block syntax"))
|
|
.stdout(predicate::str::contains("--from <FORMAT>"))
|
|
.stdout(predicate::str::contains("--to <FORMAT>"));
|
|
}
|
|
|
|
#[test]
|
|
fn json_path_encodes_to_ison_table_block() {
|
|
cargo_command()
|
|
.args(["--from", "json", "--to", "ison"])
|
|
.arg(fixture_path("fixtures/json-family/ison/users.json"))
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains(
|
|
"table.users\nid:int name:str active:bool\n1 Ada true\n2 Bob false\n",
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn ison_path_decodes_to_json() {
|
|
cargo_command()
|
|
.args(["--from", "ison", "--to", "json"])
|
|
.arg(fixture_path("fixtures/json-family/ison/users.ison"))
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("\"users\": ["))
|
|
.stdout(predicate::str::contains("\"name\": \"Ada\""))
|
|
.stdout(predicate::str::contains("\"active\": false"));
|
|
}
|
|
|
|
#[test]
|
|
fn stdin_json_auto_encodes_to_ison() {
|
|
cargo_command()
|
|
.write_stdin("{\"users\":[{\"id\":1,\"name\":\"Ada\",\"active\":true}]}")
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("table.users"))
|
|
.stdout(predicate::str::contains("1 Ada true"));
|
|
}
|
|
|
|
#[test]
|
|
fn format_toon_wraps_conversion_for_ai_pipelines() {
|
|
cargo_command()
|
|
.args(["--format", "toon", "--from", "json", "--to", "ison"])
|
|
.arg(fixture_path("fixtures/json-family/ison/users.json"))
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("format: ison"))
|
|
.stdout(predicate::str::contains("text:"))
|
|
.stdout(predicate::str::contains("table.users"));
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_ison_reports_line_number() {
|
|
let temp = tempdir().expect("tempdir");
|
|
let path = temp.path().join("broken.ison");
|
|
fs::write(&path, "table.users\nid:int name:str\n1\n").expect("fixture");
|
|
|
|
cargo_command()
|
|
.args(["--from", "ison", "--to", "json"])
|
|
.arg(&path)
|
|
.assert()
|
|
.failure()
|
|
.code(2)
|
|
.stderr(predicate::str::contains("line 3"))
|
|
.stderr(predicate::str::contains("expected 2 values"));
|
|
}
|
|
|
|
#[test]
|
|
fn json_path_with_spaces_encodes_to_ison() {
|
|
let temp = tempdir().expect("tempdir");
|
|
let path = temp.path().join("users with spaces.json");
|
|
fs::write(&path, r#"{"users":[{"id":1,"name":"Ada","active":true}]}"#)
|
|
.expect("spaced path fixture");
|
|
|
|
cargo_command()
|
|
.args(["--from", "json", "--to", "ison"])
|
|
.arg(&path)
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("table.users"))
|
|
.stdout(predicate::str::contains("1 Ada true"));
|
|
}
|