// Module 3: Deferred death. Each test matches a heading in scenarios.md. use engine::harness::*; fn fillers(n: usize) -> Vec { vec!["Test Filler".to_string(); n] } fn damaged(target: Id, amount: i32) -> GameEvent { GameEvent::Damaged { target, amount } } fn triggered(source: Id, trigger: &str) -> GameEvent { GameEvent::Triggered { source, trigger: trigger.to_string(), } } fn whirlwind() -> GameEvent { GameEvent::SpellCast { card: "Whirlwind".to_string(), } } #[test] fn test_03_removed_only_after_sequence() { let mut g = new_game(GameOpts { decks: Some([fillers(5), vec![]]), }); let h = g.summon("Loot Hoarder", 0); let s = g.summon("Armorsmith", 0); g.clear_log(); g.cast("Whirlwind", 0, None); let hand = g.hand(0); assert_eq!(hand.len(), 1); let c = hand[0]; assert_eq!( g.log(), vec![ whirlwind(), damaged(h, 1), damaged(s, 1), triggered(s, "damaged"), GameEvent::ArmorGained { player: 0, amount: 1 }, triggered(s, "damaged"), GameEvent::ArmorGained { player: 0, amount: 1 }, GameEvent::Destroyed { id: h }, GameEvent::DeathPhase { round: 1 }, triggered(h, "deathrattle"), GameEvent::Drew { player: 0, id: c }, ] ); assert_eq!(g.zone_of(h), Zone::Graveyard); assert_eq!(g.board(0), vec![s]); assert_eq!(g.armor(0), 2); } #[test] fn test_03_chained_death_phases() { let mut g = new_game(GameOpts::default()); let golem = g.summon("Harvest Golem", 0); let ghoul = g.summon("Unstable Ghoul", 0); let r = g.summon("Test Reactor", 0); g.deal_damage(golem, 2); g.clear_log(); g.deal_damage(ghoul, 3); let d = g.board(0)[0]; assert_eq!( g.log(), vec![ damaged(ghoul, 3), GameEvent::Destroyed { id: ghoul }, GameEvent::DeathPhase { round: 1 }, triggered(ghoul, "deathrattle"), damaged(golem, 1), damaged(r, 1), GameEvent::Destroyed { id: golem }, GameEvent::DeathPhase { round: 2 }, triggered(golem, "deathrattle"), GameEvent::Summoned { id: d }, ] ); assert_eq!(g.name_of(d), "Damaged Golem"); assert_eq!(g.board(0), vec![d, r]); assert_eq!(g.zone_of(ghoul), Zone::Graveyard); assert_eq!(g.zone_of(golem), Zone::Graveyard); assert_eq!(g.health(r), 4); } #[test] fn test_03_simultaneous_removal() { let mut g = new_game(GameOpts { decks: Some([fillers(5), vec![]]), }); let h1 = g.summon("Loot Hoarder", 0); let h2 = g.summon("Loot Hoarder", 0); g.clear_log(); g.cast("Whirlwind", 0, None); let hand = g.hand(0); assert_eq!(hand.len(), 2); let (c1, c2) = (hand[0], hand[1]); assert_eq!( g.log(), vec![ whirlwind(), damaged(h1, 1), damaged(h2, 1), GameEvent::Destroyed { id: h1 }, GameEvent::Destroyed { id: h2 }, GameEvent::DeathPhase { round: 1 }, triggered(h1, "deathrattle"), GameEvent::Drew { player: 0, id: c1 }, triggered(h2, "deathrattle"), GameEvent::Drew { player: 0, id: c2 }, ] ); assert_eq!(g.zone_of(h1), Zone::Graveyard); assert_eq!(g.zone_of(h2), Zone::Graveyard); assert_eq!(g.board(0), Vec::::new()); } #[test] fn test_03_destroy_marks_pending() { let mut g = new_game(GameOpts::default()); let golem = g.summon("Harvest Golem", 0); g.clear_log(); g.destroy(golem); let board = g.board(0); assert_eq!(board.len(), 1); let d = board[0]; assert_eq!( g.log(), vec![ GameEvent::Destroyed { id: golem }, GameEvent::DeathPhase { round: 1 }, triggered(golem, "deathrattle"), GameEvent::Summoned { id: d }, ] ); assert_eq!(g.health(golem), 3); assert_eq!(g.zone_of(golem), Zone::Graveyard); assert_eq!(g.name_of(d), "Damaged Golem"); }