From 80232d581e7a82f0ec8bd85d269a1604fdbe58c7 Mon Sep 17 00:00:00 2001 From: Brian Phillips Date: Tue, 4 Dec 2012 22:27:23 -0600 Subject: clean up types - Split out type declarations into separate class - Use namespaced types instead of global types (via MooseX::Types) - use declared types where possible, instead of quoted type names (i.e. isa => Str, instead of isa => 'Str') - Allow "authentication" attribute to coerce from a JSON::is_bool() value (instead of expecting it to be a 1 or a 0 all the time) --- lib/Net/HTTP/Spore/Meta/Method.pm | 60 ++++++++-------------------------- lib/Net/HTTP/Spore/Meta/Types.pm | 31 ++++++++++++++++++ lib/Net/HTTP/Spore/Role/Description.pm | 9 +++-- t/spore/01_new_from_string.t | 10 +++++- 4 files changed, 59 insertions(+), 51 deletions(-) create mode 100644 lib/Net/HTTP/Spore/Meta/Types.pm diff --git a/lib/Net/HTTP/Spore/Meta/Method.pm b/lib/Net/HTTP/Spore/Meta/Method.pm index 1a04eca..50e9f92 100644 --- a/lib/Net/HTTP/Spore/Meta/Method.pm +++ b/lib/Net/HTTP/Spore/Meta/Method.pm @@ -4,55 +4,21 @@ package Net::HTTP::Spore::Meta::Method; use JSON; use Moose; -use Moose::Util::TypeConstraints; use MooseX::Types::Moose qw/Str Int ArrayRef HashRef/; use MooseX::Types::URI qw/Uri/; extends 'Moose::Meta::Method'; use Net::HTTP::Spore::Response; +use Net::HTTP::Spore::Meta::Types qw(UriPath HTTPMethod Boolean); -subtype UriPath - => as 'Str' - => where { $_ =~ m!^/! } - => message {"path must start with /"}; - -enum Method => qw(OPTIONS HEAD GET POST PUT DELETE TRACE PATCH); - -subtype 'JSON::XS::Boolean' => as 'JSON::XS::Boolean'; -subtype 'JSON::PP::Boolean' => as 'JSON::PP::Boolean'; -subtype 'Boolean' => as Int => where { $_ eq 1 || $_ eq 0 }; - -coerce 'Boolean' - => from 'JSON::XS::Boolean' - => via { - if ( JSON::is_bool($_) && $_ == JSON::true ) { - return 1 - } - return 0; - } - => from 'JSON::PP::Boolean' - => via { - if ( JSON::is_bool($_) && $_ == JSON::true ) { - return 1; - } - return 0; - } - => from Str - => via { - if ($_ eq 'true') { - return 1; - } - return 0; - }; - -has path => ( is => 'ro', isa => 'UriPath', required => 1 ); -has method => ( is => 'ro', isa => 'Method', required => 1 ); -has description => ( is => 'ro', isa => 'Str', predicate => 'has_description' ); +has path => ( is => 'ro', isa => UriPath, required => 1 ); +has method => ( is => 'ro', isa => HTTPMethod, required => 1 ); +has description => ( is => 'ro', isa => Str, predicate => 'has_description' ); has required_payload => ( is => 'ro', - isa => 'Boolean', + isa => Boolean, predicate => 'payload_is_required', lazy => 1, default => 0, @@ -60,7 +26,7 @@ has required_payload => ( ); has authentication => ( is => 'ro', - isa => 'Boolean', + isa => Boolean, predicate => 'has_authentication', default => 0, coerce => 1, @@ -73,18 +39,18 @@ has base_url => ( ); has formats => ( is => 'ro', - isa => ArrayRef [Str], + isa => ArrayRef[Str], predicate => 'has_formats', ); has headers => ( is => 'ro', - isa => HashRef [Str], + isa => HashRef[Str], predicate => 'has_headers', ); has expected_status => ( traits => ['Array'], is => 'ro', - isa => ArrayRef [Int], + isa => ArrayRef[Int], auto_deref => 1, predicate => 'has_expected_status', handles => { find_expected_status => 'grep', }, @@ -92,27 +58,27 @@ has expected_status => ( has optional_params => ( traits => ['Array'], is => 'ro', - isa => ArrayRef [Str], + isa => ArrayRef[Str], predicate => 'has_optional_params', auto_deref => 1, ); has required_params => ( traits => ['Array'], is => 'ro', - isa => ArrayRef [Str], + isa => ArrayRef[Str], predicate => 'has_required_params', auto_deref => 1, ); has form_data => ( traits => ['Hash'], is => 'ro', - isa => 'HashRef', + isa => HashRef, predicate => 'has_form_data', auto_deref => 1, ); has documentation => ( is => 'ro', - isa => 'Str', + isa => Str, lazy => 1, default => sub { my $self = shift; diff --git a/lib/Net/HTTP/Spore/Meta/Types.pm b/lib/Net/HTTP/Spore/Meta/Types.pm new file mode 100644 index 0000000..3089da3 --- /dev/null +++ b/lib/Net/HTTP/Spore/Meta/Types.pm @@ -0,0 +1,31 @@ +package Net::HTTP::Spore::Meta::Types; + +# ABSTRACT: Moose type definitions for Net::HTTP::Spore + +use Moose::Util::TypeConstraints; +use MooseX::Types -declare => [ qw(UriPath Boolean HTTPMethod JSONBoolean) ]; +use MooseX::Types::Moose qw(Str Int Defined); +use JSON; + +subtype UriPath, + as Str, + where { $_ =~ m!^/! }, + message {"path must start with /"}; + +enum HTTPMethod, qw(OPTIONS HEAD GET POST PUT DELETE TRACE PATCH); + +subtype Boolean, + as Int, + where { $_ eq 1 || $_ eq 0 }; + +subtype JSONBoolean, + as Defined, + where { JSON::is_bool($_) }; + +coerce Boolean, + from JSONBoolean, + via { return $_ == JSON::true() ? 1 : 0 }, + from Str, + via { return $_ eq 'true' ? 1 : 0 }; + +1; diff --git a/lib/Net/HTTP/Spore/Role/Description.pm b/lib/Net/HTTP/Spore/Role/Description.pm index 2723fef..cad1084 100644 --- a/lib/Net/HTTP/Spore/Role/Description.pm +++ b/lib/Net/HTTP/Spore/Role/Description.pm @@ -3,7 +3,9 @@ package Net::HTTP::Spore::Role::Description; # ABSTRACT: attributes for API description use Moose::Role; +use MooseX::Types::Moose qw/ArrayRef/; use MooseX::Types::URI qw/Uri/; +use Net::HTTP::Spore::Meta::Types qw/Boolean/; has base_url => ( is => 'rw', @@ -14,19 +16,20 @@ has base_url => ( has formats => ( is => 'rw', - isa => 'ArrayRef', + isa => ArrayRef, predicate => 'has_formats', ); has authentication => ( is => 'rw', - isa => 'Bool', + isa => Boolean, predicate => 'has_authentication', + coerce => 1, ); has expected_status => ( is => 'rw', - isa => 'Array', + isa => ArrayRef, lazy => 1, default => sub { [] }, ); diff --git a/t/spore/01_new_from_string.t b/t/spore/01_new_from_string.t index 6a21994..834baa3 100644 --- a/t/spore/01_new_from_string.t +++ b/t/spore/01_new_from_string.t @@ -3,7 +3,7 @@ use warnings; use Test::More; use Test::Exception; -plan tests => 27; +plan tests => 28; use JSON; use IO::All; @@ -37,6 +37,12 @@ my $api_without_method = { methods => { get_info => { method => 'PET', path => '/show' } }, }; +my $api_with_authentication = { + base_url => "http://services.org/restapi", + authentication => JSON::true(), + methods => { get_info => { method => 'GET', path => '/show' } }, +}; + dies_ok { Net::HTTP::Spore->new_from_spec }; like $@, qr/specification file is missing/; @@ -70,6 +76,8 @@ like $@, qr/Attribute \(method\) does not pass the type constraint/; ok $client = Net::HTTP::Spore->new_from_string(JSON::encode_json($api_ok)); ok $client->meta->_find_spore_method_by_name(sub{/^get_info$/}); +ok $client = Net::HTTP::Spore->new_from_string(JSON::encode_json($api_with_authentication)); + dies_ok { Net::HTTP::Spore->new_from_strings('/a/b/c', '/a/b/c'); }; -- cgit 1.4.1