package tests::UITest;
use strict;
use base qw/Test::Unit::TestSuite/;
sub name {
return "Lire::LireUI Tests";
}
sub include_tests {
return qw/tests::UITest::init
tests::UITest::api
/;
}
package tests::UITest::init;
use base qw/Lire::Test::TestCase/;
use Curses;
use Lire::UI;
use Lire::Test::CursesUIDriver;
sub set_up {
my $self = $_[0];
$self->SUPER::set_up();
$self->{'driver'} = new Lire::Test::CursesUIDriver();
$self->{'driver'}->setup_curses_ui();
$self->{'ui'} = bless { '_ui' => new Curses::UI() }, 'Lire::UI';
$self->{'driver'}->set_curses_ui( $self->{'ui'}{'_ui'} );
return;
}
sub tear_down {
my $self = $_[0];
$self->SUPER::tear_down();
$self->{'driver'}->teardown_curses_ui();
return;
}
sub test_create_menubar {
my $self = $_[0];
$self->{'ui'}->_create_menubar();
my $mbar = $self->{'ui'}{'_ui'}->getobj( 'menubar' );
$self->assert_isa( 'Curses::UI::Menubar', $mbar );
my @menus = map { $_->{'-label'} } @{$mbar->{'-menu'}};
$self->assert_deep_equals( [ 'Lire', 'Store' ], \@menus );
my @menu_cbs = ( [ \&Lire::UI::_lire_about_cb,
\&Lire::UI::_lire_prefs_cb,
\&Lire::UI::_lire_quit_cb ],
[ \&Lire::UI::_store_new_cb,
\&Lire::UI::_store_open_cb ] );
for ( my $menu_idx = 0; $menu_idx < @menu_cbs; $menu_idx++ ) {
my $menu_cb = $menu_cbs[$menu_idx];
for ( my $i=0; $i < @$menu_cb; $i++ ) {
my $menu_def = $mbar->{'-menu'}[$menu_idx]{'-submenu'}[$i];
$self->assert_str_equals( $menu_def->{'-value'},
$menu_cb->[$i],
"'$menu_def->{'-label'}''s callback isn't set properly" );
}
}
$self->assert_str_equals( '__routine_' . \&Lire::UI::_focus_menubar_cb,
$self->{'ui'}{'_ui'}{'-bindings'}{KEY_F(10)} );
}
sub test_focus_menubar_cb {
my $self = $_[0];
my $ui = $self->{'ui'};
$ui->_create_menubar();
$ui->_create_quickstart_win();
$ui->{'_ui'}->getobj( 'quickstart_win' )->focus();
my $mbar = $ui->{'_ui'}->getobj( 'menubar' );
$self->assert_equals( 0, $mbar->{'-focus'} );
Lire::UI::_focus_menubar_cb( $ui->{'_ui'} );
$self->assert_equals( 1, $mbar->{'-focus'} );
}
sub test_create_quickstart_win {
my $self = $_[0];
$self->{'ui'}->_create_quickstart_win();
my $win = $self->{'ui'}{'_ui'}->getobj( 'quickstart_win' );
$self->assert_isa( 'Curses::UI::Window', $win );
my $viewer = $win->getobj( 'text_viewer' );
$self->assert_isa( 'Curses::UI::TextViewer', $viewer );
}
package tests::UITest::api;
use base qw/Lire::Test::TestCase tests::TestStoreFixture/;
use Lire::Config;
use Lire::UI;
use Lire::Test::CursesUIDriver;
use Lire::Config::TypeSpec;
use Lire::Config::ConfigFile;
use Lire::Utils qw/tempdir create_file/;
use Curses::UI::Dialog::Status;
sub new {
my $self = shift->SUPER::new( @_ );
$self->tests::TestStoreFixture::init();
return $self;
}
sub set_up {
my $self = $_[0];
$self->SUPER::set_up();
$self->set_up_test_store();
$self->{'driver'} = new Lire::Test::CursesUIDriver();
$self->{'driver'}->setup_curses_ui();
$self->{'ui'} = new Lire::UI();
$self->{'driver'}->set_curses_ui( $self->{'ui'}->curses_ui() );
$self->{'cfg'}{'_lr_config_spec'} = $self->lire_default_config_spec();
$self->{'cfg'}{'lr_templates_path'} = [];
$self->{'cfg_file'} = "$self->{'tmpdir'}/.lire/config.xml";
mkdir "$self->{'tmpdir'}/.lire";
$self->{'parsed_cfg'} =
new Lire::Config::ConfigFile( 'spec'=> $self->{'cfg'}{'_lr_config_spec'},
'filename' => $self->{'cfg_file'} );
$self->{'parsed_cfg'}->save();
return;
}
sub set_up_import_jobs {
my $self = $_[0];
my $spec = $self->{'cfg'}{'_lr_config_spec'};
my $jobs = $spec->get( 'import_jobs' )->instance();
$self->{'cfg'}{ 'import_jobs' } = $jobs;
my $job = $spec->get( 'import_jobs' )->get( 'import_job' )->instance();
$job->get( 'name' )->set( 'aJob' );
$job->get( 'filter' )->set( '' );
$job->get( 'log_encoding' )->set( 'UTF-8' );
$job->get( 'log_file' )->set( 'a file' );
$job->get( 'period' )->set( 'hourly' );
$job->get( 'service' )->set_plugin( 'www' );
$jobs->append( $job );
}
sub tear_down {
my $self = $_[0];
$self->SUPER::tear_down();
$self->{'driver'}->teardown_curses_ui();
return;
}
sub test_new {
my $self = $_[0];
my $ui = $self->{'ui'};
$self->assert_isa( 'Lire::UI', $ui );
$self->assert_isa( 'Curses::UI', $ui->{'_ui'} );
$self->assert_str_equals( $ui, $ui->{'_ui'}->userdata() );
$self->assert_not_null( $ui->{'_ui'}->getobj( 'quickstart_win' ),
"was _create_quickstart_win() called?" );
$self->assert_not_null( $ui->{'_ui'}->getobj( 'menubar' ),
"was _create_menubar() called?" );
}
sub test_quit_cb {
my $self = $_[0];
$self->assert_dies( qr/^Quit$/,
sub { $self->{'ui'}->_lire_quit_cb( $self->{'ui'}{'_ui'} )} );
}
sub test_mainloop {
my $self = $_[0];
my $called = 0;
$self->{'driver'}->add_event_loop_handler( sub { $called++ } );
$self->{'driver'}->add_event_loop_handler( sub { die "Quit\n" } );
my $rc = $self->{'ui'}->mainloop();
$self->assert_equals( 1, $called );
$self->assert_equals( 0, $rc );
my $err_dialog;
$self->{'driver'}->add_event_loop_handler( sub { die "Error\n" } );
$self->{'driver'}->add_event_loop_handler( sub { $err_dialog = $_[1]; } );
$rc = $self->{'ui'}->mainloop();
$self->assert_equals( 1, $rc );
$self->assert_isa( "Curses::UI::Dialog::Error", $err_dialog );
$self->assert_str_equals( $err_dialog->{'-message'},
"An error occured: Error\n" );
my $warn_dialog;
no warnings 'redefine';
my $or_status_new = \&Curses::UI::Dialog::Status::new;
local *Curses::UI::Dialog::Status::new =
sub() { $warn_dialog = $or_status_new->( @_ ) };
$self->{'driver'}->add_event_loop_handler( sub { warn "Warning\n";
die "Quit\n"} );
$self->{'driver'}->add_event_loop_handler( sub { $warn_dialog = $_[1]; } );
$rc = $self->{'ui'}->mainloop();
$self->assert_equals( 0, $rc );
$self->assert( "Curses::UI::Dialog::Status", $warn_dialog );
$self->assert_str_equals( $warn_dialog->{'-message'}, "Warning\n" );
}
sub test_cleanup {
my $self = $_[0];
my $cui = $self->{'ui'}{'_ui'};
$cui->userdata( $self->{'ui'} );
$self->{'ui'}->cleanup();
$self->assert_null( $self->{'ui'}{'_ui'},
"'_ui' attribute should be null" );
$self->assert_null( $cui->userdata(), "userdata() should be null" );
}
sub test_lire_about_cb {
my $self = $_[0];
my $driver = $self->{'driver'};
my $about_dlg = '<undef>';
$driver->add_event_loop_handler( sub { $about_dlg = $_[1] } );
Lire::UI::_lire_about_cb( $self->{'ui'}{'_ui'} );
$self->assert_isa( "Curses::UI::Dialog::Basic", $about_dlg );
$self->assert_matches( qr/\(c\) 2000-2004/,
$about_dlg->{'-message'} );
$self->assert_matches( qr/logreport\@logreport.org/,
$about_dlg->{'-message'} );
$self->assert_matches( qr/About/, $about_dlg->{'-title'} );
}
sub test_lire_prefs_cb {
my $self = $_[0];
local $ENV{'HOME'} = $self->{'tmpdir'};
no warnings 'redefine';
local *Lire::Test::HashConfig::config_files = sub { $self->{'cfg_file'} };
local *Lire::Test::HashConfig::get_config_file =
sub { return $self->{'parsed_cfg'} };
my $driver = $self->{'driver'};
my $prefs_dlg = '<undef>';
$driver->add_event_loop_handler( sub { $prefs_dlg = $_[1] } );
Lire::UI::_lire_prefs_cb( $self->{'ui'}{'_ui'} );
$self->assert_isa( "Curses::UI::Window", $prefs_dlg );
my $prefs_ui = $prefs_dlg->userdata() || '<undef>';
$self->assert_isa( 'Lire::UI::Prefs', $prefs_ui );
}
sub test_store_new_cb_ok {
my $self = $_[0];
my $dlg = '<undef>';
$self->{'driver'}->add_event_loop_handler(
sub {
$dlg = $_[1];
$dlg->getobj('pathvalue')->text( $self->{'tmpdir'} );
$dlg->getobj('filevalue')->text( 'new_store' );
$dlg->getobj('buttons')->{'-selected'} = 0;
} );
Lire::UI::_store_new_cb( $self->{'ui'}{'_ui'} );
$self->assert_isa( 'Curses::UI::Dialog::Filebrowser', $dlg );
$self->assert( -d $self->{'tmpdir'} . '/new_store',
"'$self->{'tmpdir'}/new_store' not created" );
my $store_win = $self->{'driver'}->top_window();
$self->assert_str_equals( $self->{'driver'}->find_widget( '/store_win' ),
$store_win );
my $store = $store_win->store() || '<undef>';
$self->assert_isa( 'Lire::DlfStore', $store );
$self->assert_str_equals( "$self->{'tmpdir'}/new_store", $store->path() );
}
sub test_store_new_cb_error {
my $self = $_[0];
create_file( "$self->{'tmpdir'}/new_store", "" );
$self->{'driver'}->add_event_loop_handler(
sub {
my $dlg = $_[1];
$dlg->getobj('pathvalue')->text( $self->{'tmpdir'} );
$dlg->getobj('filevalue')->text( 'new_store' );
$dlg->getobj('buttons')->{'-selected'} = 0;
} );
# Acknowledge dialog
my $dlg = '<undef>';
$self->{'driver'}->add_event_loop_handler( sub { $dlg = $_[1] } );
Lire::UI::_store_new_cb( $self->{'ui'}{'_ui'} );
$self->assert_isa( "Curses::UI::Dialog::Error", $dlg );
$self->assert_matches( qr/Error creating store:\n can't create DLF/,
$dlg->{'-message'},);
}
sub test_store_new_cb_cancel {
my $self = $_[0];
my $dlg = '<undef>';
$self->{'driver'}->add_event_loop_handler(
sub {
$dlg = $_[1];
$dlg->getobj('pathvalue')->text( $self->{'tmpdir'} );
$dlg->getobj('filevalue')->text( 'new_store' );
$dlg->getobj('buttons')->{'-selected'} = 1;
} );
Lire::UI::_store_new_cb( $self->{'ui'}{'_ui'} );
$self->assert( ! -d $self->{'tmpdir'} . '/new_store',
"'$self->{'tmpdir'}/new_store' was created unexpectedly" );
$self->assert_str_equals($self->{'driver'}->find_widget('/quickstart_win'),
$self->{'driver'}->top_window() );
return;
}
sub test_store_open_cb_ok {
my $self = $_[0];
$self->{'store'}->close();
my $dlg = '<undef>';
$self->{'driver'}->add_event_loop_handler(
sub {
$dlg = $_[1];
$dlg->getobj('pathvalue')->text( $self->{'store'}->path() );
$dlg->getobj('buttons')->{'-selected'} = 0;
} );
Lire::UI::_store_open_cb( $self->{'ui'}{'_ui'} );
$self->assert_isa( 'Curses::UI::Dialog::Dirbrowser', $dlg );
my $store_win = $self->{'driver'}->top_window();
$self->assert_str_equals( $self->{'driver'}->find_widget( '/store_win' ),
$store_win );
my $store = $store_win->store() || '<undef>';
$self->assert_isa( 'Lire::DlfStore', $store );
$self->assert_str_equals( $self->{'store'}->path(), $store->path() );
}
sub test_store_open_cb_cancel {
my $self = $_[0];
$self->{'driver'}->add_event_loop_handler(
sub {
my $dlg = $_[1];
$dlg->getobj('pathvalue')->text( $self->{'store'}->path() );
$dlg->getobj('buttons')->{'-selected'} = 1;
} );
Lire::UI::_store_open_cb( $self->{'ui'}{'_ui'} );
$self->assert_str_equals($self->{'driver'}->find_widget('/quickstart_win'),
$self->{'driver'}->top_window() );
return;
}
sub test_store_open_cb_error {
my $self = $_[0];
create_file( "$self->{'tmpdir'}/new_store", "" );
$self->{'driver'}->add_event_loop_handler(
sub {
my $dlg = $_[1];
$dlg->getobj('pathvalue')->text( "$self->{'tmpdir'}/new_store" );
$dlg->getobj('buttons')->{'-selected'} = 0;
} );
# Acknowledge dialog
my $dlg = '<undef>';
$self->{'driver'}->add_event_loop_handler( sub { $dlg = $_[1] } );
Lire::UI::_store_open_cb( $self->{'ui'}{'_ui'} );
$self->assert_isa( "Curses::UI::Dialog::Error", $dlg );
$self->assert_matches( qr/Error opening store:\n DlfStore /,
$dlg->{'-message'},);
}
sub test_get_config_file {
my $self = $_[0];
local $ENV{'HOME'} = $self->{'tmpdir'};
my @files = ( $self->{'cfg_file'} );
my %parsed_files = ( $self->{'cfg_file'} => 'Success' );
no warnings 'redefine';
local *Lire::Test::HashConfig::config_files = sub { return @files };
local *Lire::Test::HashConfig::add_config_file =
sub { push @files, $_[1] };
local *Lire::Test::HashConfig::get_config_file =
sub { return $parsed_files{$_[1]} };
unlink $self->{'cfg_file'};
$self->assert_str_equals( 'Success', $self->{'ui'}->_get_config_file() );
$self->assert_deep_equals( [ $self->{'cfg_file'} ], \@files );
$self->assert( !-f $self->{'cfg_file'}, "'$self->{'cfg_file'}' shouldn't exists" );
@files = ();
$self->assert_str_equals( 'Success', $self->{'ui'}->_get_config_file() );
$self->assert_deep_equals( [ $self->{'cfg_file'} ], \@files );
$self->assert( -s $self->{'cfg_file'}, "empty '$self->{'cfg_file'}'" );
}
sub test_update_store_menu {
my $self = $_[0];
$self->{'ui'}->_update_store_menu( 1 );
my $store_menu = $self->{'driver'}->find_menu_def( 'menubar/Store' );
$self->assert_deep_equals( [ { '-label' => 'Close',
'-value' => \&Lire::UI::_store_close_cb } ],
$store_menu->{'-submenu'} );
$self->{'ui'}->_update_store_menu( 0 );
$self->assert_deep_equals( [ { '-label' => 'New...',
'-value' => \&Lire::UI::_store_new_cb },
{ '-label' => 'Open...',
'-value' => \&Lire::UI::_store_open_cb } ],
$store_menu->{'-submenu'} );
}
sub test_store_close_cb {
my $self = $_[0];
$self->{'ui'}->_open_store_window( $self->{'store'} );
Lire::UI::_store_close_cb( $self->{'ui'}{'_ui'} );
$self->assert_null( $self->{'ui'}{'_ui'}->getobj( 'store_win' ),
'store_win should be closed' );
$self->assert( $self->{'store'}->is_closed(),
'store should have been closed' );
my $menubar = $self->{'driver'}->find_widget( '/menubar' );
$self->assert_equals( 'New...',
$menubar->{'-menu'}[1]->{'-submenu'}[0]{'-label'} );
}
sub test_open_store_window {
my $self = $_[0];
$self->{'ui'}->_open_store_window( $self->{'store'} );
my $store_win = $self->{'driver'}->top_window();
$self->assert_str_equals( $self->{'driver'}->find_widget( '/store_win' ),
$store_win );
$self->assert_isa( 'Lire::UI::StoreWindow', $store_win );
my $store = $store_win->store() || '<undef>';
$self->assert_isa( 'Lire::DlfStore', $store );
my $menubar = $self->{'driver'}->find_widget( '/menubar' );
$self->assert_equals( 'Close',
$menubar->{'-menu'}[1]->{'-submenu'}[0]{'-label'} );
}
sub test_edit_value {
my $self = $_[0];
my $value = new Lire::Config::StringSpec( 'name' => 'string' )->instance();
my $ui = $self->{'ui'};
my $ok_sub = sub {
my $dialog = $_[1];
$self->assert_str_equals( 'My title', $dialog->title() );
my $widget = $dialog->getobj( 'widget' );
$self->assert_isa( 'Lire::UI::Widget', $widget );
$self->assert_str_equals( $value, $widget->{'value'} );
my $buttons = $dialog->getobj( 'buttons' );
$buttons->{'-buttons'}[1]{'-onpress'}->();
};
$self->{'driver'}->add_event_loop_handler( $ok_sub );
$self->assert_num_equals( 1, $ui->edit_value_dialog( $value,
'My title' ) );
my $cancel_sub = sub {
my $dialog = $_[1];
$self->assert_str_equals( 'Editing string', $dialog->title() );
my $buttons = $dialog->getobj( 'buttons' );
$buttons->{'-buttons'}[0]{'-onpress'}->();
};
$self->{'driver'}->add_event_loop_handler( $cancel_sub );
$self->assert_num_equals( 0, $ui->edit_value_dialog( $value ) );
return;
}
1;
syntax highlighted by Code2HTML, v. 0.9.1