use crate::config::error::LoadError;
use crate::config::workflow::Workflow;
use std::path::Path;
fn parse(raw: &str) -> Result<Workflow, LoadError> {
Workflow::parse(raw, Path::new("<commit>:workflow.yaml"))
}
#[test]
fn workflow_without_compaction_is_ok() {
let w = parse("events:\n user_message:\n - notify_ui\n").unwrap();
assert!(w.compaction.is_none());
}
#[test]
fn rejects_a_retained_tail_at_or_over_the_commit_trigger() {
let yaml = "events: {}\ncompaction:\n intermediate:\n trigger: every_n_commits\n n: 5\n keep_recent: 5\n";
match parse(yaml).unwrap_err() {
LoadError::Invalid { key, message, .. } => {
assert_eq!(key, "compaction.intermediate.keep_recent");
assert!(message.contains("smaller than n"), "{message}");
}
other => panic!("expected Invalid, got {other:?}"),
}
let ok = "events: {}\ncompaction:\n intermediate:\n trigger: every_n_commits\n n: 5\n keep_recent: 4\n";
assert_eq!(
parse(ok)
.unwrap()
.compaction
.unwrap()
.intermediate
.keep_recent,
Some(4)
);
let time = "events: {}\ncompaction:\n intermediate:\n trigger: every_t_seconds\n n: 5\n keep_recent: 50\n";
assert!(parse(time).is_ok());
}
#[test]
fn rejects_compaction_missing_n_for_count_trigger() {
let yaml = "events: {}\ncompaction:\n intermediate:\n trigger: every_n_commits\n";
let err = parse(yaml).unwrap_err();
match err {
LoadError::Invalid { key, .. } => assert_eq!(key, "compaction.intermediate.n"),
other => panic!("expected Invalid, got {other:?}"),
}
}
#[test]
fn rejects_compaction_missing_n_for_seconds_trigger() {
let yaml = "events: {}\ncompaction:\n intermediate:\n trigger: every_t_seconds\n";
assert!(matches!(parse(yaml), Err(LoadError::Invalid { .. })));
}
#[test]
fn on_flush_trigger_does_not_need_n() {
let yaml = "events: {}\ncompaction:\n intermediate:\n trigger: on_flush\n";
assert!(parse(yaml).is_ok());
}
#[test]
fn rejects_compaction_zero_n() {
let yaml = "events: {}\ncompaction:\n intermediate:\n trigger: every_n_commits\n n: 0\n";
assert!(matches!(parse(yaml), Err(LoadError::Invalid { .. })));
}
#[test]
fn extract_bytes_is_optional_and_carries_the_landings_cap() {
let none = "events: {}\ncompaction:\n intermediate:\n trigger: on_flush\n";
assert_eq!(
parse(none)
.unwrap()
.compaction
.unwrap()
.intermediate
.extract_bytes,
None
);
let set = "events: {}\ncompaction:\n intermediate:\n trigger: on_flush\n extract_bytes: 32768\n";
assert_eq!(
parse(set)
.unwrap()
.compaction
.unwrap()
.intermediate
.extract_bytes,
Some(32768)
);
}
#[test]
fn window_percent_takes_n_as_a_percentage_and_refuses_the_rest() {
let at = |n: &str| {
parse(&format!(
"events: {{}}\ncompaction:\n intermediate:\n trigger: window_percent\n n: {n}\n"
))
};
assert_eq!(
at("100").unwrap().compaction.unwrap().intermediate.n,
Some(100)
);
assert_eq!(at("1").unwrap().compaction.unwrap().intermediate.n, Some(1));
match at("101").unwrap_err() {
LoadError::Invalid { key, message, .. } => {
assert_eq!(key, "compaction.intermediate.n");
assert!(message.contains("1..=100"), "{message}");
}
other => panic!("expected Invalid, got {other:?}"),
}
let missing = "events: {}\ncompaction:\n intermediate:\n trigger: window_percent\n";
assert!(matches!(parse(missing), Err(LoadError::Invalid { .. })));
let tail = "events: {}\ncompaction:\n intermediate:\n trigger: window_percent\n n: 50\n keep_recent: 90\n";
assert!(parse(tail).is_ok());
}
#[test]
fn the_retained_tail_is_declared_once_in_one_unit() {
let both = "events: {}\ncompaction:\n intermediate:\n trigger: on_flush\n keep_recent: 3\n keep_recent_tokens: 20000\n";
match parse(both).unwrap_err() {
LoadError::Invalid { key, message, .. } => {
assert_eq!(key, "compaction.intermediate.keep_recent_tokens");
assert!(message.contains("keep_recent"), "{message}");
assert!(message.contains("declare one"), "{message}");
}
other => panic!("expected Invalid, got {other:?}"),
}
let tokens = "events: {}\ncompaction:\n intermediate:\n trigger: on_flush\n keep_recent_tokens: 20000\n";
let c = parse(tokens).unwrap().compaction.unwrap();
assert_eq!(c.intermediate.keep_recent_tokens, Some(20000));
assert_eq!(c.intermediate.keep_recent, None);
let clocked = "events: {}\ncompaction:\n intermediate:\n trigger: every_n_commits\n n: 5\n keep_recent_tokens: 20000\n";
assert!(parse(clocked).is_ok());
}