use std::fs;
use assert_cmd::Command;
use tempfile::tempdir;
fn cbor() -> Command {
Command::cargo_bin("cbor").unwrap()
}
fn write_fixture(dir: &std::path::Path, name: &str, content: &[u8]) {
fs::write(dir.join(name), content).unwrap();
}
#[test]
fn json_roundtrip() {
let dir = tempdir().unwrap();
write_fixture(dir.path(), "in.json", b"{\"a\":1,\"b\":[2,3]}");
let cbor_bytes = cbor()
.arg("import")
.arg(dir.path().join("in.json"))
.assert()
.success()
.get_output()
.stdout
.clone();
let mut cmd = cbor();
cmd.arg("export").arg("--format=json").write_stdin(cbor_bytes);
cmd.assert().success().stdout("{\"a\":1,\"b\":[2,3]}");
}
#[test]
fn yaml_roundtrip() {
let dir = tempdir().unwrap();
write_fixture(dir.path(), "in.yaml", b"a: 1\nb:\n- 2\n- 3\n");
let cbor_bytes = cbor()
.arg("import")
.arg(dir.path().join("in.yaml"))
.assert()
.success()
.get_output()
.stdout
.clone();
let mut cmd = cbor();
cmd.arg("export").arg("--format=yaml").write_stdin(cbor_bytes);
cmd.assert().success().stdout("a: 1\nb:\n- 2\n- 3\n");
}
#[test]
fn toml_roundtrip() {
let dir = tempdir().unwrap();
write_fixture(dir.path(), "in.toml", b"a = 1\nb = [2, 3]\n");
let cbor_bytes = cbor()
.arg("import")
.arg(dir.path().join("in.toml"))
.assert()
.success()
.get_output()
.stdout
.clone();
let mut cmd = cbor();
cmd.arg("export").arg("--format=toml").write_stdin(cbor_bytes);
cmd.assert().success().stdout("a = 1\nb = [2, 3]\n");
}
#[test]
fn stdin_import_export() {
let cbor_bytes = cbor()
.arg("import")
.arg("--format=json")
.write_stdin("{\"x\":1}")
.assert()
.success()
.get_output()
.stdout
.clone();
let mut export_cmd = cbor();
export_cmd
.arg("export")
.arg("--format=json")
.write_stdin(cbor_bytes);
export_cmd.assert().success().stdout("{\"x\":1}");
}
#[test]
fn stdin_import_without_format_errors() {
let mut cmd = cbor();
cmd.arg("import").write_stdin("{\"x\":1}");
cmd.assert().failure().stderr(predicates::str::contains("No format specified"));
}
#[test]
fn multi_file_import() {
let dir = tempdir().unwrap();
write_fixture(dir.path(), "a.json", b"1");
write_fixture(dir.path(), "b.json", b"2");
let cbor_bytes = cbor()
.arg("import")
.arg("--format=json")
.arg(dir.path().join("a.json"))
.arg(dir.path().join("b.json"))
.assert()
.success()
.get_output()
.stdout
.clone();
assert_eq!(&cbor_bytes, b"\x01\x02");
let mut cmd = cbor();
cmd.arg("export").arg("--format=json").write_stdin(cbor_bytes);
cmd.assert().success().stdout("1\n2");
}
#[test]
fn custom_delimiter() {
let data = b"\x01\x02";
let mut cmd = cbor();
cmd
.arg("-d=,")
.arg("export")
.arg("--format=json")
.write_stdin(&data[..]);
cmd.assert().success().stdout("1,2");
}
#[test]
fn yaml_default_document_separator() {
let data = b"\x01\x02";
let mut cmd = cbor();
cmd.arg("export").arg("--format=yaml").write_stdin(&data[..]);
cmd.assert().success().stdout("1\n\n---\n2\n");
}
#[test]
fn verbose_goes_to_stderr() {
let dir = tempdir().unwrap();
write_fixture(dir.path(), "x.cbor", b"\x01");
let assert = cbor()
.arg("-vv")
.arg("export")
.arg("--format=json")
.arg(dir.path().join("x.cbor"))
.assert()
.success();
assert.stdout("1");
}
#[test]
fn missing_file_error() {
let dir = tempdir().unwrap();
let nonexistent = dir.path().join("nope.cbor");
cbor()
.arg("inspect")
.arg(&nonexistent)
.assert()
.failure()
.stderr(predicates::str::contains("File does not exist"));
}
#[test]
fn yml_extension_supported() {
let dir = tempdir().unwrap();
write_fixture(dir.path(), "test.yml", b"[1, 2]\n");
cbor()
.arg("import")
.arg(dir.path().join("test.yml"))
.assert()
.success();
}
#[test]
fn inspect_output() {
let dir = tempdir().unwrap();
write_fixture(dir.path(), "test.cbor", b"\x82\x01\x02");
cbor()
.arg("inspect")
.arg(dir.path().join("test.cbor"))
.assert()
.success()
.stdout(predicates::str::contains("[1, 2]"));
}
#[test]
fn inspect_stdin() {
let mut cmd = cbor();
cmd.arg("inspect").write_stdin(b"\x18\x2a"); cmd.assert().success().stdout("42\n");
}
#[test]
fn invalid_cbor_error() {
let dir = tempdir().unwrap();
write_fixture(dir.path(), "bad.cbor", b"\xff");
cbor()
.arg("export")
.arg("--format=json")
.arg(dir.path().join("bad.cbor"))
.assert()
.failure()
.stderr(predicates::str::contains("Failed to export"));
}
#[test]
fn delimiter_unescape_newline() {
let data = b"\x01\x02";
let mut cmd = cbor();
cmd
.arg(r"-d=\n")
.arg("export")
.arg("--format=json")
.write_stdin(&data[..]);
let output = cmd.assert().success().get_output().stdout.clone();
let output = String::from_utf8(output).unwrap();
assert!(output.contains('\n'), "should contain a literal newline: {output:?}");
}
#[test]
fn cross_format_json_to_yaml() {
let dir = tempdir().unwrap();
write_fixture(dir.path(), "in.json", b"{\"key\": \"value\"}");
let cbor_bytes = cbor()
.arg("import")
.arg(dir.path().join("in.json"))
.assert()
.success()
.get_output()
.stdout
.clone();
let mut cmd = cbor();
cmd
.arg("export")
.arg("--format=yaml")
.write_stdin(cbor_bytes);
cmd.assert().success().stdout("key: value\n");
}