[][src]Crate cqrs_proptest

cqrs-proptest

cqrs-proptest contains various utilities for building property tests with the proptest crate and aggregates from cqrs or cqrs-core.

Examples

use cqrs_core::{Aggregate, AggregateEvent, Event};
use cqrs_proptest::AggregateFromEventSequence;
use proptest::{prelude::*, strategy::{TupleUnion, ValueTree, W}, test_runner::TestRunner, prop_oneof};

#[derive(Debug, Default)]
struct MyAggregate {
    active: bool
}

impl Aggregate for MyAggregate {
    fn aggregate_type() -> &'static str {
        "my_aggregate"
    }
}

#[derive(Clone, Copy, Debug)]
struct CreatedEvent{};

impl Event for CreatedEvent {
    fn event_type(&self) -> &'static str {
        "created"
    }
}

impl AggregateEvent<MyAggregate> for CreatedEvent {
    fn apply_to(self, aggregate: &mut MyAggregate) {
        aggregate.active = true;
    }
}

#[derive(Clone, Copy, Debug)]
struct DeletedEvent{};

impl Event for DeletedEvent {
    fn event_type(&self) -> &'static str {
        "deleted"
    }
}

impl AggregateEvent<MyAggregate> for DeletedEvent {
    fn apply_to(self, aggregate: &mut MyAggregate) {
        aggregate.active = false;
    }
}

#[derive(Clone, Copy, Debug)]
enum MyEvents {
    Created(CreatedEvent),
    Deleted(DeletedEvent),
}

impl Event for MyEvents {
    fn event_type(&self) -> &'static str {
        match *self {
            MyEvents::Created(ref e) => e.event_type(),
            MyEvents::Deleted(ref e) => e.event_type(),
        }
    }
}

impl AggregateEvent<MyAggregate> for MyEvents {
    fn apply_to(self, aggregate: &mut MyAggregate) {
        match self {
            MyEvents::Created(e) => e.apply_to(aggregate),
            MyEvents::Deleted(e) => e.apply_to(aggregate),
        }
    }
}

impl Arbitrary for MyEvents {
    type Parameters = ();

    fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
        prop_oneof![
            Just(MyEvents::Created(CreatedEvent{})),
            Just(MyEvents::Deleted(DeletedEvent{})),
        ]
    }

    type Strategy = TupleUnion<(W<Just<Self>>, W<Just<Self>>)>;
}

any::<AggregateFromEventSequence<MyAggregate, MyEvents>>()
    .new_tree(&mut TestRunner::default())
    .unwrap()
    .current()
    .into_aggregate();

let parameters = (prop::collection::SizeRange::from(1..10), ());
any_with::<AggregateFromEventSequence<MyAggregate, MyEvents>>(parameters)
    .new_tree(&mut TestRunner::default())
    .unwrap()
    .current();

Structs

AggregateFromEventSequence

A wrapper for an aggregate that was generated from an arbitrary sequence of events.

Functions

arb_aggregate

Produces a strategy to generate an arbitrary aggregate, given a strategy to generate an arbitrary vector of events

arb_events

Produces a strategy to generate an arbitrary vector of events, given a strategy to generate an arbitrary event and a size range.

roundtrip_through_serialization

Given a serializable event, constructs a buffer, serializes the event to the buffer, and then deserializes the event, returning the deserialized value.