Skip to content

Commit

Permalink
use proptest
Browse files Browse the repository at this point in the history
  • Loading branch information
brunocodutra committed Jan 25, 2019
1 parent 0c53e4b commit 56286f0
Show file tree
Hide file tree
Showing 16 changed files with 285 additions and 199 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ futures-preview = { version = "0.3.0-alpha.12", optional = true }
[dev-dependencies]
criterion = "0.2.7"
iui = "0.3.0"
proptest = "0.8.7"
ttf-noto-sans = "0.1.1"

[dev-dependencies.conrod]
Expand Down
15 changes: 9 additions & 6 deletions src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ pub trait Dispatcher<A> {
mod tests {
use super::*;
use crate::mock::*;
use proptest::*;

#[test]
fn dispatch() {
let dispatcher: &mut Dispatcher<_, Output = _> = &mut MockDispatcher::default();
proptest! {
#[test]
fn dispatch(actions: Vec<u8>) {
let dispatcher: &mut Dispatcher<_, Output = _> = &mut MockDispatcher::default();

assert_eq!(dispatcher.dispatch(5), 5);
assert_eq!(dispatcher.dispatch(1), 1);
assert_eq!(dispatcher.dispatch(3), 3);
for action in actions {
assert_eq!(dispatcher.dispatch(action), action);
}
}
}
}
118 changes: 67 additions & 51 deletions src/dispatcher/async_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ mod tests {
use super::*;
use crate::mock::*;
use futures::executor::block_on;
use futures::future::join_all;
use proptest::*;
use std::error::Error;

#[test]
Expand All @@ -200,37 +202,67 @@ mod tests {
assert_eq!(store.inner, Store::default());
}

#[test]
fn new() {
let state = MockReducer::new(vec![42]);
let reactor = MockReactor::default();
let store = AsyncStore::<_, _, i32>::new(state.clone(), &reactor);
proptest! {
#[test]
fn new(actions: Vec<u8>) {
let state = MockReducer::new(actions);
let reactor = MockReactor::default();
let store = AsyncStore::new(state.clone(), &reactor);

assert_eq!(store.inner, Store::new(state, &reactor));
assert_eq!(store.inner, Store::new(state, &reactor));
}
}

#[test]
fn from() {
let state = MockReducer::new(vec![42]);
let reactor = MockReactor::default();
let store = AsyncStore::<_, _, i32>::from(Store::new(state.clone(), &reactor));
proptest! {
#[test]
fn from(actions: Vec<u8>) {
let state = MockReducer::new(actions);
let reactor = MockReactor::default();
let store = AsyncStore::from(Store::new(state.clone(), &reactor));

assert_eq!(store.inner, Store::new(state, &reactor));
assert_eq!(store.inner, Store::new(state, &reactor));
}
}

#[test]
fn into() {
let state = MockReducer::new(vec![42]);
let reactor = MockReactor::default();
let store: Store<_, _> = AsyncStore::<_, _, i32>::new(state.clone(), &reactor).into();
proptest! {
#[test]
fn into(actions: Vec<u8>) {
let state = MockReducer::new(actions);
let reactor = MockReactor::default();
let store: Store<_, _> = AsyncStore::new(state.clone(), &reactor).into();

assert_eq!(store, AsyncStore::<_, _, i32>::new(state, &reactor).inner);
assert_eq!(store, AsyncStore::new(state, &reactor).inner);
}
}

#[test]
fn clone() {
let store = AsyncStore::<_, _, ()>::new(MockReducer::default(), MockReactor::default());
assert_eq!(store, store.clone());
proptest! {
#[test]
fn clone(actions: Vec<u8>) {
let store = AsyncStore::new(MockReducer::new(actions), MockReactor::default());
assert_eq!(store, store.clone());
}
}

proptest! {
#[test]
fn subscribe(actions: Vec<u8>) {
let state = MockReducer::new(actions);
let mut store = AsyncStore::new(state.clone(), Some(MockReactor::default()));

assert_eq!(
store.inner,
Store::new(state.clone(), Some(MockReactor::default()))
);

assert_eq!(store.subscribe(None), Some(MockReactor::default()));
assert_eq!(store.inner, Store::new(state.clone(), None));
assert_eq!(store.subscribe(MockReactor::default()), None);

assert_eq!(
store.inner,
Store::new(state.clone(), Some(MockReactor::default()))
);
}
}

#[test]
Expand All @@ -247,36 +279,20 @@ mod tests {
assert!(store.spawn_thread().is_ok());
}

#[test]
fn dispatch() -> Result<(), Box<dyn Error>> {
let store = AsyncStore::<MockReducer<_>, MockReactor<_>, _>::default();
let mut dispatcher = store.spawn_thread()?;

assert_eq!(
block_on(dispatcher.dispatch(5)),
Ok(MockReducer::new(vec![5]))
);

assert_eq!(
block_on(dispatcher.dispatch(1)),
Ok(MockReducer::new(vec![5, 1]))
);
proptest! {
#[test]
fn dispatch(actions: Vec<u8>) {
let store = AsyncStore::<MockReducer<_>, MockReactor<_>, _>::default();
let mut dispatcher = store.spawn_thread().unwrap();

assert_eq!(
block_on(dispatcher.dispatch(3)),
Ok(MockReducer::new(vec![5, 1, 3]))
);
let promises: Vec<_> = actions
.iter()
.map(|&action| dispatcher.dispatch(action))
.collect();

Ok(())
}

#[test]
fn subscribe() {
let state = MockReducer::default();
let reactor = MockReactor::default();
let mut store = AsyncStore::<_, _, ()>::new(state, Some(reactor));

store.subscribe(None);
assert_eq!(store.inner, Store::new(MockReducer::default(), None));
for (i, state) in block_on(join_all(promises)).drain(..).enumerate() {
assert_eq!(state, Ok(MockReducer::new(actions[0..=i].into())));
}
}
}
}
70 changes: 44 additions & 26 deletions src/dispatcher/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ where
mod tests {
use super::*;
use crate::mock::*;
use proptest::*;

#[test]
fn default() {
Expand All @@ -117,41 +118,58 @@ mod tests {
assert_eq!(store.reactor, MockReactor::default());
}

#[test]
fn new() {
let state = MockReducer::new(vec![42]);
let reactor = MockReactor::default();
let store = Store::new(state.clone(), &reactor);
proptest! {
#[test]
fn new(actions: Vec<u8>) {
let state = MockReducer::new(actions);
let reactor = MockReactor::default();
let store = Store::new(state.clone(), &reactor);

assert_eq!(store.state, state);
assert_eq!(store.reactor, &reactor);
assert_eq!(store.state, state);
assert_eq!(store.reactor, &reactor);
}
}

#[test]
fn clone() {
let store = Store::new(MockReducer::<()>::default(), MockReactor::default());
assert_eq!(store, store.clone());
proptest! {
#[test]
fn clone(actions: Vec<u8>) {
let store = Store::new(MockReducer::new(actions), MockReactor::default());
assert_eq!(store, store.clone());
}
}

#[test]
fn dispatch() {
let mut store = Store::<MockReducer<_>, MockReactor<_>>::default();
proptest! {
#[test]
fn subscribe(actions: Vec<u8>) {
let state = MockReducer::new(actions);
let mut store = Store::new(state.clone(), Some(MockReactor::default()));

assert_eq!(store.dispatch(5), MockReducer::new(vec![5]));
assert_eq!(store.dispatch(1), MockReducer::new(vec![5, 1]));
assert_eq!(store.dispatch(3), MockReducer::new(vec![5, 1, 3]));
}
assert_eq!(store.state, state);
assert_eq!(store.reactor, Some(MockReactor::default()));

#[test]
fn subscribe() {
let mut store: Store<_, Option<MockReactor<_>>> = Store::new(MockReducer::default(), None);
assert_eq!(store.subscribe(None), Some(MockReactor::default()));

assert_eq!(store.state, state);
assert_eq!(store.reactor, None);

assert_eq!(store.dispatch(0), None);
assert_eq!(store.subscribe(MockReactor::default()), None);

store.subscribe(Some(MockReactor::default()));
assert_eq!(store.state, state);
assert_eq!(store.reactor, Some(MockReactor::default()));
}
}

assert_eq!(store.dispatch(5), Some(MockReducer::new(vec![0, 5])));
assert_eq!(store.dispatch(1), Some(MockReducer::new(vec![0, 5, 1])));
assert_eq!(store.dispatch(3), Some(MockReducer::new(vec![0, 5, 1, 3])));
proptest! {
#[test]
fn dispatch(actions: Vec<u8>) {
let mut store = Store::<MockReducer<_>, MockReactor<_>>::default();

for (i, &action) in actions.iter().enumerate() {
assert_eq!(
store.dispatch(action),
MockReducer::new(actions[0..=i].into())
);
}
}
}
}
47 changes: 27 additions & 20 deletions src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,33 +47,40 @@ impl<A> Dispatcher<A> for MockDispatcher<A> {
#[cfg(test)]
mod tests {
use super::*;
use proptest::*;

#[test]
fn react() {
let reactor = MockReactor::default();
proptest! {
#[test]
fn reduce(actions: Vec<u8>) {
let mut reducer = MockReducer::default();

assert_eq!(reactor.react(&5), 5);
assert_eq!(reactor.react(&1), 1);
assert_eq!(reactor.react(&3), 3);
}
for &action in &actions {
reducer.reduce(action);
}

#[test]
fn reduce() {
let mut state = MockReducer::default();
assert_eq!(reducer, MockReducer::new(actions));
}
}

state.reduce(5);
state.reduce(1);
state.reduce(3);
proptest! {
#[test]
fn react(states: Vec<u8>) {
let reactor = MockReactor::default();

assert_eq!(state, MockReducer::new(vec![5, 1, 3]));
for state in states {
assert_eq!(reactor.react(&state), state);
}
}
}

#[test]
fn dispatch() {
let mut dispatcher = MockDispatcher::default();
proptest! {
#[test]
fn dispatch(actions: Vec<u8>) {
let mut dispatcher = MockDispatcher::default();

assert_eq!(dispatcher.dispatch(5), 5);
assert_eq!(dispatcher.dispatch(1), 1);
assert_eq!(dispatcher.dispatch(3), 3);
for action in actions {
assert_eq!(dispatcher.dispatch(action), action);
}
}
}
}
15 changes: 9 additions & 6 deletions src/reactor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,16 @@ pub trait Reactor<S> {
mod tests {
use super::*;
use crate::mock::*;
use proptest::*;

#[test]
fn react() {
let reactor: &Reactor<_, Output = _> = &MockReactor::default();
proptest! {
#[test]
fn react(states: Vec<u8>) {
let reactor: &Reactor<_, Output = _> = &MockReactor::default();

assert_eq!(reactor.react(&5), 5);
assert_eq!(reactor.react(&1), 1);
assert_eq!(reactor.react(&3), 3);
for state in states {
assert_eq!(reactor.react(&state), state);
}
}
}
}
24 changes: 14 additions & 10 deletions src/reactor/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,30 @@ impl_reactor_for_array!(
mod tests {
use super::*;
use crate::mock::*;
use proptest::*;

macro_rules! test_reactor_for_array {
() => {};

( $head:ident $(, $tail:ident )* $(,)? ) => {
#[test]
fn $head() {
proptest!(|(states: Vec<u8>)| {
let reactors = [MockReactor::default(); count!($( $tail, )*)];

assert_eq!(reactors.react(&5), [5; count!($( $tail, )*)]);
assert_eq!(reactors.react(&1), [1; count!($( $tail, )*)]);
assert_eq!(reactors.react(&3), [3; count!($( $tail, )*)]);
}
for state in states {
assert_eq!(reactors.react(&state), [state; count!($( $tail, )*)]);
}
});

test_reactor_for_array!($( $tail, )*);
};
}

test_reactor_for_array!(
_32, _31, _30, _29, _28, _27, _26, _25, _24, _23, _22, _21, _20, _19, _18, _17, _16, _15,
_14, _13, _12, _11, _10, _09, _08, _07, _06, _05, _04, _03, _02, _01, _00
);
#[allow(clippy::cyclomatic_complexity)]
#[test]
fn react() {
test_reactor_for_array!(
_32, _31, _30, _29, _28, _27, _26, _25, _24, _23, _22, _21, _20, _19, _18, _17, _16,
_15, _14, _13, _12, _11, _10, _09, _08, _07, _06, _05, _04, _03, _02, _01, _00
);
}
}
Loading

0 comments on commit 56286f0

Please sign in to comment.