Open jonathandw743 opened 2 weeks ago
Are you able to turn this into a test case that doesn't rely on user input at all? Ideally using App::update
calls :)
Are you able to turn this into a test case that doesn't rely on user input at all? Ideally using
App::update
calls :)
Will do when I have the chance 👍
Are you able to turn this into a test case that doesn't rely on user input at all? Ideally using
App::update
calls :)
could you point me to a resource on how to do this please?
Here's an example of writing integration tests in Bevy in this style from leafwing-input-manager: https://github.com/Leafwing-Studios/leafwing-input-manager/blob/main/tests/integration.rs :)
Are you able to turn this into a test case that doesn't rely on user input at all? Ideally using
App::update
calls :)
fn main() {
let mut app: bevy::app::App = App::new();
app.add_plugins(DefaultPlugins);
app.insert_state(S1::A);
app.add_sub_state::<S2>();
app.add_systems(Update, transition_to_s1_b_on_click.run_if(in_state(S1::A)));
app.add_systems(Update, transition_to_s2_d_on_click.run_if(in_state(S2::C)));
app.add_systems(Update, info_states);
app.add_systems(Update, reset);
app.finish();
app.cleanup();
app.update();
app.update();
app.update();
app.update();
app.update();
app.world_mut().send_event(MouseButtonInput {
button: MouseButton::Left,
state: ButtonState::Pressed,
window: Entity::from_bits(934587943958),
});
app.update();
app.update();
app.update();
app.update();
app.update();
app.world_mut().send_event(MouseButtonInput {
button: MouseButton::Left,
state: ButtonState::Released,
window: Entity::from_bits(934587943958),
});
app.update();
app.update();
app.update();
app.update();
app.update();
app.should_exit().unwrap_or(AppExit::Success);
}
fn transition_to_s1_b_on_click(
mut mouse_events: EventReader<MouseButtonInput>,
mut ns_s1: ResMut<NextState<S1>>,
) {
for e in mouse_events.read() {
info!("\n{:#?}", e);
match e {
MouseButtonInput {
button: MouseButton::Left,
state: ButtonState::Pressed,
..
} => {
ns_s1.set(S1::B);
}
_ => {}
}
}
}
fn transition_to_s2_d_on_click(
mut mouse_events: EventReader<MouseButtonInput>,
mut ns_s2: ResMut<NextState<S2>>,
) {
for e in mouse_events.read() {
info!("\n{:#?}", e);
match e {
MouseButtonInput {
button: MouseButton::Left,
state: ButtonState::Pressed,
..
} => {
ns_s2.set(S2::D);
}
_ => {}
}
}
}
fn info_states(s1: Res<State<S1>>, s2: Option<Res<State<S2>>>) {
info!("{:?}, {:?}", s1, s2);
}
fn reset(keyboard_input: Res<ButtonInput<KeyCode>>, mut ns_s1: ResMut<NextState<S1>>) {
if keyboard_input.just_pressed(KeyCode::Escape) {
ns_s1.set(S1::A);
}
}
#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
enum S1 {
A,
B,
}
#[derive(SubStates, Debug, Clone, PartialEq, Eq, Hash, Default)]
#[source(S1 = S1::B)]
enum S2 {
#[default]
C,
D,
}
sometimes:
2024-06-22T16:34:07.858210Z INFO gam: Res(State(A)), None
2024-06-22T16:34:07.863300Z INFO gam: Res(State(A)), None
2024-06-22T16:34:07.872809Z INFO gam: Res(State(A)), None
2024-06-22T16:34:07.873689Z INFO gam: Res(State(A)), None
2024-06-22T16:34:07.874237Z INFO gam: Res(State(A)), None
2024-06-22T16:34:07.875343Z INFO gam: Res(State(A)), None
2024-06-22T16:34:07.875368Z INFO gam:
MouseButtonInput {
button: Left,
state: Pressed,
window: Entity {
index: 2580040726,
generation: 217,
},
}
2024-06-22T16:34:07.876410Z INFO gam:
MouseButtonInput {
button: Left,
state: Pressed,
window: Entity {
index: 2580040726,
generation: 217,
},
}
2024-06-22T16:34:07.876426Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-22T16:34:07.876964Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:07.877392Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:07.877996Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:07.878666Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:07.879262Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:07.880229Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:07.880631Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:07.881006Z INFO gam: Res(State(B)), Some(Res(State(D)))
sometimes:
2024-06-22T16:34:11.109256Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.113957Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.123502Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.124138Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.124997Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.125470Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.125472Z INFO gam:
MouseButtonInput {
button: Left,
state: Pressed,
window: Entity {
index: 2580040726,
generation: 217,
},
}
2024-06-22T16:34:11.125880Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-22T16:34:11.125907Z INFO gam:
MouseButtonInput {
button: Left,
state: Pressed,
window: Entity {
index: 2580040726,
generation: 217,
},
}
2024-06-22T16:34:11.126460Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:11.126831Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:11.127320Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:11.127699Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:11.128096Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:11.128543Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:11.129202Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:11.130297Z INFO gam: Res(State(B)), Some(Res(State(D)))
2024-06-22T16:34:11.109256Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.113957Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.123502Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.124138Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.124997Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.125470Z INFO gam: Res(State(A)), None
2024-06-22T16:34:11.125472Z INFO gam:
MouseButtonInput {
button: Left,
state: Pressed,
window: Entity {
index: 2580040726,
generation: 217,
},
}
2024-06-22T16:34:11.125880Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-22T16:34:11.126460Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-22T16:34:11.126831Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-22T16:34:11.127320Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-22T16:34:11.127699Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-22T16:34:11.128096Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-22T16:34:11.128543Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-22T16:34:11.129202Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-22T16:34:11.130297Z INFO gam: Res(State(B)), Some(Res(State(C)))
I cannot recreate this output using manual button presses:
2024-06-20T15:02:47.198639Z INFO gam: Res(State(A)), None
2024-06-20T15:02:47.213971Z INFO gam: Res(State(A)), None
2024-06-20T15:02:47.227818Z INFO gam: Res(State(A)), None
<mouse pressed>
2024-06-20T15:02:47.254104Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-20T15:02:47.267907Z INFO gam: Res(State(B)), Some(Res(State(C)))
2024-06-20T15:02:47.280845Z INFO gam: Res(State(B)), Some(Res(State(C)))
System Info
bevy 0.14.0-rc.2 Ubuntu 22.04
Program
Program summary:
state
S1
is set toA
stateS2
is a sub state ofS1
and has a default value ofC
when the mouse is pressed,S1
transitions toB
then sometimes,
S2
also transitions toD
Output
I would expect the output to be:
but occasionally (apparently at random) the output is:
("" is not logged)
(this is not a double press or anything like that, it happens consistently)
My guess about what is happening in the expected output and why
The mouse click event happens and is in the first
EventReader
. The state then changes toS1::B
The mouse click event leaves theEventReader
Thetransition_to_s2_d_on_click
system runs The mouse click event is no longer in theEventReader
The state does not changeMy guess about what is happening in the unexpected output and why
The mouse click event happens and is in the first
EventReader
. The state then changes toS1::B
Thetransition_to_s2_d_on_click
system runs The mouse click event is still in theEventReader
The state changes toS2::D