118 lines
3.5 KiB
Rust
118 lines
3.5 KiB
Rust
use crate::archetype::Archetype;
|
||
use crate::board::Board;
|
||
use crate::floor::Floor;
|
||
use crate::game::GameState;
|
||
use crate::glyph::Glyph;
|
||
use crate::utils::{Direction, PlayerPos, PortalDef};
|
||
use crate::world::World;
|
||
use std::cell::RefCell;
|
||
use std::collections::{BTreeMap, HashMap};
|
||
use std::rc::Rc;
|
||
|
||
/// Builds a 3×3 board with the player at `(px, py)` and the given portals.
|
||
fn make_board(px: i64, py: i64, portals: Vec<PortalDef>) -> Board {
|
||
Board {
|
||
name: "test".into(),
|
||
width: 3,
|
||
height: 3,
|
||
grid: vec![(Glyph::transparent(), Archetype::Empty); 9],
|
||
floor: Floor::Blank,
|
||
decorations: Vec::new(),
|
||
player: PlayerPos { x: px, y: py },
|
||
objects: BTreeMap::new(),
|
||
next_object_id: 1,
|
||
portals,
|
||
board_script_name: None,
|
||
load_errors: Vec::new(),
|
||
registry: HashMap::new(),
|
||
}
|
||
}
|
||
|
||
/// Two-board world used by all tests in this module.
|
||
///
|
||
/// - `"b1"`: player at `(0, 0)`, portal `"to_b2"` at `(2, 0)` → `"b2"` / `"from_b1"`
|
||
/// - `"b2"`: player at `(0, 0)`, portal `"from_b1"` at `(1, 1)` → `"b1"` / `"to_b2"`
|
||
fn two_board_world() -> World {
|
||
let b1 = make_board(
|
||
0,
|
||
0,
|
||
vec![PortalDef {
|
||
name: "to_b2".into(),
|
||
x: 2,
|
||
y: 0,
|
||
target_map: "b2".into(),
|
||
target_entry: "from_b1".into(),
|
||
}],
|
||
);
|
||
let b2 = make_board(
|
||
0,
|
||
0,
|
||
vec![PortalDef {
|
||
name: "from_b1".into(),
|
||
x: 1,
|
||
y: 1,
|
||
target_map: "b1".into(),
|
||
target_entry: "to_b2".into(),
|
||
}],
|
||
);
|
||
World {
|
||
name: "test".into(),
|
||
start: "b1".into(),
|
||
scripts: HashMap::new(),
|
||
boards: HashMap::from([
|
||
("b1".to_string(), Rc::new(RefCell::new(b1))),
|
||
("b2".to_string(), Rc::new(RefCell::new(b2))),
|
||
]),
|
||
}
|
||
}
|
||
|
||
#[test]
|
||
fn enter_board_switches_board() {
|
||
let mut game = GameState::from_world(two_board_world());
|
||
game.enter_board("b2", "from_b1");
|
||
assert_eq!(game.current_board_name(), "b2");
|
||
}
|
||
|
||
#[test]
|
||
fn enter_board_places_player_at_arrival_portal() {
|
||
let mut game = GameState::from_world(two_board_world());
|
||
game.enter_board("b2", "from_b1");
|
||
let board = game.board();
|
||
// Arrival portal "from_b1" is at (1, 1) on b2.
|
||
assert_eq!(board.player.x, 1);
|
||
assert_eq!(board.player.y, 1);
|
||
}
|
||
|
||
#[test]
|
||
fn enter_board_sets_board_transition() {
|
||
let mut game = GameState::from_world(two_board_world());
|
||
game.enter_board("b2", "from_b1");
|
||
assert_eq!(game.board_transition, Some(1.0));
|
||
}
|
||
|
||
#[test]
|
||
fn enter_board_unknown_board_logs_error() {
|
||
let mut game = GameState::from_world(two_board_world());
|
||
game.enter_board("nope", "entry");
|
||
assert_eq!(game.current_board_name(), "b1", "board should not change");
|
||
assert!(!game.log.is_empty(), "an error should be logged");
|
||
}
|
||
|
||
#[test]
|
||
fn enter_board_unknown_entry_logs_error() {
|
||
let mut game = GameState::from_world(two_board_world());
|
||
game.enter_board("b2", "nope");
|
||
assert_eq!(game.current_board_name(), "b1", "board should not change");
|
||
assert!(!game.log.is_empty(), "an error should be logged");
|
||
}
|
||
|
||
#[test]
|
||
fn try_move_onto_portal_switches_board() {
|
||
let world = two_board_world();
|
||
// Start the player one cell west of the portal at (2, 0).
|
||
world.boards["b1"].borrow_mut().player = PlayerPos { x: 1, y: 0 };
|
||
let mut game = GameState::from_world(world);
|
||
game.try_move(Direction::East);
|
||
assert_eq!(game.current_board_name(), "b2");
|
||
}
|