Skip to main content

DeclaredRows

Struct DeclaredRows 

Source
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>

Source

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.

Source

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.

Source

pub fn declared(&self) -> Vec<Check>

The declared rows, in declaration order.

This is what accept must be given as allow_skipped: the rows this deployment said it cannot exercise are exactly the skips a gate should tolerate, and no others.

Source

pub const fn fixtures(&self) -> &W

The wrapped fixtures.

Trait Implementations§

Source§

impl<W> Debug for DeclaredRows<W>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Names the declared rows. The wrapped fixtures need not be Debug, and the reasons are the report’s business rather than a rendering’s.

Source§

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,

Mounts on server the mocks that make the adapter meet scenario. Read more
Source§

fn status_support(&self, row: StatusRow) -> RowSupport

Whether this endpoint can put row on the wire at all. Read more
Source§

fn feature_support(&self, check: Check) -> RowSupport

Whether this deployment can put a feature row on the wire at all. Read more

Auto Trait Implementations§

§

impl<W> Freeze for DeclaredRows<W>
where W: Freeze,

§

impl<W> RefUnwindSafe for DeclaredRows<W>
where W: RefUnwindSafe,

§

impl<W> Send for DeclaredRows<W>
where W: Send,

§

impl<W> Sync for DeclaredRows<W>
where W: Sync,

§

impl<W> Unpin for DeclaredRows<W>
where W: Unpin,

§

impl<W> UnsafeUnpin for DeclaredRows<W>
where W: UnsafeUnpin,

§

impl<W> UnwindSafe for DeclaredRows<W>
where W: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more