package tests::UICompoundWidgetTest; use strict; use base qw/ Lire::Test::TestCase /; use Lire::Config::TypeSpec; use Curses::UI; use Curses::UI::Widget; use Curses::UI::Container; use Lire::Test::CursesUIDriver; use Lire::Test::Mock; use Lire::Utils qw/deep_copy/; sub new { my $self = shift->SUPER::new ( @_ ); $self->{'driver'} = new Lire::Test::CursesUIDriver(); my $spec = new Lire::Config::ConfigSpec(); my $compound = new Lire::Config::ConfigSpec( 'name' => 'compound' ); $spec->add( $compound ); $compound->add( new Lire::Config::IntegerSpec( 'name' => 'integer' ) ); my $list = new Lire::Config::ListSpec( 'name' => 'list', 'summary' => 'List summary', 'description' => 'List description' ); $compound->add( $list ); $list->add( new Lire::Config::StringSpec( 'name' => 'string' ) ); $compound->add( new Lire::Config::StringSpec( 'name' => 'string' ) ); $compound->add( new Lire::Config::StringSpec( 'name' => 'obsolete', 'obsolete' => 1 ) ); my $empty = new Lire::Config::ConfigSpec( 'name' => 'empty' ); $spec->add( $empty ); $self->{'compound'} = $compound->instance(); $self->{'empty'} = $empty->instance(); return $self; } sub set_up { my $self = $_[0]; $self->SUPER::set_up(); $self->{'driver'}->setup_curses_ui(); $self->{'ui'} = new Curses::UI(); $self->{'driver'}->set_curses_ui( $self->{'ui'} ); $self->{'window'} = $self->{'ui'}->add( 'window', 'Window' ); return; } sub tear_down { my $self = $_[0]; $self->SUPER::tear_down(); $self->{'driver'}->teardown_curses_ui(); return; } sub test_new { my $self = $_[0]; my $win = $self->{'window'}; $self->assert_dies( qr{missing 'value' parameter}, sub { my $widget = $win->add( 'widget', 'Lire::UI::CompoundWidget' ) }); $self->assert_dies( qr{'value' parameter should be a 'Lire::Config::Dictionary' instance, not 'HASH}, sub { my $widget = $win->add( 'widget', 'Lire::UI::CompoundWidget', 'Value' => {} ) } ); my $widget = $win->add( 'widget', 'Lire::UI::CompoundWidget', 'value' => $self->{'compound'} ); $self->assert_isa( 'Lire::UI::CompoundWidget', $widget ); $self->assert_str_equals( $self->{'compound'}, $widget->{'value'} ); my $help_viewer = $widget->getobj( 'help_viewer' ); $self->assert_isa('Curses::UI::TextViewer', $help_viewer ); my $help_summary = $widget->getobj( 'help_summary' ); $self->assert_isa( 'Curses::UI::Label', $help_summary ); my $str_widget = $widget->getobj( 'string_widget' ); $self->assert_isa( 'Lire::UI::StringWidget', $str_widget ); $self->assert_str_equals( $self->{'compound'}->get( 'string' ), $str_widget->{'value'} ); my $int_widget = $widget->getobj( 'integer_widget' ); $self->assert_isa( 'Lire::UI::IntegerWidget', $int_widget ); my $list_widget = $widget->getobj( 'list_widget' ); $self->assert_isa( 'Lire::UI::ListWidget', $list_widget ); foreach my $w ( ( $str_widget, $int_widget, $list_widget ) ) { $self->assert_str_equals( \&Lire::UI::CompoundWidget::_child_focus_cb, $w->{'-onfocus'}, "wrong focuscb for $w" ); } foreach my $name ( qw/ string integer list / ) { my $w = $widget->getobj( "${name}_label" ); $self->assert_isa( 'Curses::UI::Label', $w, ); $self->assert_str_equals( $name, $w->text() ); } return; } sub test_new_empty { my $self = $_[0]; my $win = $self->{'window'}; my $widget = $win->add( 'widget', 'Lire::UI::CompoundWidget', 'value' => $self->{'empty'} ); $self->assert_isa( 'Lire::UI::CompoundWidget', $widget ); $self->assert_str_equals( $self->{'empty'}, $widget->{'value'} ); my $label = $widget->getobj( 'empty_label' ) || '< undef >'; $self->assert_isa( 'Curses::UI::Label', $label ); $self->assert_str_equals( '-- This option does not have any attributes --', $label->text() ); } sub test_refresh_view { my $self = $_[0]; my $win = $self->{'window'}; my $widget = $win->add( 'widget', 'Lire::UI::CompoundWidget', 'value' => $self->{'compound'} ); no warnings 'redefine'; my ( $strw, $intw, $listw ) = ( 'undef' x 3 ); local *Lire::UI::StringWidget::refresh_view = sub { $strw = shift }; local *Lire::UI::IntegerWidget::refresh_view = sub { $intw = shift }; local *Lire::UI::ListWidget::refresh_view = sub { $listw = shift }; $widget->refresh_view(); $self->assert_str_equals( $strw, $widget->getobj( 'string_widget' ) ); $self->assert_str_equals( $intw, $widget->getobj( 'integer_widget' ) ); $self->assert_str_equals( $listw, $widget->getobj( 'list_widget' ) ); } sub test_child_focus_cb { my $self = $_[0]; my $win = $self->{'window'}; my $widget = $win->add( 'widget', 'Lire::UI::CompoundWidget', 'value' => $self->{'compound'} ); my $help_summary = $widget->getobj( 'help_summary' ); my $help_viewer = $widget->getobj( 'help_viewer' ); $self->assert_str_equals( '', $help_summary->text() ); $self->assert_str_equals( '', $help_viewer->text() ); Lire::UI::CompoundWidget::_child_focus_cb( $widget->getobj('list_widget')); $self->assert_str_equals( 'List summary', $help_summary->text() ); $self->assert_str_equals( 'List description', $help_viewer->text() ); Lire::UI::CompoundWidget::_child_focus_cb( $widget->getobj('string_widget')); $self->assert_str_equals( 'string', $help_summary->text() ); $self->assert_str_equals( 'No help available.', $help_viewer->text() ); my $texteditor = ''; my $nothing = ''; my $scrollpos = 0; no warnings 'redefine'; local *Curses::UI::TextViewer::cursor_up = sub { $texteditor = shift; $nothing = shift; $scrollpos = shift; }; $help_viewer->{'-yscrpos'} = 1; Lire::UI::CompoundWidget::_child_focus_cb( $widget->getobj('list_widget') ); $self->assert_str_equals( '', $texteditor ); $help_viewer->{'-yscrpos'} = 3; Lire::UI::CompoundWidget::_child_focus_cb( $widget->getobj('list_widget') ); $self->assert_str_equals( $help_viewer, $texteditor ); $self->assert_null( $nothing ); $self->assert_num_equals( 3, $scrollpos ); } sub test_layout { my $self = $_[0]; my $widget = $self->{'window'}->add( 'widget', 'Lire::UI::CompoundWidget', 'value' => $self->{'compound'} ); my $proxy = new_proxy Lire::Test::Mock( $widget ); $proxy->set_result( 'canvaswidth', 82, 'canvasheight' => 24 ); $proxy->layout(); my $integer_label = $widget->getobj( 'integer_label' ); $self->assert_num_equals( 0, $integer_label->{'-y'} ); my $list_label = $widget->getobj( 'list_label' ); $self->assert_num_equals( 2, $list_label->{'-y'} ); my $string_label = $widget->getobj( 'string_label' ); $self->assert_num_equals( 13, $string_label->{'-y'} ); foreach my $label ( ( $list_label, $integer_label, $string_label ) ) { $self->annotate( "Checking $label->{'-text'}\n" ); $self->assert_str_equals( 'right', $label->{'-textalignment'} ); $self->assert_num_equals( 0, $label->{'-x'} ); $self->assert_num_equals( 1, $label->{'-height'} ); $self->assert_num_equals( 7, $label->{'-width'} ); } my $integer_widget = $widget->getobj( 'integer_widget' ); $self->assert_num_equals( 0, $integer_widget->{'-y'} ); $self->assert_num_equals( 1, $integer_widget->{'-height'} ); my $list_widget = $widget->getobj( 'list_widget' ); $self->assert_num_equals( 2, $list_widget->{'-y'} ); $self->assert_num_equals( 10, $list_widget->{'-height'} ); my $string_widget = $widget->getobj( 'string_widget' ); $self->assert_num_equals( 13, $string_widget->{'-y'} ); $self->assert_num_equals( 1, $string_widget->{'-height'}); foreach my $wid ( ( $list_widget, $integer_widget, $string_widget ) ) { $self->assert_num_equals( 8, $wid->{'-x'} ); $self->assert_num_equals( 41, $wid->{'-width'} ); } my $summary = $widget->getobj( 'help_summary' ); $self->assert_num_equals( 50, $summary->{'-x'} ); $self->assert_num_equals( 32, $summary->{'-width'} ); $self->assert_num_equals( 0, $summary->{'-y'} ); my $help_viewer = $widget->getobj( 'help_viewer' ); $self->assert_num_equals( 50, $help_viewer->{'-x'} ); $self->assert_num_equals( 32, $help_viewer->{'-width'} ); $self->assert_num_equals( 2, $help_viewer->{'-y'} ); return; } sub test_max_label_size { my $self = $_[0]; my $new_compound = deep_copy( $self->{'compound'}->spec() ); my $widget = $self->{'window'}->add( 'widget', 'Lire::UI::CompoundWidget', 'value' => $new_compound->instance()); my $proxy = new_proxy Lire::Test::Mock( $widget ); $proxy->set_result( 'canvaswidth', 82 ); $self->assert_num_equals( 7, $proxy->_max_label_size() ); $new_compound->get( 'string' )->{'name'} = "A very very very very long"; $self->assert_num_equals( 20, $proxy->_max_label_size() ); } sub test_onvaluechanged_cb { my $self = $_[0]; my $called = 'onvaluechanged not called'; my $win = $self->{'window'}; my $widget = $win->add( 'widget', 'Lire::UI::CompoundWidget', 'value' => $self->{'compound'}, 'onvaluechanged' => sub { $called = 'called' } ); my $int_widget = $widget->getobj( 'integer_widget' ); $self->assert_isa( 'CODE', $int_widget->{'onvaluechanged'} ); $int_widget->run_event( 'onvaluechanged' ); $self->assert_str_equals( 'called', $called ); return; } 1;