Skip to content
Merged
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
8 changes: 8 additions & 0 deletions server/src/perl/Inquisitor.pm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ $INC{'namespace/autoclean.pm'} = '';
*{'namespace::clean::VERSION'} = sub { '0.27' };
*{'namespace::autoclean::import'} = sub { };
*{'namespace::clean::import'} = sub { };
*{'namespace::clean::get_functions'} = sub {
my ($pragma, $class) = @_;
no strict 'refs';
return { map { $_ => \&{"${class}::${_}"} }
grep { defined &{"${class}::${_}"} }
keys %{"${class}::"} };
};
*{'namespace::clean::clean_subroutines'} = sub { };
}

CHECK {
Expand Down
47 changes: 47 additions & 0 deletions t/02_NamespaceClean.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use strict;
use warnings;
use Capture::Tiny qw( capture );
use File::Spec;
use Test::More import => [qw( done_testing is ok like )];

# Prevent Inquisitor's CHECK block from running during test load.
BEGIN { $ENV{'PERLNAVIGATORTEST'} = 1; }

use FindBin qw( $Bin );
use lib "$Bin/../server/src/perl";
use Inquisitor ();

# Regression test: Inquisitor stubs out namespace::clean to prevent it from
# wiping the symbol table. The stub previously only provided import() and
# VERSION, omitting get_functions() and clean_subroutines(). Any module that
# calls namespace::clean->get_functions($package) at file scope would fail with:
#
# Can't locate object method "get_functions" via package "namespace::clean"
#
# This caused a cascade of false "Syntax" diagnostics in the editor.

my $testFile = File::Spec->rel2abs("$Bin/../testWorkspace/MyLib/NamespaceCleanCaller.pm");

# Verify get_functions stub exists and is callable.
ok( namespace::clean->can('get_functions'),
'namespace::clean stub provides get_functions method' );

ok( namespace::clean->can('clean_subroutines'),
'namespace::clean stub provides clean_subroutines method' );

# Verify get_functions returns a hashref (not undef or an exception).
my $funcs;
eval { $funcs = namespace::clean->get_functions('main') };
is( $@, '', 'namespace::clean->get_functions does not throw' );
ok( ref($funcs) eq 'HASH', 'namespace::clean->get_functions returns a hashref' );

# Verify that Inquisitor::run() succeeds on a file that calls
# namespace::clean->get_functions at file scope.
my $output;
eval { $output = capture(sub { Inquisitor::run($testFile) }) };
is( $@, '', 'Inquisitor::run does not die on file using namespace::clean->get_functions' );

# The file should produce symbol output (my_method should appear).
like( $output, qr/my_method/, 'Symbol from NamespaceCleanCaller.pm is found' );

done_testing;
17 changes: 17 additions & 0 deletions testWorkspace/MyLib/NamespaceCleanCaller.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package MyLib::NamespaceCleanCaller;

# This module simulates a pattern where namespace::clean->get_functions()
# is called at file scope (not inside a BEGIN block). This is legal Perl
# and works at runtime, but was broken under Inquisitor because the
# namespace::clean stub only provided import(), not get_functions().

use strict;
use warnings;
use namespace::clean;

# Call get_functions at file scope, the way some type-library frameworks do.
my $functions = namespace::clean->get_functions(__PACKAGE__);

sub my_method { return 42 }

1;