package tests::ConfigParserTest; use strict; use base qw/ Lire::Test::TestCase /; use Lire::Config::Value; use Lire::Config::Parser; use Lire::Config::TypeSpec; use Lire::Config::Dictionary; use Lire::Config::Plugin; use Lire::Utils qw/tempdir create_file /; use Lire::Test::Mock; sub new { my $self = shift()->SUPER::new( @_ ); $self->{'tmpdir'} = tempdir( "config_XXXXXX", 'CLEANUP' => 1 ); my $spec = $self->{'other_spec'} = new Lire::Config::ConfigSpec(); my $plugin = new Lire::Config::PluginSpec( 'name' => 'plugin' ); $spec->add( $plugin ); $plugin->add( new Lire::Config::OptionSpec( 'name' => 'option_1' ) ); $spec->add( new Lire::Config::RecordSpec( 'name' => 'option_1_properties') ); return $self; } sub set_up_config_spec { my $self = $_[0]; my $spec = $self->{'config_spec'} = new Lire::Config::ConfigSpec(); $spec->add( new Lire::Config::BooleanSpec( 'name' => 'bool_param' ) ); $spec->add( new Lire::Config::IntegerSpec( 'name' => 'int_param' ) ); $spec->add( new Lire::Config::DirectorySpec( 'name' => 'dir_param' ) ); $spec->get( 'dir_param' )->default( $spec->get( 'dir_param' )->instance( 'value' => '/a_dir' ) ); $spec->add( new Lire::Config::ExecutableSpec( 'name' => 'executable_param' ) ); $spec->add( new Lire::Config::FileSpec( 'name' => 'file_param' ) ); $spec->add( new Lire::Config::SelectSpec( 'name' => 'select_param' ) ); my $select_param = $spec->get( 'select_param' ); $select_param->add( new Lire::Config::OptionSpec( 'name' => 'option_1' ) ); $select_param->add( new Lire::Config::OptionSpec( 'name' => 'option_2' ) ); $spec->add( new Lire::Config::ListSpec( 'name' => 'list_param' ) ); $spec->get( 'list_param' )->add( new Lire::Config::StringSpec( 'name' => 'string_param' ) ); # Make sure that value overrides the default my $list_default = $spec->get( 'list_param' )->instance(); $list_default->append( $list_default->spec()->get( 'string_param' )->instance( 'value' => 'Default' ) ); $spec->get( 'list_param' )->default( $list_default ); $spec->add( new Lire::Config::PluginSpec( 'name' => 'plugin_param' ) ); my $plugin_param = $spec->get( 'plugin_param' ); $plugin_param->add( new Lire::Config::OptionSpec( 'name' => 'option_1' ) ); $plugin_param->add( new Lire::Config::OptionSpec( 'name' => 'option_2' ) ); $spec->add( new Lire::Config::RecordSpec( 'name' => 'option_2_properties' ) ); $spec->get( 'option_2_properties' )->add( new Lire::Config::IntegerSpec( 'name' => 'option_2_int' ) ); } sub set_up_config { my $self = $_[0]; $self->{'config_file'} = "$self->{'tmpdir'}/config.xml"; create_file( $self->{'config_file'}, < yes $self->{'config_file'} $self->{'tmpdir'} /bin/sh string1 string2 < a long string with an entity option_2 CONFIG } sub _build_expected_config { my $self = $_[0]; my $spec = $self->{'config_spec'}; my $cfg = new Lire::Config::ConfigFile( 'spec' => $spec, 'filename' => $self->{'config_file'}, ); my $global = $self->{'config_spec'}->instance(); $cfg->global( $global ); $global->set( $spec->get( "bool_param" )->instance( 'value' => "yes" )); $global->set( $spec->get( "int_param" )->instance( 'value' => 10 )); $global->set( $spec->get( "dir_param" )->instance( 'value' => $self->{'tmpdir'} )); $global->set( $spec->get( "file_param" )->instance( 'value' => $self->{'config_file'} )); $global->set( $spec->get( "executable_param" )->instance( 'value' => "/bin/sh" )); $global->set( $spec->get( "select_param" )->instance( 'value' => "option_2" )); my $list_spec = $spec->get( 'list_param' ); my $list = $list_spec->instance(); $list->clear(); $global->set( $list ); $list->append( $list_spec->get( "string_param" )->instance( 'value' => "string1" )); $list->append( $list_spec->get( "string_param" )->instance( 'value' => "string2 < a long string with an entity" )); $global->set( $spec->get( "plugin_param" )->instance( 'value' => "option_2" )); $global->get( 'plugin_param' )->set_plugin( 'option_2' ); $global->get( 'plugin_param' )->set( $spec->get( 'option_2_properties' )->get( 'option_2_int' )->instance( 'value' => 10 )); return $cfg; } sub set_up { my $self = $_[0]; $self->SUPER::set_up(); $self->{'cfg'}{'_lr_config_spec'} = $self->{'other_spec'}; return; } sub tear_down { my $self = $_[0]; $self->SUPER::tear_down(); return; } sub test_new { my $self = $_[0]; my $spec = new Lire::Config::ConfigSpec(); my $parser = new Lire::Config::Parser( 'spec' => $spec ); $self->assert_isa( 'Lire::Config::Parser', $parser ); $self->assert_str_equals( $spec, $parser->{'spec'} ); } sub test_load_config_file { my $self = $_[0]; $self->set_up_config_spec(); $self->{'cfg'}{'_lr_config_spec'} = $self->{'config_spec'}; $self->set_up_config(); my $parser = new Lire::Config::Parser( 'spec' => $self->{'config_spec'} ); my $conf = $parser->load_config_file( "$self->{'config_file'}" ); $self->assert_not_null( $conf, "load_config_file() returned undef" ); $self->assert_deep_equals( $self->_build_expected_config(), $conf ); } sub test_param_start_plugin { my $self = $_[0]; my $parser = new_proxy Lire::Test::Mock( 'Lire::Config::Parser', 'spec' => $self->{'other_spec'} ); $parser->set_result( 'depth', 0 ); $parser->init_stack( 'config_spec' ); $parser->init_stack( 'config_value' ); $parser->stack_push( 'config_value', $self->{'other_spec'}->instance() ); $parser->stack_push( 'config_spec', $self->{'other_spec'} ); $parser->param_start( 'param', { 'name' => 'plugin' , 'value' => 'option_1' } ); $self->assert_str_equals( $self->{'other_spec'}->get( 'option_1_properties' ), $parser->stack_peek( 'config_spec' ) ); $self->assert_deep_equals( $self->{'other_spec'}->get( 'plugin' )->instance( 'value' => 'option_1' ), $parser->stack_peek( 'config_value' ) ); } 1;