Merge pull request #853 from wing328/perl_support_map3

[Perl] update deserialization to support Map and List
This commit is contained in:
Tony Tam 2015-06-17 08:25:45 -07:00
commit dd356b54c0
10 changed files with 280 additions and 31 deletions

View File

@ -198,33 +198,53 @@ sub deserialize
{ {
my ($self, $class, $data) = @_; my ($self, $class, $data) = @_;
$log->debugf("deserializing %s for %s", $data, $class); $log->debugf("deserializing %s for %s", $data, $class);
my $_result;
if (not defined $data) { if (not defined $data) {
return undef; return undef;
} elsif ( lc(substr($class, 0, 4)) eq 'map[') { #hash } elsif ( (substr($class, 0, 5)) eq 'HASH[') { #hash
$_result = \(json_decode $data); if ($class =~ /^HASH\[(.*),(.*)\]$/) {
} elsif ( lc(substr($class, 0, 6)) eq 'array[' ) { # array of data my ($key_type, $type) = ($1, $2);
my %hash;
my $decoded_data = decode_json $data;
foreach my $key (keys %$decoded_data) {
if (ref $decoded_data->{$key} eq 'HASH') {
$hash{$key} = $self->deserialize($type, encode_json $decoded_data->{$key});
} else {
$hash{$key} = $self->deserialize($type, $decoded_data->{$key});
}
}
return \%hash;
} else {
#TODO log error
}
} elsif ( (substr($class, 0, 6)) eq 'ARRAY[' ) { # array of data
return $data if $data eq '[]'; # return if empty array return $data if $data eq '[]'; # return if empty array
my $_sub_class = substr($class, 6, -1); my $_sub_class = substr($class, 6, -1);
my @_json_data = json_decode $data; my $_json_data = decode_json $data;
my @_values = (); my @_values = ();
foreach my $_value (@_json_data) { foreach my $_value (@$_json_data) {
push @_values, $self->deserialize($_sub_class, $_value); if (ref $_value eq 'ARRAY') {
push @_values, $self->deserialize($_sub_class, encode_json $_value);
} else {
push @_values, $self->deserialize($_sub_class, $_value);
}
} }
$_result = \@_values; return \@_values;
} elsif ($class eq 'DateTime') { } elsif ($class eq 'DateTime') {
$_result = DateTime->from_epoch(epoch => str2time($data)); return DateTime->from_epoch(epoch => str2time($data));
} elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { #TODO revise the primitive type } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) {
$_result= $data; return $data;
} else { # model } else { # model
my $_instance = use_module("WWW::{{invokerPackage}}::Object::$class")->new; my $_instance = use_module("WWW::SwaggerClient::Object::$class")->new;
$_result = $_instance->from_hash(decode_json $data); if (ref $data eq "HASH") {
return $_instance->from_hash($data);
} else { # string, need to json decode first
return $_instance->from_hash(decode_json $data);
}
} }
return $_result;
} }
# return 'Accept' based on an array of accept provided # return 'Accept' based on an array of accept provided

View File

@ -198,33 +198,53 @@ sub deserialize
{ {
my ($self, $class, $data) = @_; my ($self, $class, $data) = @_;
$log->debugf("deserializing %s for %s", $data, $class); $log->debugf("deserializing %s for %s", $data, $class);
my $_result;
if (not defined $data) { if (not defined $data) {
return undef; return undef;
} elsif ( lc(substr($class, 0, 4)) eq 'map[') { #hash } elsif ( (substr($class, 0, 5)) eq 'HASH[') { #hash
$_result = \(json_decode $data); if ($class =~ /^HASH\[(.*),(.*)\]$/) {
} elsif ( lc(substr($class, 0, 6)) eq 'array[' ) { # array of data my ($key_type, $type) = ($1, $2);
my %hash;
my $decoded_data = decode_json $data;
foreach my $key (keys %$decoded_data) {
if (ref $decoded_data->{$key} eq 'HASH') {
$hash{$key} = $self->deserialize($type, encode_json $decoded_data->{$key});
} else {
$hash{$key} = $self->deserialize($type, $decoded_data->{$key});
}
}
return \%hash;
} else {
#TODO log error
}
} elsif ( (substr($class, 0, 6)) eq 'ARRAY[' ) { # array of data
return $data if $data eq '[]'; # return if empty array return $data if $data eq '[]'; # return if empty array
my $_sub_class = substr($class, 6, -1); my $_sub_class = substr($class, 6, -1);
my @_json_data = json_decode $data; my $_json_data = decode_json $data;
my @_values = (); my @_values = ();
foreach my $_value (@_json_data) { foreach my $_value (@$_json_data) {
push @_values, $self->deserialize($_sub_class, $_value); if (ref $_value eq 'ARRAY') {
push @_values, $self->deserialize($_sub_class, encode_json $_value);
} else {
push @_values, $self->deserialize($_sub_class, $_value);
}
} }
$_result = \@_values; return \@_values;
} elsif ($class eq 'DateTime') { } elsif ($class eq 'DateTime') {
$_result = DateTime->from_epoch(epoch => str2time($data)); return DateTime->from_epoch(epoch => str2time($data));
} elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) { #TODO revise the primitive type } elsif (grep /^$class$/, ('string', 'int', 'float', 'bool', 'object')) {
$_result= $data; return $data;
} else { # model } else { # model
my $_instance = use_module("WWW::SwaggerClient::Object::$class")->new; my $_instance = use_module("WWW::SwaggerClient::Object::$class")->new;
$_result = $_instance->from_hash(decode_json $data); if (ref $data eq "HASH") {
return $_instance->from_hash($data);
} else { # string, need to json decode first
return $_instance->from_hash(decode_json $data);
}
} }
return $_result;
} }
# return 'Accept' based on an array of accept provided # return 'Accept' based on an array of accept provided

