diff --git a/lib/Overload/FileCheck.pm b/lib/Overload/FileCheck.pm index 295e03f..9372a60 100644 --- a/lib/Overload/FileCheck.pm +++ b/lib/Overload/FileCheck.pm @@ -196,6 +196,10 @@ sub import { } } + if ( defined $_next_check ) { + Carp::croak(qq[Missing CODE ref for mock '$_next_check' in import list]); + } + # callback the exporter logic return __PACKAGE__->export_to_level( 1, $class, @for_exporter ); } @@ -342,9 +346,12 @@ sub _check_from_stat { k => sub { _xs_unmock_op($optype); _to_bool( scalar -k _ ) }, # sticky bit # Heuristic text/binary checks (use glob _ to pass the cached stat) - T => sub { _xs_unmock_op($optype); _to_bool( scalar -T *_ ) }, # ASCII or UTF-8 text (heuristic) + T => sub { return CHECK_IS_NULL unless @stat; _xs_unmock_op($optype); _to_bool( scalar -T *_ ) }, # ASCII or UTF-8 text (heuristic) B => sub { # binary file (opposite of -T) - return CHECK_IS_TRUE if @stat && ( $stat[ST_MODE] & _S_IFMT ) == S_IFDIR; + return CHECK_IS_NULL unless @stat; # file not found + # Check directory via mode bits directly instead of calling the + # mocked -d operator, which would trigger a redundant stat callback. + return CHECK_IS_TRUE if _check_mode_type( $stat[ST_MODE], S_IFDIR ) == CHECK_IS_TRUE; _xs_unmock_op($optype); return _to_bool( scalar -B *_ ); }, diff --git a/t/import-trailing-option.t b/t/import-trailing-option.t new file mode 100644 index 0000000..8490afa --- /dev/null +++ b/t/import-trailing-option.t @@ -0,0 +1,42 @@ +#!/usr/bin/perl -w + +use strict; +use warnings; + +use Test2::Bundle::Extended; +use Test2::Tools::Explain; + +# Load the module without calling import so we can test import() directly. +require Overload::FileCheck; + +# Verify that a trailing dash-option without a CODE ref in the import list +# produces a clear error instead of being silently discarded. + +like( + dies { + Overload::FileCheck->import( '-e' => sub { 1 }, '-f' ); + }, + qr/Missing CODE ref for mock '-f'/, + 'trailing dash-option without value croaks' +); + +# Clean up the -e mock from the partial import above (it succeeded before -f error). +Overload::FileCheck::unmock_all_file_checks(); + +like( + dies { + Overload::FileCheck->import('-z'); + }, + qr/Missing CODE ref for mock '-z'/, + 'single dash-option without value croaks' +); + +# Valid imports should still work fine. +ok( + lives { + Overload::FileCheck->import(':check'); + }, + 'exporter tag imports normally' +); + +done_testing;