//! Integration tests for the `isonl` command. //! //! The pipe-delimited record expectations track public examples on //! and . 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 ")) .stdout(predicate::str::contains("--to ")); } #[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:")); }