package tests::I18NTest;

use strict;

use base qw/ Lire::Test::TestCase tests::TestStoreFixture /;

use Lire::I18N qw/ set_fh_encoding ensure_utf8 ensure_local_codeset
                   local_codeset mark_unicode dgettext dgettext_para  /;

use File::Temp qw/ tempfile /;
use Config;
use POSIX qw/ setlocale LC_MESSAGES LC_CTYPE /;
use Lire::Utils qw/file_content/;

sub new {
    my $self = shift()->SUPER::new( @_ );

    $self->init();
    $self->init_i18n();
    eval {
        require 5.8.0;
        die "no PerlIO" unless $Config{'useperlio'};

        require Encode;
        Encode->import( qw/ is_utf8 _utf8_off / );
    };
    $self->{'encode_support'} = ! $@;
    $self->{'latin1str'} = 'test accentué';
    $self->{'utf8str'} = 'test accentué';

    return $self;
}

sub set_up {
    my $self = shift->SUPER::set_up();

    $self->{'_old_ctypes'} = setlocale( LC_CTYPE );
    $self->set_up_locale();
    setlocale( LC_CTYPE, 'fr_CA.ISO-8859-1' );
    ( $self->{'tmp_fh'}, $self->{'tmp_filename'} ) = tempfile();

    return $self;
}

