diff options
| author | salmonik <salmonik@tuta.io> | 2026-10-29 18:22:40 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-10-29 18:22:40 +0100 |
| commit | b5a52fc0312afdf5d5fbe53275dc88d6d881c2ff (patch) | |
| tree | d12e3c7f6c23ae1698199d16ee763551edfd8c12 /tests/client_core.rs | |
| parent | v2.1.2: ignore ANSI when measuring board height (diff) | |
| download | zagan-bet-b5a52fc0312afdf5d5fbe53275dc88d6d881c2ff.tar.gz zagan-bet-b5a52fc0312afdf5d5fbe53275dc88d6d881c2ff.zip | |
v2.2.0: add blackjack with reserved bets and hit/stand/double
Diffstat (limited to '')
| -rw-r--r-- | tests/client_core.rs | 201 |
1 files changed, 200 insertions, 1 deletions
diff --git a/tests/client_core.rs b/tests/client_core.rs index 7fb7e29..cfcf608 100644 --- a/tests/client_core.rs +++ b/tests/client_core.rs | |||
| @@ -4,8 +4,9 @@ | |||
| 4 | //! logical `Effect`s that `ClientCore` emits, so assertions are about what a | 4 | //! logical `Effect`s that `ClientCore` emits, so assertions are about what a |
| 5 | //! player would see, not about ANSI sequences. | 5 | //! player would see, not about ANSI sequences. |
| 6 | 6 | ||
| 7 | use zagan_bet::blackjack::BlackjackState; | ||
| 7 | use zagan_bet::client::core::{ClientCore, Effect, InteractiveCommand, Key}; | 8 | use zagan_bet::client::core::{ClientCore, Effect, InteractiveCommand, Key}; |
| 8 | use zagan_bet::client::games::response::parse_spin_response; | 9 | use zagan_bet::client::games::response::{parse_blackjack_response, parse_spin_response}; |
| 9 | use zagan_bet::client::ui::command_names; | 10 | use zagan_bet::client::ui::command_names; |
| 10 | 11 | ||
| 11 | const WIN3: &str = "CCCCLLCLODGSDGS"; | 12 | const WIN3: &str = "CCCCLLCLODGSDGS"; |
| @@ -139,6 +140,11 @@ impl Harness { | |||
| 139 | self.line("play roulette"); | 140 | self.line("play roulette"); |
| 140 | self.reply("INFO alice 1 1000"); | 141 | self.reply("INFO alice 1 1000"); |
| 141 | } | 142 | } |
| 143 | |||
| 144 | fn enter_blackjack(&mut self) { | ||
| 145 | self.line("play blackjack"); | ||
| 146 | self.reply("INFO alice 1 1000"); | ||
| 147 | } | ||
| 142 | } | 148 | } |
| 143 | 149 | ||
| 144 | #[test] | 150 | #[test] |
| @@ -647,3 +653,196 @@ fn roulette_rejects_an_out_of_range_number() { | |||
| 647 | assert!(h.board()[4].contains("ERROR: Number must be 0-36")); | 653 | assert!(h.board()[4].contains("ERROR: Number must be 0-36")); |
| 648 | assert!(h.board()[2].contains("Bets: (none)")); | 654 | assert!(h.board()[2].contains("Bets: (none)")); |
| 649 | } | 655 | } |
| 656 | |||
| 657 | fn bj_state( | ||
| 658 | session: &str, | ||
| 659 | phase: &str, | ||
| 660 | player: &[&str], | ||
| 661 | dealer: &[&str], | ||
| 662 | player_total: u8, | ||
| 663 | dealer_total: u8, | ||
| 664 | bet: u64, | ||
| 665 | base_bet: u64, | ||
| 666 | balance: i64, | ||
| 667 | actions: &[&str], | ||
| 668 | result: &str, | ||
| 669 | winnings: u64, | ||
| 670 | ) -> BlackjackState { | ||
| 671 | BlackjackState { | ||
| 672 | session_id: session.to_string(), | ||
| 673 | phase: phase.to_string(), | ||
| 674 | player: player.iter().map(|card| card.to_string()).collect(), | ||
| 675 | dealer: dealer.iter().map(|card| card.to_string()).collect(), | ||
| 676 | player_total, | ||
| 677 | dealer_total, | ||
| 678 | bet, | ||
| 679 | base_bet, | ||
| 680 | balance, | ||
| 681 | actions: actions.iter().map(|action| action.to_string()).collect(), | ||
| 682 | result: result.to_string(), | ||
| 683 | winnings, | ||
| 684 | } | ||
| 685 | } | ||
| 686 | |||
| 687 | #[test] | ||
| 688 | fn blackjack_deals_hits_and_settles() { | ||
| 689 | let mut h = Harness::new(); | ||
| 690 | h.enter_blackjack(); | ||
| 691 | |||
| 692 | assert_eq!(h.board().len(), 6); | ||
| 693 | assert!(h.board()[4].contains("Press [SPACE] to deal.")); | ||
| 694 | |||
| 695 | h.key(Key::Char(' ')); | ||
| 696 | assert!(h | ||
| 697 | .sent | ||
| 698 | .iter() | ||
| 699 | .any(|line| line == "PLAY_START blackjack 10")); | ||
| 700 | |||
| 701 | let player = bj_state( | ||
| 702 | "bj1", | ||
| 703 | "player", | ||
| 704 | &["10S", "6H"], | ||
| 705 | &["9D", "?"], | ||
| 706 | 16, | ||
| 707 | 9, | ||
| 708 | 10, | ||
| 709 | 10, | ||
| 710 | 990, | ||
| 711 | &["hit", "stand", "double"], | ||
| 712 | "playing", | ||
| 713 | 0, | ||
| 714 | ); | ||
| 715 | h.reply(&format!( | ||
| 716 | "BLACKJACK_STATE {}", | ||
| 717 | serde_json::to_string(&player).unwrap() | ||
| 718 | )); | ||
| 719 | |||
| 720 | assert_eq!(h.board().len(), 6); | ||
| 721 | assert!(h.board()[2].contains("Dealer: [9♦] [ ? ] 9")); | ||
| 722 | assert!(h.board()[3].contains("You: [10♠] [6♥] 16")); | ||
| 723 | assert!(h.board()[4].contains("Hit, stand or double.")); | ||
| 724 | assert!(h.board()[5].contains("[D]ouble")); | ||
| 725 | |||
| 726 | h.key(Key::Char('h')); | ||
| 727 | assert_eq!( | ||
| 728 | h.sent.last().map(String::as_str), | ||
| 729 | Some("BLACKJACK_ACTION bj1 hit") | ||
| 730 | ); | ||
| 731 | |||
| 732 | let done = bj_state( | ||
| 733 | "bj1", | ||
| 734 | "done", | ||
| 735 | &["10S", "6H", "5D"], | ||
| 736 | &["9D", "8C"], | ||
| 737 | 21, | ||
| 738 | 17, | ||
| 739 | 10, | ||
| 740 | 10, | ||
| 741 | 1010, | ||
| 742 | &[], | ||
| 743 | "win", | ||
| 744 | 20, | ||
| 745 | ); | ||
| 746 | h.reply(&format!( | ||
| 747 | "BLACKJACK_STATE {}", | ||
| 748 | serde_json::to_string(&done).unwrap() | ||
| 749 | )); | ||
| 750 | |||
| 751 | assert!(h.board()[4].contains("Win! Won 20 PLN")); | ||
| 752 | assert!(h.board()[5].contains("[SPACE] New hand")); | ||
| 753 | |||
| 754 | h.key(Key::Char('q')); | ||
| 755 | assert!(h.board().is_empty()); | ||
| 756 | assert!(h.screen.lines.iter().any(|line| line == "Game exited.")); | ||
| 757 | } | ||
| 758 | |||
| 759 | #[test] | ||
| 760 | fn blackjack_cancel_sends_a_cancel_action() { | ||
| 761 | let mut h = Harness::new(); | ||
| 762 | h.enter_blackjack(); | ||
| 763 | h.key(Key::Char(' ')); | ||
| 764 | |||
| 765 | let player = bj_state( | ||
| 766 | "bj1", | ||
| 767 | "player", | ||
| 768 | &["10S", "6H"], | ||
| 769 | &["9D", "?"], | ||
| 770 | 16, | ||
| 771 | 9, | ||
| 772 | 10, | ||
| 773 | 10, | ||
| 774 | 990, | ||
| 775 | &["hit", "stand", "double"], | ||
| 776 | "playing", | ||
| 777 | 0, | ||
| 778 | ); | ||
| 779 | h.reply(&format!( | ||
| 780 | "BLACKJACK_STATE {}", | ||
| 781 | serde_json::to_string(&player).unwrap() | ||
| 782 | )); | ||
| 783 | |||
| 784 | h.key(Key::Char('q')); | ||
| 785 | assert_eq!( | ||
| 786 | h.sent.last().map(String::as_str), | ||
| 787 | Some("BLACKJACK_ACTION bj1 cancel") | ||
| 788 | ); | ||
| 789 | |||
| 790 | let cancelled = bj_state( | ||
| 791 | "bj1", | ||
| 792 | "done", | ||
| 793 | &["10S", "6H"], | ||
| 794 | &["9D", "?"], | ||
| 795 | 16, | ||
| 796 | 9, | ||
| 797 | 10, | ||
| 798 | 10, | ||
| 799 | 1000, | ||
| 800 | &[], | ||
| 801 | "cancelled", | ||
| 802 | 0, | ||
| 803 | ); | ||
| 804 | h.reply(&format!( | ||
| 805 | "BLACKJACK_STATE {}", | ||
| 806 | serde_json::to_string(&cancelled).unwrap() | ||
| 807 | )); | ||
| 808 | |||
| 809 | assert!(h.board().is_empty()); | ||
| 810 | assert!(h.screen.lines.iter().any(|line| line == "Game exited.")); | ||
| 811 | } | ||
| 812 | |||
| 813 | #[test] | ||
| 814 | fn blackjack_ready_board_can_change_the_next_bet() { | ||
| 815 | let mut h = Harness::new(); | ||
| 816 | h.enter_blackjack(); | ||
| 817 | |||
| 818 | h.key(Key::Char('=')); | ||
| 819 | assert!(h.board()[1].contains("Bet: 20 PLN")); | ||
| 820 | |||
| 821 | h.key(Key::Char(' ')); | ||
| 822 | assert!(h | ||
| 823 | .sent | ||
| 824 | .iter() | ||
| 825 | .any(|line| line == "PLAY_START blackjack 20")); | ||
| 826 | } | ||
| 827 | |||
| 828 | #[test] | ||
| 829 | fn parses_a_blackjack_state() { | ||
| 830 | let state = bj_state( | ||
| 831 | "bj1", | ||
| 832 | "player", | ||
| 833 | &["10S", "6H"], | ||
| 834 | &["9D", "?"], | ||
| 835 | 16, | ||
| 836 | 9, | ||
| 837 | 10, | ||
| 838 | 10, | ||
| 839 | 990, | ||
| 840 | &["hit", "stand"], | ||
| 841 | "playing", | ||
| 842 | 0, | ||
| 843 | ); | ||
| 844 | let response = format!("BLACKJACK_STATE {}", serde_json::to_string(&state).unwrap()); | ||
| 845 | |||
| 846 | assert_eq!(parse_blackjack_response(&response).unwrap(), state); | ||
| 847 | assert!(parse_blackjack_response("ERROR Insufficient balance").is_err()); | ||
| 848 | } | ||
