//! Headless software-render первого кадра в PNG (спека §6 / §9.3 п.6 / §9.4 «шагающий скелет»). //! Работает без дисплея (и на dev-Mac, и в Lima): Slint software-renderer → PNG. //! //! Один тест намеренно: Slint-платформа процесс-глобальна и ставится один раз, а `render_screenshot` //! в проде зовётся ровно раз на процесс (oneshot-сервис / `just shell-frame`) — параллельный прогон //! нескольких рендер-тестов в одном бинаре ушёл бы в дефолтный winit-бэкенд (на macOS — только main-thread). use shturman_shell::{render_screenshot, Initial}; use std::path::Path; /// Декодировать PNG → (ширина, высота, RGB-байты). fn decode(path: &Path) -> (u32, u32, Vec) { let dec = png::Decoder::new(std::fs::File::open(path).unwrap()); let mut reader = dec.read_info().unwrap(); let (w, h) = (reader.info().width, reader.info().height); let mut buf = vec![0u8; reader.output_buffer_size()]; let info = reader.next_frame(&mut buf).unwrap(); buf.truncate(info.buffer_size()); (w, h, buf) } #[test] fn renders_first_frame_reflecting_theme() { let dir = tempfile::tempdir().unwrap(); // --- ночь: кадр не пустой, верный размер, тёмный фон --- let night = dir.path().join("night.png"); render_screenshot( &Initial { theme: "night".into(), ignition: "running".into(), network: "unknown".into(), }, 12, &night, ) .expect("render ночь"); let (w, h, npx) = decode(&night); assert_eq!((w, h), (1024, 600), "размер кадра"); // «не пустой» содержательно: кадр не одноцветный (нарисованы тайлы/текст, не только фон). let first = npx[0]; assert!( npx.iter().any(|&b| b != first), "кадр одноцветный — рендер пустой" ); // угол (0,0) = фон окна — ночью тёмный (#0e1014). let (nr, ng, nb) = (npx[0], npx[1], npx[2]); assert!( nr < 64 && ng < 64 && nb < 64, "ночной фон не тёмный: {nr},{ng},{nb}" ); // --- день: тот же угол — светлый (#f4f5f7) — тема отражена --- let day = dir.path().join("day.png"); render_screenshot( &Initial { theme: "day".into(), ..Default::default() }, 12, &day, ) .expect("render день"); let (_, _, dpx) = decode(&day); let (dr, dg, db) = (dpx[0], dpx[1], dpx[2]); assert!( dr > 192 && dg > 192 && db > 192, "дневной фон не светлый: {dr},{dg},{db}" ); }