From f07221b4e1d8aa464a44fe566884ccc0565406e9 Mon Sep 17 00:00:00 2001 From: salmonik Date: Sun, 1 Nov 2026 16:17:19 +0100 Subject: v3.2.0: straight and split bets anywhere on the felt; add history command --- tests/client_core.rs | 90 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 19 deletions(-) (limited to 'tests/client_core.rs') diff --git a/tests/client_core.rs b/tests/client_core.rs index bb8772e..b0bba6f 100644 --- a/tests/client_core.rs +++ b/tests/client_core.rs @@ -608,24 +608,29 @@ fn roulette_cursor_places_bets_and_spins() { assert!(h.board()[1].contains("Balance: 1000 Kr")); assert!(h.board()[1].contains("Chip: 10 Kr")); assert!(h.board()[9].contains("Bets: (none)")); - // The cursor starts on number 1, the bottom-left corner. + // The cursor starts on number 1, the bottom-left cell. assert!(h.board()[5].contains("[ 1 ]")); + assert!(h.board()[10].contains("Bet: 1 · pays 36x")); - // Up twice: straight 2, then the split between 2 and 3. + // One step up is the split between 1 and 2, two steps is number 2. h.key(Key::Up); + assert!(h.board()[5].contains("[ 1 ]")); + assert!(h.board()[4].contains("[ 2 ]")); + assert!(h.board()[10].contains("Bet: 1/2 · pays 18x")); + h.key(Key::Up); + assert!(!h.board()[5].contains("[ 1 ]")); assert!(h.board()[4].contains("[ 2 ]")); - assert!(h.board()[3].contains("[ 3 ]")); + assert!(h.board()[10].contains("Bet: 2 · pays 36x")); h.key(Key::Enter); - assert!(h.board()[9].contains("2/3 10")); - assert!(h.board()[9].contains("Total: 10 Kr")); + assert!(h.board()[9].contains("2 10")); - // Back down to number 1 and place a straight. - h.key(Key::Down); - h.key(Key::Down); + // Right from 2 is the split with 5. + h.key(Key::Right); + assert!(h.board()[10].contains("Bet: 2/5 · pays 18x")); h.key(Key::Enter); - assert!(h.board()[9].contains("1 10")); + assert!(h.board()[9].contains("2/5 10")); assert!(h.board()[9].contains("Total: 20 Kr")); h.key(Key::Char(' ')); @@ -636,18 +641,17 @@ fn roulette_cursor_places_bets_and_spins() { .expect("roulette request"); assert_eq!( request, - "PLAY_START roulette 20 {\"chips\":[{\"target\":{\"bet\":\"split\",\"a\":2,\"b\":3},\"amount\":10},{\"target\":{\"bet\":\"straight\",\"number\":1},\"amount\":10}]}" + "PLAY_START roulette 20 {\"chips\":[{\"target\":{\"bet\":\"straight\",\"number\":2},\"amount\":10},{\"target\":{\"bet\":\"split\",\"a\":2,\"b\":5},\"amount\":10}]}" ); - let bets = r#"{"chips":[{"target":{"bet":"split","a":2,"b":3},"amount":10},{"target":{"bet":"straight","number":1},"amount":10}]}"#; + let bets = r#"{"chips":[{"target":{"bet":"straight","number":2},"amount":10},{"target":{"bet":"split","a":2,"b":5},"amount":10}]}"#; h.reply(&format!( - "ROULETTE_RESULT session-1 180 20 1160 3 red {bets}" + "ROULETTE_RESULT session-1 540 20 1520 2 black {bets}" )); - assert_eq!(h.board().len(), 12); - assert!(h.board()[1].contains("Balance: 1160 Kr")); - assert!(h.board()[10].contains("Won 180 Kr at 3 RED ODD")); - assert!(h.board()[10].contains("+160")); + assert!(h.board()[1].contains("Balance: 1520 Kr")); + assert!(h.board()[10].contains("Won 540 Kr at 2 BLACK EVEN")); + assert!(h.board()[10].contains("+520")); } #[test] @@ -658,19 +662,18 @@ fn roulette_cursor_reaches_the_outside_rows() { h.key(Key::Down); assert!(h.board()[6].starts_with("[") && h.board()[6].contains("1st 12")); h.key(Key::Down); - assert!(h.board()[7].starts_with("[") && h.board()[7].contains("2:1")); + assert!(h.board()[7].starts_with("[") && h.board()[7].contains("col 1 2:1")); h.key(Key::Down); assert!(h.board()[8].starts_with("[") && h.board()[8].contains("1-18")); h.key(Key::Enter); assert!(h.board()[9].contains("1-18 10")); - // Back up to the felt: the bottom edge of the first dozen is the 1/4 split. + // Back up to the felt: the dozens return to number 1. h.key(Key::Up); h.key(Key::Up); h.key(Key::Up); assert!(h.board()[5].contains("[ 1 ]")); - assert!(h.board()[5].contains("[ 4 ]")); } #[test] @@ -1146,3 +1149,52 @@ fn a_round_is_live_only_while_money_is_reserved() { h.push(&crash_line("CRASH_BUSTED", &busted)); assert!(!h.core.is_live_game()); } + +#[test] +fn history_prints_recent_plays() { + let mut h = Harness::new(); + h.line("history"); + assert_eq!(h.sent.last().map(String::as_str), Some("HISTORY")); + + let json = r#"[{"game":"roulette","bet":10,"winnings":20,"balance_after":1010,"at":"2026-10-30 01:20:11","details":{"number":"17","color":"black"}}]"#; + h.reply(&format!("HISTORY {json}")); + + assert!(h + .screen + .lines + .iter() + .any(|line| line.starts_with("Recent plays (1)"))); + let row = h + .screen + .lines + .iter() + .find(|line| line.contains("roulette")) + .expect("play row"); + assert!(row.contains("2026-10-30 01:20"), "row: {row}"); + assert!(row.contains("1010"), "row: {row}"); + assert!(row.contains("17 black"), "row: {row}"); +} + +#[test] +fn history_without_plays_says_so() { + let mut h = Harness::new(); + h.line("history"); + h.reply("HISTORY []"); + assert!(h + .screen + .lines + .iter() + .any(|line| line == "No plays recorded yet.")); +} + +#[test] +fn history_rejects_a_bad_count_without_sending() { + let mut h = Harness::new(); + h.line("history 0"); + assert!(!h.sent.iter().any(|line| line == "HISTORY 0")); + assert!(h + .screen + .lines + .iter() + .any(|line| line.contains("Usage: history [1-50]"))); +} -- cgit v1.2.3