3
# $Id: view_affordance.t 2384 2005-12-14 04:27:23Z theory $
5
##############################################################################
7
##############################################################################
10
use Test::More tests => 209;
12
##############################################################################
13
# Create a simple class.
14
##############################################################################
16
package Class::Meta::Test;
21
use_ok('Class::Meta');
22
use_ok('Class::Meta::Types::Numeric', 'affordance');
23
use_ok('Class::Meta::Types::String', 'affordance');
27
ok( my $c = Class::Meta->new(
29
package => __PACKAGE__,
30
trust => 'Class::Meta::TrustMe',
31
name => 'Class::Meta::TestPerson Class',
32
desc => 'Special person class just for testing Class::Meta.',
33
), "Create Class::Meta object" );
36
ok( $c->add_constructor( name => 'new',
38
"Add new constructor" );
40
# Add a couple of attributes with created methods.
41
ok( $c->add_attribute( name => 'id',
42
view => Class::Meta::PUBLIC,
49
ok( $c->add_attribute( name => 'name',
50
view => Class::Meta::PROTECTED,
56
"Add protected name attribute" );
57
ok( $c->add_attribute( name => 'age',
58
view => Class::Meta::PRIVATE,
61
desc => "The person's age.",
65
"Add private age attribute" );
66
ok( $c->add_attribute( name => 'sn',
67
view => Class::Meta::TRUSTED,
70
desc => "The person's serial number.",
74
"Add trusted sn attribute" );
78
##############################################################################
79
# From within the package, the private and public attributes should just work.
80
##############################################################################
82
ok( my $obj = __PACKAGE__->new, "Create new object" );
83
ok( my $class = __PACKAGE__->my_class, "Get class object" );
84
is_deeply( [map { $_->name } $class->attributes], [qw(id name age sn)],
85
'Call to attributes() should return all attributes' );
87
# Check id public attribute.
88
is( $obj->get_id, 22, 'Check default ID' );
89
ok( $obj->set_id(12), "Set ID" );
90
is( $obj->get_id, 12, 'Check 12 ID' );
91
ok( my $attr = $class->attributes('id'), 'Get "id" attribute object' );
92
is( $attr->get($obj), 12, "Check indirect 12 ID" );
93
ok( $attr->set($obj, 15), "Indirectly set ID" );
94
is( $attr->get($obj), 15, "Check indirect 15 ID" );
96
# Check name protected attribute succeeds.
97
is( $obj->get_name, '', 'Check empty name' );
98
ok( $obj->set_name('Larry'), "Set name" );
99
is( $obj->get_name, 'Larry', 'Check "Larry" name' );
100
ok( $attr = $class->attributes('name'), 'Get "name" attribute object' );
101
is( $attr->get($obj), 'Larry', 'Check indirect "Larry" name' );
102
ok( $attr->set($obj, 'Chip'), "Indirectly set name" );
103
is( $attr->get($obj), 'Chip', 'Check indirect "chip" name' );
105
# Check age private attribute succeeds.
106
is( $obj->get_age, 0, 'Check default age' );
107
ok( $obj->set_age(42), "Set age" );
108
is( $obj->get_age, 42, 'Check 42 age' );
109
ok( $attr = $class->attributes('age'), 'Get "age" attribute object' );
110
is( $attr->get($obj), 42, "Check indirect 12 age" );
111
ok( $attr->set($obj, 15), "Indirectly set age" );
112
is( $attr->get($obj), 15, "Check indirect 15 age" );
114
# Check sn trusted attribute succeeds.
115
is( $obj->get_sn, '', 'Check empty sn' );
116
ok( $obj->set_sn('123456789'), "Set sn" );
117
is( $obj->get_sn, '123456789', 'Check "123456789" sn' );
118
ok( $attr = $class->attributes('sn'), 'Get "sn" attribute object' );
119
is( $attr->get($obj), '123456789', 'Check indirect "123456789" sn' );
120
ok( $attr->set($obj, '987654321'), "Indirectly set sn" );
121
is( $attr->get($obj), '987654321', 'Check indirect "987654321" sn' );
123
# Make sure that we can set all of the attributes via new().
124
ok( $obj = __PACKAGE__->new( id => 10,
128
"Create another new object" );
130
is( $obj->get_id, 10, 'Check 10 ID' );
131
is( $obj->get_name, 'Damian', 'Check Damian name' );
132
is( $obj->get_age, 35, 'Check 35 age' );
133
is( $obj->get_sn, 'au', 'Check sn is "au"');
135
# Do the same with the constructor object.
136
ok( my $ctor = $class->constructors('new'), 'Get "new" constructor object' );
137
ok( $obj = $ctor->call(__PACKAGE__,
142
"Create another new object" );
144
is( $obj->get_id, 10, 'Check 10 ID' );
145
is( $obj->get_name, 'Damian', 'Check Damian name' );
146
is( $obj->get_age, 35, 'Check 35 age' );
147
is( $obj->get_sn, 'au', 'Check sn is "au"');
149
##############################################################################
150
# Set up an inherited package.
151
##############################################################################
152
package Class::Meta::Testarama;
154
use base 'Class::Meta::Test';
158
Class::Meta->new(key => 'testarama')->build;
161
ok( $obj = __PACKAGE__->new, "Create new Testarama object" );
162
ok( $class = __PACKAGE__->my_class, "Get Testarama class object" );
163
is_deeply( [map { $_->name } $class->attributes], [qw(id name)],
164
"Call to attributes() should return public and protected attrs" );
166
# Check id public attribute.
167
is( $obj->get_id, 22, 'Check default ID' );
168
ok( $obj->set_id(12), "Set ID" );
169
is( $obj->get_id, 12, 'Check 12 ID' );
170
ok( $attr = $class->attributes('id'), 'Get "id" attribute object' );
171
is( $attr->get($obj), 12, "Check indirect 12 ID" );
172
ok( $attr->set($obj, 15), "Indirectly set ID" );
173
is( $attr->get($obj), 15, "Check indirect 15 ID" );
175
# Check name protected attribute succeeds.
176
is( $obj->get_name, '', 'Check empty name' );
177
ok( $obj->set_name('Larry'), "Set name" );
178
is( $obj->get_name, 'Larry', 'Check Larry name' );
179
ok( $attr = $class->attributes('name'), 'Get "name" attribute object' );
180
is( $attr->get($obj), 'Larry', 'Check indirect "Larry" name' );
181
ok( $attr->set($obj, 'Chip'), "Indirectly set name" );
182
is( $attr->get($obj), 'Chip', 'Check indirect "chip" name' );
184
# Check age private attribute
185
eval { $obj->set_age(12) };
186
ok( my $err = $@, 'Catch private exception');
187
like( $err, qr/age is a private attribute of Class::Meta::Test/,
188
'Correct private exception');
189
eval { $obj->get_age };
190
ok( $err = $@, 'Catch another private exception');
191
like( $err, qr/age is a private attribute of Class::Meta::Test/,
192
'Correct private exception again');
194
# Check that age fails when accessed indirectly, too.
195
ok( $attr = $class->attributes('age'), 'Get "age" attribute object' );
196
eval { $attr->set($obj, 12) };
197
ok( $err = $@, 'Catch indirect private exception');
198
like( $err, qr/age is a private attribute of Class::Meta::Test/,
199
'Correct indirectprivate exception');
200
eval { $attr->get($obj) };
201
ok( $err = $@, 'Catch another indirect private exception');
202
like( $err, qr/age is a private attribute of Class::Meta::Test/,
203
'Correct indirect private exception again');
205
# Check fail sn trusted attribute
206
eval { $obj->set_sn('foo') };
207
ok( $err = $@, 'Catch private exception');
208
like( $err, qr/sn is a trusted attribute of Class::Meta::Test/,
209
'Correct private exception');
210
eval { $obj->get_sn };
211
ok( $err = $@, 'Catch another private exception');
212
like( $err, qr/sn is a trusted attribute of Class::Meta::Test/,
213
'Correct private exception again');
215
# Check that sn fails when accessed indirectly, too.
216
ok( $attr = $class->attributes('sn'), 'Get "sn" attribute object' );
217
eval { $attr->set($obj, 'foo') };
218
ok( $err = $@, 'Catch indirect private exception');
219
like( $err, qr/sn is a trusted attribute of Class::Meta::Test/,
220
'Correct indirectprivate exception');
221
eval { $attr->get($obj) };
222
ok( $err = $@, 'Catch another indirect private exception');
223
like( $err, qr/sn is a trusted attribute of Class::Meta::Test/,
224
'Correct indirect private exception again');
226
# Make sure that we can set protected attributes via new().
227
ok( $obj = __PACKAGE__->new( id => 10,
229
"Create another new object" );
231
is( $obj->get_id, 10, 'Check 10 ID' );
232
is( $obj->get_name, 'Damian', 'Check Damian name' );
234
# Make sure that the private attribute fails.
235
eval { __PACKAGE__->new( age => 44 ) };
236
ok( $err = $@, 'Catch constructor private exception');
237
like( $err, qr/age is a private attribute of Class::Meta::Test/,
238
'Correct private constructor exception');
240
# Make sure that the trusted attribute fails.
241
eval { __PACKAGE__->new( sn => 'foo' ) };
242
ok( $err = $@, 'Catch constructor trusted exception');
243
like( $err, qr/sn is a trusted attribute of Class::Meta::Test/,
244
'Correct trusted constructor exception');
246
# Do the same with the constructor object.
247
ok( $ctor = $class->constructors('new'), 'Get "new" constructor object' );
248
ok( $obj = $ctor->call(__PACKAGE__,
251
"Create another new object" );
253
is( $obj->get_id, 10, 'Check 10 ID' );
254
is( $obj->get_name, 'Damian', 'Check Damian name' );
256
# Make sure that the private attribute fails.
257
eval { $ctor->call(__PACKAGE__, age => 44 ) };
258
ok( $err = $@, 'Catch indirect constructor private exception');
259
like( $err, qr/age is a private attribute of Class::Meta::Test/,
260
'Correct indirect private constructor exception');
262
# Make sure that the private attribute fails.
263
eval { $ctor->call(__PACKAGE__, sn => 'foo' ) };
264
ok( $err = $@, 'Catch indirect constructor trusted exception');
265
like( $err, qr/sn is a trusted attribute of Class::Meta::Test/,
266
'Correct indirect trusted constructor exception');
268
##############################################################################
269
# Set up a trusted package.
270
##############################################################################
271
package Class::Meta::TrustMe;
274
BEGIN { Test::More->import }
276
ok( $obj = Class::Meta::Test->new, "Create new Test object" );
277
ok( $class = Class::Meta::Test->my_class, "Get Test class object" );
278
is_deeply( [map { $_->name } $class->attributes], [qw(id sn)],
279
"Call to attributes() should return public and trusted attrs" );
280
is_deeply( [map { $_->name } Class::Meta::Testarama->my_class->attributes],
282
"Call to inherited attributes() should also return public and protected attrs" );
284
# Check id public attribute.
285
is( $obj->get_id, 22, 'Check default ID' );
286
ok( $obj->set_id(12), "Set ID" );
287
is( $obj->get_id, 12, 'Check 12 ID' );
288
ok( $attr = $class->attributes('id'), 'Get "id" attribute object' );
289
is( $attr->get($obj), 12, "Check indirect 12 ID" );
290
ok( $attr->set($obj, 15), "Indirectly set ID" );
291
is( $attr->get($obj), 15, "Check indirect 15 ID" );
293
# Check name protected attribute
294
eval { $obj->set_name('foo') };
295
ok( $err = $@, "Catch protected exception");
296
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
297
"Correct protected exception" );
298
eval { $obj->get_name };
299
ok( $err = $@, "Catch another protected exception");
300
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
301
"Another correct protected exception" );
303
# Check that name fails when accessed indirectly, too.
304
ok( $attr = $class->attributes('name'), 'Get "name" attribute object' );
305
eval { $attr->set($obj, 'foo') };
306
ok( $err = $@, "Catch indirect protected exception");
307
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
308
"Correct indirect protected exception" );
309
eval { $attr->get($obj, 'foo') };
310
ok( $err = $@, "Catch another indirect protected exception");
311
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
312
"Another correct indirect protected exception" );
314
# Check age private attribute
315
eval { $obj->set_age(12) };
316
ok( $err = $@, 'Catch private exception');
317
like( $err, qr/age is a private attribute of Class::Meta::Test/,
318
'Correct private exception');
319
eval { $obj->get_age };
320
ok( $err = $@, 'Catch another private exception');
321
like( $err, qr/age is a private attribute of Class::Meta::Test/,
322
'Correct private exception again');
324
# Check that age fails when accessed indirectly, too.
325
ok( $attr = $class->attributes('age'), 'Get "age" attribute object' );
326
eval { $attr->set($obj, 12) };
327
ok( $err = $@, 'Catch indirect private exception');
328
like( $err, qr/age is a private attribute of Class::Meta::Test/,
329
'Correct indirectprivate exception');
330
eval { $attr->get($obj) };
331
ok( $err = $@, 'Catch another indirect private exception');
332
like( $err, qr/age is a private attribute of Class::Meta::Test/,
333
'Correct indirect private exception again');
335
# Check sn trusted attribute succeeds.
336
is( $obj->get_sn, '', 'Check empty sn' );
337
ok( $obj->set_sn('123456789'), "Set sn" );
338
is( $obj->get_sn, '123456789', 'Check "123456789" sn' );
339
ok( $attr = $class->attributes('sn'), 'Get "sn" attribute object' );
340
is( $attr->get($obj), '123456789', 'Check indirect "123456789" sn' );
341
ok( $attr->set($obj, '987654321'), "Indirectly set sn" );
342
is( $attr->get($obj), '987654321', 'Check indirect "987654321" sn' );
344
# Make sure that sn trusted attribute works for subclasses, too.
345
ok( $obj = Class::Meta::Testarama->new, "Create new Testarama object" );
346
is( $obj->get_sn, '', 'Check empty sn' );
347
ok( $obj->set_sn('123456789'), "Set sn" );
348
is( $obj->get_sn, '123456789', 'Check "123456789" sn' );
349
ok( $attr = $class->attributes('sn'), 'Get "sn" attribute object' );
350
is( $attr->get($obj), '123456789', 'Check indirect "123456789" sn' );
351
ok( $attr->set($obj, '987654321'), "Indirectly set sn" );
352
is( $attr->get($obj), '987654321', 'Check indirect "987654321" sn' );
354
# Make sure that we can set trusted attributes via new().
355
ok( $obj = Class::Meta::Test->new( id => 10,
357
"Create another new object" );
358
is( $obj->get_id, 10, 'Check 10 ID' );
359
is( $obj->get_sn, 'foo', 'Check foo sn' );
361
# Make sure that the private attribute fails.
362
eval { Class::Meta::Test->new( age => 44 ) };
363
ok( $err = $@, "Catch constructor private exception");
364
like( $err, qr/age is a private attribute of Class::Meta::Test/,
365
"Got the right constructor private exception");
367
# Make sure that the protected attribute fails.
368
eval { Class::Meta::Test->new( name => 'Damian' ) };
369
ok( $err = $@, "Catch constructor protected exception");
370
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
371
"Got the right constructor protected exception");
373
# Do the same with the new constructor object.
374
ok( $ctor = $class->constructors('new'), 'Get "new" constructor object' );
375
ok( $obj = $ctor->call('Class::Meta::Test',
378
"Create another new object" );
380
is( $obj->get_id, 10, 'Check 10 ID' );
381
is( $obj->get_sn, 'foo', 'Check foo sn' );
383
# Make sure that the private attribute fails.
384
eval { $ctor->call('Class::Meta::Test', age => 44 ) };
385
ok( $err = $@, "Catch indirect constructor private exception");
386
like( $err, qr/age is a private attribute of Class::Meta::Test/,
387
"Got the right indirect constructor private exception");
389
# Make sure that the protected attribute fails.
390
eval { $ctor->call('Class::Meta::Test', name => 'Damian' ) };
391
ok( $err = $@, "Catch indirect constructor protected exception");
392
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
393
"Got the right indirect constructor protected exception");
395
##############################################################################
396
# Now do test in a completely independent package.
397
##############################################################################
400
ok( $obj = Class::Meta::Test->new, "Create new object in main" );
401
ok( $class = Class::Meta::Test->my_class, "Get class object in main" );
403
# Make sure we can access id.
404
is( $obj->get_id, 22, 'Check default ID' );
405
ok( $obj->set_id(12), "Set ID" );
406
is( $obj->get_id, 12, 'Check 12 ID' );
407
ok( $attr = $class->attributes('id'), 'Get "id" attribute object' );
408
is( $attr->get($obj), 12, "Check indirect 12 ID" );
409
ok( $attr->set($obj, 15), "Indirectly set ID" );
410
is( $attr->get($obj), 15, "Check indirect 15 ID" );
412
# Check name protected attribute
413
eval { $obj->set_name('foo') };
414
ok( $err = $@, 'Catch protected exception');
415
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
416
'Correct protected exception');
417
eval { $obj->get_name };
418
ok( $err = $@, 'Catch another protected exception');
419
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
420
'Correct protected exception again');
422
# Check that name fails when accessed indirectly, too.
423
ok( $attr = $class->attributes('name'), 'Get "name" attribute object' );
424
eval { $attr->set($obj, 'foo') };
425
ok( $err = $@, 'Catch indirect protected exception');
426
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
427
'Correct indirectprotected exception');
428
eval { $attr->get($obj) };
429
ok( $err = $@, 'Catch another indirect protected exception');
430
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
431
'Correct indirect protected exception again');
433
# Check age private attribute
434
eval { $obj->set_age(12) };
435
ok( $err = $@, 'Catch private exception');
436
like( $err, qr/age is a private attribute of Class::Meta::Test/,
437
'Correct private exception');
438
eval { $obj->get_age };
439
ok( $err = $@, 'Catch another private exception');
440
like( $err, qr/age is a private attribute of Class::Meta::Test/,
441
'Correct private exception again');
443
# Check that age fails when accessed indirectly, too.
444
ok( $attr = $class->attributes('age'), 'Get "age" attribute object' );
445
eval { $attr->set($obj, 12) };
446
ok( $err = $@, 'Catch indirect private exception');
447
like( $err, qr/age is a private attribute of Class::Meta::Test/,
448
'Correct indirectprivate exception');
449
eval { $attr->get($obj) };
450
ok( $err = $@, 'Catch another indirect private exception');
451
like( $err, qr/age is a private attribute of Class::Meta::Test/,
452
'Correct indirect private exception again');
454
# Check sn trusted attribute
455
eval { $obj->set_sn('foo') };
456
ok( $err = $@, 'Catch private exception');
457
like( $err, qr/sn is a trusted attribute of Class::Meta::Test/,
458
'Correct private exception');
459
eval { $obj->get_sn };
460
ok( $err = $@, 'Catch another private exception');
461
like( $err, qr/sn is a trusted attribute of Class::Meta::Test/,
462
'Correct private exception again');
464
# Check that sn fails when accessed indirectly, too.
465
ok( $attr = $class->attributes('sn'), 'Get "sn" attribute object' );
466
eval { $attr->set($obj, 'foo') };
467
ok( $err = $@, 'Catch indirect private exception');
468
like( $err, qr/sn is a trusted attribute of Class::Meta::Test/,
469
'Correct indirectprivate exception');
470
eval { $attr->get($obj) };
471
ok( $err = $@, 'Catch another indirect private exception');
472
like( $err, qr/sn is a trusted attribute of Class::Meta::Test/,
473
'Correct indirect private exception again');
475
# Try the constructor with parameters.
476
ok( $obj = Class::Meta::Test->new( id => 1 ), "Create new object with id" );
477
is( $obj->get_id, 1, 'Check 1 ID' );
478
ok( $ctor = $class->constructors('new'), "Get new constructor" );
479
ok( $obj = $ctor->call('Class::Meta::Test', id => 52 ),
480
"Indirectly create new object with id" );
481
is( $obj->get_id, 52, 'Check 52 ID' );
483
# Make sure that the protected attribute fails.
484
eval { Class::Meta::Test->new( name => 'foo' ) };
485
ok( $err = $@, 'Catch constructor protected exception');
486
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
487
'Correct protected constructor exception');
488
eval { $ctor->call('Class::Meta::Test', name => 'foo' ) };
489
ok( $err = $@, 'Catch indirect constructor protected exception');
490
like( $err, qr/name is a protected attribute of Class::Meta::Test/,
491
'Correct indirect protected constructor exception');
493
# Make sure that the private attribute fails.
494
eval { Class::Meta::Test->new( age => 44 ) };
495
ok( $err = $@, 'Catch constructor private exception');
496
like( $err, qr/age is a private attribute of Class::Meta::Test/,
497
'Correct private constructor exception');
498
eval { $ctor->call('Class::Meta::Test', age => 44 ) };
499
ok( $err = $@, 'Catch indirect constructor private exception');
500
like( $err, qr/age is a private attribute of Class::Meta::Test/,
501
'Correct indirect private constructor exception');