1
Fork 0
mirror of https://github.com/RGBCube/alejandra synced 2025-07-29 03:27:44 +00:00

test: add cli tests

This commit is contained in:
Kevin Amado 2024-12-08 23:29:11 -07:00
parent cdc093ab71
commit 6db8876433
9 changed files with 381 additions and 19 deletions

2
.gitignore vendored
View file

@ -4,4 +4,6 @@
/**/target/
/.direnv
/.idea/
/front/build
/front/worktree
/tarpaulin*

View file

@ -1,5 +1,6 @@
use std::collections::HashMap;
use std::io::Write;
use std::path::PathBuf;
use alejandra::config::Config;
use alejandra::config::Indentation;
@ -11,28 +12,28 @@ fn cases() {
let configs = HashMap::from([
("default", Config::default()),
("indentation-tabs", Config {
indentation: Indentation::Tabs,
..Default::default()
}),
("indentation-tabs", Config { indentation: Indentation::Tabs }),
]);
let cases_path = PathBuf::new().join("tests").join("cases");
for (config_name, config) in configs {
let cases: Vec<String> =
std::fs::read_dir(format!("tests/cases/{}", config_name))
.unwrap()
.map(|entry| entry.unwrap().file_name().into_string().unwrap())
.collect();
let config_cases_path = cases_path.join(config_name);
let cases: Vec<String> = std::fs::read_dir(&config_cases_path)
.unwrap()
.map(|entry| entry.unwrap().file_name().into_string().unwrap())
.collect();
for case in cases {
let path_in =
format!("tests/cases/{}/{}/in.nix", config_name, case);
let case_path = config_cases_path.join(&case);
let path_in = case_path.join("in.nix");
let content_in = std::fs::read_to_string(&path_in).unwrap();
let path_out =
format!("tests/cases/{}/{}/out.nix", config_name, case);
let path_out = case_path.join("out.nix");
let content_got = alejandra::format::in_memory(
path_in.clone(),
path_in.to_str().unwrap().to_owned(),
content_in.clone(),
config,
)
@ -45,14 +46,12 @@ fn cases() {
.unwrap();
}
let content_out =
std::fs::read_to_string(path_out.clone()).unwrap();
let content_out = std::fs::read_to_string(&path_out).unwrap();
assert_eq!(
content_out, content_got,
"Test case `{}/{}` failed; see \
`src/alejandra/tests/cases/{}/{}/`",
config_name, case, config_name, case,
"Test case `{:?}` failed",
case_path
);
}
}

View file

@ -0,0 +1,167 @@
use std::fmt::Write as _;
use std::io::Write as _;
use std::path::PathBuf;
use std::process::Command;
use std::process::Stdio;
#[derive(Debug)]
struct TestCase {
args: &'static [&'static str],
stdin: Option<&'static str>,
}
const CASES: &[TestCase] = &[
TestCase { args: &["--help"], stdin: None },
TestCase { args: &["--version"], stdin: None },
TestCase { args: &[], stdin: None },
TestCase { args: &["--quiet"], stdin: Some("[]") },
TestCase { args: &["--quiet", "--quiet"], stdin: Some("[]") },
TestCase { args: &["--check", "--quiet"], stdin: Some("[]\n") },
TestCase { args: &["--check", "--quiet"], stdin: Some("[\t]") },
TestCase { args: &["--check", "--quiet", "--quiet"], stdin: Some("[]\n") },
TestCase { args: &["--check", "--quiet", "--quiet"], stdin: Some("[\t]") },
TestCase { args: &["--quiet"], stdin: Some("[") },
TestCase { args: &["--quiet", "--quiet"], stdin: Some("[") },
TestCase { args: &[".", "--exclude", ".", "--quiet"], stdin: None },
TestCase {
args: &["--exclude", ".", "--quiet", "--quiet", "--", "."],
stdin: None,
},
TestCase {
args: &["--check", "tests/inputs/changed.nix", "--quiet"],
stdin: None,
},
TestCase {
args: &[
"-c",
"tests/inputs/changed.nix",
"-q",
"-e",
"tests/changed.nix",
],
stdin: None,
},
TestCase {
args: &["--check", "tests/inputs/changed.nix", "-qq"],
stdin: None,
},
TestCase {
args: &["--check", "tests/inputs/unchanged.nix", "-q"],
stdin: None,
},
TestCase {
args: &["--check", "tests/inputs/unchanged.nix", "-qq"],
stdin: None,
},
TestCase {
args: &["--check", "tests/inputs/error.nix", "-q"],
stdin: None,
},
TestCase {
args: &["--check", "tests/inputs/error.nix", "-qq"],
stdin: None,
},
TestCase {
args: &[
"--check",
"tests/inputs/unchanged.nix",
"--experimental-config",
"../../alejandra.toml",
"--threads",
"1",
],
stdin: None,
},
TestCase {
args: &[
"--check",
"tests/inputs/unchanged.nix",
"--experimental-config",
"tests/configs/empty_config.toml",
"-t",
"1",
],
stdin: None,
},
TestCase {
args: &[
"--check",
"tests/inputs/unchanged.nix",
"--experimental-config",
"tests/configs/wrong_key.toml",
],
stdin: None,
},
];
#[test]
fn cases() {
let should_update = std::env::var("UPDATE").is_ok();
let output_path = PathBuf::new().join("tests").join("output.txt");
let mut output_got = String::new();
for case in CASES {
output_got.push_str("===\n");
output_got.push_str(&format!("args: {:?}\n", case.args));
let mut child = Command::new("cargo")
.args(["run", "--quiet", "--"])
.args(case.args)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("command failed");
if let Some(stdin) = case.stdin {
output_got.push_str(&format!("stdin: {:?}\n", stdin));
child
.stdin
.take()
.unwrap()
.write_all(stdin.as_bytes())
.expect("unable to write to child stdin");
}
let output = child.wait_with_output().expect("child command failed");
let stdout = String::from_utf8(output.stdout).expect("invalid utf-8");
if !stdout.is_empty() {
output_got
.push_str(&format!("stdout:\n{}\n", indent_and_clean(&stdout)));
}
let stderr = String::from_utf8(output.stderr).expect("invalid utf-8");
if !stderr.is_empty() {
output_got
.push_str(&format!("stderr:\n{}\n", indent_and_clean(&stderr)));
}
output_got
.push_str(&format!("exit code: {:?}\n", output.status.code()));
}
if should_update {
std::fs::File::create(&output_path)
.unwrap()
.write_all(output_got.as_bytes())
.unwrap();
}
let output_expected = std::fs::read_to_string(&output_path).unwrap();
assert_eq!(output_expected, output_got);
}
fn indent_and_clean(data: &str) -> String {
data.lines().filter(|line| !line.starts_with(['👏', '🤟', '⭐'])).fold(
String::new(),
|mut output, line| {
let _ = writeln!(output, " {}", line);
output
},
)
}

