mirror of
https://github.com/RGBCube/alejandra
synced 2025-07-30 12:07:46 +00:00
test: add cli tests
This commit is contained in:
parent
cdc093ab71
commit
6db8876433
9 changed files with 381 additions and 19 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,4 +4,6 @@
|
||||||
/**/target/
|
/**/target/
|
||||||
/.direnv
|
/.direnv
|
||||||
/.idea/
|
/.idea/
|
||||||
|
/front/build
|
||||||
|
/front/worktree
|
||||||
/tarpaulin*
|
/tarpaulin*
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use alejandra::config::Config;
|
use alejandra::config::Config;
|
||||||
use alejandra::config::Indentation;
|
use alejandra::config::Indentation;
|
||||||
|
@ -11,28 +12,28 @@ fn cases() {
|
||||||
|
|
||||||
let configs = HashMap::from([
|
let configs = HashMap::from([
|
||||||
("default", Config::default()),
|
("default", Config::default()),
|
||||||
("indentation-tabs", Config {
|
("indentation-tabs", Config { indentation: Indentation::Tabs }),
|
||||||
indentation: Indentation::Tabs,
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
let cases_path = PathBuf::new().join("tests").join("cases");
|
||||||
|
|
||||||
for (config_name, config) in configs {
|
for (config_name, config) in configs {
|
||||||
let cases: Vec<String> =
|
let config_cases_path = cases_path.join(config_name);
|
||||||
std::fs::read_dir(format!("tests/cases/{}", config_name))
|
|
||||||
.unwrap()
|
let cases: Vec<String> = std::fs::read_dir(&config_cases_path)
|
||||||
.map(|entry| entry.unwrap().file_name().into_string().unwrap())
|
.unwrap()
|
||||||
.collect();
|
.map(|entry| entry.unwrap().file_name().into_string().unwrap())
|
||||||
|
.collect();
|
||||||
|
|
||||||
for case in cases {
|
for case in cases {
|
||||||
let path_in =
|
let case_path = config_cases_path.join(&case);
|
||||||
format!("tests/cases/{}/{}/in.nix", config_name, case);
|
|
||||||
|
let path_in = case_path.join("in.nix");
|
||||||
let content_in = std::fs::read_to_string(&path_in).unwrap();
|
let content_in = std::fs::read_to_string(&path_in).unwrap();
|
||||||
|
|
||||||
let path_out =
|
let path_out = case_path.join("out.nix");
|
||||||
format!("tests/cases/{}/{}/out.nix", config_name, case);
|
|
||||||
let content_got = alejandra::format::in_memory(
|
let content_got = alejandra::format::in_memory(
|
||||||
path_in.clone(),
|
path_in.to_str().unwrap().to_owned(),
|
||||||
content_in.clone(),
|
content_in.clone(),
|
||||||
config,
|
config,
|
||||||
)
|
)
|
||||||
|
@ -45,14 +46,12 @@ fn cases() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
let content_out =
|
let content_out = std::fs::read_to_string(&path_out).unwrap();
|
||||||
std::fs::read_to_string(path_out.clone()).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
content_out, content_got,
|
content_out, content_got,
|
||||||
"Test case `{}/{}` failed; see \
|
"Test case `{:?}` failed",
|
||||||
`src/alejandra/tests/cases/{}/{}/`",
|
case_path
|
||||||
config_name, case, config_name, case,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
167
src/alejandra_cli/tests/cli.rs
Normal file
167
src/alejandra_cli/tests/cli.rs
Normal 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
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
0
src/alejandra_cli/tests/configs/empty_config.toml
Normal file
0
src/alejandra_cli/tests/configs/empty_config.toml
Normal file
1
src/alejandra_cli/tests/configs/wrong_key.toml
Normal file
1
src/alejandra_cli/tests/configs/wrong_key.toml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
asdf = "asdf"
|
1
src/alejandra_cli/tests/inputs/changed.nix
Normal file
1
src/alejandra_cli/tests/inputs/changed.nix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[]
|
1
src/alejandra_cli/tests/inputs/error.nix
Normal file
1
src/alejandra_cli/tests/inputs/error.nix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[
|
1
src/alejandra_cli/tests/inputs/unchanged.nix
Normal file
1
src/alejandra_cli/tests/inputs/unchanged.nix
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[]
|
190
src/alejandra_cli/tests/output.txt
Normal file
190
src/alejandra_cli/tests/output.txt
Normal 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)
|
Loading…
Add table
Add a link
Reference in a new issue