summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/client_core.rs130
1 files changed, 126 insertions, 4 deletions
diff --git a/tests/client_core.rs b/tests/client_core.rs
index b0bba6f..695dcb1 100644
--- a/tests/client_core.rs
+++ b/tests/client_core.rs
@@ -10,7 +10,10 @@ use zagan_bet::client::core::{ClientCore, Effect, InteractiveCommand, Key};
10use zagan_bet::client::games::response::{ 10use zagan_bet::client::games::response::{
11 parse_blackjack_response, parse_crash_response, parse_spin_response, 11 parse_blackjack_response, parse_crash_response, parse_spin_response,
12}; 12};
13use zagan_bet::client::games::roulette::{Cursor, Direction};
13use zagan_bet::client::ui::command_names; 14use zagan_bet::client::ui::command_names;
15use zagan_bet::client::view::{Command, RoulettePhase, View};
16use zagan_bet::roulette::BetTarget;
14use zagan_bet::crash::CrashState; 17use zagan_bet::crash::CrashState;
15 18
16const WIN3: &str = "CCCCLLCLODGSDGS"; 19const WIN3: &str = "CCCCLLCLODGSDGS";
@@ -36,7 +39,8 @@ impl Screen {
36 for effect in effects { 39 for effect in effects {
37 match effect { 40 match effect {
38 Effect::Print(lines) => self.lines.extend(lines.iter().cloned()), 41 Effect::Print(lines) => self.lines.extend(lines.iter().cloned()),
39 Effect::ReplaceRegion(lines) => { 42 Effect::Render(view) => {
43 let lines = zagan_bet::client::tui::render_view(view);
40 if let Some(start) = self.region_start { 44 if let Some(start) = self.region_start {
41 self.lines.truncate(start); 45 self.lines.truncate(start);
42 } else { 46 } else {
@@ -52,14 +56,15 @@ impl Screen {
52 self.region_start = None; 56 self.region_start = None;
53 self.region_len = 0; 57 self.region_len = 0;
54 } 58 }
55 Effect::AnimateRoulette { final_lines, .. } => { 59 Effect::AnimateRoulette { view, .. } => {
60 let lines = zagan_bet::client::tui::render_view(view);
56 if let Some(start) = self.region_start { 61 if let Some(start) = self.region_start {
57 self.lines.truncate(start); 62 self.lines.truncate(start);
58 } else { 63 } else {
59 self.region_start = Some(self.lines.len()); 64 self.region_start = Some(self.lines.len());
60 } 65 }
61 self.lines.extend(final_lines.iter().cloned()); 66 self.lines.extend(lines.iter().cloned());
62 self.region_len = final_lines.len(); 67 self.region_len = lines.len();
63 } 68 }
64 Effect::SetPrompt { text, cursor_col } => { 69 Effect::SetPrompt { text, cursor_col } => {
65 self.prompt = text.clone(); 70 self.prompt = text.clone();
@@ -1198,3 +1203,120 @@ fn history_rejects_a_bad_count_without_sending() {
1198 .iter() 1203 .iter()
1199 .any(|line| line.contains("Usage: history [1-50]"))); 1204 .any(|line| line.contains("Usage: history [1-50]")));
1200} 1205}
1206
1207#[test]
1208fn the_roulette_view_reflects_the_cursor_and_bets() {
1209 let mut h = Harness::new();
1210 h.enter_roulette();
1211
1212 let View::Roulette(view) = h.core.view() else {
1213 panic!("expected a roulette view");
1214 };
1215 assert_eq!(view.cursor, Cursor::Lattice { x: 1, y: 5 });
1216 assert_eq!(
1217 view.cursor.target(),
1218 Some(BetTarget::Straight { number: 1 })
1219 );
1220 assert!(view.bets.is_empty());
1221 assert_eq!(view.chip, 10);
1222 assert_eq!(view.phase, RoulettePhase::Placing);
1223
1224 h.core.command(Command::MoveCursor(Direction::Up));
1225 h.core.command(Command::MoveCursor(Direction::Up));
1226 let effects = h.core.command(Command::PlaceBet);
1227 h.apply(effects);
1228
1229 let View::Roulette(view) = h.core.view() else {
1230 panic!("expected a roulette view");
1231 };
1232 assert_eq!(
1233 view.cursor.target(),
1234 Some(BetTarget::Straight { number: 2 })
1235 );
1236 assert_eq!(view.bets.total(), 10);
1237 assert_eq!(
1238 view.bets.amount_on(&BetTarget::Straight { number: 2 }),
1239 10
1240 );
1241}
1242
1243#[test]
1244fn clicking_a_bet_target_does_not_move_the_cursor() {
1245 let mut h = Harness::new();
1246 h.enter_roulette();
1247
1248 let effects = h.core.command(Command::PlaceBetAt(BetTarget::Split { a: 1, b: 4 }));
1249 h.apply(effects);
1250
1251 let View::Roulette(view) = h.core.view() else {
1252 panic!("expected a roulette view");
1253 };
1254 assert_eq!(view.bets.amount_on(&BetTarget::Split { a: 1, b: 4 }), 10);
1255 assert_eq!(
1256 view.cursor.target(),
1257 Some(BetTarget::Straight { number: 1 }),
1258 "a click places a chip without dragging the keyboard cursor"
1259 );
1260}
1261
1262#[test]
1263fn the_roulette_view_reports_the_result() {
1264 let mut h = Harness::new();
1265 h.enter_roulette();
1266 h.core.command(Command::PlaceBet);
1267
1268 h.key(Key::Char(' '));
1269 let bets = r#"{"chips":[{"target":{"bet":"straight","number":1},"amount":10}]}"#;
1270 h.reply(&format!("ROULETTE_RESULT s1 360 10 1350 1 red {bets}"));
1271
1272 let View::Roulette(view) = h.core.view() else {
1273 panic!("expected a roulette view");
1274 };
1275 assert_eq!(view.phase, RoulettePhase::Result);
1276 assert_eq!(view.number, Some(1));
1277 assert_eq!(view.color.as_deref(), Some("red"));
1278 assert_eq!(view.winnings, Some(360));
1279 assert_eq!(view.balance, Some(1350));
1280 assert!(view.error.is_none());
1281}
1282
1283#[test]
1284fn the_chip_size_is_a_command() {
1285 let mut h = Harness::new();
1286 h.enter_roulette();
1287
1288 h.core.command(Command::AdjustChip(10));
1289 let View::Roulette(view) = h.core.view() else {
1290 panic!("expected a roulette view");
1291 };
1292 assert_eq!(view.chip, 20);
1293
1294 h.core.command(Command::SetChip(5));
1295 let View::Roulette(view) = h.core.view() else {
1296 panic!("expected a roulette view");
1297 };
1298 assert_eq!(view.chip, 10, "the chip never goes below 10");
1299}
1300
1301#[test]
1302fn unported_games_still_reach_the_frontend_as_text() {
1303 let mut h = Harness::new();
1304 h.enter_slots("10");
1305
1306 match h.core.view() {
1307 View::Text(lines) => assert_eq!(lines.len(), 10),
1308 other => panic!("expected the text bridge, got {other:?}"),
1309 }
1310}
1311
1312#[test]
1313fn leaving_through_a_command_clears_the_screen() {
1314 let mut h = Harness::new();
1315 h.enter_roulette();
1316
1317 let effects = h.core.command(Command::Leave);
1318 h.apply(effects);
1319
1320 assert!(!h.core.is_in_game());
1321 assert!(h.screen.lines.iter().any(|line| line == "Game exited."));
1322}