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 2.566 seconds using v1.01-cache-2.11-cpan-600a1bdf6e4 )