#![cfg(feature = "skia-native")]
use velox_dom::{Props, VNode, h};
use velox_style::{Stylesheet, apply_styles};
fn props(s: &str) -> Props {
Props::from_inline(s)
}
fn px(rgba: &[u8], w: i32, x: i32, y: i32) -> (u8, u8, u8) {
let base = ((y as usize) * (w as usize) + x as usize) * 4;
(rgba[base], rgba[base + 1], rgba[base + 2])
}
fn scrollable_tree() -> VNode {
h(
"div",
props("width:200px; height:100px; overflow:auto;"),
vec![h(
"div",
props("width:200px; height:300px; background:#FF0000;"),
vec![],
)],
)
}
#[test]
fn scrollbar_thumb_painted_on_scrollable_container() {
let sheet = Stylesheet::default();
let styled = apply_styles(&scrollable_tree(), &sheet);
let rgba =
velox_renderer::render_vnode_to_rgba(&styled, &sheet, 200, 300).expect("render to rgba");
let (r, g, b) = px(&rgba, 200, 100, 50);
assert!(
r > 200 && g < 60 && b < 60,
"content visible inside container, got rgb=({r},{g},{b})"
);
let (r, g, b) = px(&rgba, 200, 100, 150);
assert!(
r < 60 && g < 60 && b < 60,
"content clipped below container, got rgb=({r},{g},{b})"
);
let (r, g, b) = px(&rgba, 200, 194, 15);
assert!(
r > 120 && (20..200).contains(&g) && g != 255 && b < 100,
"thumb painted near right edge, got rgb=({r},{g},{b})"
);
let (r, g, b) = px(&rgba, 200, 150, 15);
assert!(
r > 200 && g < 60,
"no thumb bleeding into content area, got rgb=({r},{g},{b})"
);
}
#[test]
fn non_scrollable_container_paints_no_thumb() {
let vnode = h(
"div",
props("width:200px; height:100px;"),
vec![h(
"div",
props("width:200px; height:300px; background:#FF0000;"),
vec![],
)],
);
let sheet = Stylesheet::default();
let styled = apply_styles(&vnode, &sheet);
let rgba =
velox_renderer::render_vnode_to_rgba(&styled, &sheet, 200, 300).expect("render to rgba");
let (r, g, b) = px(&rgba, 200, 194, 15);
assert!(
r > 200 && g < 60,
"no scrollbar thumb without overflow, got rgb=({r},{g},{b})"
);
}
#[test]
fn scrolled_content_renders_shifted_with_thumb_at_bottom() {
let vnode = h(
"div",
props("width:200px; height:100px; overflow:auto; scroll-top:100px;"),
vec![
h(
"div",
props("width:200px; height:100px; background:#FF0000;"),
vec![],
),
h(
"div",
props("width:200px; height:100px; background:#00FF00;"),
vec![],
),
],
);
let sheet = Stylesheet::default();
let styled = apply_styles(&vnode, &sheet);
let rgba =
velox_renderer::render_vnode_to_rgba(&styled, &sheet, 200, 300).expect("render to rgba");
let (r, g, b) = px(&rgba, 200, 100, 50);
assert!(
g > 200 && r < 60 && b < 60,
"scrolled content (green) visible, got rgb=({r},{g},{b})"
);
let (r, g, b) = px(&rgba, 200, 100, 150);
assert!(
r < 60 && g < 60,
"below-container area clipped, got rgb=({r},{g},{b})"
);
let (r, g, b) = px(&rgba, 200, 194, 70);
assert!(
r < 100 && g > 120 && b < 100,
"thumb near bottom over scrolled content, got rgb=({r},{g},{b})"
);
let (r, g, b) = px(&rgba, 200, 194, 15);
assert!(
g > 200 && r < 60,
"top track shows content, not thumb, got rgb=({r},{g},{b})"
);
}