1

I'm trying to write tests for my Rust program that is using the SPECS framework. I'm not sure how to run unit tests on the system's run function because it uses the framework's storage types to read values. Does anyone have a good method for getting around this? Here is my code for a movement system:

use specs::prelude::*;
use crate::components::{Position, Velocity, Antenna};
pub struct Movement;
impl<'a> System<'a> for Movement {
    type SystemData = (
        WriteStorage<'a, Position>,
        WriteStorage<'a, Velocity>,
    );

    fn run(&mut self, (mut position, velocity): Self::SystemData) {
        for(pos, vel) in (&mut position, &velocity).join() {
            pos.x += vel.x;
            pos.y += vel.y;
        }
    }
}
Shizz
  • 43
  • 6

1 Answers1

0

You could make run simpler by forwarding to a function in Movement, and then test that function instead. Make this new function generic on P and V for position and velocity.

You'll probably need to add some traits for P and V and implement them for WriteStorage and whatever type you're going to use for testing, (maybe just &[f32])

Something like:

use specs::prelude::*;
use crate::components::{Position, Velocity, Antenna};
pub struct Movement;

trait ValueList<T> { /* ... */ }
impl<T> ValueList<T> for WriteStorage<'a, T> { /* ... */ }
impl<T> ValueList<T> for &[T] { /* ... */ }

impl Movement {
    fn run_impl<P,V>(position:P, velocity:V)
    where
        P: ValueList<Position>
        V: ValueList<Velocity>
    {
        for(pos, vel) in (&mut position, &velocity).join() {
            pos.x += vel.x;
            pos.y += vel.y;
        }
    }
}

impl<'a> System<'a> for Movement {
    type SystemData = (
        WriteStorage<'a, Position>,
        WriteStorage<'a, Velocity>,
    );

    fn run(&mut self, (mut position, velocity): Self::SystemData) {
        Self::run_impl(position, velocity);
    }
}

#[test]
fn test_run() {
   let p:Vec<Position> = vec![...];
   let v:Vec<Velocity> = vec![...];

   Movement::run_impl(p,v);
   ...
}
Michael Anderson
  • 70,661
  • 7
  • 134
  • 187