use bevy::prelude::*;
#[derive(Component)]
struct Player {
mana: u32,
}
impl Default for Player {
fn default() -> Self {
Self { mana: 10 }
}
}
fn game_plugin(app: &mut App) {
app.add_systems(Startup, (spawn_player, window_title_system).chain());
app.add_systems(Update, spell_casting);
}
fn window_title_system(mut windows: Query<&mut Window>) {
for (index, mut window) in windows.iter_mut().enumerate() {
window.title = format!("This is window {index}!");
}
}
fn spawn_player(mut commands: Commands) {
commands.spawn(Player::default());
}
fn spell_casting(mut player: Query<&mut Player>, keyboard_input: Res<ButtonInput<KeyCode>>) {
if keyboard_input.just_pressed(KeyCode::Space) {
let Ok(mut player) = player.single_mut() else {
return;
};
if player.mana > 0 {
player.mana -= 1;
}
}
}
fn create_test_app() -> App {
let mut app = App::new();
app.add_plugins(MinimalPlugins);
app.insert_resource(ButtonInput::<KeyCode>::default());
app.world_mut().spawn(Window::default());
app
}
#[test]
fn test_player_spawn() {
let mut app = create_test_app();
app.add_plugins(game_plugin);
app.update();
let expected = Player::default();
let actual = app.world_mut().query::<&Player>().single(app.world());
assert!(actual.is_ok(), "There should be exactly 1 player.");
assert_eq!(
expected.mana,
actual.unwrap().mana,
"Player does not have expected starting mana."
);
}
#[test]
fn test_spell_casting() {
let mut app = create_test_app();
app.add_plugins(game_plugin);
app.world_mut()
.resource_mut::<ButtonInput<KeyCode>>()
.press(KeyCode::Space);
app.update();
let expected = Player::default();
let actual = app
.world_mut()
.query::<&Player>()
.single(app.world())
.unwrap();
assert_eq!(
expected.mana - 1,
actual.mana,
"A single mana point should have been used."
);
app.world_mut()
.resource_mut::<ButtonInput<KeyCode>>()
.clear();
app.update();
let after_keypress_event = app
.world_mut()
.query::<&Player>()
.single(app.world())
.unwrap();
assert_eq!(
expected.mana - 1,
after_keypress_event.mana,
"No further mana should have been used."
);
}
#[test]
fn test_window_title() {
let mut app = create_test_app();
app.add_plugins(game_plugin);
app.update();
let window = app
.world_mut()
.query::<&Window>()
.single(app.world())
.unwrap();
assert_eq!(window.title, "This is window 0!");
}