package tests::ConfigReferenceSpecTest;

use strict;

use tests::ConfigSpecTest;

use base qw/tests::ConfigSelectSpecTest/;

use Lire::Config::TypeSpec;
use Lire::Config::ReferenceSpec;
use Lire::Config::Index;
use Lire::Test::Mock;

sub set_up {
    my $self = $_[0];
    $self->tests::ConfigScalarSpecTest::set_up();

    $self->{'_old_index_reg'} = \%Lire::Config::Index::REGISTRY;
    %Lire::Config::Index::REGISTRY = ();

    my %index = ( 'test1' => 'My Test 1',
                  'test2' => 'My Test 2' );
    my $index = new Lire::Test::Mock( 'Lire::Config::Index',
                                      'entries' => [ sort keys %index ],
                                      'has_entry' => sub { defined $index{$_[1]} },
                                      'get_ref' => sub {  $index{$_[1]} }
                                    );
    Lire::Config::Index->set_index( 'my_index', $index );

    return;
}

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

    *Lire::Config::Index::REGISTRY = $self->{'_old_index_reg'};

    $self->SUPER::tear_down();
    $self->tear_down_locale();

    return;
}

sub type {
    return 'Lire::Config::ReferenceSpec';
}

sub additional_new_params {
    return ( 'index' => 'my_index' );
}

sub normalize_test_data {
    return (
            'test1' => "test1",
            'Test2' => undef,
           );
}

sub valid_test_data {
    return qw/ test1 test2 /;
}

sub invalid_test_data {
    return qw/ test3 /;
}

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

    $self->assert_dies( qr/Lire::Config::ReferenceSpec cannot contain any components/,
                        sub { $self->{'spec'}->add() } );
}

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

    $self->SUPER::test_normalize();
}

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

    $self->SUPER::test_is_valid();
}

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

    my @options = $self->{'spec'}->options();

    $self->assert_num_equals( 2, scalar( @options ) );
    $self->assert_isa( 'Lire::Config::OptionSpec', $options[0] );
    $self->assert_deep_equals( [ 'test1', 'test2' ],
                               [ map { $_->name() } @options ] );

    Lire::Config::Index->set_index( 'my_index', undef );
    @options = $self->{'spec'}->options();
    $self->assert_num_equals( 0, scalar @options );
}

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

    my $value = $self->{'spec'}->instance();
    $self->assert_null( $value->as_value() );
    $value->set( 'test3' );
    $self->assert_null( $value->as_value() );

    $value->set( 'test1' );
    $self->assert_str_equals( 'My Test 1', $value->as_value() );
    $value->set( 'test2' );
    $self->assert_str_equals( 'My Test 2', $value->as_value() );

    Lire::Config::Index->set_index( 'my_index', undef );
    $self->assert_null( $value->as_value() );
}

1;


syntax highlighted by Code2HTML, v. 0.9.1