perl-Test-Spec
perl-Test-Spec copied to clipboard
Implement `around all` behavior
Greetings!
Conceptually, what I want to do is something like this:
subtest "foo" => sub {
my $cnt = 0;
my $chk_cnt = 0;
no warnings "redefine";
local $X::Y::reformat_harddrive = sub { $cnt++ };
local $X::Y::check_harddrive = sub { $chk_cnt++ };
use warnings "redefine";
ok(foo(0), "foo 0 returns true");
is($cnt, 0, 'foo 0 does not call reformat_harddrive()');
ok(foo(1), "foo 1 returns true");
is($cnt, 1, 'foo 1 calls reformat_harddrive()');
ok(bar(0), "bar 0 returns true");
is($cnt, 2, 'bar 0 does not call reformat_harddrive()');
ok(foo(1), "bar 1 returns true");
is($cnt, 3, 'bar 1 calls reformat_harddrive()');
is($chk_cnt, "all calls call check_harddrive()');
};
In Test::Spec I have to kind of simulate local() vars to do this:
our $cnt = 0;
our $chk_cnt = 0;
description "foo" => sub {
around {
no warnings "redefine";
local $X::Y::reformat_harddrive = sub { $cnt++ };
local $X::Y::check_harddrive = sub { $chk_cnt++ };
use warnings "redefine";
yield;
};
before all => sub { local $cnt = 0;local $chk_cnt = 0; };
after all => sub { local $cnt = 0;local $chk_cnt = 0; };
… tests above it()-ified here …
};
Two problems with that:
- we're needlessly mocking the functions fo every
it*() - the simulated
local()via before/after all is fragile
It’d be really cool to be able to call around like before/after, like so:
our $cnt = 0;
our $chk_cnt = 0;
description "foo" => sub {
around all {
local $cnt = 0;
local $chk_cnt = 0;
no warnings "redefine";
local $X::Y::reformat_harddrive = sub { $cnt++ };
local $X::Y::check_harddrive = sub { $chk_cnt++ };
use warnings "redefine";
yield;
};
… tests above it()-ified here …
};
unless that violates the spec then I guess this is a noop :)
If the behavior described in #48 is the intent then this can be closed because you can accomplish this (and without out the state of each test affecting the others) w/ something like:
around {
my $cnt = 0;
my $chk_cnt = 0;
no warnings "redefine";
local $X::Y::reformat_harddrive = sub { $cnt++ };
local $X::Y::check_harddrive = sub { $chk_cnt++ };
use warnings "redefine";
yield;
$cnt = 0;
$chk_cnt = 0;
};
a more realistic example might be:
around {
my $mocked_module = Test::MockModule->new(…);
$mocked_module->redefine(…);
$mocked_module->redefine(…);
$mocked_module->redefine(…);
yield;
$mocked_module->unmock_all();
};