Merge branch 'stable'
[gitmo/Class-MOP.git] / t / 017_add_method_modifier.t
CommitLineData
ddc8edba 1use strict;
2use warnings;
3
86a4d873 4use Test::More;
871e9eb5 5use Test::Fatal;
ddc8edba 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
871e9eb5 68 ::like(
69 ::exception{ CheckingAccount->meta->add_before_method_modifier(
70 'does_not_exist' => sub { }
71 );
72 },
cc6c0b0b 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' );
871e9eb5 93is( exception {
69b95026 94 $savings_account->withdraw(50);
871e9eb5 95}, undef, '... withdrew from savings successfully' );
69b95026 96is( $savings_account->balance, 200,
6c681a5b 97 '... got the right savings balance after withdrawal' );
871e9eb5 98isnt( exception {
69b95026 99 $savings_account->withdraw(250);
871e9eb5 100}, undef, '... could not withdraw from savings successfully' );
ddc8edba 101
102$savings_account->deposit(150);
69b95026 103is( $savings_account->balance, 350,
104 '... got the right savings balance after deposit' );
ddc8edba 105
106my $checking_account = CheckingAccount->new(
69b95026 107 balance => 100,
108 overdraft => $savings_account
109);
110isa_ok( $checking_account, 'CheckingAccount' );
111isa_ok( $checking_account, 'BankAccount' );
ddc8edba 112
69b95026 113is( $checking_account->overdraft_account, $savings_account,
114 '... got the right overdraft account' );
ddc8edba 115
69b95026 116is( $checking_account->balance, 100, '... got the right checkings balance' );
ddc8edba 117
871e9eb5 118is( exception {
69b95026 119 $checking_account->withdraw(50);
871e9eb5 120}, undef, '... withdrew from checking successfully' );
69b95026 121is( $checking_account->balance, 50,
6c681a5b 122 '... got the right checkings balance after withdrawal' );
69b95026 123is( $savings_account->balance, 350,
6c681a5b 124 '... got the right savings balance after checking withdrawal (no overdraft)'
69b95026 125);
ddc8edba 126
871e9eb5 127is( exception {
69b95026 128 $checking_account->withdraw(200);
871e9eb5 129}, undef, '... withdrew from checking successfully' );
69b95026 130is( $checking_account->balance, 0,
6c681a5b 131 '... got the right checkings balance after withdrawal' );
69b95026 132is( $savings_account->balance, 200,
6c681a5b 133 '... got the right savings balance after overdraft withdrawal' );
ddc8edba 134
86a4d873 135done_testing;