First commit. Version 0.1.0
This commit is contained in:
108
tests/scroll.rs
Normal file
108
tests/scroll.rs
Normal file
@@ -0,0 +1,108 @@
|
||||
// Integration coverage for `scroll`. The pure clamping math already lives in
|
||||
// `widget::scroll::tests`; these tests exercise the wiring: `preferred_size`
|
||||
// claims remaining space, and interactive children inside the viewport remain
|
||||
// reachable through `UiSurface`'s widget rects.
|
||||
|
||||
use ltk::core::{ Canvas, RenderOptions, UiSurface };
|
||||
use ltk::{ button, column, scroll, text, Color, Element, Point };
|
||||
|
||||
#[ derive( Clone, Debug, PartialEq, Eq ) ]
|
||||
enum Msg
|
||||
{
|
||||
Pressed( u32 ),
|
||||
}
|
||||
|
||||
fn list_view() -> Element<Msg>
|
||||
{
|
||||
scroll(
|
||||
column::<Msg>()
|
||||
.padding( 0.0 )
|
||||
.spacing( 4.0 )
|
||||
.push( button( "A" ).on_press( Msg::Pressed( 0 ) ) )
|
||||
.push( button( "B" ).on_press( Msg::Pressed( 1 ) ) )
|
||||
.push( button( "C" ).on_press( Msg::Pressed( 2 ) ) ),
|
||||
).into()
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn scroll_preferred_size_returns_zero_height_to_act_as_filler()
|
||||
{
|
||||
let canvas = Canvas::new( 800, 600 );
|
||||
let s = scroll::<Msg>( column::<Msg>() );
|
||||
let ( w, h ) = s.preferred_size( 320.0, &canvas );
|
||||
assert_eq!( w, 320.0 );
|
||||
assert_eq!( h, 0.0 );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn scroll_with_buttons_exposes_them_through_widget_rects()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 320, 480 );
|
||||
let _ = surface.render(
|
||||
&list_view(),
|
||||
RenderOptions::full_canvas( 320, 480 ).background( Color::rgb( 0.1, 0.1, 0.1 ) ),
|
||||
);
|
||||
// Three interactive buttons are visible inside the scroll viewport.
|
||||
assert_eq!( surface.widget_rects().len(), 3 );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn buttons_inside_scroll_dispatch_their_press_messages()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 320, 480 );
|
||||
let _ = surface.render(
|
||||
&list_view(),
|
||||
RenderOptions::full_canvas( 320, 480 ),
|
||||
);
|
||||
let first = &surface.widget_rects()[ 0 ];
|
||||
let msg = surface.handlers( first.flat_idx ).and_then( |h| h.press_msg() );
|
||||
assert_eq!( msg, Some( Msg::Pressed( 0 ) ) );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn hit_test_inside_scroll_returns_button_under_pointer()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 320, 480 );
|
||||
let _ = surface.render(
|
||||
&list_view(),
|
||||
RenderOptions::full_canvas( 320, 480 ),
|
||||
);
|
||||
let first = &surface.widget_rects()[ 0 ];
|
||||
let centre = Point
|
||||
{
|
||||
x: first.rect.x + first.rect.width * 0.5,
|
||||
y: first.rect.y + first.rect.height * 0.5,
|
||||
};
|
||||
assert_eq!( surface.hit_test( centre ), Some( first.flat_idx ) );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn empty_scroll_renders_without_panic()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 320, 480 );
|
||||
let view: Element<Msg> = scroll( column::<Msg>() ).into();
|
||||
let out = surface.render(
|
||||
&view,
|
||||
RenderOptions::full_canvas( 320, 480 ),
|
||||
);
|
||||
assert!( out.full_redraw );
|
||||
assert!( surface.widget_rects().is_empty(), "no buttons inside → no interactive widgets" );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn scroll_around_text_only_child_produces_no_interactive_widgets()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 320, 480 );
|
||||
let view: Element<Msg> = scroll(
|
||||
column::<Msg>()
|
||||
.push( text( "header" ) )
|
||||
.push( text( "body" ) ),
|
||||
).into();
|
||||
let _ = surface.render(
|
||||
&view,
|
||||
RenderOptions::full_canvas( 320, 480 ),
|
||||
);
|
||||
// Text is non-interactive — widget_rects only tracks focusable / hittable
|
||||
// widgets.
|
||||
assert!( surface.widget_rects().is_empty() );
|
||||
}
|
||||
Reference in New Issue
Block a user