feat(nix): add style linter scaffold
This commit was merged in pull request #58.
This commit is contained in:
1 parent
82ad65a3a4
commit
7b09cea3af
8 files changed
+457
No files matched your search
@@ -0,0 +1,133 @@
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use nix_style_linter::RunStatus;
|
||||
|
||||
static TEST_DIRECTORY_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
#[test]
|
||||
fn malformed_file_reports_parse_error() {
|
||||
let workspace = TestWorkspace::new("malformed_file_reports_parse_error");
|
||||
let path = workspace.write("broken.nix", "let x = ; in x\n");
|
||||
|
||||
let output = run_linter(&[path]);
|
||||
|
||||
assert_eq!(output.status, RunStatus::Diagnostics);
|
||||
assert_eq!(output.stderr, "");
|
||||
assert!(output.stdout.starts_with(&format!(
|
||||
"{}:1:9: parse-error: unexpected TOKEN_SEMICOLON at 8..9",
|
||||
workspace.path("broken.nix").display()
|
||||
)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn valid_file_exits_clean() {
|
||||
let workspace = TestWorkspace::new("valid_file_exits_clean");
|
||||
let path = workspace.write("valid.nix", "let x = 1; in x\n");
|
||||
|
||||
let output = run_linter(&[path]);
|
||||
|
||||
assert_eq!(output.status, RunStatus::Clean);
|
||||
assert_eq!(output.stdout, "");
|
||||
assert_eq!(output.stderr, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_path_reports_tool_error() {
|
||||
let workspace = TestWorkspace::new("missing_path_reports_tool_error");
|
||||
let path = workspace.path("missing.nix");
|
||||
|
||||
let output = run_linter(&[path.clone()]);
|
||||
|
||||
assert_eq!(output.status, RunStatus::ToolError);
|
||||
assert_eq!(output.stdout, "");
|
||||
assert!(output.stderr.starts_with(&format!(
|
||||
"error: failed to inspect {}:",
|
||||
path.display()
|
||||
)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn directory_inputs_recurse_through_nix_files() {
|
||||
let workspace = TestWorkspace::new("directory_inputs_recurse_through_nix_files");
|
||||
workspace.write("ignored.txt", "let x = ; in x\n");
|
||||
workspace.write("nested/broken.nix", "let\n x = 1;\n y = ;\nin y\n");
|
||||
|
||||
let output = run_linter(&[workspace.root.clone()]);
|
||||
|
||||
assert_eq!(output.status, RunStatus::Diagnostics);
|
||||
assert_eq!(output.stderr, "");
|
||||
assert!(output.stdout.starts_with(&format!(
|
||||
"{}:3:7: parse-error: unexpected TOKEN_SEMICOLON at 19..20",
|
||||
workspace.path("nested/broken.nix").display()
|
||||
)));
|
||||
assert!(!output.stdout.contains("ignored.txt"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_invocation_reports_tool_error() {
|
||||
let output = run_linter(&[]);
|
||||
|
||||
assert_eq!(output.status, RunStatus::ToolError);
|
||||
assert_eq!(output.stdout, "");
|
||||
assert_eq!(output.stderr, "error: expected at least one path\n");
|
||||
}
|
||||
|
||||
struct LinterOutput {
|
||||
status: RunStatus,
|
||||
stdout: String,
|
||||
stderr: String,
|
||||
}
|
||||
|
||||
fn run_linter(paths: &[PathBuf]) -> LinterOutput {
|
||||
let mut stdout = Vec::new();
|
||||
let mut stderr = Vec::new();
|
||||
let status = nix_style_linter::run(paths, &mut stdout, &mut stderr).unwrap();
|
||||
|
||||
LinterOutput {
|
||||
status,
|
||||
stdout: String::from_utf8(stdout).unwrap(),
|
||||
stderr: String::from_utf8(stderr).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
struct TestWorkspace {
|
||||
root: PathBuf,
|
||||
}
|
||||
|
||||
impl TestWorkspace {
|
||||
fn new(name: &str) -> Self {
|
||||
let id = TEST_DIRECTORY_ID.fetch_add(1, Ordering::Relaxed);
|
||||
let root = std::env::temp_dir().join(format!(
|
||||
"nix-style-linter-{process}-{name}-{id}",
|
||||
process = std::process::id()
|
||||
));
|
||||
|
||||
if root.exists() {
|
||||
fs::remove_dir_all(&root).unwrap();
|
||||
}
|
||||
fs::create_dir_all(&root).unwrap();
|
||||
|
||||
Self { root }
|
||||
}
|
||||
|
||||
fn path(&self, relative: impl AsRef<Path>) -> PathBuf {
|
||||
self.root.join(relative)
|
||||
}
|
||||
|
||||
fn write(&self, relative: impl AsRef<Path>, contents: &str) -> PathBuf {
|
||||
let path = self.path(relative);
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent).unwrap();
|
||||
}
|
||||
fs::write(&path, contents).unwrap();
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestWorkspace {
|
||||
fn drop(&mut self) {
|
||||
fs::remove_dir_all(&self.root).unwrap();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user