Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/App/Yath/Script/V1.pm
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ sub do_begin {
my $ORIG_TMP_PERMS;
my %ORIG_SIG = map { defined($SIG{$_}) ? ($_ => "$SIG{$_}") : () } keys %SIG;
my @ORIG_ARGV = @$argv;
my @ORIG_INC = @INC;
# Skip @INC hook refs (coderef / arrayref / blessed); they can't cross exec via -I nor round-trip JSON.
my @ORIG_INC = grep { ref $_ eq '' } @INC;
my %CONFIG;

@ARGV = @$argv;
Expand Down
3 changes: 2 additions & 1 deletion lib/Test2/Harness/Util.pm
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ sub process_includes {
@list = @start;
}

push @list => @INC if delete $params{include_current};
# Skip @INC hook refs; clean_path would stringify them to bogus paths.
push @list => grep { ref $_ eq '' } @INC if delete $params{include_current};

@list = map { $_ eq '.' ? $_ : clean_path($_) || $_ } @list if delete $params{clean};

Expand Down
63 changes: 63 additions & 0 deletions t/integration/inc_hook.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use Test2::V0;

use File::Spec;

use App::Yath::Tester qw/yath/;

use App::Yath::Util qw/find_yath/;
find_yath();

my $dir = __FILE__;
$dir =~ s{\.t$}{}g;

my $hook_dir = File::Spec->rel2abs($dir);
my $target = File::Spec->catfile($hook_dir, 'simple.tx');

# Each fixture injects one of the three @INC hook forms documented in
# perlvar "@INC": blessed object, coderef, arrayref. Without filtering,
# the ref would be snapshotted into settings->harness->orig_inc, crash
# JSON encoding in write_settings_to, and inject "HASH(0x...)" /
# "CODE(0x...)" / "ARRAY(0x...)" garbage paths into child -I flags.
my @cases = (
{
name => 'blessed object hook',
module => 'FakeHook',
ref_re => qr/FakeHook=HASH\(/,
},
{
name => 'coderef hook',
module => 'CoderefHook',
ref_re => qr{/CODE\(0x},
},
{
name => 'arrayref hook',
module => 'ArrayrefHook',
ref_re => qr{/ARRAY\(0x},
},
);

for my $case (@cases) {
yath(
command => 'test',
args => [$target],
env => {
PERL5OPT => "-I$hook_dir -M$case->{module}",
},
exit => 0,
test => sub {
my $out = shift;
unlike(
$out->{output},
qr/encountered object/,
"$case->{name}: no JSON encode error",
);
unlike(
$out->{output},
$case->{ref_re},
"$case->{name}: no stringified ref leaked into output",
);
},
);
}

done_testing;
7 changes: 7 additions & 0 deletions t/integration/inc_hook/ArrayrefHook.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package ArrayrefHook;
use strict;
use warnings;

unshift @INC, [sub { return }];

1;
7 changes: 7 additions & 0 deletions t/integration/inc_hook/CoderefHook.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package CoderefHook;
use strict;
use warnings;

unshift @INC, sub { return };

1;
10 changes: 10 additions & 0 deletions t/integration/inc_hook/FakeHook.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package FakeHook;
use strict;
use warnings;

# INC is a special identifier that lives in main::, hence the FQN.
sub FakeHook::INC { return }

unshift @INC, bless({}, __PACKAGE__);

1;
5 changes: 5 additions & 0 deletions t/integration/inc_hook/simple.tx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use Test2::V0;

ok(1, 'basic test runs under @INC hook');

done_testing;