View File

@ -317,7 +317,7 @@ sub new {
# authentication setting, if any # authentication setting, if any
my $auth_settings = ['petstore_auth', 'api_key']; my $auth_settings = ['api_key', 'petstore_auth'];
# make the API Call # make the API Call
my $response = $self->{api_client}->call_api($_resource_path, $_method, my $response = $self->{api_client}->call_api($_resource_path, $_method,

View File

@ -27,7 +27,7 @@
<version>1.2.1</version> <version>1.2.1</version>
<executions> <executions>
<execution> <execution>
<id>Test::More</id> <id>Test::More for Pet</id>
<phase>integration-test</phase> <phase>integration-test</phase>
<goals> <goals>
<goal>exec</goal> <goal>exec</goal>
@ -39,6 +39,19 @@
</arguments> </arguments>
</configuration> </configuration>
</execution> </execution>
<execution>
<id>Test::More for Store</id>
<phase>integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>perl</executable>
<arguments>
<argument>t/02_store_api.t</argument>
</arguments>
</configuration>
</execution>
</executions> </executions>
</plugin> </plugin>
</plugins> </plugins>

View File

@ -0,0 +1,88 @@
use Test::More tests => 22;
use Test::Exception;
use lib 'lib';
use strict;
use warnings;
use JSON;
use_ok('WWW::SwaggerClient::StoreApi');
use_ok('WWW::SwaggerClient::ApiClient');
use_ok('WWW::SwaggerClient::Object::Pet');
use_ok('WWW::SwaggerClient::Object::Tag');
use_ok('WWW::SwaggerClient::Object::Category');
my $api_client = WWW::SwaggerClient::ApiClient->new();
my $store_api = WWW::SwaggerClient::StoreApi->new('api_client' => $api_client);
is $store_api->{api_client}->{base_url}, 'http://petstore.swagger.io/v2', 'get the default base URL from api client';
my $get_inventory_response = $store_api->get_inventory();
like ($get_inventory_response->{pending}, qr/^\d+$/, "pending is numeric");
like ($get_inventory_response->{sold}, qr/^\d+$/, "sold is numeric");
my $pet_json = <<JSON;
{
"pet": {
"id": 0,
"category": {
"id": 0,
"name": "string"
},
"name": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "tag string"
}
],
"status": "available"
}
}
JSON
is ref(decode_json $pet_json), "HASH", "the decoded json string is a hash";
is ref $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}, "WWW::SwaggerClient::Object::Pet", "get Pet object from hash";
is $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}->{name}, "doggie", "get the name of the Pet object";
is $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}->{category}->{name}, "string", "get the category name of the Pet object";
is ref $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}->{category}, "WWW::SwaggerClient::Object::Category", "get the Category the Pet object";
is ref $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}->{tags}[0], "WWW::SwaggerClient::Object::Tag", "get the Tag of the Pet object";
is $api_client->deserialize("HASH[string,Pet]", $pet_json)->{pet}->{tags}[0]->{name}, "tag string", "get the Tag name of the Pet object";
my $array_json = <<JSON;
[
{
"id": 0,
"category": {
"id": 0,
"name": "string"
},
"name": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "tag string"
}
],
"status": "available"
}
]
JSON
is ref(decode_json $array_json), "ARRAY", "the decoded json string is an array";
is ref $api_client->deserialize("ARRAY[Pet]", $array_json)->[0], "WWW::SwaggerClient::Object::Pet", "get Pet object from hash";
is $api_client->deserialize("ARRAY[Pet]", $array_json)->[0]->{name}, "doggie", "get the name of the Pet object";
is $api_client->deserialize("ARRAY[Pet]", $array_json)->[0]->{category}->{name}, "string", "get the category name of the Pet object";
is ref $api_client->deserialize("ARRAY[Pet]", $array_json)->[0]->{category}, "WWW::SwaggerClient::Object::Category", "get the Category the Pet object";
is ref $api_client->deserialize("ARRAY[Pet]", $array_json)->[0]->{tags}->[0], "WWW::SwaggerClient::Object::Tag", "get the Tag[0] the Pet object";
is $api_client->deserialize("ARRAY[Pet]", $array_json)->[0]->{tags}->[0]->{name}, "tag string", "get the tag name the Pet object";

