package tests::ConfigCompoundSpecTest;

use strict;

use tests::ConfigSpecTest;

use base qw/tests::ConfigTypeSpecBase/;

sub test_new_is_array {
    my $self = $_[0];

    my $spec = $self->{'spec'};
    $self->assert_isa( 'Lire::Config::CompoundSpec', $spec );
    $self->assert_str_equals( 'ARRAY', ref $spec->{'components'} );
    $self->assert_str_equals( 'HASH', ref $spec->{'index'} );

    my $str_spec = new Lire::Config::StringSpec( 'name' => 'subspec1' );
    $spec->add( $str_spec );
    my $int_spec = new Lire::Config::IntegerSpec( 'name' => 'subspec2' );
    $spec->add( $int_spec );

    $self->assert_deep_equals( [ $str_spec, $int_spec ],
                               $spec->{'components'} );

    return;
}

sub test_add {
    my $self = $_[0];

    $self->assert_equals( 0, scalar $self->{'spec'}->components() );
    my $string = new Lire::Config::StringSpec( 'name' => "test" );
    $self->{'spec'}->add( $string );
    $self->assert_dies( qr/already contains a component named \'test\'/,
                        sub { $self->{'spec'}->add( $string ) } );
    $self->assert_str_equals( $string, $self->{'spec'}->get( 'test' ));
    $self->assert_num_equals( 0, $self->{'spec'}{'index'}{'test'} );

    my $int = new Lire::Config::IntegerSpec( 'name' => "int" );
    $self->{'spec'}->add( $int );
    $self->assert_str_equals( $int, $self->{'spec'}->get( "int" ) );
    $self->assert_num_equals( 1, $self->{'spec'}{'index'}{'int'} );

    $self->assert_dies( qr/missing \'type\' parameter/,
                        sub { $self->{'spec'}->add( undef ) } );

    $self->assert_dies( qr/\'type\' parameter should be a \'Lire::Config::TypeSpec\' instance, not \'Lire::Config::Scalar/,
                        sub {$self->{'spec'}->add( new Lire::Config::Scalar( 'spec' => $self->{'spec'} ) ) } );
}

sub test_label_component {
    my $self = $_[0];

    my $spec = $self->{'spec'};
    my $str_spec = new Lire::Config::StringSpec( 'name' => 'subspec1' );
    $spec->add( $str_spec );

    $spec->{'label'} = 'subspec1';
    $self->assert_str_equals( 'subspec1', $spec->label_component() );
    $spec->{'label'} = undef;
    $self->assert_null( $spec->label_component() );
    $spec->{'label'} = 'wawa';
    $self->assert_dies( qr/\'wawa\' component does not exist/,
                        sub { $spec->label_component() } );

    my $new_spec = new Lire::Config::CompoundSpec( 'name' => 'new_wawa',
                                                   'label' => 'subspec1' );
    $self->assert_dies( qr/\'subspec1\' component does not exist/,
                        sub { $new_spec->label_component() } );
    $new_spec->add( $str_spec );
    $self->assert_str_equals( 'subspec1', $new_spec->label_component() );

    return;
}

sub test_has_component {
    my $self = $_[0];

    my $spec = $self->{'spec'};
    my $string = new Lire::Config::StringSpec( 'name' => 'test_str' );
    $self->{'spec'}->add( $string );
    my $integer = new Lire::Config::IntegerSpec( 'name' => 'test_int' );
    $self->{'spec'}->add( $integer );

    $self->assert( $spec->has_component( 'test_str' ) );
    $self->assert( $spec->has_component( 'test_int' ) );
    $self->assert( ! $spec->has_component( 'wawa' ) );
    $self->assert_dies( qr/missing \'name\' parameter/,
                        sub { $spec->has_component() } );
}

sub test_components {
    my $self = $_[0];

    my $spec = $self->{'spec'};
    $self->assert_num_equals( 0, scalar $spec->components() );
    my $string = new Lire::Config::StringSpec( 'name' => 'test_str' );
    $self->{'spec'}->add( $string );
    $self->assert_num_equals( 1, scalar $spec->components() );
    my $integer = new Lire::Config::IntegerSpec( 'name' => 'test_int' );
    $self->{'spec'}->add( $integer );
    $self->assert_num_equals( 2, scalar $spec->components() );

    $self->assert_deep_equals( [ $string, $integer ],
                               [ $spec->components() ] );
    $self->assert_num_equals( 0, $spec->{'index'}{'test_str'} );
    $self->assert_num_equals( 1, $spec->{'index'}{'test_int'} );
    $self->assert_str_equals( $integer,
                              $spec->{'components'}[ $spec->{'index'}{'test_int'} ] );
}

sub test_get {
    my $self = $_[0];

    $self->assert_dies( qr/missing \'name\' parameter/,
                        sub { $self->{'spec'}->get( undef ) } );
    $self->assert_dies( qr/invalid \'name\' parameter: \'\'/,
                        sub { $self->{'spec'}->get( '' ) } );
    $self->assert_dies( qr/invalid \'name\' parameter: \'\$%\'/,
                        sub { $self->{'spec'}->get( '$%' ) } );

    $self->assert_dies( qr/no component named \'param\'/,
                        sub { $self->{'spec'}->get( 'param' ) } );
}

sub type {
    return "Lire::Config::CompoundSpec";
}

1;


syntax highlighted by Code2HTML, v. 0.9.1