[][src]Crate amethyst_test

Test harness to support testing of Amethyst types, including:

  • Bundle
  • State
  • System
  • Resource loading.
  • Arbitrary types that Systems use during processing.

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:

extern crate amethyst_test;

use amethyst_test::prelude::*;

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

    // Start with the Transform, Input, and UI bundles
    // The type parameters here are the Axis and Action types for the `InputBundle` and
    // `UiBundle`.
    AmethystApplication::ui_base::<String, String>();

    // Start with the Animation, Transform, and Render bundles.
    // If you want the Input and UI bundles, you can use the `.with_ui_bundles::<AX, AC>()`
    // method.
    let visibility = false; // Whether the window should be shown
    AmethystApplication::render_base("test_name", visibility);
}

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::new(), "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.add_resource(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.add_resource(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.

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.

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.

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.