module_name => 'MooseX::AttributeHelpers',
license => 'perl',
requires => {
- 'Moose' => '0.24',
+ 'Class::MOP' => '0.46',
+ 'Moose' => '0.30',
},
optional => {
},
Revision history for Perl extension MooseX-AttributeHelpers
-0.03
+0.04
+ * MooseX::AttributeHelpers::Base
+ - changing this to use the new Class::MOP::Attribute
+ reader and write method ref stuff.
+ - fixed this to use find_or_create_type_constraint
+ instead of trying to parse stuff on our own.
+
+ * MooseX::AttributeHelpers::Collection
+ - this is pretty much empty subclass now cause of
+ the find_or_create_type_constraint fix above
+
+ + MooseX::AttributeHelpers::Collection::ImmutableHash
+ + MooseX::AttributeHelpers::Collection::Bag
+ - added these two new collection types
+ - added method provider roles for them
+ - added tests for them
+
+ * MooseX::AttributeHelpers::MethodProvider::Hash
+ - this is now composed from the ImmutableHash
+ method provider
+
+ * t/
+ - fixed the plans on all the tests
+
+0.03 Mon. Sept. 17, 2007
~~ more misc. doc updates ~~
* MooseX::AttributeHelpers::Counter
Build.PL
ChangeLog
-META.yml
-Makefile.PL
MANIFEST
-MANIFEST.SKIP
README
+META.yml
+Makefile.PL
lib/MooseX/AttributeHelpers.pm
lib/MooseX/AttributeHelpers/Base.pm
lib/MooseX/AttributeHelpers/Collection.pm
lib/MooseX/AttributeHelpers/Counter.pm
lib/MooseX/AttributeHelpers/Number.pm
lib/MooseX/AttributeHelpers/Collection/Array.pm
+lib/MooseX/AttributeHelpers/Collection/Bag.pm
lib/MooseX/AttributeHelpers/Collection/Hash.pm
+lib/MooseX/AttributeHelpers/Collection/ImmutableHash.pm
lib/MooseX/AttributeHelpers/Collection/List.pm
lib/MooseX/AttributeHelpers/Meta/Method/Provided.pm
lib/MooseX/AttributeHelpers/MethodProvider/Array.pm
+lib/MooseX/AttributeHelpers/MethodProvider/Bag.pm
lib/MooseX/AttributeHelpers/MethodProvider/Counter.pm
lib/MooseX/AttributeHelpers/MethodProvider/Hash.pm
+lib/MooseX/AttributeHelpers/MethodProvider/ImmutableHash.pm
lib/MooseX/AttributeHelpers/MethodProvider/List.pm
t/000_load.t
t/001_basic_counter.t
t/003_basic_hash.t
t/004_basic_number.t
t/005_basic_list.t
+t/006_basic_bag.t
t/010_array_from_role.t
+t/011_counter_with_defaults.t
t/100_collection_with_roles.t
t/pod.t
t/pod_coverage.t
-MooseX::AttributeHelpers version 0.03
+MooseX::AttributeHelpers version 0.04
===========================
See the individual module documentation for more information
package MooseX::AttributeHelpers;
-our $VERSION = '0.03';
+our $VERSION = '0.04';
our $AUTHORITY = 'cpan:STEVAN';
use MooseX::AttributeHelpers::Meta::Method::Provided;
use MooseX::AttributeHelpers::Collection::List;
use MooseX::AttributeHelpers::Collection::Array;
use MooseX::AttributeHelpers::Collection::Hash;
+use MooseX::AttributeHelpers::Collection::ImmutableHash;
+use MooseX::AttributeHelpers::Collection::Bag;
1;
use Moose;
use Moose::Util::TypeConstraints;
-our $VERSION = '0.02';
+our $VERSION = '0.03';
our $AUTHORITY = 'cpan:STEVAN';
extends 'Moose::Meta::Attribute';
my $isa = $options->{isa};
unless (blessed($isa) && $isa->isa('Moose::Meta::TypeConstraint')) {
- $isa = find_type_constraint($isa);
+ $isa = Moose::Util::TypeConstraints::find_or_create_type_constraint($isa);
}
($isa->is_a_type_of($type))
# grab the reader and writer methods
# as well, this will be useful for
# our method provider constructors
- my ($attr_reader, $attr_writer);
- if (my $reader = $attr->get_read_method) {
- $attr_reader = $class->get_method($reader);
- }
- else {
- $attr_reader = sub { $attr->get_value(@_) };
- }
-
- if (my $writer = $attr->get_write_method) {
- $attr_writer = $class->get_method($writer);
- }
- else {
- $attr_writer = sub { $attr->set_value(@_) };
- }
+ my $attr_reader = $attr->get_read_method_ref;
+ my $attr_writer = $attr->get_write_method_ref;
+
# before we install them, lets
# make sure they are valid
foreach my $key (keys %{$attr->provides}) {
my $method_name = $attr->provides->{$key};
+
+ if ($class->has_method($method_name)) {
+ confess "The method ($method_name) already exists in class (" . $class->name . ")";
+ }
+
my $method_body = $method_constructors->{$key}->(
$attr,
$attr_reader,
$attr_writer,
);
- if ($class->has_method($method_name)) {
- confess "The method ($method_name) already exists in class (" . $class->name . ")";
- }
-
$class->add_method($method_name =>
MooseX::AttributeHelpers::Meta::Method::Provided->wrap(
$method_body,
package MooseX::AttributeHelpers::Collection;
use Moose;
-use Moose::Util::TypeConstraints;
-our $VERSION = '0.01';
+our $VERSION = '0.03';
our $AUTHORITY = 'cpan:STEVAN';
extends 'MooseX::AttributeHelpers::Base';
-has 'container_type' => (
- is => 'ro',
- isa => 'Str',
- predicate => 'has_container_type',
-);
-
-has 'container_type_constraint' => (
- is => 'rw',
- isa => 'Moose::Meta::TypeConstraint',
-);
-
-before 'process_options_for_provides' => sub {
- my ($self, $options) = @_;
-
- if (exists $options->{isa}) {
- my $type = $options->{isa};
-
- # ... we should check if the type exists already
- # and then we should use it,.. however, this means
- # we need to extract the container type constraint
- # as well, which is a little trickier
-
- if ($type =~ /^(.*)\[(.*)\]$/) {
- my $core_type = $1;
- my $container_type = $2;
-
- $options->{container_type} = $container_type;
-
- my $container_type_constraint = find_type_constraint($container_type);
-
- # NOTE:
- # I am not sure DWIM-ery is a good thing
- # here, so i am going to err on the side
- # of caution, and blow up if you have
- # not made a type constraint for this yet.
- # - SL
- (defined $container_type_constraint)
- || confess "You must predefine the '$container_type' constraint before you can use it as a container type";
-
- $options->{container_type_constraint} = $container_type_constraint;
-
- if ($core_type eq 'ArrayRef') {
- $options->{isa} = subtype('ArrayRef' => where {
- foreach my $x (@$_) { ($container_type_constraint->check($x)) || return } 1;
- });
- }
- elsif ($core_type eq 'HashRef') {
- $options->{isa} = subtype('HashRef' => where {
- foreach my $x (values %$_) { ($container_type_constraint->check($x)) || return } 1;
- });
- }
- else {
- confess "Your isa must be either ArrayRef or HashRef (sorry no subtype support yet)";
- }
- }
- }
-};
-
no Moose;
-no Moose::Util::TypeConstraints;
1;
--- /dev/null
+
+package MooseX::AttributeHelpers::Collection::Bag;
+use Moose;
+use Moose::Util::TypeConstraints;
+
+our $VERSION = '0.01';
+our $AUTHORITY = 'cpan:STEVAN';
+
+use MooseX::AttributeHelpers::MethodProvider::Bag;
+
+extends 'MooseX::AttributeHelpers::Collection';
+
+has '+method_provider' => (
+ default => 'MooseX::AttributeHelpers::MethodProvider::Bag'
+);
+
+subtype 'Bag' => as 'HashRef[Int]';
+
+sub helper_type { 'Bag' }
+
+before 'process_options_for_provides' => sub {
+ my ($self, $options, $name) = @_;
+
+ # Set some default attribute options here unless already defined
+ if ((my $type = $self->helper_type) && !exists $options->{isa}){
+ $options->{isa} = $type;
+ }
+
+ $options->{default} = sub { +{} } unless exists $options->{default};
+};
+
+no Moose;
+no Moose::Util::TypeConstraints;
+
+# register the alias ...
+package Moose::Meta::Attribute::Custom::Collection::Bag;
+sub register_implementation { 'MooseX::AttributeHelpers::Collection::Bag' }
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+MooseX::AttributeHelpers::Collection::Bag
+
+=head1 SYNOPSIS
+
+ package Stuff;
+ use Moose;
+ use MooseX::AttributeHelpers;
+
+ has 'word_histogram' => (
+ metaclass => 'Collection::Bag',
+ is => 'ro',
+ isa => 'Bag', # optional ... as is defalt
+ provides => {
+ 'add' => 'add_word',
+ 'get' => 'get_count_for',
+ 'empty' => 'has_any_words',
+ 'count' => 'num_words',
+ 'delete' => 'delete_word',
+ }
+ );
+
+=head1 DESCRIPTION
+
+This module provides a Bag attribute which provides a number of
+bag-like operations. See L<MooseX::AttributeHelpers::MethodProvider::Bag>
+for more details.
+
+=head1 METHODS
+
+=over 4
+
+=item B<meta>
+
+=item B<method_provider>
+
+=item B<has_method_provider>
+
+=item B<helper_type>
+
+=item B<process_options_for_provides>
+
+=back
+
+=head1 BUGS
+
+All complex software has bugs lurking in it, and this module is no
+exception. If you find a bug please either email me, or add the bug
+to cpan-RT.
+
+=head1 AUTHOR
+
+Stevan Little E<lt>stevan@iinteractive.comE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 by Infinity Interactive, Inc.
+
+L<http://www.iinteractive.com>
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
\ No newline at end of file
package MooseX::AttributeHelpers::Collection::Hash;
use Moose;
-our $VERSION = '0.01';
+our $VERSION = '0.02';
our $AUTHORITY = 'cpan:STEVAN';
use MooseX::AttributeHelpers::MethodProvider::Hash;
=head1 DESCRIPTION
-This module provides an Array attribute which provides a number of
-array operations. See L<MooseX::AttributeHelpers::MethodProvider::Hash>
+This module provides an Hash attribute which provides a number of
+hash-like operations. See L<MooseX::AttributeHelpers::MethodProvider::Hash>
for more details.
=head1 METHODS
--- /dev/null
+
+package MooseX::AttributeHelpers::Collection::ImmutableHash;
+use Moose;
+
+our $VERSION = '0.01';
+our $AUTHORITY = 'cpan:STEVAN';
+
+use MooseX::AttributeHelpers::MethodProvider::ImmutableHash;
+
+extends 'MooseX::AttributeHelpers::Collection';
+
+has '+method_provider' => (
+ default => 'MooseX::AttributeHelpers::MethodProvider::ImmutableHash'
+);
+
+sub helper_type { 'HashRef' }
+
+no Moose;
+
+# register the alias ...
+package Moose::Meta::Attribute::Custom::Collection::ImmutableHash;
+sub register_implementation { 'MooseX::AttributeHelpers::Collection::ImmutableHash' }
+
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+MooseX::AttributeHelpers::Collection::ImmutableHash
+
+=head1 SYNOPSIS
+
+ package Stuff;
+ use Moose;
+ use MooseX::AttributeHelpers;
+
+ has 'options' => (
+ metaclass => 'Collection::ImmutableHash',
+ is => 'ro',
+ isa => 'HashRef[Str]',
+ default => sub { {} },
+ provides => {
+ 'get' => 'get_option',
+ 'empty' => 'has_options',
+ 'keys' => 'get_option_list',
+ }
+ );
+
+=head1 DESCRIPTION
+
+This module provides a immutable HashRef attribute which provides a number of
+hash-line operations. See L<MooseX::AttributeHelpers::MethodProvider::ImmutableHash>
+for more details.
+
+=head1 METHODS
+
+=over 4
+
+=item B<meta>
+
+=item B<method_provider>
+
+=item B<has_method_provider>
+
+=item B<helper_type>
+
+=back
+
+=head1 BUGS
+
+All complex software has bugs lurking in it, and this module is no
+exception. If you find a bug please either email me, or add the bug
+to cpan-RT.
+
+=head1 AUTHOR
+
+Stevan Little E<lt>stevan@iinteractive.comE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 by Infinity Interactive, Inc.
+
+L<http://www.iinteractive.com>
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
\ No newline at end of file
package MooseX::AttributeHelpers::Counter;
use Moose;
-our $VERSION = '0.02';
+our $VERSION = '0.03';
our $AUTHORITY = 'cpan:STEVAN';
use MooseX::AttributeHelpers::MethodProvider::Counter;
my ($self, $options, $name) = @_;
# Set some default attribute options here unless already defined
- if (my $type = $self->helper_type && !exists $options->{isa}){
- $options->{isa} = $self->helper_type;
+ if ((my $type = $self->helper_type) && !exists $options->{isa}){
+ $options->{isa} = $type;
}
$options->{is} = 'ro' unless exists $options->{is};
package MooseX::AttributeHelpers::MethodProvider::Array;
use Moose::Role;
-our $VERSION = '0.03';
+our $VERSION = '0.05';
our $AUTHORITY = 'cpan:STEVAN';
with 'MooseX::AttributeHelpers::MethodProvider::List';
sub push : method {
my ($attr, $reader, $writer) = @_;
- if ($attr->has_container_type) {
- my $container_type_constraint = $attr->container_type_constraint;
+ if ($attr->has_type_constraint && $attr->type_constraint->isa('Moose::Meta::TypeConstraint::Parameterized')) {
+ my $container_type_constraint = $attr->type_constraint->type_parameter;
return sub {
my $instance = CORE::shift;
$container_type_constraint->check($_)
sub unshift : method {
my ($attr, $reader, $writer) = @_;
- if ($attr->has_container_type) {
- my $container_type_constraint = $attr->container_type_constraint;
+ if ($attr->has_type_constraint && $attr->type_constraint->isa('Moose::Meta::TypeConstraint::Parameterized')) {
+ my $container_type_constraint = $attr->type_constraint->type_parameter;
return sub {
my $instance = CORE::shift;
$container_type_constraint->check($_)
sub set : method {
my ($attr, $reader, $writer) = @_;
- if ($attr->has_container_type) {
- my $container_type_constraint = $attr->container_type_constraint;
+ if ($attr->has_type_constraint && $attr->type_constraint->isa('Moose::Meta::TypeConstraint::Parameterized')) {
+ my $container_type_constraint = $attr->type_constraint->type_parameter;
return sub {
($container_type_constraint->check($_[2]))
|| confess "Value " . ($_[2]||'undef') . " did not pass container type constraint";
sub insert : method {
my ($attr, $reader, $writer) = @_;
- if ($attr->has_container_type) {
- my $container_type_constraint = $attr->container_type_constraint;
+ if ($attr->has_type_constraint && $attr->type_constraint->isa('Moose::Meta::TypeConstraint::Parameterized')) {
+ my $container_type_constraint = $attr->type_constraint->type_parameter;
return sub {
($container_type_constraint->check($_[2]))
|| confess "Value " . ($_[2]||'undef') . " did not pass container type constraint";
- splice @{$reader->($_[0])}, $_[1], 0, $_[2];
+ CORE::splice @{$reader->($_[0])}, $_[1], 0, $_[2];
};
}
else {
return sub {
- splice @{$reader->($_[0])}, $_[1], 0, $_[2];
+ CORE::splice @{$reader->($_[0])}, $_[1], 0, $_[2];
};
}
}
--- /dev/null
+package MooseX::AttributeHelpers::MethodProvider::Bag;
+use Moose::Role;
+
+our $VERSION = '0.02';
+our $AUTHORITY = 'cpan:STEVAN';
+
+with 'MooseX::AttributeHelpers::MethodProvider::ImmutableHash';
+
+sub add : method {
+ my ($attr, $reader, $writer) = @_;
+ return sub { $reader->($_[0])->{$_[1]}++ };
+}
+
+sub delete : method {
+ my ($attr, $reader, $writer) = @_;
+ return sub { CORE::delete $reader->($_[0])->{$_[1]} };
+}
+
+sub reset : method {
+ my ($attr, $reader, $writer) = @_;
+ return sub { $reader->($_[0])->{$_[1]} = 0 };
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+MooseX::AttributeHelpers::MethodProvider::Bag
+
+=head1 DESCRIPTION
+
+This is a role which provides the method generators for
+L<MooseX::AttributeHelpers::Collection::Bag>.
+
+This role is composed from the
+L<MooseX::AttributeHelpers::Collection::ImmutableHash> role.
+
+=head1 METHODS
+
+=over 4
+
+=item B<meta>
+
+=back
+
+=head1 PROVIDED METHODS
+
+=over 4
+
+=item B<count>
+
+=item B<delete>
+
+=item B<empty>
+
+=item B<exists>
+
+=item B<get>
+
+=item B<keys>
+
+=item B<add>
+
+=item B<reset>
+
+=item B<values>
+
+=item B<kv>
+
+=back
+
+=head1 BUGS
+
+All complex software has bugs lurking in it, and this module is no
+exception. If you find a bug please either email me, or add the bug
+to cpan-RT.
+
+=head1 AUTHOR
+
+Stevan Little E<lt>stevan@iinteractive.comE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 by Infinity Interactive, Inc.
+
+L<http://www.iinteractive.com>
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
package MooseX::AttributeHelpers::MethodProvider::Hash;
use Moose::Role;
-our $VERSION = '0.01';
+our $VERSION = '0.03';
our $AUTHORITY = 'cpan:STEVAN';
-sub exists : method {
- my ($attr, $reader, $writer) = @_;
- return sub { exists $reader->($_[0])->{$_[1]} ? 1 : 0 };
-}
-
-sub get : method {
- my ($attr, $reader, $writer) = @_;
- return sub { $reader->($_[0])->{$_[1]} };
-}
+with 'MooseX::AttributeHelpers::MethodProvider::ImmutableHash';
sub set : method {
my ($attr, $reader, $writer) = @_;
- if ($attr->has_container_type) {
- my $container_type_constraint = $attr->container_type_constraint;
+ if ($attr->has_type_constraint && $attr->type_constraint->isa('Moose::Meta::TypeConstraint::Parameterized')) {
+ my $container_type_constraint = $attr->type_constraint->type_parameter;
return sub {
($container_type_constraint->check($_[2]))
|| confess "Value " . ($_[2]||'undef') . " did not pass container type constraint";
}
}
-sub keys : method {
- my ($attr, $reader, $writer) = @_;
- return sub { keys %{$reader->($_[0])} };
-}
-
-sub values : method {
- my ($attr, $reader, $writer) = @_;
- return sub { values %{$reader->($_[0])} };
-}
-
-sub count : method {
- my ($attr, $reader, $writer) = @_;
- return sub { scalar keys %{$reader->($_[0])} };
-}
-
-sub empty : method {
- my ($attr, $reader, $writer) = @_;
- return sub { scalar keys %{$reader->($_[0])} ? 1 : 0 };
-}
-
sub clear : method {
my ($attr, $reader, $writer) = @_;
return sub { %{$reader->($_[0])} = () };
sub delete : method {
my ($attr, $reader, $writer) = @_;
- return sub { delete $reader->($_[0])->{$_[1]} };
+ return sub { CORE::delete $reader->($_[0])->{$_[1]} };
}
1;
This is a role which provides the method generators for
L<MooseX::AttributeHelpers::Collection::Hash>.
+This role is composed from the
+L<MooseX::AttributeHelpers::Collection::ImmutableHash> role.
+
=head1 METHODS
=over 4
=item B<values>
+=item B<kv>
+
=back
=head1 BUGS
--- /dev/null
+package MooseX::AttributeHelpers::MethodProvider::ImmutableHash;
+use Moose::Role;
+
+our $VERSION = '0.03';
+our $AUTHORITY = 'cpan:STEVAN';
+
+sub exists : method {
+ my ($attr, $reader, $writer) = @_;
+ return sub { CORE::exists $reader->($_[0])->{$_[1]} ? 1 : 0 };
+}
+
+sub get : method {
+ my ($attr, $reader, $writer) = @_;
+ return sub { $reader->($_[0])->{$_[1]} };
+}
+
+sub keys : method {
+ my ($attr, $reader, $writer) = @_;
+ return sub { CORE::keys %{$reader->($_[0])} };
+}
+
+sub values : method {
+ my ($attr, $reader, $writer) = @_;
+ return sub { CORE::values %{$reader->($_[0])} };
+}
+
+sub kv : method {
+ my ($attr, $reader, $writer) = @_;
+ return sub {
+ my $h = $reader->($_[0]);
+ map {
+ [ $_, $h->{$_} ]
+ } CORE::keys %{$h}
+ };
+}
+
+sub count : method {
+ my ($attr, $reader, $writer) = @_;
+ return sub { scalar CORE::keys %{$reader->($_[0])} };
+}
+
+sub empty : method {
+ my ($attr, $reader, $writer) = @_;
+ return sub { scalar CORE::keys %{$reader->($_[0])} ? 1 : 0 };
+}
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+MooseX::AttributeHelpers::MethodProvider::ImmutableHash
+
+=head1 DESCRIPTION
+
+This is a role which provides the method generators for
+L<MooseX::AttributeHelpers::Collection::ImmutableHash>.
+
+=head1 METHODS
+
+=over 4
+
+=item B<meta>
+
+=back
+
+=head1 PROVIDED METHODS
+
+=over 4
+
+=item B<count>
+
+=item B<empty>
+
+=item B<exists>
+
+=item B<get>
+
+=item B<keys>
+
+=item B<values>
+
+=item B<kv>
+
+=back
+
+=head1 BUGS
+
+All complex software has bugs lurking in it, and this module is no
+exception. If you find a bug please either email me, or add the bug
+to cpan-RT.
+
+=head1 AUTHOR
+
+Stevan Little E<lt>stevan@iinteractive.comE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 by Infinity Interactive, Inc.
+
+L<http://www.iinteractive.com>
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
use strict;
use warnings;
-use Test::More no_plan => 1;
+use Test::More tests => 1;
BEGIN {
use_ok('MooseX::AttributeHelpers');
use strict;
use warnings;
-use Test::More no_plan => 1;
+use Test::More tests => 14;
BEGIN {
use_ok('MooseX::AttributeHelpers');
use strict;
use warnings;
-use Test::More no_plan => 1;
+use Test::More tests => 51;
use Test::Exception;
BEGIN {
'clear' => 'clear_options',
}, '... got the right provies mapping');
-is($options->container_type, 'Int', '... got the right container type');
+is($options->type_constraint->type_parameter, 'Int', '... got the right container type');
use strict;
use warnings;
-use Test::More no_plan => 1;
+use Test::More tests => 26;
use Test::Exception;
BEGIN {
use strict;
use warnings;
-use Test::More no_plan => 1;
+use Test::More tests => 18;
BEGIN {
use_ok('MooseX::AttributeHelpers');
use strict;
use warnings;
-use Test::More no_plan => 1;
+use Test::More tests => 16;
use Test::Exception;
BEGIN {
'empty' => 'has_options',
}, '... got the right provies mapping');
-is($options->container_type, 'Int', '... got the right container type');
+is($options->type_constraint->type_parameter, 'Int', '... got the right container type');
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 18;
+use Test::Exception;
+
+BEGIN {
+ use_ok('MooseX::AttributeHelpers');
+}
+
+{
+ package Stuff;
+ use Moose;
+ use MooseX::AttributeHelpers;
+
+ has 'word_histogram' => (
+ metaclass => 'Collection::Bag',
+ is => 'ro',
+ provides => {
+ 'add' => 'add_word',
+ 'get' => 'get_count_for',
+ 'empty' => 'has_any_words',
+ 'count' => 'num_words',
+ 'delete' => 'delete_word',
+ }
+ );
+}
+
+my $stuff = Stuff->new();
+isa_ok($stuff, 'Stuff');
+
+can_ok($stuff, $_) for qw[
+ add_word
+ get_count_for
+ has_any_words
+ num_words
+ delete_word
+];
+
+ok(!$stuff->has_any_words, '... we have no words');
+is($stuff->num_words, 0, '... we have no words');
+
+lives_ok {
+ $stuff->add_word('bar');
+} '... set the words okay';
+
+ok($stuff->has_any_words, '... we have words');
+is($stuff->num_words, 1, '... we have 1 word(s)');
+is($stuff->get_count_for('bar'), 1, '... got words now');
+
+lives_ok {
+ $stuff->add_word('foo');
+ $stuff->add_word('bar') for 0 .. 3;
+ $stuff->add_word('baz') for 0 .. 10;
+} '... set the words okay';
+
+is($stuff->num_words, 3, '... we still have 1 word(s)');
+is($stuff->get_count_for('foo'), 1, '... got words now');
+is($stuff->get_count_for('bar'), 5, '... got words now');
+is($stuff->get_count_for('baz'), 11, '... got words now');
+
+
+
use strict;
use warnings;
-use Test::More no_plan => 1;
+use Test::More tests => 3;
use Test::Exception;
BEGIN {
use strict;
use warnings;
-use Test::More no_plan => 1;
+use Test::More tests => 14;
BEGIN {
use_ok('MooseX::AttributeHelpers');
use strict;
use warnings;
-use Test::More no_plan => 1;
+use Test::More tests => 29;
BEGIN {
use_ok('MooseX::AttributeHelpers');