scrolls
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::time::Duration;
|
||||
use crate::board::tests::open_board;
|
||||
use crate::game::GameState;
|
||||
use crate::game::{GameState, ScrollLine};
|
||||
use crate::utils::Direction;
|
||||
use super::{board_with_object, scripted_object, log_texts};
|
||||
|
||||
@@ -261,3 +261,67 @@ fn player_bump_fires_with_negative_one() {
|
||||
game.tick(Duration::from_millis(16));
|
||||
assert!(log_texts(&game).iter().any(|t| t == "bumped by -1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scroll_opens_on_player_bump() {
|
||||
// A solid object's bump() calls scroll([text, [choice, display]]). After the
|
||||
// player bumps it and a tick resolves the queued action, active_scroll is set
|
||||
// with the correct ScrollLine variants.
|
||||
let board = open_board(
|
||||
3, 1, (0, 0),
|
||||
vec![scripted_object(1, 0, "s")],
|
||||
&[("s", r#"fn bump(id) { scroll(["Hello world", ["eat", "Eat it"]]); }"#)],
|
||||
);
|
||||
let mut game = GameState::new(board);
|
||||
game.run_init();
|
||||
game.try_move(Direction::East);
|
||||
game.tick(Duration::from_millis(16));
|
||||
|
||||
let scroll = game.active_scroll.as_ref().expect("scroll should be active after bump");
|
||||
assert_eq!(scroll.lines.len(), 2);
|
||||
assert!(matches!(&scroll.lines[0], ScrollLine::Text(t) if t == "Hello world"));
|
||||
assert!(matches!(&scroll.lines[1], ScrollLine::Choice { choice, display }
|
||||
if choice == "eat" && display == "Eat it"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn close_scroll_without_choice_clears_it() {
|
||||
let board = open_board(
|
||||
3, 1, (0, 0),
|
||||
vec![scripted_object(1, 0, "s")],
|
||||
&[("s", r#"fn bump(id) { scroll(["Hello"]); }"#)],
|
||||
);
|
||||
let mut game = GameState::new(board);
|
||||
game.run_init();
|
||||
game.try_move(Direction::East);
|
||||
game.tick(Duration::from_millis(16));
|
||||
assert!(game.active_scroll.is_some());
|
||||
|
||||
game.close_scroll(None);
|
||||
assert!(game.active_scroll.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn close_scroll_with_choice_dispatches_send_to_source() {
|
||||
// Closing with a choice string fires send() on the object that opened the
|
||||
// scroll; fn eat() logging "eaten" confirms the dispatch arrived.
|
||||
let board = open_board(
|
||||
3, 1, (0, 0),
|
||||
vec![scripted_object(1, 0, "s")],
|
||||
&[("s", r#"
|
||||
fn bump(id) { scroll(["Muffin?", ["eat", "Eat it"]]); }
|
||||
fn eat() { log("eaten"); }
|
||||
"#)],
|
||||
);
|
||||
let mut game = GameState::new(board);
|
||||
game.run_init();
|
||||
game.try_move(Direction::East);
|
||||
game.tick(Duration::from_millis(16));
|
||||
assert!(game.active_scroll.is_some());
|
||||
|
||||
game.close_scroll(Some("eat"));
|
||||
assert!(game.active_scroll.is_none());
|
||||
// eat() queues Action::Log onto the board queue; a tick resolves it.
|
||||
game.tick(Duration::from_millis(16));
|
||||
assert!(log_texts(&game).iter().any(|t| t == "eaten"), "eat() should have logged");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user