d4bf02cad6482ff0392dc2dd8e2c974a1ed164f1
[gitmo/Class-C3-XS.git] / t / 02_MRO.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use Test::More tests => 15;
7
8 BEGIN {
9     use_ok('Class::C3');
10     # uncomment this line, and re-run the
11     # test to see the normal p5 dispatch order
12     #$Class::C3::TURN_OFF_C3 = 1;    
13 }
14
15 =pod
16
17 This example is take from: http://www.python.org/2.3/mro.html
18
19 "My first example"
20 class O: pass
21 class F(O): pass
22 class E(O): pass
23 class D(O): pass
24 class C(D,F): pass
25 class B(D,E): pass
26 class A(B,C): pass
27
28
29                           6
30                          ---
31 Level 3                 | O |                  (more general)
32                       /  ---  \
33                      /    |    \                      |
34                     /     |     \                     |
35                    /      |      \                    |
36                   ---    ---    ---                   |
37 Level 2        3 | D | 4| E |  | F | 5                |
38                   ---    ---    ---                   |
39                    \  \ _ /       |                   |
40                     \    / \ _    |                   |
41                      \  /      \  |                   |
42                       ---      ---                    |
43 Level 1            1 | B |    | C | 2                 |
44                       ---      ---                    |
45                         \      /                      |
46                          \    /                      \ /
47                            ---
48 Level 0                 0 | A |                (more specialized)
49                            ---
50
51 =cut
52
53 {
54     package Test::O;
55     use Class::C3; 
56     
57     package Test::F;   
58     use Class::C3;  
59     use base 'Test::O';        
60     
61     package Test::E;
62     use base 'Test::O';    
63     use Class::C3;     
64     
65     sub C_or_E { 'Test::E' }
66
67     package Test::D;
68     use Class::C3; 
69     use base 'Test::O';     
70     
71     sub C_or_D { 'Test::D' }       
72       
73     package Test::C;
74     use base ('Test::D', 'Test::F');
75     use Class::C3; 
76     
77     sub C_or_D { 'Test::C' }
78     sub C_or_E { 'Test::C' }    
79         
80     package Test::B;    
81     use Class::C3; 
82     use base ('Test::D', 'Test::E');    
83         
84     package Test::A;    
85     use base ('Test::B', 'Test::C');
86     use Class::C3;    
87 }
88
89 Class::C3::initialize();
90
91 is_deeply(
92     [ Class::C3::calculateMRO('Test::F') ],
93     [ qw(Test::F Test::O) ],
94     '... got the right MRO for Test::F');
95
96 is_deeply(
97     [ Class::C3::calculateMRO('Test::E') ],
98     [ qw(Test::E Test::O) ],
99     '... got the right MRO for Test::E');    
100
101 is_deeply(
102     [ Class::C3::calculateMRO('Test::D') ],
103     [ qw(Test::D Test::O) ],
104     '... got the right MRO for Test::D');       
105
106 is_deeply(
107     [ Class::C3::calculateMRO('Test::C') ],
108     [ qw(Test::C Test::D Test::F Test::O) ],
109     '... got the right MRO for Test::C'); 
110
111 is_deeply(
112     [ Class::C3::calculateMRO('Test::B') ],
113     [ qw(Test::B Test::D Test::E Test::O) ],
114     '... got the right MRO for Test::B');     
115
116 is_deeply(
117     [ Class::C3::calculateMRO('Test::A') ],
118     [ qw(Test::A Test::B Test::C Test::D Test::E Test::F Test::O) ],
119     '... got the right MRO for Test::A');  
120     
121 is(Test::A->C_or_D, 'Test::C', '... got the expected method output');
122 is(Test::A->can('C_or_D')->(), 'Test::C', '... can got the expected method output');
123
124 is(Test::A->C_or_E, 'Test::C', '... got the expected method output');
125 is(Test::A->can('C_or_E')->(), 'Test::C', '... can got the expected method output');
126
127 # remove the C3
128 Class::C3::uninitialize();
129
130 is(Test::A->C_or_D, 'Test::D', '...  old method resolution has been restored');
131 is(Test::A->can('C_or_D')->(), 'Test::D', '...  old can(method) resolution has been restored');
132
133 is(Test::A->C_or_E, 'Test::E', '...  old method resolution has been restored');
134 is(Test::A->can('C_or_E')->(), 'Test::E', '...  old can(method) resolution has been restored');
135
136