sub tear_down {
    my $self = shift->SUPER::tear_down();

    $self->tear_down_locale();
    unlink( $self->{'tmp_filename'} );

    setlocale( LC_CTYPE, $self->{'_old_ctypes'} )
      if $self->{'_old_ctypes'};

    return $self;
}

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

    $self->assert_equals( $self->{'encode_support'}, 
                          $Lire::I18N::USE_ENCODING );
}

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

    return unless $self->{'encode_support'};

    my $fh = $self->{'tmp_fh'};
    $self->assert_died( sub { set_fh_encoding() },
                        qr/missing 'fh' parameter/ );
    $self->assert_died( sub { set_fh_encoding( $fh ) },
                        qr/missing 'encoding' parameter/ );

    {
        local $SIG{__WARN__} = sub { $self->annotate( $@ ) };
        $self->assert_died( sub { set_fh_encoding( $fh, 'wawa' ) },
                            qr/error setting encoding on FH:/ );
    }

    set_fh_encoding( $fh, 'utf8' );
    print $fh $self->{'latin1str'};
    close $fh;

    $self->assert_str_equals( $self->{'utf8str'},
                              file_content( $self->{'tmp_filename'} ) );

    setlocale( LC_CTYPE, 'fr_CA.utf-8' );
    open( $fh, "> $self->{'tmp_filename'}" )
      or $self->error( "can't write to write $self->{'tmp_filename'}: $!" );
    set_fh_encoding( $fh, 'utf8' );
    print $fh $self->{'utf8str'};
    close $fh;

    $self->assert_str_equals( $self->{'utf8str'},
                              file_content( $self->{'tmp_filename'} ) );
}

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

    $self->assert_str_equals( 'iso-8859-1', local_codeset() );
    setlocale( LC_CTYPE, 'fr_CA.UTF8' );
    $self->assert_str_equals( 'utf8', local_codeset() );
}

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

    local $Lire::I18N::USE_ENCODING = 0;

    my $fh = $self->{'tmp_fh'};
    set_fh_encoding( $fh, 'utf8' );
    print $fh $self->{'latin1str'};
    close $fh;

    $self->assert_str_equals( $self->{'latin1str'},
                              file_content( $self->{'tmp_filename'} ) );
}

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

    return unless $self->{'encode_support'};

    my $iso_string = ensure_utf8( "cha\x{ee}ne iso accentu\x{e9}e" );
    my $uni_string = ensure_utf8( "unicode string: \x{0100} (A bar)" );

    $self->assert( is_utf8( $iso_string ),
                   "\$iso_string not marked as utf-8" );
    $self->assert( is_utf8( $uni_string ),
                   "\$uni_string not marked as utf-8" );

    _utf8_off( $iso_string );
    $self->assert_str_equals( "cha\x{c3}\x{ae}ne iso accentu\x{c3}\x{a9}e",
                              $iso_string );
    _utf8_off( $uni_string );
    $self->assert_str_equals( "unicode string: \x{c4}\x{80} (A bar)",
                              $uni_string );

    setlocale( LC_CTYPE, 'fr_CA.UTF-8' );
    my $string = ensure_utf8( $self->{'utf8str'} );
    $self->assert( is_utf8( $string ), 'string should be utf8' );
    _utf8_off( $string );
    $self->assert_str_equals( $self->{'utf8str'}, $string );
}

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

    local $Lire::I18N::USE_ENCODING = 0;

    my @warnings =();
    local $SIG{__WARN__} = sub { push @warnings, @_ };
    $self->assert_null( ensure_utf8( undef ),
                        "ensure_utf8( undef) returned non-undef" );
    $self->annotate( join( "\n", @warnings) );
    $self->assert_equals( 0, scalar @warnings );

    my $iso_string = ensure_utf8( "cha\x{ee}ne iso accentu\x{e9}e" );
    my $uni_string = ensure_utf8( "unicode string: \x{0100} (A bar)" );

    $self->assert_str_equals( "Eacute: ?", ensure_utf8( "Eacute: \xe9" ) );
    $self->assert_str_equals( "cha?ne iso accentu?e", $iso_string );
    $self->assert_str_equals( "unicode string: ? (A bar)", $uni_string );
}

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

    return unless $self->{'encode_support'};

    my $uni_string = ensure_utf8( "Caractères accentués." );
    $self->assert( is_utf8( $uni_string ),
                   "\$uni_string not marked as utf-8" );
    $self->assert_str_equals( "Caractères accentués.", $uni_string );

    my $s = ensure_local_codeset( $uni_string );
    $self->assert( !is_utf8( $s ), "\$s  marked as utf-8" );
    $self->assert_str_equals( "Caractères accentués.", $s );

    $s = ensure_local_codeset( $s );
    $self->assert_str_equals( "Caractères accentués.", $s );
}

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

    return unless $self->{'encode_support'};
    my $uni_string = ensure_utf8( "Caractères accentués." );

    my $s = dgettext( 'lire-test', $uni_string );
    $self->assert_str_equals( "Caractères accentués.", $s );
}

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

    return unless $self->{'encode_support'};

    my $byte_string = "cha\x{c3}\x{ae}ne iso accentu\x{c3}\x{a9}e";
    $self->assert( !is_utf8( $byte_string ),
                   "\$byte_string marked as utf-8" );

    my $uni_string = mark_unicode( $byte_string );
    $self->assert( is_utf8( $uni_string ),
                   "\$byte_string not marked as utf-8" );
    $self->assert_str_equals( "cha\x{ee}ne iso accentu\x{e9}e",
                              $uni_string );
}

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

    local $Lire::I18N::USE_ENCODING = 0;

    my $byte_string = "cha\x{c3}\x{ae}ne iso accentu\x{c3}\x{a9}e";
    # 22 bytes, 20 characters
    $self->assert_equals( 22, length( $byte_string) );

    my $uni_string = mark_unicode( $byte_string );
    $self->assert_str_equals( $byte_string, $uni_string );

}

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

    no warnings 'redefine';
    my $domain;
    my $string;
    my $old_dgettext = \&Lire::I18N::dgettext;
    my $dgettext = sub { $domain = shift; $string = "@_";
                         return $old_dgettext->( $domain, $string ); };
    local *Lire::I18N::dgettext = $dgettext;

    $self->assert_null( dgettext_para( 'lire-test', undef ) ,
                        'dgettext_para should have returned undef' );

    $self->assert_str_equals( '  <para>JPEG Files</para>',
                              dgettext_para( 'lire-test',
                                             '  <para>JPEG Files</para>' ) );
    $self->assert_str_equals( "JPEG Files",
                              dgettext_para( 'lire-test',
                                             "JPEG Files" ) );

    $self->assert_str_equals( "\n   <para>Connection identifier.\n</para>  \n  ",
                              dgettext_para( 'lire-test',
                                             "\n   <para>Connection identifier.\n</para>  \n  ",
                                              ) );

    setlocale( LC_MESSAGES, 'fr_CA.iso8859-1' );
    dgettext_para( 'lire-test', "  <para>  Wawa files  </para>  \n" );
    $self->assert_str_equals( 'Wawa files', $string );

    $self->assert_str_equals( "\n  <para>Fichiers JPEG</para>  \n",
                              dgettext_para( 'lire-test',
                                             "\n  <para>JPEG Files</para>  \n" ) );
    $self->assert_str_equals( "Fichiers JPEG",
                              dgettext_para( 'lire-test', "JPEG Files" ) );

    return;
}

1;


syntax highlighted by Code2HTML, v. 0.9.1