Include method name in immutable methods (fixes #49680)
[gitmo/Class-MOP.git] / t / 017_add_method_modifier.t
CommitLineData
ddc8edba 1use strict;
2use warnings;
3
82307066 4use Test::More tests => 21;
ddc8edba 5use Test::Exception;
6
efd3d14c 7use Class::MOP;
ddc8edba 8
9{
69b95026 10
ddc8edba 11 package BankAccount;
69b95026 12
ddc8edba 13 use strict;
14 use warnings;
15 use metaclass;
69b95026 16
ddc8edba 17 use Carp 'confess';
69b95026 18
19 BankAccount->meta->add_attribute(
20 'balance' => (
21 accessor => 'balance',
22 init_arg => 'balance',
23 default => 0
24 )
25 );
26
ddc8edba 27 sub new { (shift)->meta->new_object(@_) }
96ceced8 28
ddc8edba 29 sub deposit {
69b95026 30 my ( $self, $amount ) = @_;
31 $self->balance( $self->balance + $amount );
ddc8edba 32 }
69b95026 33
ddc8edba 34 sub withdraw {
69b95026 35 my ( $self, $amount ) = @_;
a4258ffd 36 my $current_balance = $self->balance();
69b95026 37 ( $current_balance >= $amount )
ddc8edba 38 || confess "Account overdrawn";
69b95026 39 $self->balance( $current_balance - $amount );
ddc8edba 40 }
41
69b95026 42 package CheckingAccount;
ddc8edba 43
69b95026 44 use strict;
45 use warnings;
46 use metaclass;
47
48 use base 'BankAccount';
49
50 CheckingAccount->meta->add_attribute(
51 'overdraft_account' => (
52 accessor => 'overdraft_account',
53 init_arg => 'overdraft',
54 )
55 );
56
57 CheckingAccount->meta->add_before_method_modifier(
58 'withdraw' => sub {
59 my ( $self, $amount ) = @_;
60 my $overdraft_amount = $amount - $self->balance();
61 if ( $overdraft_amount > 0 ) {
62 $self->overdraft_account->withdraw($overdraft_amount);
63 $self->deposit($overdraft_amount);
64 }
65 }
66 );
67
cc6c0b0b 68 ::throws_ok(
69 sub {
70 CheckingAccount->meta->add_before_method_modifier(
71 'does_not_exist' => sub { } );
72 },
73 qr/\QThe method 'does_not_exist' was not found in the inheritance hierarchy for CheckingAccount/
74 );
75
69b95026 76 ::ok( CheckingAccount->meta->has_method('withdraw'),
77 '... checking account now has a withdraw method' );
78 ::isa_ok( CheckingAccount->meta->get_method('withdraw'),
79 'Class::MOP::Method::Wrapped' );
80 ::isa_ok( BankAccount->meta->get_method('withdraw'),
81 'Class::MOP::Method' );
82307066 82
83 CheckingAccount->meta->add_method( foo => sub { 'foo' } );
84 CheckingAccount->meta->add_before_method_modifier( foo => sub { 'wrapped' } );
85 ::isa_ok( CheckingAccount->meta->get_method('foo'),
86 'Class::MOP::Method::Wrapped' );
69b95026 87}
ddc8edba 88
69b95026 89my $savings_account = BankAccount->new( balance => 250 );
90isa_ok( $savings_account, 'BankAccount' );
ddc8edba 91
69b95026 92is( $savings_account->balance, 250, '... got the right savings balance' );
ddc8edba 93lives_ok {
69b95026 94 $savings_account->withdraw(50);
95}
96'... withdrew from savings successfully';
97is( $savings_account->balance, 200,
6c681a5b 98 '... got the right savings balance after withdrawal' );
195f5bf8 99dies_ok {
69b95026 100 $savings_account->withdraw(250);
101}
102'... could not withdraw from savings successfully';
ddc8edba 103
104$savings_account->deposit(150);
69b95026 105is( $savings_account->balance, 350,
106 '... got the right savings balance after deposit' );
ddc8edba 107
108my $checking_account = CheckingAccount->new(
69b95026 109 balance => 100,
110 overdraft => $savings_account
111);
112isa_ok( $checking_account, 'CheckingAccount' );
113isa_ok( $checking_account, 'BankAccount' );
ddc8edba 114
69b95026 115is( $checking_account->overdraft_account, $savings_account,
116 '... got the right overdraft account' );
ddc8edba 117
69b95026 118is( $checking_account->balance, 100, '... got the right checkings balance' );
ddc8edba 119
120lives_ok {
69b95026 121 $checking_account->withdraw(50);
122}
123'... withdrew from checking successfully';
124is( $checking_account->balance, 50,
6c681a5b 125 '... got the right checkings balance after withdrawal' );
69b95026 126is( $savings_account->balance, 350,
6c681a5b 127 '... got the right savings balance after checking withdrawal (no overdraft)'
69b95026 128);
ddc8edba 129
96ceced8 130lives_ok {
69b95026 131 $checking_account->withdraw(200);
132}
133'... withdrew from checking successfully';
134is( $checking_account->balance, 0,
6c681a5b 135 '... got the right checkings balance after withdrawal' );
69b95026 136is( $savings_account->balance, 200,
6c681a5b 137 '... got the right savings balance after overdraft withdrawal' );
ddc8edba 138