summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/client_core.rs46
-rw-r--r--tests/client_ui.rs19
-rw-r--r--tests/slots.rs14
3 files changed, 51 insertions, 28 deletions
diff --git a/tests/client_core.rs b/tests/client_core.rs
index ea99d52..e75a611 100644
--- a/tests/client_core.rs
+++ b/tests/client_core.rs
@@ -128,19 +128,19 @@ impl Harness {
128} 128}
129 129
130#[test] 130#[test]
131fn play_shows_a_nine_line_board_and_fetches_the_balance() { 131fn play_shows_a_ten_line_board_and_fetches_the_balance() {
132 let mut h = Harness::new(); 132 let mut h = Harness::new();
133 h.line("play slots 50"); 133 h.line("play slots 50");
134 134
135 assert_eq!(h.board().len(), 9); 135 assert_eq!(h.board().len(), 10);
136 assert!(h.board()[1].contains("Bet: 50 PLN")); 136 assert!(h.board()[1].contains("Bet: 50 PLN"));
137 assert!(!h.board()[1].contains("Lines:")); 137 assert!(!h.board()[1].contains("Lines:"));
138 assert!(h.board()[5].contains("Pays 3/4/5 x bet:")); 138 assert!(h.board()[5].contains("Pays 3/4/5 x bet:"));
139 assert!(h.board()[5].contains("S 9/30/150")); 139 assert!(h.board()[6].contains("G 4/12/40 D 6/18/70 S 9/30/150"));
140 assert!(h.sent.contains(&"INFO".to_string())); 140 assert!(h.sent.contains(&"INFO".to_string()));
141 141
142 h.reply("INFO alice 1 1000"); 142 h.reply("INFO alice 1 1000");
143 assert_eq!(h.board().len(), 9); 143 assert_eq!(h.board().len(), 10);
144 assert!(h.board()[1].contains("Balance: 1000 PLN")); 144 assert!(h.board()[1].contains("Balance: 1000 PLN"));
145} 145}
146 146
@@ -151,22 +151,22 @@ fn spin_replaces_the_board_and_keeps_the_controls_line() {
151 let lines_before_spin = h.screen.lines.len(); 151 let lines_before_spin = h.screen.lines.len();
152 152
153 h.key(Key::Char(' ')); 153 h.key(Key::Char(' '));
154 assert_eq!(h.board().len(), 9); 154 assert_eq!(h.board().len(), 10);
155 assert!(h.board()[6].contains("Spinning...")); 155 assert!(h.board()[7].contains("Spinning..."));
156 assert!(h.board()[8].contains("[Q] Quit")); 156 assert!(h.board()[9].contains("[Q] Quit"));
157 assert!(h.sent.iter().any(|line| line == "PLAY_START slots 50")); 157 assert!(h.sent.iter().any(|line| line == "PLAY_START slots 50"));
158 assert_eq!(h.screen.lines.len(), lines_before_spin); 158 assert_eq!(h.screen.lines.len(), lines_before_spin);
159 159
160 h.reply("GAME_RESULT session-1 100 50 1050 CCCCLLCLODGSDGS win 1 0,3,6"); 160 h.reply("GAME_RESULT session-1 100 50 1050 CCCCLLCLODGSDGS win 1 0,3,6");
161 assert_eq!(h.board().len(), 9); 161 assert_eq!(h.board().len(), 10);
162 assert!(h 162 assert!(h
163 .board() 163 .board()
164 .get(2) 164 .get(2)
165 .is_some_and(|line| line.contains("{ C } { C } { C } [ D ] [ D ]"))); 165 .is_some_and(|line| line.contains("{ C } { C } { C } [ D ] [ D ]")));
166 assert!(h.board()[6].contains("Won 100 PLN")); 166 assert!(h.board()[7].contains("Won 100 PLN"));
167 assert!(h.board()[7].contains("Winning lines: 1")); 167 assert!(h.board()[8].contains("Winning lines: 1"));
168 assert!(h.board()[1].contains("Balance: 1050 PLN")); 168 assert!(h.board()[1].contains("Balance: 1050 PLN"));
169 assert!(h.board()[8].contains("[Q] Quit")); 169 assert!(h.board()[9].contains("[Q] Quit"));
170 assert_eq!(h.screen.lines.len(), lines_before_spin); 170 assert_eq!(h.screen.lines.len(), lines_before_spin);
171} 171}
172 172
@@ -180,7 +180,7 @@ fn changing_the_bet_after_a_spin_does_not_leave_stale_lines() {
180 180
181 h.key(Key::Char('+')); 181 h.key(Key::Char('+'));
182 182
183 assert_eq!(h.board().len(), 9); 183 assert_eq!(h.board().len(), 10);
184 assert!(h.board()[1].contains("Bet: 60 PLN")); 184 assert!(h.board()[1].contains("Bet: 60 PLN"));
185 assert!(h 185 assert!(h
186 .board() 186 .board()
@@ -205,9 +205,9 @@ fn a_losing_spin_shows_no_win_and_no_winning_lines() {
205 205
206 h.reply(&format!("GAME_RESULT session-1 0 10 990 {LOSS} none -")); 206 h.reply(&format!("GAME_RESULT session-1 0 10 990 {LOSS} none -"));
207 207
208 assert_eq!(h.board().len(), 9); 208 assert_eq!(h.board().len(), 10);
209 assert!(h.board()[6].contains("No win.")); 209 assert!(h.board()[7].contains("No win."));
210 assert_eq!(h.board()[7], ""); 210 assert_eq!(h.board()[8], "");
211 assert!(!h.board()[2].contains('{')); 211 assert!(!h.board()[2].contains('{'));
212} 212}
213 213
@@ -219,9 +219,9 @@ fn a_mega_win_shows_all_winning_lines() {
219 219
220 h.reply(&format!("GAME_RESULT session-1 750 10 1740 {ALL_C} mega 1,2,3,4,5 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14")); 220 h.reply(&format!("GAME_RESULT session-1 750 10 1740 {ALL_C} mega 1,2,3,4,5 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14"));
221 221
222 assert_eq!(h.board().len(), 9); 222 assert_eq!(h.board().len(), 10);
223 assert!(h.board()[6].contains("MEGA WIN! 750 PLN")); 223 assert!(h.board()[7].contains("MEGA WIN! 750 PLN"));
224 assert!(h.board()[7].contains("Winning lines: 1,2,3,4,5")); 224 assert!(h.board()[8].contains("Winning lines: 1,2,3,4,5"));
225 assert_eq!(h.board()[2].matches("{ C }").count(), 5); 225 assert_eq!(h.board()[2].matches("{ C }").count(), 5);
226} 226}
227 227
@@ -245,8 +245,8 @@ fn a_server_error_replaces_the_status_line() {
245 245
246 h.reply("ERROR Insufficient balance"); 246 h.reply("ERROR Insufficient balance");
247 247
248 assert_eq!(h.board().len(), 9); 248 assert_eq!(h.board().len(), 10);
249 assert!(h.board()[6].contains("ERROR: Insufficient balance")); 249 assert!(h.board()[7].contains("ERROR: Insufficient balance"));
250 assert!(h.board()[2].contains("[ ? ]")); 250 assert!(h.board()[2].contains("[ ? ]"));
251 assert!(!h.board().iter().any(|line| line.contains("Spinning"))); 251 assert!(!h.board().iter().any(|line| line.contains("Spinning")));
252} 252}
@@ -259,8 +259,8 @@ fn an_empty_reply_is_an_error_not_a_silent_spin() {
259 259
260 h.reply(""); 260 h.reply("");
261 261
262 assert_eq!(h.board().len(), 9); 262 assert_eq!(h.board().len(), 10);
263 assert!(h.board()[6].contains("No response from server")); 263 assert!(h.board()[7].contains("No response from server"));
264} 264}
265 265
266#[test] 266#[test]
@@ -344,7 +344,7 @@ fn play_without_a_bet_uses_the_default() {
344 let mut h = Harness::new(); 344 let mut h = Harness::new();
345 h.line("play slots"); 345 h.line("play slots");
346 346
347 assert_eq!(h.board().len(), 9); 347 assert_eq!(h.board().len(), 10);
348 assert!(h.board()[1].contains("Bet: 10 PLN")); 348 assert!(h.board()[1].contains("Bet: 10 PLN"));
349} 349}
350 350
diff --git a/tests/client_ui.rs b/tests/client_ui.rs
index a22fbe7..ea432e0 100644
--- a/tests/client_ui.rs
+++ b/tests/client_ui.rs
@@ -1,6 +1,7 @@
1use zagan_bet::client::ui::{ 1use zagan_bet::client::ui::{
2 command_names, completion_lines, display_width, first_contact_lines, format_pong, 2 command_names, completion_lines, display_width, first_contact_lines, format_pong,
3 help_lines, host_lines, input_cursor_column, lines_to_move_up, parse_bet_arg, record_history, 3 help_lines, host_lines, input_cursor_column, lines_to_move_up, parse_bet_arg, record_history,
4 visual_line_count,
4}; 5};
5use std::time::Duration; 6use std::time::Duration;
6 7
@@ -98,6 +99,24 @@ fn redraw_moves_up_by_line_count_minus_one() {
98} 99}
99 100
100#[test] 101#[test]
102fn visual_line_count_accounts_for_terminal_wrapping() {
103 let lines = vec![
104 "12345".to_string(),
105 "123456".to_string(),
106 String::new(),
107 ];
108
109 assert_eq!(visual_line_count(&lines, 5), 4); // 1 + 2 + 1
110 assert_eq!(visual_line_count(&lines, 6), 3); // 1 + 1 + 1
111 assert_eq!(visual_line_count(&lines, 80), 3);
112 assert_eq!(visual_line_count(&[], 80), 0);
113
114 let wide = "x".repeat(75);
115 assert_eq!(visual_line_count(&[wide.clone()], 75), 1);
116 assert_eq!(visual_line_count(&[wide], 72), 2);
117}
118
119#[test]
101fn input_cursor_is_after_the_removed_character() { 120fn input_cursor_is_after_the_removed_character() {
102 assert_eq!(input_cursor_column(10, 8), 18); 121 assert_eq!(input_cursor_column(10, 8), 18);
103 assert_eq!(input_cursor_column(10, 0), 10); 122 assert_eq!(input_cursor_column(10, 0), 10);
diff --git a/tests/slots.rs b/tests/slots.rs
index b7292b8..bdf8f10 100644
--- a/tests/slots.rs
+++ b/tests/slots.rs
@@ -1,6 +1,6 @@
1//! Regression tests for the server-side 5x3 slots game. 1//! Regression tests for the server-side 5x3 slots game.
2 2
3use zagan_bet::slots::{paytable_line, PAYTABLE}; 3use zagan_bet::slots::{paytable_lines, PAYTABLE};
4use zagan_bet::server::games::slots::{LineWin, SlotsGame, PAYLINES, REELS, ROWS}; 4use zagan_bet::server::games::slots::{LineWin, SlotsGame, PAYLINES, REELS, ROWS};
5use zagan_bet::server::games::traits::{Game, GamePhase}; 5use zagan_bet::server::games::traits::{Game, GamePhase};
6 6
@@ -108,16 +108,20 @@ fn theoretical_rtp_is_just_under_one() {
108} 108}
109 109
110#[test] 110#[test]
111fn the_paytable_line_lists_every_symbol_and_fits_80_columns() { 111fn the_paytable_lines_list_every_symbol_and_fit_80_columns() {
112 let line = paytable_line(); 112 let lines = paytable_lines();
113 let joined = lines.join(" ");
113 114
115 assert_eq!(lines.len(), 2, "paytable should be split into two lines");
114 for (symbol, three, four, five) in PAYTABLE { 116 for (symbol, three, four, five) in PAYTABLE {
115 assert!( 117 assert!(
116 line.contains(&format!("{symbol} {three}/{four}/{five}")), 118 joined.contains(&format!("{symbol} {three}/{four}/{five}")),
117 "paytable is missing {symbol}" 119 "paytable is missing {symbol}"
118 ); 120 );
119 } 121 }
120 assert!(line.len() <= 80, "paytable is too wide: {line:?}"); 122 for line in lines {
123 assert!(line.len() <= 80, "paytable is too wide: {line:?}");
124 }
121} 125}
122 126
123#[test] 127#[test]