Perl: насмешливый -d -f и друзья. Как поместить их в CORE :: GLOBAL - PullRequest
12 голосов
/ 23 декабря 2009

Документация CORE показала мне, как весело высмеивать различные встроенные функции Perl. Тем не менее, я не совсем уверен, как заменить '-d' & c. с моими методами. Так что на самом деле это просто вопрос о том, как заменить функцию с дефисом в CORE :: GLOBAL.

Было бы неплохо справочное руководство.

package Testing::MockDir;

use strict;
use warnings;
use Exporter();
use Symbol 'qualify_to_ref';

*import = \&Exporter::import;

our @EXPORT_OK = qw(SetMockDir UnsetMockDir);

our %EXPORT_TAGS = (
    'all' => \@EXPORT_OK,
);

my %path2List = ();
my %handle2List = ();

BEGIN {
    *CORE::GLOBAL::opendir = \&Testing::MockDir::opendir;
    *CORE::GLOBAL::readdir = \&Testing::MockDir::readdir;
    *CORE::GLOBAL::closedir = \&Testing::MockDir::closedir;

    ######################### the "-" is really the problem here
    *CORE::GLOBAL::-d = \&Testing::MockDir::mock_d; # This does not work <<<<<
}

sub mock_d ($) {
    die 'It worked';
}

sub SetMockDir {
    my ($path, @files) = @_;
    $path2List{$path} = [@files];
}

sub UnsetMockDir {
    my ($path) = @_;
    delete $path2List{$path};
}

sub opendir (*$) {
    my $handle = qualify_to_ref(shift, caller);
    my ($path) = @_;
    return CORE::opendir($handle, $path) unless defined $path2List{$path};
    $handle2List{$handle} = $path2List{$path};
    return 1;
}

sub readdir (*) {
    my $handle = qualify_to_ref(shift, caller);
    return CORE::readdir($handle) unless defined $handle2List{$handle};
    return shift @{$handle2List{$handle}} unless wantarray;

    my @files = @{$handle2List{$handle}};
    $handle2List{$handle} = [];
    return @files;
}

sub closedir (*) {
    my $handle = qualify_to_ref(shift, caller);
    return CORE::closedir($handle) unless defined $handle2List{$handle};
    delete $handle2List{$handle};
    return 1;
}

1;

Ответы [ 5 ]

12 голосов
/ 24 декабря 2009

CORE :: GLOBAL не работает на вещах без прототипов. Единственный способ, которым я могу подумать, это переписать дерево кодов операций ... что не для слабонервных. Вы можете выполнить это с комбинацией B :: Utils и B :: Generate и большим количеством экспериментов.

Самое простое, что можно сделать, это использовать File :: Temp , чтобы создать временную структуру каталогов на свой вкус.

7 голосов
/ 23 декабря 2009

Это может быть невозможно. Раздел perlsub в Переопределение встроенных функций неясно, какие функции могут быть переопределены. «Многие» могут, «некоторые» не могут, но кроме нескольких примеров, нет определенного списка.

Обычно я бы попробовал это:

{
    no strict 'refs';
    *{'CORE::GLOBAL::-d'} = \&Testing::MockDir::mock_d;
}

, который не является синтаксической ошибкой, но не имеет эффекта переопределения -d.

3 голосов
/ 05 января 2010

Спасибо всем за ответы.

То, что я в итоге сделал, так это то, что для каждого модуля / цели теста я разложил код с «-d» в его собственную функцию. Вот так ...

# Because I cannot mock -d directly
sub dirExists {
    return -d shift;
}

Тогда я могу заменить эту функцию в тестовом модуле на

my $doesDirExist = 1;
*MyModule::dirExists   = \&main::mock_dirExists;

sub mock_dirExists {
    return $doesDirExist;
}

Это довольно уродливо, но я не хотел зацикливаться на этом слишком долго, и это хорошо работает для моих целей

2 голосов
/ 24 декабря 2009

Проблема в том, что ваше приложение зависит от жестко заданных спецификаций файлов. Вы должны параметризовать спецификации файла; тогда вам больше не нужно издеваться, вы можете просто использовать Directory :: Scratch или что-то в этом роде.

0 голосов
/ 24 декабря 2009

Вы можете пойти по маршруту фильтра источника:

package Testing::MockDir;
use Filter::Simple;
FILTER {   s/\s+\-d (\S+)/ Testing::MockDir::filetest 'd',$1/g };
sub filetest {
  my ($test, $file) = @_;
  print "Mocking  -$test $file\n";
  return 1;
}

(Этот пример кода не очень надежен. Например, он не будет переводить -d$dir или -d "dirname with spaces", но вы можете увеличить его, пока он не будет соответствовать потребностям вашего целевого кода).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...