From dafbb1bb814f1c4a38f7341be714c6c5cf33406f Mon Sep 17 00:00:00 2001 From: Asher <141028690+No-bodyq@users.noreply.github.com> Date: Sun, 27 Jul 2025 22:13:01 +0100 Subject: [PATCH 1/7] Add comprehensive tests for Player model functionality --- .../contract/src/models/player.cairo | 326 +++++++++++++++++- 1 file changed, 325 insertions(+), 1 deletion(-) diff --git a/poker-texas-hold-em/contract/src/models/player.cairo b/poker-texas-hold-em/contract/src/models/player.cairo index 7ac5a86..eca99e2 100644 --- a/poker-texas-hold-em/contract/src/models/player.cairo +++ b/poker-texas-hold-em/contract/src/models/player.cairo @@ -53,4 +53,328 @@ impl ContractAddressDefault of Default { /// TESTS ON PLAYER MODEL #[cfg(test)] -mod tests {} +mod tests { + use dojo::event::EventStorageTest; + use dojo_cairo_test::WorldStorageTestTrait; + use dojo::model::{ModelStorage, ModelValueStorage, ModelStorageTest}; + use dojo::world::{WorldStorage, WorldStorageTrait}; + use dojo_cairo_test::{ + spawn_test_world, NamespaceDef, TestResource, ContractDefTrait, ContractDef, + }; + use poker::models::game::{Game, GameTrait, ShowdownType}; + use poker::models::player::{Player, PlayerTrait}; + use poker::tests::setup::setup::{CoreContract, deploy_contracts}; + use poker::models::base::GameErrors; + use poker::traits::game::get_default_game_params; + use starknet::ContractAddress; + use starknet::testing::{set_account_contract_address, set_contract_address}; + + fn PLAYER_1() -> ContractAddress { + starknet::contract_address_const::<'PLAYER_1'>() + } + + fn PLAYER_2() -> ContractAddress { + starknet::contract_address_const::<'PLAYER_2'>() + } + + fn PLAYER_3() -> ContractAddress { + starknet::contract_address_const::<'PLAYER_3'>() + } + + fn PLAYER_4() -> ContractAddress { + starknet::contract_address_const::<'PLAYER_4'>() + } + + fn mock_poker_game(ref world: WorldStorage) { + let game = Game { + id: 1, + in_progress: true, + has_ended: false, + current_round: 1, + round_in_progress: true, + current_player_count: 2, + players: array![PLAYER_1(), PLAYER_2(), PLAYER_3()], + deck: array![], + next_player: Option::Some(PLAYER_1()), + community_cards: array![], + pots: array![0], + current_bet: 0, + params: get_default_game_params(), + reshuffled: 0, + should_end: false, + deck_root: 0, + dealt_cards_root: 0, + nonce: 0, + community_dealing: false, + showdown: false, + round_count: 0, + highest_staker: Option::None, + previous_offset: 0, + }; + + let player_1 = Player { + id: PLAYER_1(), + alias: 'dub_zn', + chips: 2000, + current_bet: 0, + total_rounds: 1, + locked: (true, 1), + is_dealer: false, + in_round: true, + out: (0, 0), + pub_key: 0x1, + locked_chips: 0, + is_blacklisted: false, + eligible_pots: 1, + }; + + let player_2 = Player { + id: PLAYER_2(), + alias: 'Birdmannn', + chips: 5000, + current_bet: 0, + total_rounds: 1, + locked: (true, 2), + is_dealer: false, + in_round: true, + out: (0, 0), + pub_key: 0x2, + locked_chips: 0, + is_blacklisted: false, + eligible_pots: 1, + }; + + let player_3 = Player { + id: PLAYER_3(), + alias: 'chiscookeke11', + chips: 5000, + current_bet: 0, + total_rounds: 1, + locked: (false, 1), + is_dealer: false, + in_round: true, + out: (0, 0), + pub_key: 0x3, + locked_chips: 0, + is_blacklisted: false, + eligible_pots: 1, + }; + + world.write_model(@game); + world.write_models(array![@player_1, @player_2, @player_3].span()); + } + + fn mock_allowable_game(ref world: WorldStorage) { + let game = Game { + id: 2, + in_progress: true, + has_ended: false, + current_round: 1, + round_in_progress: false, + current_player_count: 2, + players: array![PLAYER_1(), PLAYER_2(), PLAYER_3()], + deck: array![], + next_player: Option::Some(PLAYER_1()), + community_cards: array![], + pots: array![0], + current_bet: 0, + params: get_default_game_params(), + reshuffled: 0, + should_end: false, + deck_root: 0, + dealt_cards_root: 0, + nonce: 0, + community_dealing: false, + showdown: false, + round_count: 0, + highest_staker: Option::None, + previous_offset: 0, + }; + + let player_1 = Player { + id: PLAYER_1(), + alias: 'dub_zn', + chips: 2000, + current_bet: 0, + total_rounds: 1, + locked: (true, 1), + is_dealer: false, + in_round: true, + out: (0, 0), + pub_key: 0x1, + locked_chips: 0, + is_blacklisted: false, + eligible_pots: 1, + }; + + let player_2 = Player { + id: PLAYER_2(), + alias: 'Birdmannn', + chips: 5000, + current_bet: 0, + total_rounds: 1, + locked: (true, 2), + is_dealer: false, + in_round: true, + out: (0, 0), + pub_key: 0x2, + locked_chips: 0, + is_blacklisted: false, + eligible_pots: 1, + }; + + let player_3 = Player { + id: PLAYER_3(), + alias: 'chiscookeke11', + chips: 5000, + current_bet: 0, + total_rounds: 1, + locked: (false, 1), + is_dealer: false, + in_round: true, + out: (0, 0), + pub_key: 0x3, + locked_chips: 0, + is_blacklisted: false, + eligible_pots: 1, + }; + + world.write_model(@game); + world.write_models(array![@player_1, @player_2, @player_3].span()); + } + + #[test] + fn test_exit_with_out_true_succeeds() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_poker_game(ref world); + let mut game: Game = world.read_model(1); + let mut player: Player = world.read_model(PLAYER_1()); + + player.exit(ref game, true); + + assert_eq!(player.out, (game.id, game.reshuffled), "Player out should be set to game id and reshuffled"); + assert_eq!(player.current_bet, 0, "Player current bet should be reset to 0"); + assert_eq!(player.is_dealer, false, "Player should not be dealer after exit"); + assert_eq!(player.in_round, false, "Player should not be in round after exit"); + assert_eq!(player.locked, (false, 0), "Player should be unlocked after exit"); + assert_eq!(game.current_player_count, 1, "Game player count should decrease by 1"); + } + + #[test] + fn test_exit_with_out_false_succeeds() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_poker_game(ref world); + let mut game: Game = world.read_model(1); + let mut player: Player = world.read_model(PLAYER_1()); + + player.exit(ref game, false); + + assert_eq!(player.out, (0, 0), "Player out should be set to game id and reshuffled"); + assert_eq!(player.current_bet, 0, "Player current bet should be reset to 0"); + assert_eq!(player.is_dealer, false, "Player should not be dealer after exit"); + assert_eq!(player.in_round, false, "Player should not be in round after exit"); + assert_eq!(player.locked, (false, 0), "Player should be unlocked after exit"); + assert_eq!(game.current_player_count, 1, "Game player count should decrease by 1"); + } + + #[test] + #[should_panic(expected: 'CANNOT EXIT, PLAYER NOT LOCKED')] + fn test_exit_without_lock_fails() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_poker_game(ref world); + let mut game: Game = world.read_model(1); + let mut player: Player = world.read_model(PLAYER_3()); + + player.exit(ref game, true); + } + + #[test] + fn test_exit_with_splitted_showdown_returns_locked_chips() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_poker_game(ref world); + let mut game: Game = world.read_model(1); + let mut player: Player = world.read_model(PLAYER_1()); + + let stake = 1000; + game.params.showdown_type = ShowdownType::Splitted(stake); + player.chips = 2000; + player.locked_chips = stake; + + player.exit(ref game, true); + + assert_eq!(player.chips, 3000, "Player should get locked chips back"); + assert_eq!(player.locked_chips, 0, "Locked chips should be reset to 0"); + } + + + #[test] + #[should_panic(expected: 'GAME PLAYER COUNT SUB')] + fn test_exit_with_zero_player_count_fails() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_poker_game(ref world); + let mut game: Game = world.read_model(1); + let mut player: Player = world.read_model(PLAYER_1()); + + game.current_player_count = 0; + player.exit(ref game, true); + } + + #[test] + #[should_panic(expected: 'BAD REQUEST')] + fn test_exit_with_invalid_player_fails() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_poker_game(ref world); + let mut game: Game = world.read_model(1); + let mut player: Player = world.read_model(PLAYER_2()); + + player.exit(ref game, true); + } + + #[test] + fn test_enter_succeeds_new_player(){ + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_allowable_game(ref world); + let mut game: Game = world.read_model(2); + + let mut player = Player { + id: PLAYER_4(), + alias: 'Nobody', + chips: 5000, + current_bet: 0, + total_rounds: 1, + locked: (false, 1), + is_dealer: false, + in_round: true, + out: (0, 0), + pub_key: 0x3, + locked_chips: 0, + is_blacklisted: false, + eligible_pots: 1, + }; + + let is_full = player.enter(ref game); + assert_eq!(player.locked, (true, game.id), "Player should be locked to game"); + assert_eq!(player.in_round, true, "Player should be in round"); + assert_eq!(game.current_player_count, 3, "Game player count should increase"); + assert_eq!(player.eligible_pots, 1, "Player should be eligible for 1 pot"); + assert_eq!(is_full, false, "Game should not be full"); + + assert_eq!(game.players.len(), 4, "Player should be added to game players"); + assert_eq!(*game.players.at(3), PLAYER_4(), "Last player should be PLAYER_4"); + } + +} From cec47d7045dd716c377a67661d1e8db89ffc16ba Mon Sep 17 00:00:00 2001 From: Asher <141028690+No-bodyq@users.noreply.github.com> Date: Mon, 28 Jul 2025 18:15:31 +0100 Subject: [PATCH 2/7] Add tests for player model and game mechanics --- .../contract/src/models/player.cairo | 236 ++++++++++++++++-- 1 file changed, 216 insertions(+), 20 deletions(-) diff --git a/poker-texas-hold-em/contract/src/models/player.cairo b/poker-texas-hold-em/contract/src/models/player.cairo index eca99e2..ceedaff 100644 --- a/poker-texas-hold-em/contract/src/models/player.cairo +++ b/poker-texas-hold-em/contract/src/models/player.cairo @@ -243,6 +243,84 @@ mod tests { world.write_models(array![@player_1, @player_2, @player_3].span()); } + fn mock_unlocked_player() -> Player { + Player { + id: PLAYER_4(), + alias: 'Nobody', + chips: 5000, + current_bet: 0, + total_rounds: 1, + locked: (false, 1), + is_dealer: false, + in_round: true, + out: (0, 0), + pub_key: 0x3, + locked_chips: 0, + is_blacklisted: false, + eligible_pots: 1, + } + } + + fn mock_uninitialized_game(ref world: WorldStorage) { + let game = Game { + id: 3, + in_progress: false, + has_ended: false, + current_round: 0, + round_in_progress: false, + current_player_count: 0, + players: array![], + deck: array![], + next_player: Option::None, + community_cards: array![], + pots: array![], + current_bet: 0, + params: get_default_game_params(), + reshuffled: 0, + should_end: false, + deck_root: 0, + dealt_cards_root: 0, + nonce: 0, + community_dealing: false, + showdown: false, + round_count: 0, + highest_staker: Option::None, + previous_offset: 0, + }; + + world.write_model(@game); + } + + fn mock_ended_game(ref world: WorldStorage) { + let game = Game { + id: 4, + in_progress: false, + has_ended: true, + current_round: 0, + round_in_progress: false, + current_player_count: 0, + players: array![PLAYER_1()], + deck: array![], + next_player: Option::None, + community_cards: array![], + pots: array![], + current_bet: 0, + params: get_default_game_params(), + reshuffled: 0, + should_end: false, + deck_root: 0, + dealt_cards_root: 0, + nonce: 0, + community_dealing: false, + showdown: false, + round_count: 0, + highest_staker: Option::None, + previous_offset: 0, + }; + + world.write_model(@game); + } + #[test] fn test_exit_with_out_true_succeeds() { let contracts = array![CoreContract::Actions]; @@ -254,7 +332,11 @@ mod tests { player.exit(ref game, true); - assert_eq!(player.out, (game.id, game.reshuffled), "Player out should be set to game id and reshuffled"); + assert_eq!( + player.out, + (game.id, game.reshuffled), + "Player out should be set to game id and reshuffled", + ); assert_eq!(player.current_bet, 0, "Player current bet should be reset to 0"); assert_eq!(player.is_dealer, false, "Player should not be dealer after exit"); assert_eq!(player.in_round, false, "Player should not be in round after exit"); @@ -294,7 +376,7 @@ mod tests { player.exit(ref game, true); } - #[test] + #[test] fn test_exit_with_splitted_showdown_returns_locked_chips() { let contracts = array![CoreContract::Actions]; let (mut world, systems) = deploy_contracts(contracts); @@ -312,9 +394,9 @@ mod tests { assert_eq!(player.chips, 3000, "Player should get locked chips back"); assert_eq!(player.locked_chips, 0, "Locked chips should be reset to 0"); - } + } + - #[test] #[should_panic(expected: 'GAME PLAYER COUNT SUB')] fn test_exit_with_zero_player_count_fails() { @@ -343,28 +425,14 @@ mod tests { } #[test] - fn test_enter_succeeds_new_player(){ + fn test_enter_succeeds_new_player() { let contracts = array![CoreContract::Actions]; let (mut world, systems) = deploy_contracts(contracts); mock_allowable_game(ref world); let mut game: Game = world.read_model(2); - let mut player = Player { - id: PLAYER_4(), - alias: 'Nobody', - chips: 5000, - current_bet: 0, - total_rounds: 1, - locked: (false, 1), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x3, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - }; + let mut player = mock_unlocked_player(); let is_full = player.enter(ref game); assert_eq!(player.locked, (true, game.id), "Player should be locked to game"); @@ -377,4 +445,132 @@ mod tests { assert_eq!(*game.players.at(3), PLAYER_4(), "Last player should be PLAYER_4"); } + #[test] + fn test_is_full_returns_true_when_game_full() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_allowable_game(ref world); + let mut game: Game = world.read_model(2); + + game.current_player_count = 2; + game.params.max_no_of_players = 3; + + let mut player = mock_unlocked_player(); + let is_full = player.enter(ref game); + + assert_eq!(is_full, true, "Game should be full after player enters"); + assert_eq!(game.current_player_count, 3, "Game should have max players"); + } + + #[test] + #[should_panic(expected: 'PLAYER ALREADY LOCKED')] + fn test_enter_fails_when_player_already_locked() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_allowable_game(ref world); + let mut game: Game = world.read_model(2); + + let mut player: Player = world.read_model(PLAYER_1()); + player.locked = (true, game.id); + + player.enter(ref game); + } + + #[test] + #[should_panic(expected: 'GAME NOT INITIALIZED')] + fn test_enter_fails_when_game_not_initialized() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_uninitialized_game(ref world); + let mut game: Game = world.read_model(3); + + let mut player = mock_unlocked_player(); + player.enter(ref game); + } + + #[test] + #[should_panic(expected: 'GAME ALREADY ENDED')] + fn test_enter_fails_when_game_ended() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_ended_game(ref world); + let mut game: Game = world.read_model(4); + + let mut player = mock_unlocked_player(); + player.enter(ref game); + } + + #[test] + #[should_panic(expected: 'INSUFFICIENT CHIPS')] + fn test_enter_fails_when_insufficient_chips() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_allowable_game(ref world); + let mut game: Game = world.read_model(2); + let stake = 1000; + game.params.showdown_type = ShowdownType::Splitted(stake); + + let mut player = mock_unlocked_player(); + player.chips = 0; + + player.enter(ref game); + } + + #[test] + fn test_refresh_stake_succeeds_with_splitted_showdown() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + + mock_allowable_game(ref world); + let mut game: Game = world.read_model(2); + let stake = 1000; + game.params.showdown_type = ShowdownType::Splitted(stake); + + let mut player = mock_unlocked_player(); + player.chips = 2000; + + let result = player.refresh_stake(ref game); + + assert_eq!(result, true, "Refresh stake should succeed"); + assert_eq!(player.chips, 1000, "Player chips should be reduced by stake"); + assert_eq!(player.locked_chips, 1000, "Locked chips should equal stake"); + } + + #[test] + fn test_refresh_stake_fails_with_insufficient_chips() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + mock_allowable_game(ref world); + let mut game: Game = world.read_model(2); + let stake = 1000; + game.params.showdown_type = ShowdownType::Splitted(stake); + + let mut player = mock_unlocked_player(); + player.chips = 500; + + let result = player.refresh_stake(ref game); + + assert_eq!(result, false, "Refresh stake should fail"); + } + + #[test] + fn test_is_maxed_returns_true_when_player_maxed() { + let contracts = array![CoreContract::Actions]; + let (mut world, systems) = deploy_contracts(contracts); + mock_poker_game(ref world); + let mut game: Game = world.read_model(1); + let mut player: Player = world.read_model(PLAYER_1()); + player.chips = 0; + player.current_bet = 0; + player.eligible_pots = 0; + + let result = player.is_maxed(@game); + + assert_eq!(result, true, "Player should be maxed"); + } } From 1860bccea29e274d38b5f4c6253b978ec0b6725a Mon Sep 17 00:00:00 2001 From: Asher <141028690+No-bodyq@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:36:08 +0100 Subject: [PATCH 3/7] Refactor player model tests to use flexible mock functions for improved readability and maintainability --- .../contract/src/models/player.cairo | 308 ++++-------------- .../contract/src/tests/test_actions.cairo | 216 +++++++----- 2 files changed, 203 insertions(+), 321 deletions(-) diff --git a/poker-texas-hold-em/contract/src/models/player.cairo b/poker-texas-hold-em/contract/src/models/player.cairo index ceedaff..45e300c 100644 --- a/poker-texas-hold-em/contract/src/models/player.cairo +++ b/poker-texas-hold-em/contract/src/models/player.cairo @@ -69,256 +69,84 @@ mod tests { use starknet::ContractAddress; use starknet::testing::{set_account_contract_address, set_contract_address}; - fn PLAYER_1() -> ContractAddress { - starknet::contract_address_const::<'PLAYER_1'>() - } - - fn PLAYER_2() -> ContractAddress { - starknet::contract_address_const::<'PLAYER_2'>() - } - - fn PLAYER_3() -> ContractAddress { - starknet::contract_address_const::<'PLAYER_3'>() - } - - fn PLAYER_4() -> ContractAddress { - starknet::contract_address_const::<'PLAYER_4'>() - } - - fn mock_poker_game(ref world: WorldStorage) { - let game = Game { - id: 1, - in_progress: true, - has_ended: false, - current_round: 1, - round_in_progress: true, - current_player_count: 2, - players: array![PLAYER_1(), PLAYER_2(), PLAYER_3()], - deck: array![], - next_player: Option::Some(PLAYER_1()), - community_cards: array![], - pots: array![0], - current_bet: 0, - params: get_default_game_params(), - reshuffled: 0, - should_end: false, - deck_root: 0, - dealt_cards_root: 0, - nonce: 0, - community_dealing: false, - showdown: false, - round_count: 0, - highest_staker: Option::None, - previous_offset: 0, - }; - - let player_1 = Player { - id: PLAYER_1(), - alias: 'dub_zn', - chips: 2000, - current_bet: 0, - total_rounds: 1, - locked: (true, 1), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x1, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - }; - - let player_2 = Player { - id: PLAYER_2(), - alias: 'Birdmannn', - chips: 5000, - current_bet: 0, - total_rounds: 1, - locked: (true, 2), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x2, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - }; - - let player_3 = Player { - id: PLAYER_3(), - alias: 'chiscookeke11', - chips: 5000, - current_bet: 0, - total_rounds: 1, - locked: (false, 1), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x3, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - }; - - world.write_model(@game); - world.write_models(array![@player_1, @player_2, @player_3].span()); - } + use crate::tests::test_actions::tests::{PLAYER_1, PLAYER_2, PLAYER_3, PLAYER_4, mock_poker_game, mock_player, mock_poker_game_flex}; fn mock_allowable_game(ref world: WorldStorage) { - let game = Game { - id: 2, - in_progress: true, - has_ended: false, - current_round: 1, - round_in_progress: false, - current_player_count: 2, - players: array![PLAYER_1(), PLAYER_2(), PLAYER_3()], - deck: array![], - next_player: Option::Some(PLAYER_1()), - community_cards: array![], - pots: array![0], - current_bet: 0, - params: get_default_game_params(), - reshuffled: 0, - should_end: false, - deck_root: 0, - dealt_cards_root: 0, - nonce: 0, - community_dealing: false, - showdown: false, - round_count: 0, - highest_staker: Option::None, - previous_offset: 0, - }; - - let player_1 = Player { - id: PLAYER_1(), - alias: 'dub_zn', - chips: 2000, - current_bet: 0, - total_rounds: 1, - locked: (true, 1), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x1, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - }; - - let player_2 = Player { - id: PLAYER_2(), - alias: 'Birdmannn', - chips: 5000, - current_bet: 0, - total_rounds: 1, - locked: (true, 2), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x2, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - }; - - let player_3 = Player { - id: PLAYER_3(), - alias: 'chiscookeke11', - chips: 5000, - current_bet: 0, - total_rounds: 1, - locked: (false, 1), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x3, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - }; - - world.write_model(@game); - world.write_models(array![@player_1, @player_2, @player_3].span()); + let player_1 = mock_player( + PLAYER_1(), 'dub_zn', 2000, 0, 1, (true, 1), false, true, (0, 0), 0x1, 0, false, 1 + ); + let player_2 = mock_player( + PLAYER_2(), 'Birdmannn', 5000, 0, 1, (true, 2), false, true, (0, 0), 0x2, 0, false, 1 + ); + let player_3 = mock_player( + PLAYER_3(), 'chiscookeke11', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1 + ); + mock_poker_game_flex( + ref world, + 2, + true, + false, + 1, + false, + 2, + array![PLAYER_1(), PLAYER_2(), PLAYER_3()], + array![], + Option::Some(PLAYER_1()), + array![], + array![0], + 0, + get_default_game_params(), + 0, false, 0, 0, 0, false, false, 0, Option::None, 0, + array![player_1, player_2, player_3] + ); } fn mock_unlocked_player() -> Player { - Player { - id: PLAYER_4(), - alias: 'Nobody', - chips: 5000, - current_bet: 0, - total_rounds: 1, - locked: (false, 1), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x3, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - } + mock_player( + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1 + ) } fn mock_uninitialized_game(ref world: WorldStorage) { - let game = Game { - id: 3, - in_progress: false, - has_ended: false, - current_round: 0, - round_in_progress: false, - current_player_count: 0, - players: array![], - deck: array![], - next_player: Option::None, - community_cards: array![], - pots: array![], - current_bet: 0, - params: get_default_game_params(), - reshuffled: 0, - should_end: false, - deck_root: 0, - dealt_cards_root: 0, - nonce: 0, - community_dealing: false, - showdown: false, - round_count: 0, - highest_staker: Option::None, - previous_offset: 0, - }; - - world.write_model(@game); + mock_poker_game_flex( + ref world, + 3, + false, + false, + 0, + false, + 0, + array![], + array![], + Option::None, + array![], + array![], + 0, + get_default_game_params(), + 0, false, 0, 0, 0, false, false, 0, Option::None, 0, + array![] + ); } fn mock_ended_game(ref world: WorldStorage) { - let game = Game { - id: 4, - in_progress: false, - has_ended: true, - current_round: 0, - round_in_progress: false, - current_player_count: 0, - players: array![PLAYER_1()], - deck: array![], - next_player: Option::None, - community_cards: array![], - pots: array![], - current_bet: 0, - params: get_default_game_params(), - reshuffled: 0, - should_end: false, - deck_root: 0, - dealt_cards_root: 0, - nonce: 0, - community_dealing: false, - showdown: false, - round_count: 0, - highest_staker: Option::None, - previous_offset: 0, - }; - - world.write_model(@game); + mock_poker_game_flex( + ref world, + 4, + false, + true, + 0, + false, + 0, + array![PLAYER_1()], + array![], + Option::None, + array![], + array![], + 0, + get_default_game_params(), + 0, false, 0, 0, 0, false, false, 0, Option::None, 0, + array![] + ); } #[test] @@ -372,6 +200,7 @@ mod tests { mock_poker_game(ref world); let mut game: Game = world.read_model(1); let mut player: Player = world.read_model(PLAYER_3()); + player.locked = (false, 0); player.exit(ref game, true); } @@ -420,6 +249,7 @@ mod tests { mock_poker_game(ref world); let mut game: Game = world.read_model(1); let mut player: Player = world.read_model(PLAYER_2()); + player.locked = (true, 999); player.exit(ref game, true); } diff --git a/poker-texas-hold-em/contract/src/tests/test_actions.cairo b/poker-texas-hold-em/contract/src/tests/test_actions.cairo index e2a6a3a..a97ca8c 100644 --- a/poker-texas-hold-em/contract/src/tests/test_actions.cairo +++ b/poker-texas-hold-em/contract/src/tests/test_actions.cairo @@ -1,5 +1,5 @@ #[cfg(test)] -mod tests { +pub mod tests { use dojo::event::EventStorageTest; use dojo_cairo_test::WorldStorageTestTrait; use dojo::model::{ModelStorage, ModelValueStorage, ModelStorageTest}; @@ -7,7 +7,8 @@ mod tests { use dojo_cairo_test::{ spawn_test_world, NamespaceDef, TestResource, ContractDefTrait, ContractDef, }; - use poker::models::game::{Game, GameTrait}; + use poker::models::game::{Game, GameTrait, GameParams, ShowdownType}; + use poker::models::card::{Card}; use poker::models::player::{Player, PlayerTrait}; use poker::traits::game::get_default_game_params; use poker::systems::interface::{IActionsDispatcher, IActionsDispatcherTrait}; @@ -15,18 +16,117 @@ mod tests { use starknet::ContractAddress; use starknet::testing::{set_account_contract_address, set_contract_address}; - fn PLAYER_1() -> ContractAddress { + pub fn PLAYER_1() -> ContractAddress { starknet::contract_address_const::<'PLAYER_1'>() } - fn PLAYER_2() -> ContractAddress { + pub fn PLAYER_2() -> ContractAddress { starknet::contract_address_const::<'PLAYER_2'>() } - fn PLAYER_3() -> ContractAddress { + pub fn PLAYER_3() -> ContractAddress { starknet::contract_address_const::<'PLAYER_3'>() } + pub fn PLAYER_4() -> ContractAddress { + starknet::contract_address_const::<'PLAYER_4'>() + } + + // Flexible player mock + pub fn mock_player( + id: ContractAddress, + alias: felt252, + chips: u256, + current_bet: u256, + total_rounds: u64, + locked: (bool, u64), + is_dealer: bool, + in_round: bool, + out: (u64, u64), + pub_key: felt252, + locked_chips: u256, + is_blacklisted: bool, + eligible_pots: u8, + ) -> Player { + Player { + id, + alias, + chips, + current_bet, + total_rounds, + locked, + is_dealer, + in_round, + out, + pub_key, + locked_chips, + is_blacklisted, + eligible_pots, + } + } + + // Flexible game mock + pub fn mock_poker_game_flex( + ref world: WorldStorage, + id: u64, + in_progress: bool, + has_ended: bool, + current_round: u8, + round_in_progress: bool, + current_player_count: u32, + players: Array, + deck: Array, + next_player: Option, + community_cards: Array, + pots: Array, + current_bet: u256, + params: GameParams, + reshuffled: u64, + should_end: bool, + deck_root: felt252, + dealt_cards_root: felt252, + nonce: u64, + community_dealing: bool, + showdown: bool, + round_count: u64, + highest_staker: Option, + previous_offset: u256, + player_states: Array, + ) { + let temp_player_states = player_states.span(); + let mut player_states = array![]; + for player in temp_player_states { + player_states.append(player); + }; + let game = Game { + id, + in_progress, + has_ended, + current_round, + round_in_progress, + current_player_count, + players, + deck, + next_player, + community_cards, + pots, + current_bet, + params, + reshuffled, + should_end, + deck_root, + dealt_cards_root, + nonce, + community_dealing, + showdown, + round_count, + highest_staker, + previous_offset, + }; + world.write_model(@game); + world.write_models(player_states.span()); + } + // [Actions] - check() tests #[test] fn test_check_succeeds_when_player_current_bet_equals_game() { @@ -343,82 +443,34 @@ mod tests { } // [Mocks] - fn mock_poker_game(ref world: WorldStorage) { - let game = Game { - id: 1, - in_progress: true, - has_ended: false, - current_round: 1, - round_in_progress: true, - current_player_count: 2, - players: array![PLAYER_1(), PLAYER_2(), PLAYER_3()], - deck: array![], - next_player: Option::Some(PLAYER_1()), - community_cards: array![], - pots: array![0], - current_bet: 0, - params: get_default_game_params(), - reshuffled: 0, - should_end: false, - deck_root: 0, - dealt_cards_root: 0, - nonce: 0, - community_dealing: false, - showdown: false, - round_count: 0, - highest_staker: Option::None, - previous_offset: 0, - }; - - let player_1 = Player { - id: PLAYER_1(), - alias: 'dub_zn', - chips: 2000, - current_bet: 0, - total_rounds: 1, - locked: (true, 1), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x1, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - }; - - let player_2 = Player { - id: PLAYER_2(), - alias: 'Birdmannn', - chips: 5000, - current_bet: 0, - total_rounds: 1, - locked: (true, 1), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x2, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - }; - - let player_3 = Player { - id: PLAYER_3(), - alias: 'chiscookeke11', - chips: 5000, - current_bet: 0, - total_rounds: 1, - locked: (true, 1), - is_dealer: false, - in_round: true, - out: (0, 0), - pub_key: 0x3, - locked_chips: 0, - is_blacklisted: false, - eligible_pots: 1, - }; - - world.write_model(@game); - world.write_models(array![@player_1, @player_2, @player_3].span()); + // Default mock usage for legacy tests + pub fn mock_poker_game(ref world: WorldStorage) { + let player_1 = mock_player( + PLAYER_1(), 'dub_zn', 2000, 0, 1, (true, 1), false, true, (0, 0), 0x1, 0, false, 1 + ); + let player_2 = mock_player( + PLAYER_2(), 'Birdmannn', 5000, 0, 1, (true, 1), false, true, (0, 0), 0x2, 0, false, 1 + ); + let player_3 = mock_player( + PLAYER_3(), 'chiscookeke11', 5000, 0, 1, (true, 1), false, true, (0, 0), 0x3, 0, false, 1 + ); + mock_poker_game_flex( + ref world, + 1, // id + true, // in_progress + false, // has_ended + 1, // current_round + true, // round_in_progress + 2, // current_player_count + array![PLAYER_1(), PLAYER_2(), PLAYER_3()], + array![], + Option::Some(PLAYER_1()), + array![], + array![0], + 0, + get_default_game_params(), + 0, false, 0, 0, 0, false, false, 0, Option::None, 0, + array![player_1, player_2, player_3] + ); } } From 06a7b6bfacc36fadbadadd5003ddb126bb2769c8 Mon Sep 17 00:00:00 2001 From: Asher <141028690+No-bodyq@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:39:12 +0100 Subject: [PATCH 4/7] fmt --- .../contract/src/models/player.cairo | 63 +++++++++++++++---- .../contract/src/tests/test_actions.cairo | 31 +++++++-- 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/poker-texas-hold-em/contract/src/models/player.cairo b/poker-texas-hold-em/contract/src/models/player.cairo index 45e300c..8cd7158 100644 --- a/poker-texas-hold-em/contract/src/models/player.cairo +++ b/poker-texas-hold-em/contract/src/models/player.cairo @@ -69,17 +69,31 @@ mod tests { use starknet::ContractAddress; use starknet::testing::{set_account_contract_address, set_contract_address}; - use crate::tests::test_actions::tests::{PLAYER_1, PLAYER_2, PLAYER_3, PLAYER_4, mock_poker_game, mock_player, mock_poker_game_flex}; + use crate::tests::test_actions::tests::{ + PLAYER_1, PLAYER_2, PLAYER_3, PLAYER_4, mock_poker_game, mock_player, mock_poker_game_flex, + }; fn mock_allowable_game(ref world: WorldStorage) { let player_1 = mock_player( - PLAYER_1(), 'dub_zn', 2000, 0, 1, (true, 1), false, true, (0, 0), 0x1, 0, false, 1 + PLAYER_1(), 'dub_zn', 2000, 0, 1, (true, 1), false, true, (0, 0), 0x1, 0, false, 1, ); let player_2 = mock_player( - PLAYER_2(), 'Birdmannn', 5000, 0, 1, (true, 2), false, true, (0, 0), 0x2, 0, false, 1 + PLAYER_2(), 'Birdmannn', 5000, 0, 1, (true, 2), false, true, (0, 0), 0x2, 0, false, 1, ); let player_3 = mock_player( - PLAYER_3(), 'chiscookeke11', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1 + PLAYER_3(), + 'chiscookeke11', + 5000, + 0, + 1, + (false, 1), + false, + true, + (0, 0), + 0x3, + 0, + false, + 1, ); mock_poker_game_flex( ref world, @@ -96,14 +110,23 @@ mod tests { array![0], 0, get_default_game_params(), - 0, false, 0, 0, 0, false, false, 0, Option::None, 0, - array![player_1, player_2, player_3] + 0, + false, + 0, + 0, + 0, + false, + false, + 0, + Option::None, + 0, + array![player_1, player_2, player_3], ); } fn mock_unlocked_player() -> Player { mock_player( - PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1 + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, ) } @@ -123,8 +146,17 @@ mod tests { array![], 0, get_default_game_params(), - 0, false, 0, 0, 0, false, false, 0, Option::None, 0, - array![] + 0, + false, + 0, + 0, + 0, + false, + false, + 0, + Option::None, + 0, + array![], ); } @@ -144,8 +176,17 @@ mod tests { array![], 0, get_default_game_params(), - 0, false, 0, 0, 0, false, false, 0, Option::None, 0, - array![] + 0, + false, + 0, + 0, + 0, + false, + false, + 0, + Option::None, + 0, + array![], ); } diff --git a/poker-texas-hold-em/contract/src/tests/test_actions.cairo b/poker-texas-hold-em/contract/src/tests/test_actions.cairo index a97ca8c..fe7732f 100644 --- a/poker-texas-hold-em/contract/src/tests/test_actions.cairo +++ b/poker-texas-hold-em/contract/src/tests/test_actions.cairo @@ -446,13 +446,25 @@ pub mod tests { // Default mock usage for legacy tests pub fn mock_poker_game(ref world: WorldStorage) { let player_1 = mock_player( - PLAYER_1(), 'dub_zn', 2000, 0, 1, (true, 1), false, true, (0, 0), 0x1, 0, false, 1 + PLAYER_1(), 'dub_zn', 2000, 0, 1, (true, 1), false, true, (0, 0), 0x1, 0, false, 1, ); let player_2 = mock_player( - PLAYER_2(), 'Birdmannn', 5000, 0, 1, (true, 1), false, true, (0, 0), 0x2, 0, false, 1 + PLAYER_2(), 'Birdmannn', 5000, 0, 1, (true, 1), false, true, (0, 0), 0x2, 0, false, 1, ); let player_3 = mock_player( - PLAYER_3(), 'chiscookeke11', 5000, 0, 1, (true, 1), false, true, (0, 0), 0x3, 0, false, 1 + PLAYER_3(), + 'chiscookeke11', + 5000, + 0, + 1, + (true, 1), + false, + true, + (0, 0), + 0x3, + 0, + false, + 1, ); mock_poker_game_flex( ref world, @@ -469,8 +481,17 @@ pub mod tests { array![0], 0, get_default_game_params(), - 0, false, 0, 0, 0, false, false, 0, Option::None, 0, - array![player_1, player_2, player_3] + 0, + false, + 0, + 0, + 0, + false, + false, + 0, + Option::None, + 0, + array![player_1, player_2, player_3], ); } } From 1838e914b1778dc1d46f820674a3d3f2ac33ea4a Mon Sep 17 00:00:00 2001 From: Asher <141028690+No-bodyq@users.noreply.github.com> Date: Sat, 2 Aug 2025 10:40:54 +0100 Subject: [PATCH 5/7] Refactor player model tests --- .../contract/src/models/player.cairo | 113 +++++------------- 1 file changed, 27 insertions(+), 86 deletions(-) diff --git a/poker-texas-hold-em/contract/src/models/player.cairo b/poker-texas-hold-em/contract/src/models/player.cairo index 8cd7158..a26fb24 100644 --- a/poker-texas-hold-em/contract/src/models/player.cairo +++ b/poker-texas-hold-em/contract/src/models/player.cairo @@ -192,15 +192,11 @@ mod tests { #[test] fn test_exit_with_out_true_succeeds() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_poker_game(ref world); - let mut game: Game = world.read_model(1); - let mut player: Player = world.read_model(PLAYER_1()); - + let mut game = world.read_model(1); + let mut player = world.read_model(PLAYER_1()); player.exit(ref game, true); - assert_eq!( player.out, (game.id, game.reshuffled), @@ -215,15 +211,11 @@ mod tests { #[test] fn test_exit_with_out_false_succeeds() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_poker_game(ref world); - let mut game: Game = world.read_model(1); - let mut player: Player = world.read_model(PLAYER_1()); - + let mut game = world.read_model(1); + let mut player = world.read_model(PLAYER_1()); player.exit(ref game, false); - assert_eq!(player.out, (0, 0), "Player out should be set to game id and reshuffled"); assert_eq!(player.current_bet, 0, "Player current bet should be reset to 0"); assert_eq!(player.is_dealer, false, "Player should not be dealer after exit"); @@ -235,48 +227,36 @@ mod tests { #[test] #[should_panic(expected: 'CANNOT EXIT, PLAYER NOT LOCKED')] fn test_exit_without_lock_fails() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_poker_game(ref world); - let mut game: Game = world.read_model(1); + let mut game = world.read_model(1); let mut player: Player = world.read_model(PLAYER_3()); player.locked = (false, 0); - player.exit(ref game, true); } #[test] fn test_exit_with_splitted_showdown_returns_locked_chips() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_poker_game(ref world); let mut game: Game = world.read_model(1); let mut player: Player = world.read_model(PLAYER_1()); - let stake = 1000; game.params.showdown_type = ShowdownType::Splitted(stake); player.chips = 2000; player.locked_chips = stake; - player.exit(ref game, true); - assert_eq!(player.chips, 3000, "Player should get locked chips back"); assert_eq!(player.locked_chips, 0, "Locked chips should be reset to 0"); } - #[test] #[should_panic(expected: 'GAME PLAYER COUNT SUB')] fn test_exit_with_zero_player_count_fails() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_poker_game(ref world); let mut game: Game = world.read_model(1); let mut player: Player = world.read_model(PLAYER_1()); - game.current_player_count = 0; player.exit(ref game, true); } @@ -284,52 +264,39 @@ mod tests { #[test] #[should_panic(expected: 'BAD REQUEST')] fn test_exit_with_invalid_player_fails() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_poker_game(ref world); let mut game: Game = world.read_model(1); let mut player: Player = world.read_model(PLAYER_2()); player.locked = (true, 999); - player.exit(ref game, true); } #[test] fn test_enter_succeeds_new_player() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); let mut game: Game = world.read_model(2); - - let mut player = mock_unlocked_player(); - + let mut player: Player = mock_unlocked_player(); let is_full = player.enter(ref game); assert_eq!(player.locked, (true, game.id), "Player should be locked to game"); assert_eq!(player.in_round, true, "Player should be in round"); assert_eq!(game.current_player_count, 3, "Game player count should increase"); assert_eq!(player.eligible_pots, 1, "Player should be eligible for 1 pot"); assert_eq!(is_full, false, "Game should not be full"); - assert_eq!(game.players.len(), 4, "Player should be added to game players"); assert_eq!(*game.players.at(3), PLAYER_4(), "Last player should be PLAYER_4"); } #[test] fn test_is_full_returns_true_when_game_full() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); let mut game: Game = world.read_model(2); - game.current_player_count = 2; game.params.max_no_of_players = 3; - - let mut player = mock_unlocked_player(); + let mut player: Player = mock_unlocked_player(); let is_full = player.enter(ref game); - assert_eq!(is_full, true, "Game should be full after player enters"); assert_eq!(game.current_player_count, 3, "Game should have max players"); } @@ -337,76 +304,57 @@ mod tests { #[test] #[should_panic(expected: 'PLAYER ALREADY LOCKED')] fn test_enter_fails_when_player_already_locked() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); let mut game: Game = world.read_model(2); - let mut player: Player = world.read_model(PLAYER_1()); player.locked = (true, game.id); - player.enter(ref game); } #[test] #[should_panic(expected: 'GAME NOT INITIALIZED')] fn test_enter_fails_when_game_not_initialized() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_uninitialized_game(ref world); let mut game: Game = world.read_model(3); - - let mut player = mock_unlocked_player(); + let mut player: Player = mock_unlocked_player(); player.enter(ref game); } #[test] #[should_panic(expected: 'GAME ALREADY ENDED')] fn test_enter_fails_when_game_ended() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_ended_game(ref world); let mut game: Game = world.read_model(4); - - let mut player = mock_unlocked_player(); + let mut player: Player = mock_unlocked_player(); player.enter(ref game); } #[test] #[should_panic(expected: 'INSUFFICIENT CHIPS')] fn test_enter_fails_when_insufficient_chips() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); let mut game: Game = world.read_model(2); let stake = 1000; game.params.showdown_type = ShowdownType::Splitted(stake); - - let mut player = mock_unlocked_player(); + let mut player: Player = mock_unlocked_player(); player.chips = 0; - player.enter(ref game); } #[test] fn test_refresh_stake_succeeds_with_splitted_showdown() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); - + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); let mut game: Game = world.read_model(2); let stake = 1000; game.params.showdown_type = ShowdownType::Splitted(stake); - - let mut player = mock_unlocked_player(); + let mut player: Player = mock_unlocked_player(); player.chips = 2000; - let result = player.refresh_stake(ref game); - assert_eq!(result, true, "Refresh stake should succeed"); assert_eq!(player.chips, 1000, "Player chips should be reduced by stake"); assert_eq!(player.locked_chips, 1000, "Locked chips should equal stake"); @@ -414,34 +362,27 @@ mod tests { #[test] fn test_refresh_stake_fails_with_insufficient_chips() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); let mut game: Game = world.read_model(2); let stake = 1000; game.params.showdown_type = ShowdownType::Splitted(stake); - - let mut player = mock_unlocked_player(); + let mut player: Player = mock_unlocked_player(); player.chips = 500; - let result = player.refresh_stake(ref game); - assert_eq!(result, false, "Refresh stake should fail"); } #[test] fn test_is_maxed_returns_true_when_player_maxed() { - let contracts = array![CoreContract::Actions]; - let (mut world, systems) = deploy_contracts(contracts); + let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_poker_game(ref world); let mut game: Game = world.read_model(1); let mut player: Player = world.read_model(PLAYER_1()); player.chips = 0; player.current_bet = 0; player.eligible_pots = 0; - let result = player.is_maxed(@game); - assert_eq!(result, true, "Player should be maxed"); } } From 20952956586589d9b32e5363327001145b79fcb5 Mon Sep 17 00:00:00 2001 From: Asher <141028690+No-bodyq@users.noreply.github.com> Date: Sat, 2 Aug 2025 10:54:43 +0100 Subject: [PATCH 6/7] Refactor player model tests --- .../contract/src/models/player.cairo | 149 +++++++++--------- 1 file changed, 75 insertions(+), 74 deletions(-) diff --git a/poker-texas-hold-em/contract/src/models/player.cairo b/poker-texas-hold-em/contract/src/models/player.cairo index a26fb24..b4563b0 100644 --- a/poker-texas-hold-em/contract/src/models/player.cairo +++ b/poker-texas-hold-em/contract/src/models/player.cairo @@ -124,71 +124,6 @@ mod tests { ); } - fn mock_unlocked_player() -> Player { - mock_player( - PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, - ) - } - - fn mock_uninitialized_game(ref world: WorldStorage) { - mock_poker_game_flex( - ref world, - 3, - false, - false, - 0, - false, - 0, - array![], - array![], - Option::None, - array![], - array![], - 0, - get_default_game_params(), - 0, - false, - 0, - 0, - 0, - false, - false, - 0, - Option::None, - 0, - array![], - ); - } - - fn mock_ended_game(ref world: WorldStorage) { - mock_poker_game_flex( - ref world, - 4, - false, - true, - 0, - false, - 0, - array![PLAYER_1()], - array![], - Option::None, - array![], - array![], - 0, - get_default_game_params(), - 0, - false, - 0, - 0, - 0, - false, - false, - 0, - Option::None, - 0, - array![], - ); - } #[test] fn test_exit_with_out_true_succeeds() { @@ -277,7 +212,9 @@ mod tests { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); let mut game: Game = world.read_model(2); - let mut player: Player = mock_unlocked_player(); + let mut player: Player = mock_player( + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + ); let is_full = player.enter(ref game); assert_eq!(player.locked, (true, game.id), "Player should be locked to game"); assert_eq!(player.in_round, true, "Player should be in round"); @@ -295,7 +232,9 @@ mod tests { let mut game: Game = world.read_model(2); game.current_player_count = 2; game.params.max_no_of_players = 3; - let mut player: Player = mock_unlocked_player(); + let mut player: Player = mock_player( + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + ); let is_full = player.enter(ref game); assert_eq!(is_full, true, "Game should be full after player enters"); assert_eq!(game.current_player_count, 3, "Game should have max players"); @@ -316,9 +255,37 @@ mod tests { #[should_panic(expected: 'GAME NOT INITIALIZED')] fn test_enter_fails_when_game_not_initialized() { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); - mock_uninitialized_game(ref world); + mock_poker_game_flex( + ref world, + 3, + false, + false, + 0, + false, + 0, + array![], + array![], + Option::None, + array![], + array![], + 0, + get_default_game_params(), + 0, + false, + 0, + 0, + 0, + false, + false, + 0, + Option::None, + 0, + array![], + ); let mut game: Game = world.read_model(3); - let mut player: Player = mock_unlocked_player(); + let mut player: Player = mock_player( + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + ); player.enter(ref game); } @@ -326,9 +293,37 @@ mod tests { #[should_panic(expected: 'GAME ALREADY ENDED')] fn test_enter_fails_when_game_ended() { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); - mock_ended_game(ref world); + mock_poker_game_flex( + ref world, + 4, + false, + true, + 0, + false, + 0, + array![PLAYER_1()], + array![], + Option::None, + array![], + array![], + 0, + get_default_game_params(), + 0, + false, + 0, + 0, + 0, + false, + false, + 0, + Option::None, + 0, + array![], + ); let mut game: Game = world.read_model(4); - let mut player: Player = mock_unlocked_player(); + let mut player: Player = mock_player( + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + ); player.enter(ref game); } @@ -340,7 +335,9 @@ mod tests { let mut game: Game = world.read_model(2); let stake = 1000; game.params.showdown_type = ShowdownType::Splitted(stake); - let mut player: Player = mock_unlocked_player(); + let mut player: Player = mock_player( + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + ); player.chips = 0; player.enter(ref game); } @@ -352,7 +349,9 @@ mod tests { let mut game: Game = world.read_model(2); let stake = 1000; game.params.showdown_type = ShowdownType::Splitted(stake); - let mut player: Player = mock_unlocked_player(); + let mut player: Player = mock_player( + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + ); player.chips = 2000; let result = player.refresh_stake(ref game); assert_eq!(result, true, "Refresh stake should succeed"); @@ -367,7 +366,9 @@ mod tests { let mut game: Game = world.read_model(2); let stake = 1000; game.params.showdown_type = ShowdownType::Splitted(stake); - let mut player: Player = mock_unlocked_player(); + let mut player: Player = mock_player( + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + ); player.chips = 500; let result = player.refresh_stake(ref game); assert_eq!(result, false, "Refresh stake should fail"); From a55faacf73f6eb9d6bfc703c1f7be63ee85367af Mon Sep 17 00:00:00 2001 From: Asher <141028690+No-bodyq@users.noreply.github.com> Date: Sun, 3 Aug 2025 20:11:32 +0100 Subject: [PATCH 7/7] Refactor player model tests --- .../contract/src/models/player.cairo | 105 +++------------- .../contract/src/tests/test_actions.cairo | 117 +++++------------- 2 files changed, 50 insertions(+), 172 deletions(-) diff --git a/poker-texas-hold-em/contract/src/models/player.cairo b/poker-texas-hold-em/contract/src/models/player.cairo index b4563b0..533fadb 100644 --- a/poker-texas-hold-em/contract/src/models/player.cairo +++ b/poker-texas-hold-em/contract/src/models/player.cairo @@ -75,50 +75,24 @@ mod tests { fn mock_allowable_game(ref world: WorldStorage) { let player_1 = mock_player( - PLAYER_1(), 'dub_zn', 2000, 0, 1, (true, 1), false, true, (0, 0), 0x1, 0, false, 1, + PLAYER_1(), 'dub_zn', 2000, 0, 1, (true, 1), false, true, (0, 0), ); let player_2 = mock_player( - PLAYER_2(), 'Birdmannn', 5000, 0, 1, (true, 2), false, true, (0, 0), 0x2, 0, false, 1, + PLAYER_2(), 'Birdmannn', 5000, 0, 1, (true, 2), false, true, (0, 0), ); let player_3 = mock_player( - PLAYER_3(), - 'chiscookeke11', - 5000, - 0, - 1, - (false, 1), - false, - true, - (0, 0), - 0x3, - 0, - false, - 1, + PLAYER_3(), 'chiscookeke11', 5000, 0, 1, (false, 1), false, true, (0, 0), ); mock_poker_game_flex( ref world, - 2, true, false, 1, false, 2, array![PLAYER_1(), PLAYER_2(), PLAYER_3()], - array![], Option::Some(PLAYER_1()), array![], - array![0], - 0, - get_default_game_params(), - 0, - false, - 0, - 0, - 0, - false, - false, - 0, - Option::None, 0, array![player_1, player_2, player_3], ); @@ -145,7 +119,7 @@ mod tests { } #[test] - fn test_exit_with_out_false_succeeds() { + fn test_exit_with_out_false_succeeds_and_updates_out() { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_poker_game(ref world); let mut game = world.read_model(1); @@ -211,15 +185,14 @@ mod tests { fn test_enter_succeeds_new_player() { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); - let mut game: Game = world.read_model(2); + let mut game: Game = world.read_model(1); let mut player: Player = mock_player( - PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), ); let is_full = player.enter(ref game); assert_eq!(player.locked, (true, game.id), "Player should be locked to game"); assert_eq!(player.in_round, true, "Player should be in round"); assert_eq!(game.current_player_count, 3, "Game player count should increase"); - assert_eq!(player.eligible_pots, 1, "Player should be eligible for 1 pot"); assert_eq!(is_full, false, "Game should not be full"); assert_eq!(game.players.len(), 4, "Player should be added to game players"); assert_eq!(*game.players.at(3), PLAYER_4(), "Last player should be PLAYER_4"); @@ -229,11 +202,11 @@ mod tests { fn test_is_full_returns_true_when_game_full() { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); - let mut game: Game = world.read_model(2); + let mut game: Game = world.read_model(1); game.current_player_count = 2; game.params.max_no_of_players = 3; let mut player: Player = mock_player( - PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), ); let is_full = player.enter(ref game); assert_eq!(is_full, true, "Game should be full after player enters"); @@ -245,7 +218,7 @@ mod tests { fn test_enter_fails_when_player_already_locked() { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); - let mut game: Game = world.read_model(2); + let mut game: Game = world.read_model(1); let mut player: Player = world.read_model(PLAYER_1()); player.locked = (true, game.id); player.enter(ref game); @@ -256,35 +229,11 @@ mod tests { fn test_enter_fails_when_game_not_initialized() { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_poker_game_flex( - ref world, - 3, - false, - false, - 0, - false, - 0, - array![], - array![], - Option::None, - array![], - array![], - 0, - get_default_game_params(), - 0, - false, - 0, - 0, - 0, - false, - false, - 0, - Option::None, - 0, - array![], + ref world, false, false, 0, false, 0, array![], Option::None, array![], 0, array![], ); - let mut game: Game = world.read_model(3); + let mut game: Game = world.read_model(1); let mut player: Player = mock_player( - PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), ); player.enter(ref game); } @@ -295,34 +244,20 @@ mod tests { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_poker_game_flex( ref world, - 4, false, true, 0, false, 0, array![PLAYER_1()], - array![], Option::None, array![], - array![], - 0, - get_default_game_params(), - 0, - false, - 0, - 0, - 0, - false, - false, - 0, - Option::None, 0, array![], ); - let mut game: Game = world.read_model(4); + let mut game: Game = world.read_model(1); let mut player: Player = mock_player( - PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), ); player.enter(ref game); } @@ -332,11 +267,11 @@ mod tests { fn test_enter_fails_when_insufficient_chips() { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); - let mut game: Game = world.read_model(2); + let mut game: Game = world.read_model(1); let stake = 1000; game.params.showdown_type = ShowdownType::Splitted(stake); let mut player: Player = mock_player( - PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), ); player.chips = 0; player.enter(ref game); @@ -346,11 +281,11 @@ mod tests { fn test_refresh_stake_succeeds_with_splitted_showdown() { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); - let mut game: Game = world.read_model(2); + let mut game: Game = world.read_model(1); let stake = 1000; game.params.showdown_type = ShowdownType::Splitted(stake); let mut player: Player = mock_player( - PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), ); player.chips = 2000; let result = player.refresh_stake(ref game); @@ -363,11 +298,11 @@ mod tests { fn test_refresh_stake_fails_with_insufficient_chips() { let (mut world, _) = deploy_contracts(array![CoreContract::Actions]); mock_allowable_game(ref world); - let mut game: Game = world.read_model(2); + let mut game: Game = world.read_model(1); let stake = 1000; game.params.showdown_type = ShowdownType::Splitted(stake); let mut player: Player = mock_player( - PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), 0x3, 0, false, 1, + PLAYER_4(), 'Nobody', 5000, 0, 1, (false, 1), false, true, (0, 0), ); player.chips = 500; let result = player.refresh_stake(ref game); diff --git a/poker-texas-hold-em/contract/src/tests/test_actions.cairo b/poker-texas-hold-em/contract/src/tests/test_actions.cairo index fe7732f..e5ef414 100644 --- a/poker-texas-hold-em/contract/src/tests/test_actions.cairo +++ b/poker-texas-hold-em/contract/src/tests/test_actions.cairo @@ -43,54 +43,35 @@ pub mod tests { is_dealer: bool, in_round: bool, out: (u64, u64), - pub_key: felt252, - locked_chips: u256, - is_blacklisted: bool, - eligible_pots: u8, ) -> Player { - Player { - id, - alias, - chips, - current_bet, - total_rounds, - locked, - is_dealer, - in_round, - out, - pub_key, - locked_chips, - is_blacklisted, - eligible_pots, - } + let mut player: Player = Default::default(); + player.id = id; + player.alias = alias; + player.chips = chips; + player.current_bet = current_bet; + player.total_rounds = total_rounds; + player.locked = locked; + player.is_dealer = is_dealer; + player.in_round = in_round; + player.out = out; + player.locked_chips = 0; + player.eligible_pots = 1; + + player } // Flexible game mock pub fn mock_poker_game_flex( ref world: WorldStorage, - id: u64, in_progress: bool, has_ended: bool, current_round: u8, round_in_progress: bool, current_player_count: u32, players: Array, - deck: Array, next_player: Option, community_cards: Array, - pots: Array, current_bet: u256, - params: GameParams, - reshuffled: u64, - should_end: bool, - deck_root: felt252, - dealt_cards_root: felt252, - nonce: u64, - community_dealing: bool, - showdown: bool, - round_count: u64, - highest_staker: Option, - previous_offset: u256, player_states: Array, ) { let temp_player_states = player_states.span(); @@ -98,31 +79,19 @@ pub mod tests { for player in temp_player_states { player_states.append(player); }; - let game = Game { - id, - in_progress, - has_ended, - current_round, - round_in_progress, - current_player_count, - players, - deck, - next_player, - community_cards, - pots, - current_bet, - params, - reshuffled, - should_end, - deck_root, - dealt_cards_root, - nonce, - community_dealing, - showdown, - round_count, - highest_staker, - previous_offset, - }; + + let mut game: Game = Default::default(); + game.id = 1; + game.in_progress = in_progress; + game.has_ended = has_ended; + game.current_round = current_round; + game.round_in_progress = round_in_progress; + game.current_player_count = current_player_count; + game.players = players; + game.next_player = next_player; + game.pots = array![0]; + game.current_bet = current_bet; + game.params = get_default_game_params(); world.write_model(@game); world.write_models(player_states.span()); } @@ -446,50 +415,24 @@ pub mod tests { // Default mock usage for legacy tests pub fn mock_poker_game(ref world: WorldStorage) { let player_1 = mock_player( - PLAYER_1(), 'dub_zn', 2000, 0, 1, (true, 1), false, true, (0, 0), 0x1, 0, false, 1, + PLAYER_1(), 'dub_zn', 2000, 0, 1, (true, 1), false, true, (0, 0), ); let player_2 = mock_player( - PLAYER_2(), 'Birdmannn', 5000, 0, 1, (true, 1), false, true, (0, 0), 0x2, 0, false, 1, + PLAYER_2(), 'Birdmannn', 5000, 0, 1, (true, 1), false, true, (0, 0), ); let player_3 = mock_player( - PLAYER_3(), - 'chiscookeke11', - 5000, - 0, - 1, - (true, 1), - false, - true, - (0, 0), - 0x3, - 0, - false, - 1, + PLAYER_3(), 'chiscookeke11', 5000, 0, 1, (true, 1), false, true, (0, 0), ); mock_poker_game_flex( ref world, - 1, // id true, // in_progress false, // has_ended 1, // current_round true, // round_in_progress 2, // current_player_count array![PLAYER_1(), PLAYER_2(), PLAYER_3()], - array![], Option::Some(PLAYER_1()), array![], - array![0], - 0, - get_default_game_params(), - 0, - false, - 0, - 0, - 0, - false, - false, - 0, - Option::None, 0, array![player_1, player_2, player_3], );