First commit. Version 0.1.0
This commit is contained in:
227
tests/core_surface.rs
Normal file
227
tests/core_surface.rs
Normal file
@@ -0,0 +1,227 @@
|
||||
use ltk::core::{ Canvas, RenderOptions, UiSurface };
|
||||
use ltk::{ button, column, window_controls, Color, Element, Point, WindowButtonKind };
|
||||
|
||||
#[ derive( Clone, Debug, PartialEq, Eq ) ]
|
||||
enum Msg
|
||||
{
|
||||
Pressed,
|
||||
Close,
|
||||
Maximize,
|
||||
Minimize,
|
||||
}
|
||||
|
||||
fn view() -> Element<Msg>
|
||||
{
|
||||
column::<Msg>()
|
||||
.padding( 16.0 )
|
||||
.push( button( "Press" ).on_press( Msg::Pressed ) )
|
||||
.into()
|
||||
}
|
||||
|
||||
fn decoration_view() -> Element<Msg>
|
||||
{
|
||||
window_controls(
|
||||
Some( Msg::Minimize ),
|
||||
WindowButtonKind::Maximize,
|
||||
Some( Msg::Maximize ),
|
||||
Some( Msg::Close ),
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn core_surface_new_is_software_by_default()
|
||||
{
|
||||
let surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
assert!( matches!( surface.canvas(), Canvas::Software( _ ) ) );
|
||||
assert!( surface.canvas().borrowed_gles_texture().is_none() );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn core_surface_renders_and_exposes_handlers_without_run()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
let out = surface.render(
|
||||
&view(),
|
||||
RenderOptions::full_canvas( 240, 120 ).background( Color::rgb( 0.1, 0.1, 0.1 ) ),
|
||||
);
|
||||
|
||||
assert!( out.full_redraw );
|
||||
assert_eq!( surface.widget_rects().len(), 1 );
|
||||
|
||||
let first = &surface.widget_rects()[ 0 ];
|
||||
let hit = surface.hit_test( Point { x: first.rect.x + 1.0, y: first.rect.y + 1.0 } );
|
||||
assert_eq!( hit, Some( first.flat_idx ) );
|
||||
|
||||
let msg = surface.handlers( first.flat_idx ).and_then( |h| h.press_msg() );
|
||||
assert_eq!( msg, Some( Msg::Pressed ) );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn core_surface_can_drive_window_controls()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 180, 48 );
|
||||
let _ = surface.render(
|
||||
&decoration_view(),
|
||||
RenderOptions::full_canvas( 180, 48 ).background( Color::rgb( 0.08, 0.08, 0.09 ) ),
|
||||
);
|
||||
|
||||
assert_eq!( surface.widget_rects().len(), 3 );
|
||||
|
||||
let close = surface.widget_rects()[ 2 ].flat_idx;
|
||||
let msg = surface.handlers( close ).and_then( |h| h.press_msg() );
|
||||
assert_eq!( msg, Some( Msg::Close ) );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn core_surface_reports_partial_damage_for_focus_change()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
let opts = RenderOptions::full_canvas( 240, 120 ).background( Color::rgb( 0.1, 0.1, 0.1 ) );
|
||||
let _ = surface.render( &view(), opts );
|
||||
|
||||
let idx = surface.widget_rects()[ 0 ].flat_idx;
|
||||
surface.set_focused( Some( idx ) );
|
||||
let out = surface.render( &view(), opts );
|
||||
|
||||
assert!( !out.full_redraw, "focus-only transition should be partial damage" );
|
||||
assert!( !out.damage_rects.is_empty() );
|
||||
}
|
||||
|
||||
// ── interaction-only damage paths ─────────────────────────────────────────────
|
||||
|
||||
#[ test ]
|
||||
fn hover_only_change_produces_partial_damage()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
let opts = RenderOptions::full_canvas( 240, 120 ).background( Color::rgb( 0.1, 0.1, 0.1 ) );
|
||||
let _ = surface.render( &view(), opts );
|
||||
|
||||
let idx = surface.widget_rects()[ 0 ].flat_idx;
|
||||
surface.set_hovered( Some( idx ) );
|
||||
let out = surface.render( &view(), opts );
|
||||
|
||||
assert!( !out.full_redraw, "hover-only transition should be partial damage" );
|
||||
assert!( !out.damage_rects.is_empty() );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn pressed_only_change_produces_partial_damage()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
let opts = RenderOptions::full_canvas( 240, 120 ).background( Color::rgb( 0.1, 0.1, 0.1 ) );
|
||||
let _ = surface.render( &view(), opts );
|
||||
|
||||
let idx = surface.widget_rects()[ 0 ].flat_idx;
|
||||
surface.set_pressed( Some( idx ) );
|
||||
let out = surface.render( &view(), opts );
|
||||
|
||||
assert!( !out.full_redraw );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn focused_hovered_pressed_setters_round_trip()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
let opts = RenderOptions::full_canvas( 240, 120 );
|
||||
let _ = surface.render( &view(), opts );
|
||||
|
||||
let idx = surface.widget_rects()[ 0 ].flat_idx;
|
||||
surface.set_focused( Some( idx ) );
|
||||
surface.set_hovered( Some( idx ) );
|
||||
surface.set_pressed( Some( idx ) );
|
||||
|
||||
assert_eq!( surface.focused(), Some( idx ) );
|
||||
assert_eq!( surface.hovered(), Some( idx ) );
|
||||
assert_eq!( surface.pressed(), Some( idx ) );
|
||||
|
||||
surface.set_focused( None );
|
||||
surface.set_hovered( None );
|
||||
surface.set_pressed( None );
|
||||
|
||||
assert_eq!( surface.focused(), None );
|
||||
assert_eq!( surface.hovered(), None );
|
||||
assert_eq!( surface.pressed(), None );
|
||||
}
|
||||
|
||||
// ── full-redraw paths ─────────────────────────────────────────────────────────
|
||||
|
||||
#[ test ]
|
||||
fn first_render_is_a_full_redraw()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
let out = surface.render(
|
||||
&view(),
|
||||
RenderOptions::full_canvas( 240, 120 ).background( Color::rgb( 0.1, 0.1, 0.1 ) ),
|
||||
);
|
||||
assert!( out.full_redraw, "the first render of a fresh surface is always a full redraw" );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn mark_content_dirty_forces_next_render_to_full_redraw()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
let opts = RenderOptions::full_canvas( 240, 120 ).background( Color::rgb( 0.1, 0.1, 0.1 ) );
|
||||
let _ = surface.render( &view(), opts );
|
||||
|
||||
// No interaction change — the next render would normally be partial.
|
||||
surface.mark_content_dirty();
|
||||
let out = surface.render( &view(), opts );
|
||||
assert!( out.full_redraw );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn resize_forces_next_render_to_full_redraw()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
let _ = surface.render( &view(), RenderOptions::full_canvas( 240, 120 ) );
|
||||
|
||||
surface.resize( 320, 200 );
|
||||
assert_eq!( surface.size(), ( 320, 200 ) );
|
||||
|
||||
let out = surface.render( &view(), RenderOptions::full_canvas( 320, 200 ) );
|
||||
assert!( out.full_redraw );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn tree_size_change_forces_full_redraw()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 320, 200 );
|
||||
let opts = RenderOptions::full_canvas( 320, 200 );
|
||||
let _ = surface.render( &view(), opts );
|
||||
let initial_count = surface.widget_rects().len();
|
||||
|
||||
// Render a different tree (decoration_view has 3 buttons; view has 1).
|
||||
let out = surface.render( &decoration_view(), opts );
|
||||
assert!( out.full_redraw );
|
||||
assert_ne!( surface.widget_rects().len(), initial_count );
|
||||
}
|
||||
|
||||
// ── lookups ───────────────────────────────────────────────────────────────────
|
||||
|
||||
#[ test ]
|
||||
fn hit_test_outside_any_widget_returns_none()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 320, 200 );
|
||||
let _ = surface.render( &view(), RenderOptions::full_canvas( 320, 200 ) );
|
||||
|
||||
// (0, 0) is the top-left corner — far from the centred button.
|
||||
assert_eq!( surface.hit_test( Point { x: 0.0, y: 0.0 } ), None );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn handlers_lookup_for_unknown_idx_returns_none()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
let _ = surface.render( &view(), RenderOptions::full_canvas( 240, 120 ) );
|
||||
assert!( surface.handlers( 999_999 ).is_none() );
|
||||
}
|
||||
|
||||
#[ test ]
|
||||
fn widget_lookup_for_known_idx_returns_some()
|
||||
{
|
||||
let mut surface = UiSurface::<Msg>::new( 240, 120 );
|
||||
let _ = surface.render( &view(), RenderOptions::full_canvas( 240, 120 ) );
|
||||
let idx = surface.widget_rects()[ 0 ].flat_idx;
|
||||
assert!( surface.widget( idx ).is_some() );
|
||||
}
|
||||
Reference in New Issue
Block a user