-
Notifications
You must be signed in to change notification settings - Fork 36
/
011-more-extensions.t
88 lines (67 loc) · 2.6 KB
/
011-more-extensions.t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
use mop;
class ValidatedAttribute extends mop::attribute {
has $!validator is ro = sub { 1 };
}
class ValidatedAccessorMeta extends mop::class {
method attribute_class { 'ValidatedAttribute' }
method FINALIZE {
foreach my $attribute ( $self->attributes ) {
my $name = $attribute->name;
my $validator = $attribute->validator;
my $accessor_name = $attribute->key_name;
$self->add_method(
$self->method_class->new(
name => $accessor_name,
body => sub {
my $self = shift;
if (@_) {
my $value = shift;
die "invalid value '$value' for attribute '$name'"
unless $validator->($value);
$attribute->store_data_in_slot_for($self, $value);
}
$attribute->fetch_data_in_slot_for($self);
}
)
);
}
$self->next::method;
}
}
sub validated {
my ($meta, $validator) = @_;
my $meta_attr = mop::meta($meta)->get_attribute('$!validator');
$meta_attr->store_data_in_slot_for($meta, $validator);
}
class Foo meta ValidatedAccessorMeta {
has $!bar;
has $!baz;
has $!age is validated(sub { $_[0] =~ /^\d+$/ });
}
ok(mop::meta('Foo')->has_method('bar'), '... the bar method was generated for us');
ok(mop::meta('Foo')->has_method('baz'), '... the baz method was generated for us');
{
my $foo = Foo->new;
ok($foo->isa( 'Foo' ), '... we is-a Foo');
ok($foo->isa( 'mop::object' ), '... we is-a Object');
is($foo->bar, undef, '... there is no value for bar');
is($foo->baz, undef, '... there is no value for baz');
is($foo->age, undef, '... there is no value for age');
eval { $foo->bar( 100 ) };
is($@, "", '... set the bar value without dying');
eval { $foo->baz( 'BAZ' ) };
is($@, "", '... set the baz value without dying');
eval { $foo->age( 34 ) };
is($@, "", '... set the age value without dying');
is($foo->bar, 100, '... and got the expected value for bar');
is($foo->baz, 'BAZ', '... and got the expected value for bar');
is($foo->age, 34, '... and got the expected value for age');
eval { $foo->age( 'not an int' ) };
like($@, qr/invalid value 'not an int' for attribute '\$\!age'/, '... could not set to a non-int value');
is($foo->age, 34, '... kept the old value of age');
}
done_testing;