diff --git a/src/lib.rs b/src/lib.rs index a3ba06b..ed44fce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -467,344 +467,4 @@ pub trait Agent : fmt::Debug { fn choose_lost_influence(&self, cards: &[Card]) -> Card; } -#[cfg(test)] -mod test { - use super::*; - - #[derive(Debug)] - struct DummyAgent(Card, Option, bool); - impl Agent for DummyAgent { - fn should_action_challenge(&self, _action_challenge: &phase::ActionChallenge) -> bool { - self.2 - } - fn choose_block_card(&self, _block: &phase::Block) -> Option { - self.1 - } - fn should_block_challenge(&self, _block_challenge: &phase::BlockChallenge) -> bool { - self.2 - } - fn exchange(&self, _cards: &[Card]) -> [Card; 2] { - [self.0, self.1.unwrap()] - } - fn choose_lost_influence(&self, _cards: &[Card]) -> Card { - self.0 - } - } - - #[test] - fn test_action_challenge() { - let challenge_agent = DummyAgent(Contessa, None, true); - let non_challenge_agent = DummyAgent(Duke, None, false); - let deck = vec![]; - let discard = vec![]; - let players = vec![ - Player { coins: 2, cards: vec![Duke, Captain] }, - Player { coins: 2, cards: vec![Contessa] }, - Player { coins: 2, cards: vec![Ambassador] }, - ]; - let game = Game { - deck, - discard, - players, - turn: 0 - }; - - // Test non-challengable - { - let mut game = game.clone(); - assert_eq!( - game.action_challenge(phase::ActionChallenge { - action: Income, - target: None, - }, &[&challenge_agent, &challenge_agent, &challenge_agent]), - Ok(Phase::Block(phase::Block { - action: Income, - target: None - })) - ); - } - - // Test failed challenge - { - let mut game = game.clone(); - assert_eq!( - game.action_challenge(phase::ActionChallenge { - action: Steal, - target: Some(2), - }, &[&challenge_agent, &challenge_agent, &challenge_agent]), - Ok(Phase::Block(phase::Block { - action: Steal, - target: Some(2) - })) - ); - } - - // Test successful challenge - { - let mut game = game.clone(); - assert_eq!( - game.action_challenge(phase::ActionChallenge { - action: Assassinate, - target: Some(2), - }, &[&non_challenge_agent, &challenge_agent, &challenge_agent]), - Ok(Phase::Done), - ); - } - } - - #[test] - fn test_block() { - let non_blocking_agent = DummyAgent(Duke, None, false); - let ambassador_block_agent = DummyAgent(Ambassador, Some(Ambassador), false); - let duke_block_agent = DummyAgent(Duke, Some(Duke), false); - - let deck = vec![]; - let discard = vec![]; - let players = vec![ - Player { coins: 2, cards: vec![Duke, Captain] }, - Player { coins: 2, cards: vec![Contessa] }, - Player { coins: 2, cards: vec![Ambassador] }, - ]; - let game = Game { - deck, - discard, - players, - turn: 0 - }; - - - // Test unblockable - { - let mut game = game.clone(); - assert_eq!( - game.block(phase::Block { - action: Income, - target: None, - }, &[&non_blocking_agent, &ambassador_block_agent, &ambassador_block_agent]), - Ok(Phase::Resolution(phase::Resolution { - action: Income, - target: None - })) - ); - } - - // Test target blocked - { - let mut game = game.clone(); - assert_eq!( - game.block(phase::Block { - action: Steal, - target: Some(2), - }, &[&non_blocking_agent, &ambassador_block_agent, &ambassador_block_agent]), - Ok(Phase::BlockChallenge(phase::BlockChallenge { - blocker: 2, - block_card: Ambassador, - action: Steal, - target: Some(2), - })) - ); - } - - // Test target non-blocked - { - let mut game = game.clone(); - assert_eq!( - game.block(phase::Block { - action: Steal, - target: Some(2), - }, &[&non_blocking_agent, &ambassador_block_agent, &non_blocking_agent]), - Ok(Phase::Resolution(phase::Resolution { - action: Steal, - target: Some(2), - })) - ); - } - - // Test anyone blocked - { - let mut game = game.clone(); - assert_eq!( - game.block(phase::Block { - action: ForeignAid, - target: None, - }, &[&non_blocking_agent, &non_blocking_agent, &duke_block_agent]), - Ok(Phase::BlockChallenge(phase::BlockChallenge { - blocker: 2, - block_card: Duke, - action: ForeignAid, - target: None, - })) - ); - } - - // Test no one blocked - { - let mut game = game.clone(); - assert_eq!( - game.block(phase::Block { - action: ForeignAid, - target: None, - }, &[&non_blocking_agent, &non_blocking_agent, &non_blocking_agent]), - Ok(Phase::Resolution(phase::Resolution { - action: ForeignAid, - target: None, - })) - ); - } - - // Test bad block card - { - let mut game = game.clone(); - assert!( - game.block(phase::Block { - action: ForeignAid, - target: None, - }, &[&non_blocking_agent, &ambassador_block_agent, &non_blocking_agent]) - .is_err() - ); - } - - } - - #[test] - fn test_block_challenge() { - let challenge_agent = DummyAgent(Assassin, None, true); - let non_challenge_agent = DummyAgent(Assassin, None, false); - let block_agent = DummyAgent(Contessa, None, false); - let deck = vec![]; - let discard = vec![]; - let players = vec![ - Player { coins: 2, cards: vec![Assassin] }, - Player { coins: 2, cards: vec![Contessa] }, - ]; - let game = Game { - deck, - discard, - players, - turn: 0 - }; - - // Test non-challenge - { - let mut game = game.clone(); - assert_eq!( - game.block_challenge( phase::BlockChallenge { - blocker: 1, - block_card: Contessa, - action: Assassinate, - target: Some(1), - }, &[&non_challenge_agent, &block_agent]), - Ok(Phase::Done) - ); - assert!(game.discard.is_empty()); - } - - // Test failed challenge - { - let mut game = game.clone(); - assert_eq!( - game.block_challenge( phase::BlockChallenge { - blocker: 1, - block_card: Contessa, - action: Assassinate, - target: Some(1), - }, &[&challenge_agent, &block_agent]), - Ok(Phase::Done) - ); - assert!(!game.discard.is_empty()); - } - - // Test successful challenge - { - let mut game = game.clone(); - assert_eq!( - game.block_challenge( phase::BlockChallenge { - blocker: 1, - block_card: Duke, - action: ForeignAid, - target: None, - }, &[&challenge_agent, &block_agent]), - Ok(Phase::Resolution(phase::Resolution { - action: ForeignAid, - target: None, - })) - ); - assert!(!game.discard.is_empty()); - } - - } - - #[test] - fn test_resolution() { - let dummy_agent = DummyAgent(Assassin, Some(Duke), false); - let loser_agent = DummyAgent(Captain, Some(Duke), false); - let deck = vec![Contessa, Contessa]; - let discard = vec![]; - let players = vec![ - Player { coins: 2, cards: vec![Duke, Assassin] }, - Player { coins: 1, cards: vec![Captain] }, - ]; - let game = Game { - deck, - discard, - players, - turn: 0, - }; - - // Test income - { - let mut game = game.clone(); - game.resolution(phase::Resolution { - action: Income, - target: None, - }, &[&dummy_agent, &dummy_agent]).unwrap(); - assert_eq!(game.players[0].coins, 3); - } - - // Test foreign aid - { - let mut game = game.clone(); - game.resolution(phase::Resolution { - action: ForeignAid, - target: None, - }, &[&dummy_agent, &dummy_agent]).unwrap(); - assert_eq!(game.players[0].coins, 4); - } - - // Test coup / assassinate - { - let mut game = game.clone(); - game.resolution(phase::Resolution { - action: Coup, - target: Some(1), - }, &[&dummy_agent, &loser_agent]).unwrap(); - assert!(game.players[1].cards.is_empty()); - assert_eq!(game.discard, vec![Captain]); - } - - // Test steal - { - let mut game = game.clone(); - game.resolution(phase::Resolution { - action: Steal, - target: Some(1), - }, &[&dummy_agent, &dummy_agent]).unwrap(); - assert_eq!(game.players[0].coins, 3); - assert_eq!(game.players[1].coins, 0); - } - - // Test exchange - { - let mut game = game.clone(); - game.resolution(phase::Resolution { - action: Exchange, - target: Some(1), - }, &[&dummy_agent, &dummy_agent]).unwrap(); - game.players[0].cards.sort(); - assert_eq!(game.players[0].cards, vec![Contessa, Contessa]); - game.deck.sort(); - assert_eq!(game.deck, vec![Duke, Assassin]); - assert!(game.discard.is_empty()); - } - } -} +mod test; diff --git a/src/test.rs b/src/test.rs new file mode 100644 index 0000000..26a3603 --- /dev/null +++ b/src/test.rs @@ -0,0 +1,338 @@ +use super::*; + +#[derive(Debug)] +struct DummyAgent(Card, Option, bool); +impl Agent for DummyAgent { + fn should_action_challenge(&self, _action_challenge: &phase::ActionChallenge) -> bool { + self.2 + } + fn choose_block_card(&self, _block: &phase::Block) -> Option { + self.1 + } + fn should_block_challenge(&self, _block_challenge: &phase::BlockChallenge) -> bool { + self.2 + } + fn exchange(&self, _cards: &[Card]) -> [Card; 2] { + [self.0, self.1.unwrap()] + } + fn choose_lost_influence(&self, _cards: &[Card]) -> Card { + self.0 + } +} + +#[test] +fn test_action_challenge() { + let challenge_agent = DummyAgent(Contessa, None, true); + let non_challenge_agent = DummyAgent(Duke, None, false); + let deck = vec![]; + let discard = vec![]; + let players = vec![ + Player { coins: 2, cards: vec![Duke, Captain] }, + Player { coins: 2, cards: vec![Contessa] }, + Player { coins: 2, cards: vec![Ambassador] }, + ]; + let game = Game { + deck, + discard, + players, + turn: 0 + }; + + // Test non-challengable + { + let mut game = game.clone(); + assert_eq!( + game.action_challenge(phase::ActionChallenge { + action: Income, + target: None, + }, &[&challenge_agent, &challenge_agent, &challenge_agent]), + Ok(Phase::Block(phase::Block { + action: Income, + target: None + })) + ); + } + + // Test failed challenge + { + let mut game = game.clone(); + assert_eq!( + game.action_challenge(phase::ActionChallenge { + action: Steal, + target: Some(2), + }, &[&challenge_agent, &challenge_agent, &challenge_agent]), + Ok(Phase::Block(phase::Block { + action: Steal, + target: Some(2) + })) + ); + } + + // Test successful challenge + { + let mut game = game.clone(); + assert_eq!( + game.action_challenge(phase::ActionChallenge { + action: Assassinate, + target: Some(2), + }, &[&non_challenge_agent, &challenge_agent, &challenge_agent]), + Ok(Phase::Done), + ); + } +} + +#[test] +fn test_block() { + let non_blocking_agent = DummyAgent(Duke, None, false); + let ambassador_block_agent = DummyAgent(Ambassador, Some(Ambassador), false); + let duke_block_agent = DummyAgent(Duke, Some(Duke), false); + + let deck = vec![]; + let discard = vec![]; + let players = vec![ + Player { coins: 2, cards: vec![Duke, Captain] }, + Player { coins: 2, cards: vec![Contessa] }, + Player { coins: 2, cards: vec![Ambassador] }, + ]; + let game = Game { + deck, + discard, + players, + turn: 0 + }; + + + // Test unblockable + { + let mut game = game.clone(); + assert_eq!( + game.block(phase::Block { + action: Income, + target: None, + }, &[&non_blocking_agent, &ambassador_block_agent, &ambassador_block_agent]), + Ok(Phase::Resolution(phase::Resolution { + action: Income, + target: None + })) + ); + } + + // Test target blocked + { + let mut game = game.clone(); + assert_eq!( + game.block(phase::Block { + action: Steal, + target: Some(2), + }, &[&non_blocking_agent, &ambassador_block_agent, &ambassador_block_agent]), + Ok(Phase::BlockChallenge(phase::BlockChallenge { + blocker: 2, + block_card: Ambassador, + action: Steal, + target: Some(2), + })) + ); + } + + // Test target non-blocked + { + let mut game = game.clone(); + assert_eq!( + game.block(phase::Block { + action: Steal, + target: Some(2), + }, &[&non_blocking_agent, &ambassador_block_agent, &non_blocking_agent]), + Ok(Phase::Resolution(phase::Resolution { + action: Steal, + target: Some(2), + })) + ); + } + + // Test anyone blocked + { + let mut game = game.clone(); + assert_eq!( + game.block(phase::Block { + action: ForeignAid, + target: None, + }, &[&non_blocking_agent, &non_blocking_agent, &duke_block_agent]), + Ok(Phase::BlockChallenge(phase::BlockChallenge { + blocker: 2, + block_card: Duke, + action: ForeignAid, + target: None, + })) + ); + } + + // Test no one blocked + { + let mut game = game.clone(); + assert_eq!( + game.block(phase::Block { + action: ForeignAid, + target: None, + }, &[&non_blocking_agent, &non_blocking_agent, &non_blocking_agent]), + Ok(Phase::Resolution(phase::Resolution { + action: ForeignAid, + target: None, + })) + ); + } + + // Test bad block card + { + let mut game = game.clone(); + assert!( + game.block(phase::Block { + action: ForeignAid, + target: None, + }, &[&non_blocking_agent, &ambassador_block_agent, &non_blocking_agent]) + .is_err() + ); + } + +} + +#[test] +fn test_block_challenge() { + let challenge_agent = DummyAgent(Assassin, None, true); + let non_challenge_agent = DummyAgent(Assassin, None, false); + let block_agent = DummyAgent(Contessa, None, false); + let deck = vec![]; + let discard = vec![]; + let players = vec![ + Player { coins: 2, cards: vec![Assassin] }, + Player { coins: 2, cards: vec![Contessa] }, + ]; + let game = Game { + deck, + discard, + players, + turn: 0 + }; + + // Test non-challenge + { + let mut game = game.clone(); + assert_eq!( + game.block_challenge( phase::BlockChallenge { + blocker: 1, + block_card: Contessa, + action: Assassinate, + target: Some(1), + }, &[&non_challenge_agent, &block_agent]), + Ok(Phase::Done) + ); + assert!(game.discard.is_empty()); + } + + // Test failed challenge + { + let mut game = game.clone(); + assert_eq!( + game.block_challenge( phase::BlockChallenge { + blocker: 1, + block_card: Contessa, + action: Assassinate, + target: Some(1), + }, &[&challenge_agent, &block_agent]), + Ok(Phase::Done) + ); + assert!(!game.discard.is_empty()); + } + + // Test successful challenge + { + let mut game = game.clone(); + assert_eq!( + game.block_challenge( phase::BlockChallenge { + blocker: 1, + block_card: Duke, + action: ForeignAid, + target: None, + }, &[&challenge_agent, &block_agent]), + Ok(Phase::Resolution(phase::Resolution { + action: ForeignAid, + target: None, + })) + ); + assert!(!game.discard.is_empty()); + } + +} + +#[test] +fn test_resolution() { + let dummy_agent = DummyAgent(Assassin, Some(Duke), false); + let loser_agent = DummyAgent(Captain, Some(Duke), false); + let deck = vec![Contessa, Contessa]; + let discard = vec![]; + let players = vec![ + Player { coins: 2, cards: vec![Duke, Assassin] }, + Player { coins: 1, cards: vec![Captain] }, + ]; + let game = Game { + deck, + discard, + players, + turn: 0, + }; + + // Test income + { + let mut game = game.clone(); + game.resolution(phase::Resolution { + action: Income, + target: None, + }, &[&dummy_agent, &dummy_agent]).unwrap(); + assert_eq!(game.players[0].coins, 3); + } + + // Test foreign aid + { + let mut game = game.clone(); + game.resolution(phase::Resolution { + action: ForeignAid, + target: None, + }, &[&dummy_agent, &dummy_agent]).unwrap(); + assert_eq!(game.players[0].coins, 4); + } + + // Test coup / assassinate + { + let mut game = game.clone(); + game.resolution(phase::Resolution { + action: Coup, + target: Some(1), + }, &[&dummy_agent, &loser_agent]).unwrap(); + assert!(game.players[1].cards.is_empty()); + assert_eq!(game.discard, vec![Captain]); + } + + // Test steal + { + let mut game = game.clone(); + game.resolution(phase::Resolution { + action: Steal, + target: Some(1), + }, &[&dummy_agent, &dummy_agent]).unwrap(); + assert_eq!(game.players[0].coins, 3); + assert_eq!(game.players[1].coins, 0); + } + + // Test exchange + { + let mut game = game.clone(); + game.resolution(phase::Resolution { + action: Exchange, + target: Some(1), + }, &[&dummy_agent, &dummy_agent]).unwrap(); + game.players[0].cards.sort(); + assert_eq!(game.players[0].cards, vec![Contessa, Contessa]); + game.deck.sort(); + assert_eq!(game.deck, vec![Duke, Assassin]); + assert!(game.discard.is_empty()); + } +}