Модуль Moose с ошибками, нужна помощь в поиске причины - PullRequest
1 голос
/ 12 февраля 2011

Я пытаюсь реорганизовать свои тесты для Dist :: Zilla :: Plugin :: Catalyst , чтобы он был более СУХИМ, пытаюсь использовать Moose для этой задачи, но у меня возникают проблемы, ина всю жизнь я не могу понять, что это такое, некоторые из них, похоже, были проблемами инициализации заказа.

примечание: код, вероятно, не самый лучший, предложения приветствуются

t / 01-PluginCatalystNew.t ....... Не удается вызвать метод "subdir" для неопределенного значения в /home/xenoterracide/projects/Dist-Zilla-Plugin-Catalyst/.build/8kE7QQR_FL / t / lib / DZPCshared.pm строка 26.

Вот модуль Moose,

use strict;
use warnings;
package DZPCshared;
use Path::Class;
use Moose;
use namespace::autoclean;

has 'appname' => (
    is       => 'ro',
    required => 1,
);

has 'tempdir' => (
    is       => 'ro',
    required => 1,
);

has 'directories' => (
    isa      => 'ArrayRef[Str]',
    traits   => ['Array'],
    is       => 'ro',
    required => 1,
    lazy     => 1,
    default  => sub {
        my $self = shift;
        my $mr   = dir( $self->tempdir )->subdir('mint');
        my $mrl  = $mr->subdir('lib');
        my $mrr  = $mr->subdir('root');
        my $mrs  = $mr->subdir('script');
        my $mrt  = $mr->subdir('t');
        my $mrri = $mr->subdir('root')->subdir('static')->subdir('images');
        return my $directories = [ $mr, $mrl, $mrr, $mrs, $mrt, $mrri ];
    },
);

has 'scripts' => (
    isa      => 'ArrayRef[Str]',
    traits   => ['Array'],
    is       => 'ro',
    default  => sub {
        my $self = shift;
        my ( $mr, $mrl, $mrr, $mrs, $mrt, $mrri ) = @{ $self->directories };
        my $lc_app = lc $self->appname;
        return my $scripts = [
            $mrs->file  ( $lc_app . '_cgi.pl'     ),
            $mrs->file  ( $lc_app . '_create.pl'  ),
            $mrs->file  ( $lc_app . '_fastcgi.pl' ),
            $mrs->file  ( $lc_app . '_server.pl'  ),
            $mrs->file  ( $lc_app . '_test.pl'    ),
        ];
    },
);

has 'files' => (
    isa      => 'ArrayRef[Str]',
    traits   => ['Array'],
    is       => 'ro',
    default  => sub {
        my $self = shift;
        my ( $mr, $mrl, $mrr, $mrs, $mrt, $mrri ) = @{ $self->directories };
        my $lc_app = lc $self->appname;
        return my $files = [
            $mr->file   ( $lc_app . '.conf'               ),
            $mrl->file  ( $self->app_name . '.pm'               ),
            $mrl->subdir( $self->app_name )->subdir('Controller')->file('Root.pm'),
            $mrr->file  ( 'favicon.ico'                   ),
            $mrri->file ( 'btn_120x50_built.png'          ),
            $mrri->file ( 'btn_120x50_built_shadow.png'   ),
            $mrri->file ( 'btn_120x50_powered.png'        ),
            $mrri->file ( 'btn_120x50_powered_shadow.png' ),
            $mrri->file ( 'btn_88x31_built.png'           ),
            $mrri->file ( 'btn_88x31_built_shadow.png'    ),
            $mrri->file ( 'btn_88x31_powered.png'         ),
            $mrri->file ( 'btn_88x31_powered_shadow.png'  ),
            $mrri->file ( 'catalyst_logo.png'             ),
            $mrt->file  ( '01app.t'                       ),
        ];
    },
);

__PACKAGE__->meta->make_immutable;
1;

и тест

#!/usr/bin/perl
use strict;
use warnings;
use Test::More;

if ( $Moose::VERSION >= 1.9902 and $Moose::VERSION < 2.0 ) {
    plan skip_all => 'Module is broken on Devel Moose, don\'t test';
}

use Dist::Zilla::Tester;
use Path::Class;
use FindBin;
use lib "$FindBin::Bin/lib";
use DZPCshared;

my $tzil = Minter->_new_from_profile(
    [ Default => 'default' ],
    { name => 'CatApp' },
    { global_config_root => dir('corpus/mint')->absolute },
);

$tzil->mint_dist;

my $dzpcs = DZPCshared->new({
    appname => $tzil->name,
    tempdir => $tzil->tempdir,
});

subtest 'catalyst files exist' => sub {
    my $should_exists = [ @{$dzpcs->files}, @{$dzpcs->scripts} ];

    foreach ( @{$should_exists} ) {
        ok  ( -e $_ , "$_" . ' exists' );
    }
};

subtest 'catalyst scripts should be executable' => sub {
    plan skip_all => 'skip failing executable tests on windows' if $^O eq 'MSWin32';
    my $should_exec = @{$dzpcs->scripts};

    foreach ( @{$should_exec} ) {
        ok  ( -x $_ , "$_" . ' exists' );
    }
};
done_testing;

(примечание:ps не уверен, что в этом возможен минимальный тестовый пример)

(примечание: также предыдущая версия работала)

1 Ответ

5 голосов
/ 12 февраля 2011

Я немного поиграл с вашим кодом - у вас ленивый атрибут directories, используемый в не ленивых атрибутах default.Из-за этого по умолчанию directories вызывается до полной сборки экземпляра.Таким образом, $self->tempdir в строке 26 равно undef, и вы получили сообщение об ошибке.

Я сделал атрибуты scripts и files ленивыми и, похоже, работает (он выдает ошибку проверки в каталогах - у вас естьArrayRef[Str], но вместо этого создайте ArrayRef[Path::Class::Dir] - но это не связано с вашей текущей проблемой).

...