package tests::ConfigTest; use strict; use base qw/ Lire::Test::TestCase/; use Lire::Config; use Lire::Config::Build qw/ ac_path /; use Lire::Utils qw/tilde_expand tempdir/; use File::Path qw/mkpath/; sub new { my $self = shift()->SUPER::new( @_ ); $self->{'tmpdir'} = tempdir( "config_XXXXXX", 'CLEANUP' => 1 ); $self->{'confdir'} = "$self->{'tmpdir'}/config"; mkdir $self->{'confdir'} or $self->error( "mkdir $self->{'confdir'} failed: $!" ); $self->{'specdir'} = "$self->{'tmpdir'}/specs"; mkdir $self->{'specdir'} or $self->error( "mkdir $self->{'specdir'} failed: $!" ); $self->_make_config_spec; $self->_make_main_config_file; $self->_make_override_config_file; $self; } sub _make_config_spec { my $self = $_[0]; my $fh; open $fh, "> $self->{'specdir'}/spec.xml" or $self->error( "open of $self->{'specdir'}/spec.xml failed: $!" ); print $fh < SPEC close $fh; } sub _make_main_config_file { my $self = $_[0]; my $fh; $self->{'main_config_file'} = "$self->{'confdir'}/main.xml"; open $fh, "> $self->{'main_config_file'}" or $self->error( "open of $self->{'main_config_file'} failed: $!\n" ); print $fh < $self->{'tmpdir'} yes $self->{'tmpdir'}/nodir $self->{'main_config_file'} $self->{'tmpdir'}/no_such_file /bin/sh $self->{'tmpdir'}/main.xml string 1 string 2 512 $self->{'tmpdir'}/specs $self->{'tmpdir'}/nosuchdir txt option 3 main/global main/global CONFIG close $fh; } sub _make_override_config_file { my $self = $_[0]; my $fh; # must not be placed in $self->{'confdir'} $self->{'override_config_file'} = "$self->{'tmpdir'}/override.xml"; open $fh, "> $self->{'override_config_file'}" or $self->error( "open of $self->{'override_config_file'} failed: $!\n"); print $fh < 1024 option_2 override/global override/global OVERRIDE close $fh; } sub set_up { my $self = $_[0]; # Since Lire::Test::TestCase::set_up messes with Lire::Config, # we don't chain up. return; } sub tear_down { my $self = $_[0]; return; } sub test_instance { my $self = $_[0]; my $cfg = Lire::Config->instance; $self->assert_not_null( $cfg, "instance() returned undef" ); $self->assert( $cfg->isa( 'Lire::Config'), "is not a Lire::Config object"); } sub test_old_config_api { my $self = $_[0]; Lire::Config->init_vars(); foreach my $varname ( qw/VERSION/ ) { no strict 'refs'; my $var = "Lire::Config::$varname"; $self->assert_not_null( ${$var}, "$var is undef" ); } } sub test_config_files { my $self = $_[0]; my @files = Lire::Config->config_files(); my $cfg = Lire::Config->instance(); $cfg->add_config_file( $self->{'main_config_file'} ); my @new_files = $cfg->config_files(); $self->assert( scalar @new_files == @files + 1, "config_files() doesn't contain one more entry" ); $self->assert_equals( $self->{'main_config_file'}, $new_files[-1] ); Lire::Config->del_config_file( $self->{'main_config_file'} ); @new_files = $cfg->config_files(); $self->assert_deep_equals( \@files, \@new_files ); $cfg->add_config_path( $self->{'confdir'} ); @new_files = $cfg->config_files(); $self->assert( scalar @new_files == 1 + scalar @files, "config_files() doesn't contain one more entry" ); $self->assert_equals( $self->{'main_config_file'}, $new_files[@new_files-1] ); Lire::Config->del_config_file( $self->{'main_config_file'} ); @new_files = $cfg->config_files; $self->assert_deep_equals( \@files, \@new_files ); } sub test_config_spec_path { my ( $self ) = @_; my @path = Lire::Config->config_spec_path; my $or_dir_count = @path; $self->assert_not_null( \@path, "config_spec_path returned undef" ); my $tmpdir = tempdir( "ConfigTest_XXXXXX", 'CLEANUP' => 1 ); Lire::Config->add_config_spec_path_dir( $tmpdir ); my @new_path = Lire::Config->config_spec_path; my $new_dir_count = @new_path; $self->assert( $new_dir_count == $or_dir_count + 1, "config_spec_path doesn't contain one more entry" ); $self->assert( grep { $_ eq $tmpdir } @new_path, "config_spec_path doesn't contain new entry" ); Lire::Config->del_config_spec_path_dir( $tmpdir ); @new_path = Lire::Config->config_spec_path; $self->assert_deep_equals( \@path, \@new_path ); } sub _set_up_config_files { my ( $self, $cfg ) = @_; foreach my $f ( $cfg->config_files ) { $cfg->del_config_file( $f ); } $cfg->add_config_file( $self->{'main_config_file'} ); foreach my $d ( $cfg->config_spec_path ) { $cfg->del_config_spec_path_dir( $d ); } $cfg->add_config_spec_path_dir( $self->{'specdir'} ); } sub test_init { my $self = $_[0]; my $cfg = new Lire::Config::XMLFilesConfig(); $self->_set_up_config_files( $cfg ); eval { $cfg->get( "dir_var" ) }; $self->assert_not_null( $@, "get() before init() should throw an exception" ); my $warnings = 0; local $SIG{'__WARN__'} = sub { $warnings++ }; $cfg->init; $self->assert_equals( 0, $warnings ); $self->assert_equals( $self->{'tmpdir'}, $cfg->get( 'dir_var' ) ); $self->assert_equals( 1, $cfg->get( 'bool_var' ) ); $self->assert_null( scalar $cfg->get( "bad_dir_var" ), "invalid directory passed check" ); $self->assert_equals( $self->{'main_config_file'}, $cfg->get( 'file_var' ) ); $self->assert_null( scalar $cfg->get( "bad_file_var" ), "invalid file passed check" ); $self->assert_equals( "/bin/sh", $cfg->get( 'exe_var' ) ); $self->assert_null( scalar $cfg->get( "bad_exe_var" ), "invalid executable passed check" ); $self->assert_deep_equals( [ "string 1", "string 2" ], $cfg->get( 'list_var' ) ); $self->assert_equals( 512, $cfg->get( "int_var") ); $self->assert_deep_equals( [ $self->{'specdir'} ], $cfg->get( "list_of_dirs" ), ); $self->assert_equals( "txt", $cfg->get( "output_format" ) ); $self->assert_null( scalar $cfg->get( "wrong_select" ), "select option with invalid option didn't return undef" ); $cfg->add_config_file( $self->{'override_config_file'} ); $self->assert_equals( 1024, $cfg->get( "int_var" ) ); $self->assert_equals( "option_2", $cfg->get( "wrong_select" ) ); $cfg->del_config_file( $self->{'override_config_file'} ); $self->assert_equals( 512, $cfg->get( "int_var" ) ); $self->assert_null( scalar $cfg->get( "wrong_select" ), "select option with invalid option didn't return undef" ); } sub test_get_var { my $self = $_[0]; my $cfg = new Lire::Config::XMLFilesConfig(); $self->_set_up_config_files( $cfg ); $self->assert_died( sub { $cfg->get_var( 'dir_var' ) }, qr/Configuration queried without/ ); { local $SIG{'__WARN__'} = sub {}; $cfg->init; } $self->assert_died( sub { $cfg->get_var( 'no_such_var') }, qr/No such configuration variable/ ); my $var = $cfg->get_var( 'dir_var' ); $self->assert_not_null( $var, "get_var() returned null" ); $self->assert( UNIVERSAL::isa( $var, 'Lire::Config::Scalar'), "get_var() returned wrong type" ); $self->assert_equals( $self->{'tmpdir'}, $var->as_value ); $self->assert_str_equals( $cfg->{'_defaults'}->get( 'missing_var' ), $cfg->get_var( 'missing_var' ) ); } 1;