View File

@ -5,6 +5,7 @@ use lib 'lib';
use strict; use strict;
use warnings; use warnings;
use WWW::SwaggerClient::PetApi; use WWW::SwaggerClient::PetApi;
use WWW::SwaggerClient::StoreApi;
use WWW::SwaggerClient::ApiClient; use WWW::SwaggerClient::ApiClient;
use WWW::SwaggerClient::Configuration; use WWW::SwaggerClient::Configuration;
use WWW::SwaggerClient::Object::Pet; use WWW::SwaggerClient::Object::Pet;
@ -45,4 +46,30 @@ print "\nget_pet_by_id:".Dumper $api->get_pet_by_id(pet_id => $pet_id);
print "\nupdate_pet_with_form:".Dumper $api->update_pet_with_form(pet_id => $pet_id, name => 'test_name', status => 'test status'); print "\nupdate_pet_with_form:".Dumper $api->update_pet_with_form(pet_id => $pet_id, name => 'test_name', status => 'test status');
print "\ndelete_pet:".Dumper $api->delete_pet(pet_id => $pet_id); print "\ndelete_pet:".Dumper $api->delete_pet(pet_id => $pet_id);
my $store_api = WWW::SwaggerClient::StoreApi->new();
print "\nget_inventory:".Dumper $store_api->get_inventory();
my $pet_json = <<JSON;
{
"pet": {
"id": 0,
"category": {
"id": 0,
"name": "string"
},
"name": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "tag string"
}
],
"status": "available"
}
}
JSON
print "\napi_client->deserialize:".Dumper($api->{api_client}->deserialize("HASH[string,Pet]", $pet_json));

View File

@ -0,0 +1,5 @@
main: Contrib
title: php-coveralls
internal: yes
todo: yes
wipeout: yes

View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<ruleset name="PHP">
<description>The coding standard for standard PHP application</description>
<exclude-pattern>*/img/*</exclude-pattern>
<exclude-pattern>*/images/*</exclude-pattern>
<exclude-pattern>*/less/*</exclude-pattern>
<exclude-pattern>*/css/*</exclude-pattern>
<exclude-pattern>*/js/*</exclude-pattern>
<exclude-pattern>*.html</exclude-pattern>
<exclude-pattern>*.twig</exclude-pattern>
<exclude-pattern>*.yml</exclude-pattern>
<exclude-pattern>*.xml</exclude-pattern>
<exclude-pattern>*.txt</exclude-pattern>
<exclude-pattern>*.less</exclude-pattern>
<exclude-pattern>*.css</exclude-pattern>
<exclude-pattern>*.js</exclude-pattern>
<exclude-pattern>*.jpg</exclude-pattern>
<exclude-pattern>*.jpeg</exclude-pattern>
<exclude-pattern>*.png</exclude-pattern>
<exclude-pattern>*.gif</exclude-pattern>
<!-- Include the whole PSR-2 standard -->
<rule ref="PSR2"/>
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="140"/>
<property name="absoluteLineLimit" value="0"/>
</properties>
</rule>
</ruleset>

View File

@ -0,0 +1,45 @@
<?xml version="1.0"?>
<ruleset name="My first PHPMD rule set"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="
http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>My custom rule set that checks my code...</description>
<!-- Import the entire unused code rule set -->
<rule ref="rulesets/unusedcode.xml" />
<rule ref="rulesets/design.xml" />
<rule ref="rulesets/naming.xml">
<exclude name="ShortVariable"/>
<exclude name="LongVariable"/>
</rule>
<rule ref="rulesets/naming.xml/ShortVariable">
<properties>
<property name="minimum" value="2" />
</properties>
</rule>
<rule ref="rulesets/naming.xml/LongVariable">
<properties>
<property name="maximum" value="30" />
</properties>
</rule>
<rule ref="rulesets/codesize.xml">
<exclude name="TooManyMethods"/>
<exclude name="ExcessiveClassComplexity"/>
</rule>
<rule ref="rulesets/codesize.xml/TooManyMethods">
<properties>
<property name="maxmethods" value="20" />
</properties>
</rule>
<rule ref="rulesets/codesize.xml/ExcessiveClassComplexity">
<properties>
<property name="maximum" value="70" />
</properties>
</rule>
</ruleset>