use crate::core::{Calendar, CalendarError, DeadlineSpec, Timestamp};
use super::conformance::Report;
pub fn check(calendar: &dyn Calendar, supported: &[DeadlineSpec], report: &mut Report) {
let from = Timestamp::from_unix_timestamp(1_760_000_000).expect("a valid test instant");
report.checked += 1;
if supported.is_empty() {
report.record(
"a calendar resolves something",
"no supported spec was given, so this battery would pass without \
resolving anything",
);
return;
}
the_digest_is_stable(calendar, report);
for spec in supported {
resolution_is_pure(calendar, from, spec, report);
a_count_at_the_edge_of_its_type_is_refused(calendar, from, spec, report);
}
a_rule_it_does_not_know_is_refused(calendar, from, report);
}
fn the_digest_is_stable(calendar: &dyn Calendar, r: &mut Report) {
r.checked += 1;
if calendar.digest() != calendar.digest() {
r.record(
"the digest identifies the ruleset",
"two reads of the digest disagreed, so the instants this calendar \
produced cannot be attributed to any ruleset at all",
);
}
}
fn resolution_is_pure(
calendar: &dyn Calendar,
from: Timestamp,
spec: &DeadlineSpec,
r: &mut Report,
) {
r.checked += 1;
let first = calendar.resolve(from, spec);
let second = calendar.resolve(from, spec);
match (first, second) {
(Ok(a), Ok(b)) if a == b => {}
(Ok(a), Ok(b)) => r.record(
"resolution is pure",
format!(
"'{}' resolved to {a} and then to {b}; two runs a millisecond apart \
would disagree about one regulatory window",
spec.kind
),
),
(Err(a), Err(b)) if a.to_string() == b.to_string() => {}
(a, b) => r.record(
"resolution is pure",
format!(
"'{}' answered {a:?} and then {b:?}; a rule that refuses \
intermittently is a rule nobody can act on",
spec.kind
),
),
}
}
fn a_count_at_the_edge_of_its_type_is_refused(
calendar: &dyn Calendar,
from: Timestamp,
spec: &DeadlineSpec,
r: &mut Report,
) {
for hostile in hostile_variants(spec) {
r.checked += 1;
match calendar.resolve(from, &hostile) {
Err(_) => {}
Ok(at) => r.record(
"a count no instant can carry is refused",
format!(
"'{}' with {} resolved to {at}; a window that long is a typo with \
no correct reading, and an obligation registered at that instant \
is one nobody will ever be warned about",
hostile.kind, hostile.params
),
),
}
}
}
fn hostile_variants(spec: &DeadlineSpec) -> Vec<DeadlineSpec> {
let serde_json::Value::Object(params) = &spec.params else {
return Vec::new();
};
let mut out = Vec::new();
for extreme in [i64::MAX, i64::MIN] {
let mut hostile = params.clone();
let mut touched = false;
for value in hostile.values_mut() {
if value.is_i64() || value.is_u64() {
*value = serde_json::Value::from(extreme);
touched = true;
}
}
if touched {
out.push(DeadlineSpec::new(
spec.kind.clone(),
serde_json::Value::Object(hostile),
));
}
}
out
}
fn a_rule_it_does_not_know_is_refused(calendar: &dyn Calendar, from: Timestamp, r: &mut Report) {
r.checked += 1;
let unknown = DeadlineSpec::new(
"agentplane.conformance/no-such-rule",
serde_json::json!({ "n": 5 }),
);
match calendar.resolve(from, &unknown) {
Err(CalendarError::UnknownKind(_)) => {}
Err(other) => r.record(
"an unknown rule is refused by name",
format!(
"a rule this calendar does not implement was refused as {other}, so a \
deployment cannot tell a missing rule from a malformed one"
),
),
Ok(at) => r.record(
"an unknown rule is refused, never approximated",
format!(
"a rule this calendar does not implement resolved to {at}; a wrong \
working-day answer is worse than no answer, because it looks right"
),
),
}
}