mirror of
https://github.com/instructkr/claw-code.git
synced 2026-04-05 16:39:04 +08:00
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
153 lines
4.0 KiB
Rust
153 lines
4.0 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum GreenLevel {
|
|
TargetedTests,
|
|
Package,
|
|
Workspace,
|
|
MergeReady,
|
|
}
|
|
|
|
impl GreenLevel {
|
|
#[must_use]
|
|
pub fn as_str(self) -> &'static str {
|
|
match self {
|
|
Self::TargetedTests => "targeted_tests",
|
|
Self::Package => "package",
|
|
Self::Workspace => "workspace",
|
|
Self::MergeReady => "merge_ready",
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for GreenLevel {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{}", self.as_str())
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct GreenContract {
|
|
pub required_level: GreenLevel,
|
|
}
|
|
|
|
impl GreenContract {
|
|
#[must_use]
|
|
pub fn new(required_level: GreenLevel) -> Self {
|
|
Self { required_level }
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn evaluate(self, observed_level: Option<GreenLevel>) -> GreenContractOutcome {
|
|
match observed_level {
|
|
Some(level) if level >= self.required_level => GreenContractOutcome::Satisfied {
|
|
required_level: self.required_level,
|
|
observed_level: level,
|
|
},
|
|
_ => GreenContractOutcome::Unsatisfied {
|
|
required_level: self.required_level,
|
|
observed_level,
|
|
},
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn is_satisfied_by(self, observed_level: GreenLevel) -> bool {
|
|
observed_level >= self.required_level
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
#[serde(tag = "outcome", rename_all = "snake_case")]
|
|
pub enum GreenContractOutcome {
|
|
Satisfied {
|
|
required_level: GreenLevel,
|
|
observed_level: GreenLevel,
|
|
},
|
|
Unsatisfied {
|
|
required_level: GreenLevel,
|
|
observed_level: Option<GreenLevel>,
|
|
},
|
|
}
|
|
|
|
impl GreenContractOutcome {
|
|
#[must_use]
|
|
pub fn is_satisfied(&self) -> bool {
|
|
matches!(self, Self::Satisfied { .. })
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn given_matching_level_when_evaluating_contract_then_it_is_satisfied() {
|
|
// given
|
|
let contract = GreenContract::new(GreenLevel::Package);
|
|
|
|
// when
|
|
let outcome = contract.evaluate(Some(GreenLevel::Package));
|
|
|
|
// then
|
|
assert_eq!(
|
|
outcome,
|
|
GreenContractOutcome::Satisfied {
|
|
required_level: GreenLevel::Package,
|
|
observed_level: GreenLevel::Package,
|
|
}
|
|
);
|
|
assert!(outcome.is_satisfied());
|
|
}
|
|
|
|
#[test]
|
|
fn given_higher_level_when_checking_requirement_then_it_still_satisfies_contract() {
|
|
// given
|
|
let contract = GreenContract::new(GreenLevel::TargetedTests);
|
|
|
|
// when
|
|
let is_satisfied = contract.is_satisfied_by(GreenLevel::Workspace);
|
|
|
|
// then
|
|
assert!(is_satisfied);
|
|
}
|
|
|
|
#[test]
|
|
fn given_lower_level_when_evaluating_contract_then_it_is_unsatisfied() {
|
|
// given
|
|
let contract = GreenContract::new(GreenLevel::Workspace);
|
|
|
|
// when
|
|
let outcome = contract.evaluate(Some(GreenLevel::Package));
|
|
|
|
// then
|
|
assert_eq!(
|
|
outcome,
|
|
GreenContractOutcome::Unsatisfied {
|
|
required_level: GreenLevel::Workspace,
|
|
observed_level: Some(GreenLevel::Package),
|
|
}
|
|
);
|
|
assert!(!outcome.is_satisfied());
|
|
}
|
|
|
|
#[test]
|
|
fn given_no_green_level_when_evaluating_contract_then_contract_is_unsatisfied() {
|
|
// given
|
|
let contract = GreenContract::new(GreenLevel::MergeReady);
|
|
|
|
// when
|
|
let outcome = contract.evaluate(None);
|
|
|
|
// then
|
|
assert_eq!(
|
|
outcome,
|
|
GreenContractOutcome::Unsatisfied {
|
|
required_level: GreenLevel::MergeReady,
|
|
observed_level: None,
|
|
}
|
|
);
|
|
}
|
|
}
|