Files
kiln/kiln-core/src/tests/game_portals.rs
T

118 lines
3.5 KiB
Rust
Raw Normal View History

2026-06-13 16:24:29 -05:00
use crate::archetype::Archetype;
use crate::board::Board;
2026-07-10 23:16:28 -05:00
use crate::floor::Floor;
2026-06-13 16:24:29 -05:00
use crate::game::GameState;
2026-06-15 23:35:18 -05:00
use crate::glyph::Glyph;
2026-06-25 00:04:42 -05:00
use crate::utils::{Direction, PlayerPos, PortalDef};
2026-06-13 16:24:29 -05:00
use crate::world::World;
2026-06-15 23:35:18 -05:00
use std::cell::RefCell;
use std::collections::{BTreeMap, HashMap};
use std::rc::Rc;
2026-06-13 16:24:29 -05:00
/// Builds a 3×3 board with the player at `(px, py)` and the given portals.
2026-06-28 00:12:52 -05:00
fn make_board(px: i64, py: i64, portals: Vec<PortalDef>) -> Board {
2026-06-13 16:24:29 -05:00
Board {
name: "test".into(),
width: 3,
height: 3,
2026-07-10 23:16:28 -05:00
grid: vec![(Glyph::transparent(), Archetype::Empty); 9],
floor: Floor::Blank,
decorations: Vec::new(),
2026-06-25 00:04:42 -05:00
player: PlayerPos { x: px, y: py },
2026-06-13 16:24:29 -05:00
objects: BTreeMap::new(),
next_object_id: 1,
portals,
board_script_name: None,
load_errors: Vec::new(),
2026-06-13 17:58:04 -05:00
registry: HashMap::new(),
2026-06-13 16:24:29 -05:00
}
}
/// 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 {
2026-06-15 23:35:18 -05:00
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(),
}],
);
2026-06-13 16:24:29 -05:00
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).
2026-06-25 00:04:42 -05:00
world.boards["b1"].borrow_mut().player = PlayerPos { x: 1, y: 0 };
2026-06-13 16:24:29 -05:00
let mut game = GameState::from_world(world);
game.try_move(Direction::East);
assert_eq!(game.current_board_name(), "b2");
}