use crate::workspace::{Member, Workspace};
pub(crate) const DEFAULT_MIN_LINES_PERCENT: f64 = 100.0;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum ThresholdSource {
Package,
Workspace,
Default,
}
impl ThresholdSource {
pub(crate) fn as_str(self) -> &'static str {
match self {
Self::Package => "package",
Self::Workspace => "workspace",
Self::Default => "default",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub(crate) struct Threshold {
pub(crate) min_lines_percent: f64,
pub(crate) source: ThresholdSource,
}
impl Threshold {
pub(crate) fn resolve(member: &Member, workspace: &Workspace) -> Self {
if let Some(v) = member.min_lines_percent {
Self {
min_lines_percent: v,
source: ThresholdSource::Package,
}
} else if let Some(v) = workspace.default_min_lines_percent {
Self {
min_lines_percent: v,
source: ThresholdSource::Workspace,
}
} else {
Self {
min_lines_percent: DEFAULT_MIN_LINES_PERCENT,
source: ThresholdSource::Default,
}
}
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use std::path::PathBuf;
use super::*;
fn member(name: &str, min_lines_percent: Option<f64>) -> Member {
Member {
name: name.to_owned(),
manifest_dir: PathBuf::from(format!("/repo/crates/{name}")),
min_lines_percent,
expect_no_coverable_lines: false,
}
}
fn workspace(default: Option<f64>) -> Workspace {
Workspace {
members: Vec::new(),
default_min_lines_percent: default,
}
}
#[test]
fn per_crate_wins() {
let m = member("alpha", Some(82.0));
let ws = workspace(Some(50.0));
let t = Threshold::resolve(&m, &ws);
assert!((t.min_lines_percent - 82.0).abs() < f64::EPSILON);
assert_eq!(t.source, ThresholdSource::Package);
}
#[test]
fn workspace_used_when_no_per_crate() {
let m = member("alpha", None);
let ws = workspace(Some(50.0));
let t = Threshold::resolve(&m, &ws);
assert!((t.min_lines_percent - 50.0).abs() < f64::EPSILON);
assert_eq!(t.source, ThresholdSource::Workspace);
}
#[test]
fn default_used_when_nothing_set() {
let m = member("alpha", None);
let ws = workspace(None);
let t = Threshold::resolve(&m, &ws);
assert!((t.min_lines_percent - 100.0).abs() < f64::EPSILON);
assert_eq!(t.source, ThresholdSource::Default);
assert!((DEFAULT_MIN_LINES_PERCENT - 100.0).abs() < f64::EPSILON);
}
#[test]
fn per_crate_zero_is_an_opt_out_not_a_skip() {
let m = member("alpha", Some(0.0));
let ws = workspace(Some(50.0));
let t = Threshold::resolve(&m, &ws);
assert!((t.min_lines_percent - 0.0).abs() < f64::EPSILON);
assert_eq!(t.source, ThresholdSource::Package);
}
#[test]
fn source_as_str() {
assert_eq!(ThresholdSource::Package.as_str(), "package");
assert_eq!(ThresholdSource::Workspace.as_str(), "workspace");
assert_eq!(ThresholdSource::Default.as_str(), "default");
}
}