forked from Crockan/MercuryToolbox
109 lines
3.2 KiB
Rust
109 lines
3.2 KiB
Rust
//! Integration tests for the `isonl` command.
|
|
//!
|
|
//! The pipe-delimited record expectations track public examples on
|
|
//! <https://ison.dev> and <https://ison.dev/spec.html>. The v1 CLI tests
|
|
//! JSONL/ISONL interop for scalar object records first.
|
|
|
|
use assert_cmd::Command;
|
|
use predicates::prelude::*;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
fn cargo_command() -> Command {
|
|
Command::cargo_bin("isonl").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_line_oriented_json_interop() {
|
|
cargo_command()
|
|
.arg("--help")
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("Convert between JSONL and ISONL"))
|
|
.stdout(predicate::str::contains("--from <FORMAT>"))
|
|
.stdout(predicate::str::contains("--to <FORMAT>"));
|
|
}
|
|
|
|
#[test]
|
|
fn jsonl_stdin_encodes_to_isonl_records() {
|
|
cargo_command()
|
|
.args(["--from", "jsonl", "--to", "isonl"])
|
|
.write_stdin("{\"id\":1,\"name\":\"Ada\",\"active\":true}\n{\"id\":2,\"name\":\"Bob\",\"active\":false}\n")
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains(
|
|
"object.record|id:int name:str active:bool|1 Ada true\n",
|
|
))
|
|
.stdout(predicate::str::contains(
|
|
"object.record|id:int name:str active:bool|2 Bob false\n",
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn isonl_path_decodes_to_jsonl() {
|
|
cargo_command()
|
|
.args(["--from", "isonl", "--to", "jsonl"])
|
|
.arg(fixture_path("fixtures/json-family/ison/users.isonl"))
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains(
|
|
"{\"id\":1,\"name\":\"Ada\",\"active\":true}\n",
|
|
))
|
|
.stdout(predicate::str::contains(
|
|
"{\"id\":2,\"name\":\"Bob\",\"active\":false}\n",
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn format_toon_wraps_jsonl_conversion_for_ai_pipelines() {
|
|
cargo_command()
|
|
.args(["--format", "toon", "--from", "isonl", "--to", "jsonl"])
|
|
.arg(fixture_path("fixtures/json-family/ison/users.isonl"))
|
|
.assert()
|
|
.success()
|
|
.stdout(predicate::str::contains("format: jsonl"))
|
|
.stdout(predicate::str::contains("records: 2"))
|
|
.stdout(predicate::str::contains("text:"));
|
|
}
|
|
|
|
#[test]
|
|
fn invalid_isonl_reports_line_number() {
|
|
cargo_command()
|
|
.args(["--from", "isonl", "--to", "jsonl"])
|
|
.write_stdin("object.record|id:int name:str|1\n")
|
|
.assert()
|
|
.failure()
|
|
.code(2)
|
|
.stderr(predicate::str::contains("line 1"))
|
|
.stderr(predicate::str::contains("expected 2 values"));
|
|
}
|
|
|
|
#[test]
|
|
fn empty_stdin_reports_usage_diagnostic() {
|
|
cargo_command()
|
|
.args(["--from", "jsonl", "--to", "isonl"])
|
|
.write_stdin("")
|
|
.assert()
|
|
.failure()
|
|
.code(2)
|
|
.stderr(
|
|
predicate::str::contains("input is empty").or(predicate::str::contains(
|
|
"provide one JSONL/ISONL path or pipe input into stdin",
|
|
)),
|
|
)
|
|
.stderr(predicate::str::contains("Usage:"));
|
|
}
|