#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CcFlag {
InTarget,
Warn,
TooComplex,
}
pub fn cyclomatic_complexity(num_dependencies: usize, num_activities: usize) -> (i64, CcFlag) {
let c = num_dependencies as i64 - num_activities as i64 + 2;
let flag = if c <= 12 {
CcFlag::InTarget
} else if c <= 15 {
CcFlag::Warn
} else {
CcFlag::TooComplex
};
(c, flag)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EffFlag {
Low,
InTarget,
High,
}
pub fn project_efficiency(
sum_planned_effort: u64,
sum_actual_effort: u64,
) -> Option<(f64, EffFlag)> {
if sum_actual_effort == 0 {
return None;
}
let ratio = sum_planned_effort as f64 / sum_actual_effort as f64;
let flag = if ratio < 0.15 {
EffFlag::Low
} else if ratio <= 0.25 {
EffFlag::InTarget
} else {
EffFlag::High
};
Some((ratio, flag))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cc_boundary_12_is_in_target() {
let (c, flag) = cyclomatic_complexity(20, 10);
assert_eq!(c, 12);
assert_eq!(flag, CcFlag::InTarget);
}
#[test]
fn cc_boundary_13_is_warn() {
let (c, flag) = cyclomatic_complexity(21, 10);
assert_eq!(c, 13);
assert_eq!(flag, CcFlag::Warn);
}
#[test]
fn cc_boundary_15_is_warn() {
let (c, flag) = cyclomatic_complexity(23, 10);
assert_eq!(c, 15);
assert_eq!(flag, CcFlag::Warn);
}
#[test]
fn cc_boundary_16_is_too_complex() {
let (c, flag) = cyclomatic_complexity(24, 10);
assert_eq!(c, 16);
assert_eq!(flag, CcFlag::TooComplex);
}
#[test]
fn cc_small_network_in_target() {
let (c, flag) = cyclomatic_complexity(2, 5);
assert_eq!(c, -1);
assert_eq!(flag, CcFlag::InTarget);
}
#[test]
fn efficiency_none_when_actual_is_zero() {
assert_eq!(project_efficiency(100, 0), None);
assert_eq!(project_efficiency(0, 0), None);
}
#[test]
fn efficiency_equal_planned_actual_is_high() {
let (ratio, flag) = project_efficiency(100, 100).expect("Some expected");
assert!((ratio - 1.0).abs() < 1e-9);
assert_eq!(flag, EffFlag::High);
}
#[test]
fn efficiency_boundary_015_is_in_target() {
let (ratio, flag) = project_efficiency(15, 100).expect("Some expected");
assert!((ratio - 0.15).abs() < 1e-9);
assert_eq!(flag, EffFlag::InTarget);
}
#[test]
fn efficiency_boundary_025_is_in_target() {
let (ratio, flag) = project_efficiency(25, 100).expect("Some expected");
assert!((ratio - 0.25).abs() < 1e-9);
assert_eq!(flag, EffFlag::InTarget);
}
#[test]
fn efficiency_just_above_025_is_high() {
let (ratio, flag) = project_efficiency(26, 100).expect("Some expected");
assert!((ratio - 0.26).abs() < 1e-9);
assert_eq!(flag, EffFlag::High);
}
#[test]
fn efficiency_just_below_015_is_low() {
let (ratio, flag) = project_efficiency(14, 100).expect("Some expected");
assert!((ratio - 0.14).abs() < 1e-9);
assert_eq!(flag, EffFlag::Low);
}
#[test]
fn efficiency_zero_planned_is_low() {
let (ratio, flag) = project_efficiency(0, 50).expect("Some expected");
assert!((ratio - 0.0).abs() < 1e-9);
assert_eq!(flag, EffFlag::Low);
}
}