use crate::checkers::{
file::FileCheck,
get_option_boolean_from_check_table,
utils::{
get_lines_from_check_table, get_marker_from_check_table, remove_between_markers,
replace_vars,
},
};
use super::super::base::CheckConstructor;
pub(super) use super::super::{
GenericChecker,
base::{CheckDefinitionError, CheckError, Checker},
};
#[derive(Debug)]
pub(crate) struct LinesAbsent {
file_check: FileCheck,
lines: String,
marker_lines: Option<(String, String)>,
}
impl CheckConstructor for LinesAbsent {
type Output = LinesAbsent;
fn from_check_table(
generic_check: GenericChecker,
check_table: toml_edit::Table,
) -> Result<Self::Output, CheckDefinitionError> {
let marker_lines = get_marker_from_check_table(&check_table)?;
let lines = get_lines_from_check_table(&check_table, None)?;
let is_template =
get_option_boolean_from_check_table(&check_table, "is_template")?.unwrap_or(false);
let lines = if is_template {
replace_vars(lines.as_str(), &generic_check.variables)
} else {
lines
};
let file_check = FileCheck::from_check_table(generic_check, &check_table)?;
Ok(Self {
file_check,
lines,
marker_lines,
})
}
}
impl Checker for LinesAbsent {
fn checker_type(&self) -> String {
"lines_absent".to_string()
}
fn checker_object(&self) -> String {
self.file_check.check_object()
}
fn generic_checker(&self) -> &GenericChecker {
&self.file_check.generic_check
}
fn check_(&self, fix: bool) -> Result<crate::checkers::base::CheckResult, CheckError> {
let contents = self.file_check.get_file_contents()?;
let new_contents = if let Some((start_marker, end_marker)) = self.marker_lines.as_ref() {
remove_between_markers(&contents, start_marker, end_marker)
} else {
let mut contents = contents.clone();
contents = contents.replace(format!("\n{}", self.lines).as_str(), "");
contents = contents.replace(self.lines.as_str(), "");
contents
};
self.file_check
.conclude_check_new_contents(new_contents, fix)
}
}
#[cfg(test)]
mod tests {
use std::fs::File;
use std::io::Write;
use crate::checkers::base::CheckResult;
use crate::checkers::test_helpers;
use super::*;
use tempfile::tempdir;
fn get_lines_absent_check(
lines: String,
marker: Option<String>,
) -> (LinesAbsent, tempfile::TempDir) {
let generic_check = test_helpers::get_generic_check();
let mut check_table = toml_edit::Table::new();
let dir = tempdir().unwrap();
let file_to_check = dir.path().join("file_to_check");
check_table.insert("file", file_to_check.to_string_lossy().to_string().into());
check_table.insert("lines", lines.into());
if let Some(marker) = marker {
check_table.insert("marker", marker.into());
}
(
LinesAbsent::from_check_table(generic_check, check_table).unwrap(),
dir,
)
}
#[test]
fn test_lines_absent() {
let (lines_absent_check, _tmpdir) = get_lines_absent_check("1\n2\n".into(), None);
assert_eq!(
lines_absent_check.check_(false).unwrap(),
CheckResult::NoFixNeeded
);
File::create(lines_absent_check.file_check.file_to_check.as_ref().clone()).unwrap();
assert_eq!(
lines_absent_check.check_(false).unwrap(),
CheckResult::NoFixNeeded
);
let mut file: File =
File::create(lines_absent_check.file_check.file_to_check.as_ref().clone()).unwrap();
writeln!(file, "a").unwrap();
assert_eq!(
lines_absent_check.check_(false).unwrap(),
CheckResult::NoFixNeeded
);
let mut file: File =
File::create(lines_absent_check.file_check.file_to_check.as_ref().clone()).unwrap();
write!(file, "1\n2\nb\n").unwrap();
assert_eq!(
lines_absent_check.check_(false).unwrap(),
CheckResult::FixNeeded(
"Set file contents to: \n@@ -1,3 +1 @@\n-1\n-2\n b\n".to_string()
)
);
assert_eq!(
lines_absent_check.check_(true).unwrap(),
CheckResult::FixExecuted(
"Set file contents to: \n@@ -1,3 +1 @@\n-1\n-2\n b\n".to_string()
)
);
assert_eq!(
lines_absent_check.check_(false).unwrap(),
CheckResult::NoFixNeeded,
);
}
}