#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
use Tickit::Test 0.12;
use Tickit::Widget::Scroller;
use Tickit::Widget::Scroller::Item::Text;
# Tests are simpler if the terminal is much smaller
# TODO: mk_window once Tickit::Test can take a size there too
my ( $term, $win ) = mk_term_and_window lines => 5, cols => 15;
my $scrolled_delta = 0;
my $scroller = Tickit::Widget::Scroller->new(
on_scrolled => sub { $scrolled_delta += $_[1] },
);
$scroller->push(
map { Tickit::Widget::Scroller::Item::Text->new( "Item of text $_ which is long" ) } 1 .. 9
);
$scroller->set_window( $win );
flush_tickit;
is_termlog( [ GOTO(0,0),
SETPEN,
PRINT("Item of text 1 "),
GOTO(1,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(2,0),
SETPEN,
PRINT("Item of text 2 "),
GOTO(3,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(4,0),
SETPEN,
PRINT("Item of text 3 ") ],
'Termlog initially' );
is_display( [ [TEXT("Item of text 1 ")],
[TEXT("which is long")],
[TEXT("Item of text 2 ")],
[TEXT("which is long")],
[TEXT("Item of text 3 ")] ],
'Display initially' );
is( $scroller->item2line( 0, 0 ), 0, 'item2line 0, 0 initially' );
is( $scroller->item2line( 0, -1 ), 1, 'item2line 0, -1 initially' );
is( $scroller->item2line( 1, 0 ), 2, 'item2line 1, 0 initially' );
is( $scroller->item2line( 1, -1 ), 3, 'item2line 1, -1 initially' );
is( $scroller->item2line( 2, 0 ), 4, 'item2line 2, 0 initially' );
is( $scroller->item2line( 2, -1 ), undef, 'item2line 2, -1 initially offscreen' );
is_deeply( [ $scroller->item2line( 2, -1 ) ], [ undef, "below" ], 'list item2line 2, -1 initially below screen' );
is_deeply( [ $scroller->item2line( 2, -1, 1 ) ], [ 5, "below" ], 'list item2line 2, -1 initially below screen with count_offscreen' );
is( $scroller->lines_above, 0, 'lines_above initially' );
is( $scroller->lines_below, 13, 'lines_below initially' );
$scroller->scroll( +10 );
is( $scrolled_delta, 10, '$scrolled_delta after ->scroll' );
flush_tickit;
is_termlog( [ GOTO(0,0),
SETPEN,
PRINT("Item of text 6 "),
GOTO(1,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(2,0),
SETPEN,
PRINT("Item of text 7 "),
GOTO(3,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(4,0),
SETPEN,
PRINT("Item of text 8 ") ],
'Termlog after scroll +10' );
is_display( [ [TEXT("Item of text 6 ")],
[TEXT("which is long")],
[TEXT("Item of text 7 ")],
[TEXT("which is long")],
[TEXT("Item of text 8 ")] ],
'Display after scroll +10' );
is( $scroller->item2line( 0, 0 ), undef, 'item2line 0, 0 offscreen after scroll +10' );
is( $scroller->item2line( 0, -1 ), undef, 'item2line 0, -1 offscreen after scroll +10' );
is( $scroller->item2line( 5, 0 ), 0, 'item2line 5, 0 after scroll +10' );
is( $scroller->item2line( 5, -1 ), 1, 'item2line 5, -1 after scroll +10' );
is( $scroller->item2line( 8, 0 ), undef, 'item2line 8, 0 offscreen after scroll +10' );
is_deeply( [ $scroller->item2line( 0, 0 ) ], [ undef, "above" ], 'list item2line 0, 0 above screen after scroll +10' );
is_deeply( [ $scroller->item2line( 0, 0, 1 ) ], [ -10, "above" ], 'list item2line 0, 0 above screen after scroll +10 with count_offscreen' );
is_deeply( [ $scroller->item2line( 8, 0 ) ], [ undef, "below" ], 'list item2line 8, 0 below screen after scroll +10' );
is_deeply( [ $scroller->item2line( 8, 0, 1 ) ], [ 6, "below" ], 'list item2line 8, 0 below screen after scroll +10 with count_offscreen' );
is( $scroller->lines_above, 10, 'lines_above after scroll +10' );
is( $scroller->lines_below, 3, 'lines_below after scroll +10' );
$scroller->scroll( -1 );
is( $scrolled_delta, 9, '$scrolled_delta after ->scroll -1' );
flush_tickit;
is_termlog( [ SETBG(undef),
SCROLLRECT(0,0,5,15, -1,0),
GOTO(0,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2) ],
'Termlog after scroll -1' );
is_display( [ [TEXT("which is long")],
[TEXT("Item of text 6 ")],
[TEXT("which is long")],
[TEXT("Item of text 7 ")],
[TEXT("which is long")] ],
'Display after scroll -1' );
is( $scroller->lines_above, 9, 'lines_above after scroll -1' );
is( $scroller->lines_below, 4, 'lines_below after scroll -1' );
$scroller->scroll( +1 );
is( $scrolled_delta, 10, '$scrolled_delta after ->scroll +1' );
flush_tickit;
is_termlog( [ SETBG(undef),
SCROLLRECT(0,0,5,15, +1,0),
GOTO(4,0),
SETPEN,
PRINT("Item of text 8 ") ],
'Termlog after scroll +1' );
is_display( [ [TEXT("Item of text 6 ")],
[TEXT("which is long")],
[TEXT("Item of text 7 ")],
[TEXT("which is long")],
[TEXT("Item of text 8 ")] ],
'Display after scroll +1' );
$scroller->scroll( -10 );
is( $scrolled_delta, 0, '$scrolled_delta after ->scroll -10' );
flush_tickit;
is_termlog( [ GOTO(0,0),
SETPEN,
PRINT("Item of text 1 "),
GOTO(1,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(2,0),
SETPEN,
PRINT("Item of text 2 "),
GOTO(3,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(4,0),
SETPEN,
PRINT("Item of text 3 ") ],
'Termlog after scroll -10' );
is_display( [ [TEXT("Item of text 1 ")],
[TEXT("which is long")],
[TEXT("Item of text 2 ")],
[TEXT("which is long")],
[TEXT("Item of text 3 ")] ],
'Display after scroll -10' );
$scroller->scroll_to_bottom;
is( $scrolled_delta, 13, '$scrolled_delta after ->scroll_to_bottom' );
flush_tickit;
is_termlog( [ GOTO(0,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(1,0),
SETPEN,
PRINT("Item of text 8 "),
GOTO(2,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(3,0),
SETPEN,
PRINT("Item of text 9 "),
GOTO(4,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2) ],
'Termlog after scroll_to_bottom' );
is_display( [ [TEXT("which is long")],
[TEXT("Item of text 8 ")],
[TEXT("which is long")],
[TEXT("Item of text 9 ")],
[TEXT("which is long")] ],
'Display after scroll_to_bottom' );
$scroller->scroll_to_top;
is( $scrolled_delta, 0, '$scrolled_delta after ->scroll_to_top' );
flush_tickit;
is_termlog( [ GOTO(0,0),
SETPEN,
PRINT("Item of text 1 "),
GOTO(1,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(2,0),
SETPEN,
PRINT("Item of text 2 "),
GOTO(3,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(4,0),
SETPEN,
PRINT("Item of text 3 ") ],
'Termlog after scroll_to_top' );
is_display( [ [TEXT("Item of text 1 ")],
[TEXT("which is long")],
[TEXT("Item of text 2 ")],
[TEXT("which is long")],
[TEXT("Item of text 3 ")] ],
'Display after scroll_to_top' );
$scroller->scroll_to( 2, 4, 0 ); # About halfway
is( $scrolled_delta, 6, '$scrolled_delta after ->scroll_to halfway' );
flush_tickit;
is_termlog( [ GOTO(0,0),
SETPEN,
PRINT("Item of text 4 "),
GOTO(1,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(2,0),
SETPEN,
PRINT("Item of text 5 "),
GOTO(3,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2),
GOTO(4,0),
SETPEN,
PRINT("Item of text 6 ") ],
'Termlog after scroll_to middle' );
is_display( [ [TEXT("Item of text 4 ")],
[TEXT("which is long")],
[TEXT("Item of text 5 ")],
[TEXT("which is long")],
[TEXT("Item of text 6 ")] ],
'Display after scroll_to middle' );
$scroller->scroll( +5 );
flush_tickit;
drain_termlog;
{
my $pre_scroll_delta = $scrolled_delta;
$scroller->scroll( +5 ); # over the end
is( $scrolled_delta - $pre_scroll_delta, 2, 'on_scroll given actual delta, not requested' );
is( $scrolled_delta, 13, '$scrolled_delta after ->scroll +5 over the end' );
}
flush_tickit;
is_termlog( [ SETBG(undef),
SCROLLRECT(0,0,5,15, +2,0),
GOTO(3,0),
SETPEN,
PRINT("Item of text 9 "),
GOTO(4,0),
SETPEN,
PRINT("which is long"),
SETBG(undef),
ERASECH(2) ],
'Termlog down past the end' );
is_display( [ [TEXT("which is long")],
[TEXT("Item of text 8 ")],
[TEXT("which is long")],
[TEXT("Item of text 9 ")],
[TEXT("which is long")] ],
'Display after scroll down past the end' );
$scroller->scroll( -2 );
$scroller->scroll( -2 );
flush_tickit;
is_termlog( [ SETBG(undef),
SCROLLRECT(0,0,5,15, -2,0),
SETBG(undef),
SCROLLRECT(0,0,5,15, -2,0),
GOTO(0,0), SETPEN, PRINT("which is long"), SETBG(undef), ERASECH(2),
GOTO(1,0), SETPEN, PRINT("Item of text 6 "),
GOTO(2,0), SETPEN, PRINT("which is long"), SETBG(undef), ERASECH(2),
GOTO(3,0), SETPEN, PRINT("Item of text 7 "), ],
'Termlog after ->scroll(-2) x 2' );
is_display( [ [TEXT("which is long")],
[TEXT("Item of text 6 ")],
[TEXT("which is long")],
[TEXT("Item of text 7 ")],
[TEXT("which is long")] ],
'Display after ->scroll(-2) x 2' );
$scroller->scroll( +2 );
$scroller->scroll( +2 );
flush_tickit;
is_termlog( [ SETBG(undef),
SCROLLRECT(0,0,5,15, +2,0),
SETBG(undef),
SCROLLRECT(0,0,5,15, +2,0),
GOTO(1,0), SETPEN, PRINT("Item of text 8 "),
GOTO(2,0), SETPEN, PRINT("which is long"), SETBG(undef), ERASECH(2),
GOTO(3,0), SETPEN, PRINT("Item of text 9 "),
GOTO(4,0), SETPEN, PRINT("which is long"), SETBG(undef), ERASECH(2), ],
'Termlog after ->scroll(+2) x 2' );
is_display( [ [TEXT("which is long")],
[TEXT("Item of text 8 ")],
[TEXT("which is long")],
[TEXT("Item of text 9 ")],
[TEXT("which is long")] ],
'Display after ->scroll(+2) x 2' );
is( $scrolled_delta, 13, '$scrolled_delta before EOF' );
done_testing;