[][src]Crate amethyst_test

Test harness to support testing of Amethyst types, including:

The test harness minimizes boilerplate code to set up an Amethyst Application with common bundles, and can take in logic that is normally masked behind a number of layers through a thin interface.

Usage

The following shows a simple example of testing a State. More examples are in the Examples section.

// #[test]
fn loading_state_adds_load_resource() {
    assert!(
        AmethystApplication::blank()
            .with_state(|| LoadingState::new())
            .with_assertion(|world| {
                world.read_resource::<LoadResource>();
            })
            .run()
            .is_ok()
    );
}

The Amethyst application is initialized with one of the following functions, each providing a different set of bundles:

use amethyst_test::prelude::*;

#[test]
fn test_name() {
    // Start with no bundles
    AmethystApplication::blank();

    // Start with the following bundles:
    //
    // * `TransformBundle`
    // * `InputBundle`
    // * `UiBundle`
    //
    // The type parameters here are the Axis and Action types for the
    // `InputBundle` and `UiBundle`.
    use amethyst::input::StringBindings;
    AmethystApplication::ui_base::<StringBindings>();

    // If you need types from the rendering bundle, make sure you have
    // the `"test-support"` feature enabled:
    //
    // ```toml
    // # Cargo.toml
    // amethyst = { version = "..", features = ["test-support"] }
    // ```
    //
    // Then you can include the `RenderEmptyBundle`:
    use amethyst::renderer::{types::DefaultBackend, RenderEmptyBundle};
    AmethystApplication::blank()
        .with_bundle(RenderEmptyBundle::<DefaultBackend>::new());
}

Next, attach the logic you wish to test using the various .with_*(..) methods:

#[test]
fn test_name() {
    let visibility = false; // Whether the window should be shown
    AmethystApplication::render_base::<String, String, _>("test_name", visibility)
        .with_bundle(MyBundle::new())                // Registers a bundle.
        .with_bundle_fn(|| MyNonSendBundle::new())   // Registers a `!Send` bundle.
        .with_resource(MyResource::new())            // Adds a resource to the world.
        .with_system(MySystem, "my_sys", &[])        // Registers a system with the main
                                                     // dispatcher.

        // These are run in the order they are invoked.
        // You may invoke them multiple times.
        .with_setup(|world| { /* do something */ })
        .with_state(|| MyState::new())
        .with_effect(|world| { /* do something */ })
        .with_assertion(|world| { /* do something */ })
         // ...
}

Finally, call .run() to run the application. This returns amethyst::Result<()>, so you can wrap it in an assert!(..);:

#[test]
fn test_name() {
    let visibility = false; // Whether the window should be shown
    assert!(
        AmethystApplication::render_base("test_name", visibility)
            // ...
            .run()
            .is_ok()
    );
}

Examples

Testing a bundle:

// #[test]
fn bundle_registers_system_with_resource() {
    assert!(
        AmethystApplication::blank()
            .with_bundle(MyBundle)
            .with_assertion(|world| { world.read_resource::<ApplicationResource>(); })
            .run()
            .is_ok()
    );
}

Testing a system:

// #[test]
fn system_increases_component_value_by_one() {
    assert!(
        AmethystApplication::blank()
            .with_system(MySystem, "my_system", &[])
            .with_effect(|world| {
                let entity = world.create_entity().with(MyComponent(0)).build();
                world.insert(EffectReturn(entity));
            })
            .with_assertion(|world| {
                let entity = world.read_resource::<EffectReturn<Entity>>().0.clone();

                let my_component_storage = world.read_storage::<MyComponent>();
                let my_component = my_component_storage
                    .get(entity)
                    .expect("Entity should have a `MyComponent` component.");

                // If the system ran, the value in the `MyComponent` should be 1.
                assert_eq!(1, my_component.0);
            })
            .run()
            .is_ok()
    );
}

Testing a System in a custom dispatcher. This is useful when your system must run after some setup has been done:

// #[test]
fn system_increases_resource_value_by_one() {
    assert!(
        AmethystApplication::blank()
            .with_setup(|world| {
                world.insert(MyResource(0));
            })
            .with_system_single(MySystem, "my_system", &[])
            .with_assertion(|world| {
                let my_resource = world.read_resource::<MyResource>();

                // If the system ran, the value in the `MyResource` should be 1.
                assert_eq!(1, my_resource.0);
            })
            .run()
            .is_ok()
    );
}

Modules

prelude

Commonly used imports.

Structs

AmethystApplication

Builder for an Amethyst application.

CustomDispatcherState

State with a custom dispatcher.

CustomDispatcherStateBuilder

Builder for the CustomDispatcherState.

EffectReturn

Convenience type for storing and retrieving the result of an effect.

FunctionState

Runs a function in .update() then Pops itself.

InMemorySource

In-memory implementation of an asset Source, purely for tests.

MaterialAnimationFixture

Fixture to test material animation loading.

PopState

State that returns Trans::Pop on .update().

SequencerState

Pushes each State onto the Amethyst state stack in reverse order (LIFO).

SpriteRenderAnimationFixture

Fixture to test sprite render animation loading.

WaitForLoad

Reads a ProgressCounter resource and waits for it to be complete().

Constants

HIDPI

The ratio between the backing framebuffer resolution and the window size in screen pixels. This is typically one for a normal display and two for a retina display.

IN_MEMORY_SOURCE_ID

Identifies the in-memory asset source.

SCREEN_HEIGHT

Screen height used in predefined display configuration.

SCREEN_WIDTH

Screen width used in predefined display configuration.

Traits

GameUpdate

Exposes the update method of game data so that this crate's States can invoke it.