//! The tray card's placement next to the tray icon, always inside the monitor's work area. use storebound_desktop::card::*; const W: f64 = 360.0; const H: f64 = 480.0; fn r(x: f64, y: f64, w: f64, h: f64) -> Rect { Rect { x, y, w, h } } fn inside(p: (f64, f64), work: Rect) { assert!(p.0 >= work.x && p.0 + W <= work.x + work.w, "x {p:?} outside {work:?}"); assert!(p.1 >= work.y && p.1 + H <= work.y + work.h, "y {p:?} outside {work:?}"); } #[test] fn windows_bottom_taskbar_opens_above_the_icon() { let work = r(0.0, 0.0, 1920.0, 1032.0); let p = place(r(1700.0, 1040.0, 24.0, 32.0), work, W, H, 8.0); assert_eq!(p, (1532.0, 1032.0 - H - 8.0)); inside(p, work); } #[test] fn icon_in_the_corner_is_clamped_into_the_work_area() { let work = r(0.0, 0.0, 1920.0, 1032.0); let p = place(r(1900.0, 1040.0, 24.0, 32.0), work, W, H, 8.0); assert_eq!(p.0, 1920.0 - W - 8.0); inside(p, work); } #[test] fn macos_menu_bar_opens_below_the_icon() { let work = r(0.0, 25.0, 1440.0, 875.0); let p = place(r(1200.0, 0.0, 22.0, 24.0), work, W, H, 8.0); assert_eq!(p.1, 33.0); inside(p, work); } #[test] fn side_taskbars_open_beside_the_icon() { let work = r(60.0, 0.0, 1860.0, 1080.0); let left = place(r(10.0, 900.0, 40.0, 40.0), work, W, H, 8.0); assert_eq!(left.0, 68.0); inside(left, work); let work = r(0.0, 0.0, 1860.0, 1080.0); let right = place(r(1870.0, 100.0, 40.0, 40.0), work, W, H, 8.0); assert_eq!(right.0, 1860.0 - W - 8.0); inside(right, work); } #[test] fn second_monitor_with_negative_origin() { let work = r(-2560.0, 0.0, 2560.0, 1400.0); let p = place(r(-200.0, 1410.0, 24.0, 30.0), work, W, H, 8.0); inside(p, work); } #[test] fn icon_inside_the_work_area_and_a_tiny_screen() { let work = r(0.0, 0.0, 1920.0, 1080.0); inside(place(r(900.0, 1000.0, 24.0, 24.0), work, W, H, 8.0), work); inside(place(r(900.0, 20.0, 24.0, 24.0), work, W, H, 8.0), work); // smaller than the card: top-left of the work area, no panic let tiny = r(0.0, 0.0, 300.0, 300.0); assert_eq!(place(r(100.0, 310.0, 20.0, 20.0), tiny, W, H, 8.0), (8.0, 8.0)); } #[test] fn actions_and_snapshots_are_checked() { for a in ["hide", "open", "route", "refresh", "mute", "quit", "external", "ready"] { assert!(valid_action(a)); } assert!(!valid_action("sidecar_call")); assert!(!set_snapshot(serde_json::json!([1, 2]))); assert!(!set_snapshot(serde_json::json!({ "x": "y".repeat(MAX_SNAPSHOT) }))); assert!(set_snapshot(serde_json::json!({ "busy": false }))); assert_eq!(snapshot().unwrap()["busy"], false); }