View file

@ -0,0 +1 @@
asdf = "asdf"

View file

@ -0,0 +1 @@
[]

View file

@ -0,0 +1 @@
[

View file

@ -0,0 +1 @@
[]

View file

@ -0,0 +1,190 @@
===
args: ["--help"]
stdout:
Alejandra 3.1.0
The Uncompromising Nix Code Formatter
USAGE:
alejandra [OPTIONS] [INCLUDE]...
ARGS:
<INCLUDE>... Files or directories, or a single "-" (or leave empty)
to format stdin
OPTIONS:
-c, --check
Check if the input is already formatted and disable writing in-place
the modified content
-e, --exclude <EXCLUDE>
Files or directories to exclude from formatting
--experimental-config <EXPERIMENTAL_CONFIG>
[Experimental] Path to a config file. If not provided, it'll default
to `alejandra.toml` in the current directory. If not found, it'll
use the default style
-h, --help
Print help information
-q, --quiet
Use once to hide informational messages, twice to hide error
messages
-t, --threads <THREADS>
Number of formatting threads to spawn. Defaults to the number of
physical CPUs
-V, --version
Print version information
Alejandra will exit with status code:
1, if any error occurs.
2, if --check was used and any file requires formatting.
0, otherwise.
exit code: Some(0)
===
args: ["--version"]
stdout:
Alejandra 3.1.0
exit code: Some(0)
===
args: []
stderr:
Formatting stdin.
Use --help to see all command line options.
use --quiet to suppress this and other messages.
Failed! 1 error found at:
- <anonymous file on stdin>: unexpected end of file
exit code: Some(1)
===
args: ["--quiet"]
stdin: "[]"
stdout:
[]
exit code: Some(0)
===
args: ["--quiet", "--quiet"]
stdin: "[]"
stdout:
[]
exit code: Some(0)
===
args: ["--check", "--quiet"]
stdin: "[]\n"
stdout:
[]
exit code: Some(0)
===
args: ["--check", "--quiet"]
stdin: "[\t]"
stdout:
[]
exit code: Some(2)
===
args: ["--check", "--quiet", "--quiet"]
stdin: "[]\n"
stdout:
[]
exit code: Some(0)
===
args: ["--check", "--quiet", "--quiet"]
stdin: "[\t]"
stdout:
[]
exit code: Some(2)
===
args: ["--quiet"]
stdin: "["
stdout:
[
stderr:
Failed! 1 error found at:
- <anonymous file on stdin>: unexpected end of file
exit code: Some(1)
===
args: ["--quiet", "--quiet"]
stdin: "["
stdout:
[
exit code: Some(1)
===
args: [".", "--exclude", ".", "--quiet"]
exit code: Some(0)
===
args: ["--exclude", ".", "--quiet", "--quiet", "--", "."]
exit code: Some(0)
===
args: ["--check", "tests/inputs/changed.nix", "--quiet"]
exit code: Some(2)
===
args: ["-c", "tests/inputs/changed.nix", "-q", "-e", "tests/changed.nix"]
exit code: Some(2)
===
args: ["--check", "tests/inputs/changed.nix", "-qq"]
exit code: Some(2)
===
args: ["--check", "tests/inputs/unchanged.nix", "-q"]
exit code: Some(0)
===
args: ["--check", "tests/inputs/unchanged.nix", "-qq"]
exit code: Some(0)
===
args: ["--check", "tests/inputs/error.nix", "-q"]
stderr:
Failed! 1 error found at:
- tests/inputs/error.nix: unexpected end of file
exit code: Some(1)
===
args: ["--check", "tests/inputs/error.nix", "-qq"]
exit code: Some(1)
===
args: ["--check", "tests/inputs/unchanged.nix", "--experimental-config", "../../alejandra.toml", "--threads", "1"]
stderr:
Using config from: ../../alejandra.toml
Checking style in 1 file using 1 thread.
Congratulations! Your code complies with the Alejandra style.
exit code: Some(0)
===
args: ["--check", "tests/inputs/unchanged.nix", "--experimental-config", "tests/configs/empty_config.toml", "-t", "1"]
stderr:
Using config from: tests/configs/empty_config.toml
Checking style in 1 file using 1 thread.
Congratulations! Your code complies with the Alejandra style.
exit code: Some(0)
===
args: ["--check", "tests/inputs/unchanged.nix", "--experimental-config", "tests/configs/wrong_key.toml"]
stderr:
Using config from: tests/configs/wrong_key.toml
Errors found in config: TOML parse error at line 1, column 1
|
1 | asdf = "asdf"
| ^^^^
unknown field `asdf`, expected `indentation`
exit code: Some(1)