Skip to content

Commit

Permalink
Merge pull request #8 from fcastilloes/type-catalog
Browse files Browse the repository at this point in the history
Extract class TypeCatalog fixing bug
  • Loading branch information
fcastilloes committed Apr 7, 2017
2 parents d1fc9e4 + ace8675 commit da4b9dd
Show file tree
Hide file tree
Showing 5 changed files with 332 additions and 78 deletions.
93 changes: 16 additions & 77 deletions src/Api/ActionApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ class ActionApi extends Api implements Action
*/
private $return;

/**
* @var TypeCatalog
*/
private $typeCatalog;

/**
* Action constructor.
* @param KatanaLogger $logger
Expand All @@ -72,6 +77,7 @@ class ActionApi extends Api implements Action
* @param string $actionName
* @param ZeroMQRuntimeCaller $caller
* @param Transport $transport
* @param TypeCatalog $typeCatalog
* @param Param[] $params
*/
public function __construct(
Expand All @@ -87,6 +93,7 @@ public function __construct(
string $actionName,
ZeroMQRuntimeCaller $caller,
Transport $transport,
TypeCatalog $typeCatalog,
array $params = []
) {
parent::__construct(
Expand All @@ -105,27 +112,10 @@ public function __construct(
$this->caller = $caller;
$this->transport = $transport;
$this->transportCopy = clone $transport;
$this->typeCatalog = $typeCatalog;
$this->params = $this->prepareParams($params);
}

/**
* @param array $value
* @return bool
*/
private function isArrayType(array $value): bool
{
return array_keys($value) === range(0, count($value) -1);
}

/**
* @param array $value
* @return bool
*/
private function isObjectType(array $value): bool
{
return count(array_filter(array_keys($value), 'is_string')) === count($value);
}

/**
* @return Transport
*/
Expand Down Expand Up @@ -247,8 +237,9 @@ public function setDownload(FileInterface $file): Action
*/
public function setEntity(array $entity): Action
{
if (!$this->isObjectType($entity)) {
throw new TransportException('Unexpected collection');
$type = $this->typeCatalog::TYPE_OBJECT;
if (!$this->typeCatalog->validate($type, $entity)) {
throw new TransportException('Invalid Entity');
}

$this->transport->setData($this->name, $this->version, $this->actionName, $entity);
Expand All @@ -263,8 +254,9 @@ public function setEntity(array $entity): Action
*/
public function setCollection(array $collection): Action
{
if (!$this->isArrayType($collection)) {
throw new TransportException('Unexpected entity');
$type = $this->typeCatalog::TYPE_ARRAY;
if (!$this->typeCatalog->validate($type, $collection)) {
throw new TransportException('Invalid Collection');
}

$this->transport->setCollection($this->name, $this->version, $this->actionName, $collection);
Expand Down Expand Up @@ -570,7 +562,7 @@ public function setReturn($value): Action
));
}

if (!$this->validate($value, $action->getReturnType())) {
if (!$this->typeCatalog->validate($action->getReturnType(), $value)) {
throw new InvalidValueException(sprintf(
'Invalid return type given in "%s" (%s) for action: "%s"',
$this->name,
Expand Down Expand Up @@ -614,60 +606,7 @@ public function getReturn()
$service = $this->getServiceSchema($this->name, $this->version);
$action = $service->getActionSchema($this->actionName);

return $this->getDefaultReturn($action->getReturnType());
}
}

/**
* @param string $type
* @return mixed
* @throws InvalidValueException
*/
private function getDefaultReturn(string $type)
{
switch ($type) {
case 'null':
return null;
case 'boolean':
return false;
case 'integer':
case 'float':
return 0;
case 'string':
return '';
case 'array':
case 'object':
return [];
return $this->typeCatalog->getDefault($action->getReturnType());
}

throw new InvalidValueException("Invalid value type: $type");
}

/**
* @param mixed $value
* @param string $type
* @return bool
* @throws InvalidValueException
*/
private function validate($value, string $type): bool
{
switch ($type) {
case 'null':
return is_null($value);
case 'boolean':
return is_bool($value);
case 'integer':
return is_integer($value);
case 'float':
return is_float($value);
case 'string':
return is_string($value);
case 'array':
return $this->isArrayType($value);
case 'object':
return $this->isObjectType($value);
}

throw new InvalidValueException("Invalid value type: $type");
}
}
2 changes: 2 additions & 0 deletions src/Api/Factory/ServiceApiFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
namespace Katana\Sdk\Api\Factory;

use Katana\Sdk\Api\ActionApi;
use Katana\Sdk\Api\TypeCatalog;
use Katana\Sdk\Console\CliInput;
use Katana\Sdk\Mapper\CompactTransportMapper;
use Katana\Sdk\Messaging\MessagePackSerializer;
Expand Down Expand Up @@ -68,6 +69,7 @@ public function build(
$action,
$caller,
$this->mapper->getTransport($data),
new TypeCatalog(),
$this->mapper->getParams($data)
);
}
Expand Down
117 changes: 117 additions & 0 deletions src/Api/TypeCatalog.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php
/**
* PHP 7 SDK for the KATANA(tm) Framework (http://katana.kusanagi.io)
* Copyright (c) 2016-2017 KUSANAGI S.L. All rights reserved.
*
* Distributed under the MIT license
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code
*
* @link https://github.com/kusanagi/katana-sdk-php7
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @copyright Copyright (c) 2016-2017 KUSANAGI S.L. (http://kusanagi.io)
*/

namespace Katana\Sdk\Api;

use Katana\Sdk\Exception\InvalidValueException;

/**
* Contains the available types in the API.
* @package Katana\Sdk\Api
*/
class TypeCatalog
{
const TYPE_NULL = 'null';
const TYPE_BOOLEAN = 'boolean';
const TYPE_INTEGER = 'integer';
const TYPE_FLOAT = 'float';
const TYPE_STRING = 'string';
const TYPE_ARRAY = 'array';
const TYPE_OBJECT = 'object';

/**
* @param array $value
* @return bool
*/
private function isArrayType(array $value): bool
{
if ($value === []) {
return true;
}
return array_keys($value) === range(0, count($value) -1);
}

/**
* @param array $value
* @return bool
*/
private function isObjectType(array $value): bool
{
return count(array_filter(array_keys($value), 'is_string')) === count($value);
}

/**
* Return the default value for a given type.
*
* @param string $type
* @return mixed
* @throws InvalidValueException
*/
public function getDefault(string $type)
{
switch ($type) {
case self::TYPE_NULL:
return null;
case self::TYPE_BOOLEAN:
return false;
case self::TYPE_INTEGER:
case self::TYPE_FLOAT:
return 0;
case self::TYPE_STRING:
return '';
case self::TYPE_ARRAY:
case self::TYPE_OBJECT:
return [];
}

throw new InvalidValueException("Invalid value type: $type");
}

/**
* Validates a value against a type.
*
* @param mixed $value
* @param string $type
* @return bool
* @throws InvalidValueException
*/
public function validate(string $type, $value): bool
{
switch ($type) {
case self::TYPE_NULL:
return is_null($value);
case self::TYPE_BOOLEAN:
return is_bool($value);
case self::TYPE_INTEGER:
return is_integer($value);
case self::TYPE_FLOAT:
return is_float($value);
case self::TYPE_STRING:
return is_string($value);
case self::TYPE_ARRAY:
if (!is_array($value)) {
return false;
}
return $this->isArrayType($value);
case self::TYPE_OBJECT:
if (!is_array($value)) {
return false;
}
return $this->isObjectType($value);
}

throw new InvalidValueException("Invalid value type: $type");
}
}
4 changes: 3 additions & 1 deletion tests/Api/ActionApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Katana\Sdk\Api\File;
use Katana\Sdk\Api\Transport;
use Katana\Sdk\Api\TransportMeta;
use Katana\Sdk\Api\TypeCatalog;
use Katana\Sdk\Component\Component;
use Katana\Sdk\Exception\InvalidValueException;
use Katana\Sdk\Logger\KatanaLogger;
Expand Down Expand Up @@ -84,7 +85,8 @@ public function setUp()
true,
'action',
$caller->reveal(),
$this->transport->reveal()
$this->transport->reveal(),
new TypeCatalog()
);
}

Expand Down
Loading

0 comments on commit da4b9dd

Please sign in to comment.