#![allow(clippy::needless_raw_string_hashes)]
use assert_cmd::Command;
use std::io::Write;
use tempfile::tempdir;
fn aw() -> Command {
Command::cargo_bin("atomwrite").expect("atomwrite binary not found")
}
#[test]
fn json_schema_for_set() {
let out = aw()
.arg("--json-schema")
.arg("set")
.arg("a.toml")
.arg("a.b")
.arg("1")
.output()
.expect("set --json-schema");
assert!(
out.status.success(),
"set --json-schema failed: stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let schema = String::from_utf8_lossy(&out.stdout);
assert!(
schema.contains("set") || schema.contains("WriteOutput"),
"schema should mention set: {}",
schema
);
}
#[test]
fn json_schema_for_get() {
let out = aw()
.arg("--json-schema")
.arg("get")
.arg("a.toml")
.arg("a.b")
.output()
.expect("get --json-schema");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let schema = String::from_utf8_lossy(&out.stdout);
assert!(schema.contains("get") || schema.contains("ReadOutput") || schema.contains("Output"));
}
#[test]
fn json_schema_for_del() {
let out = aw()
.arg("--json-schema")
.arg("del")
.arg("a.toml")
.arg("a.b")
.output()
.expect("del --json-schema");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let schema = String::from_utf8_lossy(&out.stdout);
assert!(!schema.is_empty(), "del schema should not be empty");
}
#[test]
fn json_schema_for_case() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.rs");
std::fs::write(&f, "").unwrap();
let out = aw()
.arg("--json-schema")
.arg("case")
.arg(&f)
.arg("--to")
.arg("pascal")
.output()
.expect("case --json-schema");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let schema = String::from_utf8_lossy(&out.stdout);
assert!(!schema.is_empty(), "case schema should not be empty");
}
#[test]
fn json_schema_for_query() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.rs");
std::fs::write(&f, "").unwrap();
let out = aw()
.arg("--json-schema")
.arg("query")
.arg(&f)
.output()
.expect("query --json-schema");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let schema = String::from_utf8_lossy(&out.stdout);
assert!(!schema.is_empty(), "query schema should not be empty");
}
#[test]
fn json_schema_for_outline() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.rs");
std::fs::write(&f, "").unwrap();
let out = aw()
.arg("--json-schema")
.arg("outline")
.arg(&f)
.output()
.expect("outline --json-schema");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let schema = String::from_utf8_lossy(&out.stdout);
assert!(!schema.is_empty(), "outline schema should not be empty");
}
#[test]
fn recover_orphan_journals_empty_dir() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.txt");
std::fs::write(&f, "hello").unwrap();
let sidecars: Vec<_> = std::fs::read_dir(dir.path())
.unwrap()
.filter_map(|e| e.ok())
.filter(|e| {
e.path()
.file_name()
.and_then(|n| n.to_str())
.map(|n| n.contains(".atomwrite.journal."))
.unwrap_or(false)
})
.collect();
assert!(sidecars.is_empty(), "fresh dir should have no WAL sidecars");
}
#[test]
fn recover_orphan_journals_with_committed_entry() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.toml");
std::fs::write(&f, "[pkg]\nname=\"x\"\n").unwrap();
let out = aw()
.arg("--workspace")
.arg(dir.path())
.arg("set")
.arg("a.toml")
.arg("pkg.version")
.arg("1.0.0")
.output()
.expect("set");
assert!(
out.status.success(),
"set should succeed: stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let sidecars: Vec<_> = std::fs::read_dir(dir.path())
.unwrap()
.filter_map(|e| e.ok())
.filter(|e| {
e.path()
.file_name()
.and_then(|n| n.to_str())
.map(|n| n.contains(".atomwrite.journal."))
.unwrap_or(false)
})
.collect();
assert!(
!sidecars.is_empty(),
"successful set should leave a WAL sidecar"
);
let content = std::fs::read_to_string(sidecars[0].path()).unwrap();
assert!(
content.contains("Committed") || content.contains("committed"),
"sidecar should record Committed phase, got: {}",
content
);
}
#[test]
fn recover_orphan_journals_validation_failure_no_sidecar() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.json");
std::fs::write(&f, "{\"name\": 42}\n").unwrap();
let out = aw()
.arg("--workspace")
.arg(dir.path())
.arg("set")
.arg("a.json")
.arg("missing.deeply.nested.key")
.arg("1")
.output()
.expect("set");
let sidecars: Vec<_> = std::fs::read_dir(dir.path())
.unwrap()
.filter_map(|e| e.ok())
.filter(|e| {
e.path()
.file_name()
.and_then(|n| n.to_str())
.map(|n| n.contains(".atomwrite.journal."))
.unwrap_or(false)
})
.collect();
if !out.status.success() {
assert!(
sidecars.is_empty(),
"failed set should not leave a WAL sidecar (found {} sidecars)",
sidecars.len()
);
}
}
#[test]
fn case_subvert_zero_count() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.rs");
std::fs::write(&f, "let user_id = 1;\n").unwrap();
aw().arg("--workspace")
.arg(dir.path())
.arg("case")
.arg(&f)
.arg("--to")
.arg("pascal")
.arg("--subvert")
.assert()
.failure();
}
#[test]
fn case_subvert_one_count() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.rs");
std::fs::write(&f, "let user_id = 1;\n").unwrap();
aw().arg("--workspace")
.arg(dir.path())
.arg("case")
.arg(&f)
.arg("--to")
.arg("pascal")
.arg("--subvert")
.arg("user_id")
.assert()
.failure();
}
#[test]
fn case_subvert_two_count_succeeds_dry_run() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.rs");
std::fs::write(&f, "let user_id = 1;\n").unwrap();
let out = aw()
.arg("--workspace")
.arg(dir.path())
.arg("case")
.arg(&f)
.arg("--to")
.arg("pascal")
.arg("--subvert")
.arg("user_id")
.arg("UserId")
.arg("--dry-run")
.output()
.expect("case dry-run");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let after = std::fs::read_to_string(&f).unwrap();
assert!(after.contains("user_id"), "dry-run should not modify");
}
#[test]
fn case_subvert_three_count_odd_failure() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.rs");
std::fs::write(&f, "let user_id = 1;\n").unwrap();
aw().arg("--workspace")
.arg(dir.path())
.arg("case")
.arg(&f)
.arg("--to")
.arg("pascal")
.arg("--subvert")
.arg("user_id")
.arg("UserId")
.arg("extra")
.assert()
.failure();
}
#[test]
fn syntax_check_large_streaming_file() {
let dir = tempdir().unwrap();
let f = dir.path().join("big.rs");
{
let mut h = std::fs::File::create(&f).unwrap();
writeln!(h, "fn big() {{").unwrap();
for i in 0..50000 {
writeln!(h, " let v{} = {};", i, i).unwrap();
}
writeln!(h, "}}").unwrap();
}
let meta_before = std::fs::metadata(&f).unwrap();
assert!(meta_before.len() > 1_000_000, "test file should be > 1 MiB");
let out = aw()
.arg("--workspace")
.arg(dir.path())
.arg("write")
.arg("--syntax-check")
.arg(&f)
.output()
.expect("write --syntax-check big");
if !out.status.success() {
eprintln!("stderr: {}", String::from_utf8_lossy(&out.stderr));
eprintln!("stdout: {}", String::from_utf8_lossy(&out.stdout));
}
assert!(
out.status.success(),
"syntax check should pass on valid Rust"
);
}
#[test]
fn query_threads_1() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.rs");
std::fs::write(&f, "fn a() {}\nfn b() {}\n").unwrap();
let out = aw()
.arg("--workspace")
.arg(dir.path())
.arg("--threads")
.arg("1")
.arg("query")
.arg(&f)
.arg("--kinds")
.output()
.expect("query --threads 1");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(stdout.contains("function_item"));
}
#[test]
fn outline_threads_1() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.rs");
std::fs::write(&f, "struct S;\nfn a() {}\n").unwrap();
let out = aw()
.arg("--workspace")
.arg(dir.path())
.arg("--threads")
.arg("1")
.arg("outline")
.arg(&f)
.output()
.expect("outline --threads 1");
assert!(out.status.success());
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(stdout.contains("function_item") || stdout.contains("S"));
}
#[test]
fn shell_completion_bash_includes_query() {
let out = aw()
.arg("completions")
.arg("bash")
.arg("query")
.output()
.expect("completions bash query");
if out.status.success() {
let s = String::from_utf8_lossy(&out.stdout);
assert!(
s.contains("query") || s.contains("atomwrite"),
"completion should mention the binary or subcommand"
);
}
}
#[test]
fn shell_completion_zsh_includes_outline() {
let out = aw()
.arg("completions")
.arg("zsh")
.arg("outline")
.output()
.expect("completions zsh outline");
if out.status.success() {
let s = String::from_utf8_lossy(&out.stdout);
assert!(s.contains("outline") || s.contains("atomwrite"));
}
}
#[test]
fn shell_completion_fish_includes_set() {
let out = aw()
.arg("completions")
.arg("fish")
.arg("set")
.output()
.expect("completions fish set");
if out.status.success() {
let s = String::from_utf8_lossy(&out.stdout);
assert!(s.contains("set") || s.contains("atomwrite"));
}
}
#[test]
fn locale_pt_br_set_get_del() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.toml");
std::fs::write(&f, "[pkg]\nname=\"x\"\n").unwrap();
let out = aw()
.env("LANG", "pt_BR.UTF-8")
.env("LC_ALL", "pt_BR.UTF-8")
.arg("--workspace")
.arg(dir.path())
.arg("set")
.arg("a.toml")
.arg("pkg.version")
.arg("1.0.0")
.output()
.expect("set pt-BR");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let out = aw()
.env("LANG", "pt_BR.UTF-8")
.env("LC_ALL", "pt_BR.UTF-8")
.arg("--workspace")
.arg(dir.path())
.arg("get")
.arg("a.toml")
.arg("pkg.version")
.output()
.expect("get pt-BR");
assert!(out.status.success());
let stdout = String::from_utf8_lossy(&out.stdout);
assert!(
stdout.contains("1.0.0"),
"pt-BR get should return the value"
);
}
#[test]
fn lang_c_set_does_not_crash() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.toml");
std::fs::write(&f, "[pkg]\n").unwrap();
let out = aw()
.env("LANG", "C")
.env("LC_ALL", "C")
.arg("--workspace")
.arg(dir.path())
.arg("set")
.arg("a.toml")
.arg("pkg.version")
.arg("1.0.0")
.output()
.expect("set LANG=C");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
}
#[test]
fn query_max_filesize_1_skips_large_file() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.rs");
std::fs::write(&f, "x").unwrap();
let out = aw()
.arg("--workspace")
.arg(dir.path())
.arg("query")
.arg(&f)
.arg("--kinds")
.arg("--max-filesize")
.arg("1")
.output()
.expect("query --max-filesize 1");
let _ = out.status; }
#[test]
fn set_explicit_format_toml() {
let dir = tempdir().unwrap();
let f = dir.path().join("a.toml");
std::fs::write(&f, "[pkg]\n").unwrap();
let out = aw()
.arg("--workspace")
.arg(dir.path())
.arg("set")
.arg("a.toml")
.arg("pkg.version")
.arg("2.5.0")
.output()
.expect("set auto-detect toml");
assert!(
out.status.success(),
"stderr={}",
String::from_utf8_lossy(&out.stderr)
);
let after = std::fs::read_to_string(&f).unwrap();
assert!(
after.contains("2.5") || after.contains("2.5.0"),
"value should be set, got: {}",
after
);
}