Class-Abstract
view release on metacpan or search on metacpan
t/edge_cases.t view on Meta::CPAN
#
# Deliberately tries to break or subvert Class::Abstract by passing pathological
# inputs, mocking upstream dependencies with edge-case returns, manipulating
# @ISA at runtime, exploiting bypass mechanics, and verifying robustness under
# circular data structures.
use strict;
use warnings;
use Readonly;
use Scalar::Util qw(blessed reftype weaken);
use Test::Most;
use Test::Mockingbird;
use Test::Returns;
use Class::Abstract;
# ---------------------------------------------------------------------------
# Configuration -- every constant and boundary value in one place
# ---------------------------------------------------------------------------
t/edge_cases.t view on Meta::CPAN
ok( EC::Abstract->is_abstract(),
'EC::Abstract->is_abstract() is truthy in boolean context' );
ok( !EC::Concrete->is_abstract(),
'EC::Concrete->is_abstract() is falsy in boolean context' );
};
# ===========================================================================
# SECTION 15: Weakened reference as invocant
#
# Scalar::Util::weaken() removes the strong reference count. Once all
# strong references are gone the object is destroyed and the weak ref becomes
# undef. A live (still-referenced) weakened blessed ref must pass new().
# A dead (garbage-collected) weakened ref becomes undef and must croak.
# ===========================================================================
# Purpose: live weakened blessed ref works; dead weakened ref croaks
subtest 'weakened references as invocants' => sub {
plan tests => 3;
# Live weak ref: a strong ref also exists, so the object survives
my $strong = EC::Concrete->new();
my $weak = $strong;
weaken($weak);
diag 'weak ref: ' . (defined($weak) ? ref($weak) : 'undef') if $ENV{TEST_VERBOSE};
# $weak is still alive because $strong holds a strong reference
ok defined($weak) && blessed($weak),
'precondition: weakened ref is still alive (strong ref holds it)';
# A live weakened blessed ref must be accepted by new()
lives_ok { $strong->new() }
'live weakened blessed ref: new() succeeds via strong ref';
# Dead weak ref: no strong references, object is garbage-collected immediately
my $dead_weak = do { my $obj = EC::Concrete->new(); weaken($obj); $obj };
# The dead weak ref is undef; ref(undef) = "", so it hits the undef guard
throws_ok { Class::Abstract::new($dead_weak) }
$config{err_new_undef},
'dead weakened ref (undef) causes new() to croak with defined-class-name error';
};
# ===========================================================================
# SECTION 16: $_ is never clobbered by any public method
#
# Any grep or map over @ISA inside _is_direct_abstract could overwrite $_.
# Verify $_ is unchanged across all four public methods under varied inputs.
# ===========================================================================
# Purpose: no public method may mutate $_ in the calling scope
( run in 0.557 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )