use haz_domain::task::Task;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BooleanShortcut {
HasDeps,
NoDeps,
HasInputs,
NoInputs,
HasOutputs,
NoOutputs,
Mutex,
}
impl BooleanShortcut {
#[must_use]
pub fn matches(&self, task: &Task) -> bool {
match self {
Self::HasDeps => !task.deps.is_empty(),
Self::NoDeps => task.deps.is_empty(),
Self::HasInputs => !task.inputs.is_empty(),
Self::NoInputs => task.inputs.is_empty(),
Self::HasOutputs => !task.outputs.is_empty(),
Self::NoOutputs => task.outputs.is_empty(),
Self::Mutex => task.mutex.is_some(),
}
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use haz_domain::action::TaskAction;
use haz_domain::env::EnvSettings;
use haz_domain::mutex::{Mutex, MutexMode, MutexScope};
use haz_domain::name::{MutexName, TaskName};
use haz_domain::path::{InputSpec, OutputSpec};
use haz_domain::task::Task;
use haz_domain::task_ref::TaskRef;
use nonempty::NonEmpty;
use super::*;
fn argv(parts: &[&str]) -> NonEmpty<String> {
NonEmpty::from_vec(parts.iter().map(|s| (*s).to_owned()).collect()).unwrap()
}
fn bare_task(name: &str) -> Task {
Task {
name: TaskName::from_str(name).unwrap(),
action: TaskAction::Command(argv(&["true"])),
inputs: vec![],
outputs: vec![],
deps: vec![],
weak_deps: vec![],
mutex: None,
env: EnvSettings::default(),
}
}
#[test]
fn shortcut_variants_are_distinct() {
assert_ne!(BooleanShortcut::HasDeps, BooleanShortcut::NoDeps);
assert_ne!(BooleanShortcut::HasInputs, BooleanShortcut::NoInputs);
assert_ne!(BooleanShortcut::HasOutputs, BooleanShortcut::NoOutputs);
assert_ne!(BooleanShortcut::HasDeps, BooleanShortcut::HasInputs);
assert_ne!(BooleanShortcut::Mutex, BooleanShortcut::HasDeps);
}
#[test]
fn shortcut_variants_are_copy_and_hashable() {
use std::collections::HashSet;
let a = BooleanShortcut::HasDeps;
let b = a;
let mut set: HashSet<BooleanShortcut> = HashSet::new();
set.insert(a);
set.insert(b);
assert_eq!(set.len(), 1);
}
#[test]
fn qry_005_has_deps_and_no_deps_are_mutually_negating() {
let mut task = bare_task("t");
assert!(!BooleanShortcut::HasDeps.matches(&task));
assert!(BooleanShortcut::NoDeps.matches(&task));
task.deps.push(TaskRef::parse("~:other").unwrap());
assert!(BooleanShortcut::HasDeps.matches(&task));
assert!(!BooleanShortcut::NoDeps.matches(&task));
}
#[test]
fn qry_005_has_inputs_and_no_inputs_check_inputs_field() {
let mut task = bare_task("t");
assert!(BooleanShortcut::NoInputs.matches(&task));
assert!(!BooleanShortcut::HasInputs.matches(&task));
task.inputs.push(InputSpec::parse("src/main.rs").unwrap());
assert!(BooleanShortcut::HasInputs.matches(&task));
assert!(!BooleanShortcut::NoInputs.matches(&task));
}
#[test]
fn qry_005_has_outputs_and_no_outputs_check_outputs_field() {
let mut task = bare_task("t");
assert!(BooleanShortcut::NoOutputs.matches(&task));
assert!(!BooleanShortcut::HasOutputs.matches(&task));
task.outputs
.push(OutputSpec::parse("dist/bundle.js").unwrap());
assert!(BooleanShortcut::HasOutputs.matches(&task));
assert!(!BooleanShortcut::NoOutputs.matches(&task));
}
#[test]
fn qry_005_mutex_checks_mutex_field_presence() {
let mut task = bare_task("t");
assert!(!BooleanShortcut::Mutex.matches(&task));
task.mutex = Some(Mutex {
scope: MutexScope::Workspace,
name: MutexName::from_str("db").unwrap(),
mode: MutexMode::Exclusive,
});
assert!(BooleanShortcut::Mutex.matches(&task));
}
}