pub struct DeclaredRows<W> { /* private fields */ }Expand description
Fixtures plus the rows this deployment cannot put on the wire, declared in one table.
The harness asks two different questions about an undeliverable row —
WireFixtures::status_support for a per-status row,
WireFixtures::feature_support for a
declarable feature row — and a gate then has to be
told the same rows a third time, as the allow_skipped list. Three places,
one fact. This type holds the fact once: it answers both hooks from its own
table and hands the very same rows to accept through
declared, so a declaration and the gate that tolerates it
cannot drift apart.
A row it says nothing about falls through to the wrapped fixtures, so an adapter that already implements either hook keeps it and adds to it.
The reason is not decoration. The harness fails a reason-less declaration on purpose, and refuses one on a row that describes the adapter rather than the deployment, so this type deliberately validates nothing itself: it passes the declaration through and lets the suite judge it.
use async_trait::async_trait;
use turnframe_test::providers::conformance::{
Check, DeclaredRows, RowSupport, Scenario, StatusRow, WireFixtures,
};
use wiremock::MockServer;
struct MyFixtures;
#[async_trait]
impl WireFixtures for MyFixtures {
async fn mount(&self, _server: &MockServer, _scenario: Scenario) {
// one vendor-shaped mock per scenario
}
}
let fixtures = DeclaredRows::new(MyFixtures)
.not_producible(
Check::StreamingReconstruction,
"this deployment runs the model with its streaming route switched off",
)
.not_producible(
Check::StatusMapping(StatusRow::RequestTimeout),
"the gateway answers 504, never 408",
);
// Both hooks answer from the one table...
assert_eq!(
fixtures.feature_support(Check::StreamingReconstruction).reason(),
Some("this deployment runs the model with its streaming route switched off"),
);
assert_eq!(
fixtures.status_support(StatusRow::RequestTimeout).reason(),
Some("the gateway answers 504, never 408"),
);
// ...anything else is mounted, exactly as the wrapped fixtures said.
assert_eq!(fixtures.feature_support(Check::Refusal), RowSupport::Mounted);
// ...and the gate is told the same two rows, not a hand-kept copy of them.
assert_eq!(
fixtures.declared(),
vec![
Check::StreamingReconstruction,
Check::StatusMapping(StatusRow::RequestTimeout),
],
);Implementations§
Source§impl<W> DeclaredRows<W>
impl<W> DeclaredRows<W>
Sourcepub const fn new(fixtures: W) -> Self
pub const fn new(fixtures: W) -> Self
Wraps fixtures, declaring nothing yet.
With no declarations the wrapper is transparent: every hook delegates, so wrapping fixtures that need no declaration changes no outcome.
Sourcepub fn not_producible(self, check: Check, reason: impl Into<String>) -> Self
pub fn not_producible(self, check: Check, reason: impl Into<String>) -> Self
Declares that this deployment cannot produce check, and why.
check is a feature row or a
StatusMapping row; the wrapper routes it to
whichever hook the harness will ask. The first declaration for a row
wins, so a wrapper cannot contradict itself halfway down a builder
chain.
Trait Implementations§
Source§impl<W> Debug for DeclaredRows<W>
impl<W> Debug for DeclaredRows<W>
Source§impl<W: WireFixtures> WireFixtures for DeclaredRows<W>
impl<W: WireFixtures> WireFixtures for DeclaredRows<W>
Source§fn mount<'life0, 'life1, 'async_trait>(
&'life0 self,
server: &'life1 MockServer,
scenario: Scenario,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn mount<'life0, 'life1, 'async_trait>(
&'life0 self,
server: &'life1 MockServer,
scenario: Scenario,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn status_support(&self, row: StatusRow) -> RowSupport
fn status_support(&self, row: StatusRow) -> RowSupport
row on the wire at all. Read more