use super::conclude::agreement;
use super::types::{
COMPOSED_CONSERVATION_DISAGREEMENT, COMPOSED_DETERMINISM_DISAGREEMENT,
COMPOSED_IDEMPOTENCE_DISAGREEMENT, COMPOSED_RETURN_DISAGREEMENT, ComposedRoads, Equivalence,
Measure,
};
use crate::report::TrialConclusion;
#[must_use]
pub fn composed<Entry, Middle, Exit>(
suite: &ComposedRoads<Entry, Middle, Exit>,
entry: &Entry,
) -> Exit {
(suite.second())(&(suite.first())(entry))
}
#[must_use]
#[track_caller]
pub fn composed_determinism<Entry, Middle, Exit>(
suite: &ComposedRoads<Entry, Middle, Exit>,
entry: &Entry,
) -> TrialConclusion {
let first = composed(suite, entry);
let second = composed(suite, entry);
agreement(
suite.same(),
&first,
&second,
COMPOSED_DETERMINISM_DISAGREEMENT,
)
}
#[must_use]
#[track_caller]
pub fn composed_conservation<Entry, Middle, Exit, Quantity>(
suite: &ComposedRoads<Entry, Middle, Exit>,
entering: Measure<Entry, Quantity>,
leaving: Measure<Exit, Quantity>,
same: Equivalence<Quantity>,
entry: &Entry,
) -> TrialConclusion {
let before = entering(entry);
let after = leaving(&composed(suite, entry));
agreement(same, &before, &after, COMPOSED_CONSERVATION_DISAGREEMENT)
}
#[must_use]
#[track_caller]
pub fn composed_return<Value, Middle>(
suite: &ComposedRoads<Value, Middle, Value>,
value: &Value,
) -> TrialConclusion {
let returned = composed(suite, value);
agreement(suite.same(), value, &returned, COMPOSED_RETURN_DISAGREEMENT)
}
#[must_use]
#[track_caller]
pub fn composed_idempotence<Value, Middle>(
suite: &ComposedRoads<Value, Middle, Value>,
value: &Value,
) -> TrialConclusion {
let once = composed(suite, value);
let twice = composed(suite, &once);
agreement(
suite.same(),
&once,
&twice,
COMPOSED_IDEMPOTENCE_DISAGREEMENT,
)
}