use Sub::Install qw(reinstall_sub); use Test::More tests => 15; use strict; use warnings; # These tests largely copied from Damian Conway's Sub::Installer tests. { # Install a sub in a package... my $sub_ref = reinstall_sub({ code => \&ok, as => 'ok1' }); isa_ok($sub_ref, 'CODE', 'return value of first install_sub'); is_deeply($sub_ref, \&Test::More::ok, 'it returned the right coderef'); $sub_ref->(1, 'returned code ref runs'); ok1(1, "reinstalled sub runs"); } { my $to_avail = eval "use Test::Output; 1"; SKIP: { skip "can't run this test without Test::Output", 1 unless $to_avail; Sub::Install::reinstall_sub({ code => \&ok, as => 'tmp_ok' }); my $expected_warning = <<'END_WARNING'; Prototype mismatch: sub main::tmp_ok ($;$) vs ($$;$) at t/reinstall.t line 32 END_WARNING my $stderr = Test::Output::stderr_from( sub { Sub::Install::reinstall_sub({ code => \&is, as => 'tmp_ok' }) } ); $stderr =~ s!\\!/!g; is( $stderr, $expected_warning, "got expected warning", ); } } { # Install the same sub in the same package... my $proto = 0; local $SIG{__WARN__} = sub { return ($proto = 1) if $_[0] =~ m{Prototype mismatch.+t.reinstall\.t}; die "unexpected warning: @_"; }; my $sub_ref = reinstall_sub({ code => \&is, as => 'ok1' }); ok($proto, 'correct warning went to $SIG{__WARN__}'); isa_ok($sub_ref, 'CODE', 'return value of second install_sub'); is_deeply($sub_ref, \&Test::More::is, 'it returned the right coderef'); $sub_ref->(1, 1, 'returned code ref runs'); ok1(1,1, 'reinstalled sub reruns'); } { # Install in another package... my $new_code = sub { ok(1, "remotely installed sub runs") }; my $sub_ref = reinstall_sub({ code => $new_code, into => 'Other', as => 'ok1', }); isa_ok($sub_ref, 'CODE', 'return value of third install_sub'); is_deeply($sub_ref, $new_code, 'it returned the right coderef'); ok1(1,1, 'reinstalled sub reruns'); package Other; ok1(); } eval { my $arg = { code => sub {}, into => 'Other', as => 'ok1' }; Sub::Install::_build_public_installer(\&Sub::Install::_install_fatal)->($arg); }; like($@, qr/redefine/, "(experimental fatal installer should croak)");