diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-01 19:58:59 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-01 19:58:59 +0100 |
| commit | 10ff558853f549d3f3c7c8432488bfad9da6973a (patch) | |
| tree | 271b05fead384e2d91e5c8332fea9d00b540f0cc /gui/tests | |
| parent | v4.0.7: finish the Phase 1 boundary with a command shell (diff) | |
| download | zagan-bet-10ff558853f549d3f3c7c8432488bfad9da6973a.tar.gz zagan-bet-10ff558853f549d3f3c7c8432488bfad9da6973a.zip | |
v4.1.0: add the egui workspace member and the roulette style spike
Phase 3 of the GUI plan. gui/ is a separate package that depends on the core with default features off, so egui never enters the TUI or server build graph. It carries the theme tokens and two embedded fonts (Open Sans OFL, Hack MIT), paints the felt, chips, cursor and wheel from RouletteView, and composes the persistent header with the betting sidebar.
The reference screen runs on demo state: arrow keys move the shared Cursor, clicks place chips, and SPIN animates a 2.4 s wheel that settles with the winning pocket under the pointer. No network until Phase 4.
Verified x86_64-pc-windows-gnu cross-compile. Measured on Linux at 1080p with llvmpipe: 6.0 MB binary (4.7 MB on Windows), 52 ms to window, 137 MB idle RSS, 0% idle CPU.
Diffstat (limited to 'gui/tests')
| -rw-r--r-- | gui/tests/layout.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/gui/tests/layout.rs b/gui/tests/layout.rs new file mode 100644 index 0000000..e0c0475 --- /dev/null +++ b/gui/tests/layout.rs | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | //! Pure presentation maths. Anything that touches a `Ui` is covered by the | ||
| 2 | //! manual screenshot pass; these are the calculations a pixel test cannot | ||
| 3 | //! express. | ||
| 4 | |||
| 5 | use std::f32::consts::TAU; | ||
| 6 | |||
| 7 | use zagan_bet::roulette::{BetTarget, Outside}; | ||
| 8 | use zagan_bet_gui::roulette::{number_under, size_for, target_name}; | ||
| 9 | use zagan_bet_gui::theme::{group_digits, money}; | ||
| 10 | |||
| 11 | #[test] | ||
| 12 | fn money_is_grouped_in_threes() { | ||
| 13 | assert_eq!(group_digits(0), "0"); | ||
| 14 | assert_eq!(group_digits(999), "999"); | ||
| 15 | assert_eq!(group_digits(1000), "1 000"); | ||
| 16 | assert_eq!(group_digits(1234567), "1 234 567"); | ||
| 17 | assert_eq!(group_digits(-1500), "-1 500"); | ||
| 18 | assert_eq!(money(1000), "1 000 Kr"); | ||
| 19 | } | ||
| 20 | |||
| 21 | #[test] | ||
| 22 | fn the_wheel_pointer_reads_the_number_at_the_top() { | ||
| 23 | let segment = TAU / 37.0; | ||
| 24 | assert_eq!(number_under(0.0), 0); | ||
| 25 | |||
| 26 | // Rotating by -i segments puts wheel entry i under the pointer. | ||
| 27 | for number in [0u8, 32, 17, 26] { | ||
| 28 | let index = zagan_bet::roulette::WHEEL | ||
| 29 | .iter() | ||
| 30 | .position(|candidate| *candidate == number) | ||
| 31 | .expect("number is on the wheel"); | ||
| 32 | let rotation = -(index as f32) * segment; | ||
| 33 | assert_eq!(number_under(rotation), number); | ||
| 34 | } | ||
| 35 | |||
| 36 | // One full turn changes nothing. | ||
| 37 | assert_eq!(number_under(-TAU), 0); | ||
| 38 | } | ||
| 39 | |||
| 40 | #[test] | ||
| 41 | fn table_size_keeps_the_felt_aspect_and_fits() { | ||
| 42 | let available = eframe::egui::vec2(1300.0, 900.0); | ||
| 43 | let size = size_for(available); | ||
| 44 | assert!(size.x <= available.x + 0.01, "{size:?} overflows"); | ||
| 45 | assert!(size.y <= available.y + 0.01, "{size:?} overflows"); | ||
| 46 | |||
| 47 | // 13 cells wide and 4.89 cells tall, plus the felt border on every side. | ||
| 48 | let cell = (size.x - 12.0) / 13.0; | ||
| 49 | assert!((cell - (size.y - 12.0) / 4.89).abs() < 0.01); | ||
| 50 | } | ||
| 51 | |||
| 52 | #[test] | ||
| 53 | fn targets_read_as_bet_slips() { | ||
| 54 | assert_eq!( | ||
| 55 | target_name(&BetTarget::Straight { number: 17 }), | ||
| 56 | "Straight 17" | ||
| 57 | ); | ||
| 58 | assert_eq!( | ||
| 59 | target_name(&BetTarget::Split { a: 26, b: 29 }), | ||
| 60 | "Split 26/29" | ||
| 61 | ); | ||
| 62 | assert_eq!( | ||
| 63 | target_name(&BetTarget::Corner { | ||
| 64 | numbers: [17, 18, 20, 21] | ||
| 65 | }), | ||
| 66 | "Corner 17/18/20/21" | ||
| 67 | ); | ||
| 68 | assert_eq!(target_name(&BetTarget::Dozen { index: 1 }), "2nd 12"); | ||
| 69 | assert_eq!(target_name(&BetTarget::Column { index: 2 }), "Column 3"); | ||
| 70 | assert_eq!( | ||
| 71 | target_name(&BetTarget::Outside { | ||
| 72 | kind: Outside::High | ||
| 73 | }), | ||
| 74 | "19-36" | ||
| 75 | ); | ||
| 76 | assert_eq!( | ||
| 77 | target_name(&BetTarget::Outside { | ||
| 78 | kind: Outside::Black | ||
| 79 | }), | ||
| 80 | "Black" | ||
| 81 | ); | ||
| 82 | } | ||
