2 # Copyright (C) 2007-2010, Parrot Foundation.
7 t/oo/compositon.t - test role composition
11 % prove t/oo/compositon.t
15 Tests role composition in the OO implementation.
20 .include 'except_types.pasm'
21 .include 'test_more.pir'
24 role_with_no_methods()
25 role_with_one_method_no_methods_in_class()
26 two_roles_and_a_class_a_method_each_no_conflict()
27 two_roles_that_conflict()
28 role_that_conflicts_with_a_class_method()
29 conflict_resolution_by_exclusion()
30 conflict_resolution_by_aliasing_and_exclude()
31 conflict_resolution_by_resolve()
32 role_that_does_a_role()
33 conflict_from_indirect_role()
37 .sub badger :method :nsentry('badger')
40 .sub badger2 :method :nsentry('badger2')
41 .return('Second Badger!')
43 .sub mushroom :method :nsentry('mushroom')
46 .sub snake :method :nsentry('snake')
50 .return("You're FIRED!")
53 .return('BURNINATION!')
56 .return('You all get a pay rise of 0.0005%.')
59 .sub role_with_no_methods
68 is($I0, 1, 'roles list has the role')
71 ok(1, 'instantiated class with composed role')
74 .sub role_with_one_method_no_methods_in_class
78 $P2 = get_global "badger"
79 $P0.'add_method'("badger", $P2)
80 ok(1, 'added method to a role')
83 ok(1, 'composed role into the class')
87 is($I0, 1, 'roles list has the role')
90 ok(1, 'instantiated class with composed role')
93 is($S0, 'Badger!', 'called method composed from role')
96 .sub two_roles_and_a_class_a_method_each_no_conflict
101 $P3 = get_global "snake"
102 $P2.'add_method'("snake", $P3)
103 ok(1, 'class has a method')
105 $P3 = get_global "badger"
106 $P0.'add_method'("badger", $P3)
108 ok(1, 'composed first role into the class')
110 $P3 = get_global "mushroom"
111 $P1.'add_method'("mushroom", $P3)
113 ok(1, 'composed second role into the class')
116 ok(1, 'instantiated class')
119 is($S0, 'Badger!', 'called method from first role')
121 $S1 = $P3.'mushroom'()
122 is($S1, 'Mushroom!', 'called method from second role')
125 is($S2, 'Snake!', 'called method from class')
128 .sub two_roles_that_conflict
134 $P3 = get_global "badger"
135 $P0.'add_method'("badger", $P3)
137 ok(1, 'composed first role into the class')
139 $P3 = get_global "badger2"
140 $P1.'add_method'("badger", $P3)
143 eh = new 'ExceptionHandler'
144 eh.'handle_types'(.EXCEPTION_ROLE_COMPOSITION_METHOD_CONFLICT)
157 nok($I0, 'composition failed due to conflict')
160 .sub role_that_conflicts_with_a_class_method
165 $P2 = get_global "badger"
166 $P1.'add_method'("badger", $P2)
167 ok(1, 'class has a method')
169 $P2 = get_global "badger2"
170 $P0.'add_method'("badger", $P2)
173 eh = new 'ExceptionHandler'
174 eh.'handle_types'(.EXCEPTION_ROLE_COMPOSITION_METHOD_CONFLICT)
187 nok($I0, 'composition failed due to conflict')
190 .sub conflict_resolution_by_exclusion
194 $P2 = get_global "badger"
195 $P1.'add_method'("badger", $P2)
196 ok(1, 'class has a method')
198 $P2 = get_global "badger2"
199 $P0.'add_method'("badger", $P2)
200 $P2 = get_global "snake"
201 $P0.'add_method'("snake", $P2)
202 $P3 = new 'ResizableStringArray'
204 $P1.'add_role'($P0, 'exclude_method' => $P3)
205 ok(1, 'composition worked due to exclusion')
209 is($S0, 'Badger!', 'called method from class')
212 is($S1, 'Snake!', "called method from role that wasn't excluded")
215 .sub conflict_resolution_by_aliasing_and_exclude
219 $P2 = get_global 'badger'
220 $P1.'add_method'('badger', $P2)
221 ok(1, 'class has a method')
223 $P2 = get_global 'badger2'
224 $P0.'add_method'('badger', $P2)
225 $P2 = get_global 'snake'
226 $P0.'add_method'('snake', $P2)
228 $P3['badger'] = 'role_badger'
229 $P4 = new 'ResizableStringArray'
231 $P1.'add_role'($P0, 'alias_method' => $P3, 'exclude_method' => $P4)
232 ok(1, 'composition worked due to aliasing and exclude')
236 is($S0, 'Badger!', 'called method from class')
239 is($S1, 'Snake!', "called method from role that wasn't aliased")
241 $S2 = $P2.'role_badger'()
242 is($S2, 'Second Badger!', 'called method from role that was aliased')
245 .sub conflict_resolution_by_resolve
249 $P3 = new 'ResizableStringArray'
251 $P1.'resolve_method'($P3)
252 ok(1, 'set resolve list')
254 $P4 = $P1.'resolve_method'()
256 is($S0, 'badger', 'got resolve list and it matched')
258 $P2 = get_global 'badger'
259 $P1.'add_method'('badger', $P2)
260 ok(1, 'class has a method')
262 $P2 = get_global 'badger2'
263 $P0.'add_method'('badger', $P2)
264 $P2 = get_global 'snake'
265 $P0.'add_method'('snake', $P2)
267 ok(1, 'composition worked due to resolve')
271 is($S1, 'Badger!', 'called method from class')
274 is($S2, 'Snake!', "called method from role that wasn't resolved")
277 .sub role_that_does_a_role
278 .local pmc PHB, Manage, FirePeople
280 FirePeople = new 'Role'
281 $P0 = get_global 'fire'
282 FirePeople.'add_method'("fire", $P0)
285 $P0 = get_global 'give_payrise'
286 Manage.'add_method'("give_payrise", $P0)
287 Manage.'add_role'(FirePeople)
288 ok(1, 'adding one role to another happens')
291 PHB.'add_role'(Manage)
292 ok(1, 'added one rule that does another role to the class')
295 $S0 = $P0.'give_payrise'()
296 is($S0, 'You all get a pay rise of 0.0005%.', 'called method from direct role')
299 is($S1, "You're FIRED!", 'called method from indirect role')
302 .sub conflict_from_indirect_role
303 .local pmc eh, BurninatorBoss, Manage, FirePeople, Burninator
305 FirePeople = new 'Role'
306 $P0 = get_global 'fire'
307 FirePeople.'add_method'('fire', $P0)
310 $P0 = get_global 'give_payrise'
311 FirePeople.'add_method'('give_payrise', $P0)
312 Manage.'add_role'(FirePeople)
314 Burninator = new 'Role'
315 $P0 = get_global 'fire2'
316 Burninator.'add_method'('fire', $P0)
317 ok(1, 'all roles created')
319 BurninatorBoss = new 'Class'
320 BurninatorBoss.'add_role'(Manage)
321 ok(1, 'added first role with indirect role')
324 eh = new 'ExceptionHandler'
325 eh.'handle_types'(.EXCEPTION_ROLE_COMPOSITION_METHOD_CONFLICT)
329 BurninatorBoss.'add_role'(Burninator)
338 nok($I0, 'second role conflicts with method from indirect role')
341 .sub 'multi_composition'
344 $P0 = get_global 'mctest_2'
345 R.'add_method'("mctest", $P0)
347 $P0 = get_global 'mctest_1'
348 C.'add_method'("mctest", $P0)
350 ok(1, 'a multi in the class prevents a role conflict')
352 $P0 = inspect C, 'methods'
354 is($I0, 1, 'class had still one method after composition')
356 $I0 = isa $P0, 'MultiSub'
357 is($I0, 1, 'method was a multi sub')
359 is($I0, 2, 'multi holds both candidates')
361 .sub 'mctest_1' :multi()
370 # vim: expandtab shiftwidth=4 ft=pir: