From 14d1021c8bbb39e59e5bad75a48f97c177a4fe4e Mon Sep 17 00:00:00 2001 From: Bez Hermoso Date: Tue, 17 Jun 2014 17:05:00 -0700 Subject: [PATCH] Unified data types [actualType and subType] This is the result of https://github.com/nelmio/NelmioApiDocBundle/issues/410. This PR aims to provide a uniform way of declaring data-types of parameters for parsers and handlers to follow. In turn, this would allow formatters to determine data-types in a cleaner and less volatile manner. (See use-case that can be improved with this PR: https://github.com/nelmio/NelmioApiDocBundle/blob/master/Formatter/AbstractFormatter.php#L103) This is possible by the addition two properties to each property item in `response`, and `parameters` fields in each API endpoint produced by the `ApiDocExtractor`: * `actualType` Contains a value from one of the `DataTypes` class constants. * `subType` Can contain either `null`, or any other `DataTypes` class constant. This is relevant when the `actualType` is a `DataTypes::COLLECTION`, wherein `subType` would specify the type of the collection items. It is also relevant when `actualType` is a `DataTypes::MODEL`, wherein `subType` would contain an identifier of the model (the FQCN or anything the parser would wish to specify) Examples: ```php array( 'id' => array( 'dataType' => 'integer', 'actualType' => DataTypes::INTEGER, 'subType' => null, ), 'profile' => array( 'dataType' => 'object (Profile)', 'actualType' => DataTypes::MODEL, 'subType' => 'Foo\Entity\Profile', 'children' => array( 'name' => array( 'dataType' => 'string', 'actualType' => DataTypes::STRING, 'subType' => null, ), 'birthDate' => array( 'dataType' => 'date', 'actualType' => DataTypes::DATE, 'subType' => null, ), ) ), 'languages' => array( 'dataType' => 'array of strings', 'actualType' => DataTypes::COLLECTION, 'subType' => DataTypes::STRING, ), 'roles' => array( 'dataType' => 'array of choices', 'actualType' => DataTypes::COLLECTION, 'subType' => DataTypes::ENUM, ), 'groups' => array( 'dataType' => 'array of objects (Group)', 'actualType' => DataTypes::COLLECTION, 'subType' => 'Foo\Entity\Group', ), 'profileRevisions' => array( 'dataType' => 'array of objects (Profile)', 'actualType' => DataTypes::COLLECTION, 'subType' => 'Foo\Entity\Profile', ), 'address' => array( 'dataType' => 'object (a_type_a_custom_JMS_serializer_handler_handles)', 'actualType' => DataTypes::MODEL, 'subType' => 'a_type_a_custom_JMS_serializer_handler_handles', ), ); ``` When a formatter omits the `dataType` property or leaves it blank, it is inferred within `ApiDocExtractor` before everything is passed to formatters. --- DataTypes.php | 63 ++++++++++++ Extractor/ApiDocExtractor.php | 58 +++++++++++ Extractor/Handler/FosRestHandler.php | 16 ++- Formatter/AbstractFormatter.php | 5 +- Parser/FormTypeParser.php | 42 +++++--- Parser/JmsMetadataParser.php | 36 +++++-- Parser/ValidationParser.php | 30 ++++++ Tests/Formatter/SimpleFormatterTest.php | 125 ++++++++++++++++++++++++ Tests/Parser/FormTypeParserTest.php | 54 ++++++++++ Tests/Parser/JmsMetadataParserTest.php | 57 ++++++++--- Tests/Parser/ValidationParserTest.php | 25 +++-- 11 files changed, 467 insertions(+), 44 deletions(-) create mode 100644 DataTypes.php diff --git a/DataTypes.php b/DataTypes.php new file mode 100644 index 0000000..7e02741 --- /dev/null +++ b/DataTypes.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Nelmio\ApiDocBundle; + +/** + * All the supported data-types which will be specified in the `actualType` properties in parameters. + * + * @author Bez Hermoso + */ +class DataTypes +{ + const INTEGER = 'integer'; + + const FLOAT = 'float'; + + const STRING = 'string'; + + const BOOLEAN = 'boolean'; + + const FILE = 'file'; + + const ENUM = 'choice'; + + const COLLECTION = 'collection'; + + const MODEL = 'model'; + + const DATE = 'date'; + + const DATETIME = 'datetime'; + + const TIME = 'time'; + + /** + * Returns true if the supplied `actualType` value is considered a primitive type. Returns false, otherwise. + * + * @param string $type + * @return bool + */ + public static function isPrimitive($type) + { + return in_array(strtolower($type), array( + static::INTEGER, + static::FLOAT, + static::STRING, + static::BOOLEAN, + static::FILE, + static::DATE, + static::DATETIME, + static::TIME, + static::ENUM, + )); + } +} diff --git a/Extractor/ApiDocExtractor.php b/Extractor/ApiDocExtractor.php index 6f051a8..c18c6cd 100644 --- a/Extractor/ApiDocExtractor.php +++ b/Extractor/ApiDocExtractor.php @@ -14,6 +14,7 @@ namespace Nelmio\ApiDocBundle\Extractor; use Doctrine\Common\Annotations\Reader; use Doctrine\Common\Util\ClassUtils; use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Nelmio\ApiDocBundle\DataTypes; use Nelmio\ApiDocBundle\Parser\ParserInterface; use Nelmio\ApiDocBundle\Parser\PostParserInterface; use Symfony\Component\Routing\Route; @@ -279,6 +280,7 @@ class ApiDocExtractor } $parameters = $this->clearClasses($parameters); + $parameters = $this->generateHumanReadableTypes($parameters); if ('PUT' === $method) { // All parameters are optional with PUT (update) @@ -302,6 +304,7 @@ class ApiDocExtractor } $response = $this->clearClasses($response); + $response = $this->generateHumanReadableTypes($response); $annotation->setResponse($response); } @@ -414,6 +417,61 @@ class ApiDocExtractor return $array; } + /** + * Populates the `dataType` properties in the parameter array if empty. Recurses through children when necessary. + * + * @param array $array + * @return array + */ + protected function generateHumanReadableTypes(array $array) + { + foreach ($array as $name => $info) { + + if (empty($info['dataType'])) { + $array[$name]['dataType'] = $this->generateHumanReadableType($info['actualType'], $info['subType']); + } + + if (isset($info['children'])) { + $array[$name]['children'] = $this->generateHumanReadableTypes($info['children']); + } + } + + return $array; + } + + /** + * Creates a human-readable version of the `actualType`. `subType` is taken into account. + * + * @param string $actualType + * @param string $subType + * @return string + */ + protected function generateHumanReadableType($actualType, $subType) + { + if ($actualType == DataTypes::MODEL) { + $parts = explode('\\', $subType); + + return sprintf('object (%s)', end($parts)); + } + + if ($actualType == DataTypes::COLLECTION) { + + if (DataTypes::isPrimitive($subType)) { + return sprintf('array of %ss', $subType); + } + + if (class_exists($subType)) { + $parts = explode('\\', $subType); + + return sprintf('array of objects (%s)', end($parts)); + } + + return sprintf('array of objects (%s)', $subType); + } + + return $actualType; + } + private function getParsers(array $parameters) { if (isset($parameters['parsers'])) { diff --git a/Extractor/Handler/FosRestHandler.php b/Extractor/Handler/FosRestHandler.php index 3165e20..4b7f18f 100644 --- a/Extractor/Handler/FosRestHandler.php +++ b/Extractor/Handler/FosRestHandler.php @@ -11,6 +11,7 @@ namespace Nelmio\ApiDocBundle\Extractor\Handler; +use Nelmio\ApiDocBundle\DataTypes; use Nelmio\ApiDocBundle\Extractor\HandlerInterface; use Nelmio\ApiDocBundle\Annotation\ApiDoc; use Symfony\Component\Routing\Route; @@ -28,9 +29,13 @@ class FosRestHandler implements HandlerInterface { foreach ($annotations as $annot) { if ($annot instanceof RequestParam) { + + $requirements = $this->handleRequirements($annot->requirements); $annotation->addParameter($annot->name, array( 'required' => $annot->strict && $annot->default === null, - 'dataType' => $this->handleRequirements($annot->requirements), + 'dataType' => $requirements, + 'actualType' => $this->inferType($requirements), + 'subType' => null, 'description' => $annot->description, 'readonly' => false )); @@ -76,4 +81,13 @@ class FosRestHandler implements HandlerInterface return (string) $requirements; } + + public function inferType($requirement) + { + if (DataTypes::isPrimitive($requirement)) { + return $requirement; + } + + return DataTypes::STRING; + } } diff --git a/Formatter/AbstractFormatter.php b/Formatter/AbstractFormatter.php index 94685ed..f84a9a1 100644 --- a/Formatter/AbstractFormatter.php +++ b/Formatter/AbstractFormatter.php @@ -12,6 +12,7 @@ namespace Nelmio\ApiDocBundle\Formatter; use Nelmio\ApiDocBundle\Annotation\ApiDoc; +use Nelmio\ApiDocBundle\DataTypes; abstract class AbstractFormatter implements FormatterInterface { @@ -76,6 +77,8 @@ abstract class AbstractFormatter implements FormatterInterface 'format' => array_key_exists('format', $info) ? $info['format'] : null, 'sinceVersion' => array_key_exists('sinceVersion', $info) ? $info['sinceVersion'] : null, 'untilVersion' => array_key_exists('untilVersion', $info) ? $info['untilVersion'] : null, + 'actualType' => array_key_exists('actualType', $info) ? $info['actualType'] : null, + 'subType' => array_key_exists('subType', $info) ? $info['subType'] : null, ); if (isset($info['children']) && (!$info['readonly'] || !$ignoreNestedReadOnly)) { @@ -100,7 +103,7 @@ abstract class AbstractFormatter implements FormatterInterface protected function getNewName($name, $data, $parentName = null) { $newName = ($parentName) ? sprintf("%s[%s]", $parentName, $name) : $name; - $array = (false === strpos($data['dataType'], "array of")) ? "" : "[]"; + $array = $data['actualType'] == DataTypes::COLLECTION && $data['subType'] !== null ? '[]' : ''; return sprintf("%s%s", $newName, $array); } diff --git a/Parser/FormTypeParser.php b/Parser/FormTypeParser.php index c87166c..bddfa05 100644 --- a/Parser/FormTypeParser.php +++ b/Parser/FormTypeParser.php @@ -11,6 +11,7 @@ namespace Nelmio\ApiDocBundle\Parser; +use Nelmio\ApiDocBundle\DataTypes; use Symfony\Component\Form\Exception\UnexpectedTypeException; use Symfony\Component\Form\Exception\InvalidArgumentException; use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface; @@ -35,16 +36,16 @@ class FormTypeParser implements ParserInterface * @var array */ protected $mapTypes = array( - 'text' => 'string', - 'date' => 'date', - 'datetime' => 'datetime', - 'checkbox' => 'boolean', - 'time' => 'time', - 'number' => 'float', - 'integer' => 'int', - 'textarea' => 'string', - 'country' => 'string', - 'choice' => 'choice', + 'text' => DataTypes::STRING, + 'date' => DataTypes::DATE, + 'datetime' => DataTypes::DATETIME, + 'checkbox' => DataTypes::BOOLEAN, + 'time' => DataTypes::TIME, + 'number' => DataTypes::FLOAT, + 'integer' => DataTypes::INTEGER, + 'textarea' => DataTypes::STRING, + 'country' => DataTypes::STRING, + 'choice' => DataTypes::ENUM, ); public function __construct(FormFactoryInterface $formFactory) @@ -99,12 +100,18 @@ class FormTypeParser implements ParserInterface } $bestType = ''; + $actualType = null; + $subType = null; + for ($type = $config->getType(); null !== $type; $type = $type->getParent()) { if (isset($this->mapTypes[$type->getName()])) { $bestType = $this->mapTypes[$type->getName()]; + $actualType = $bestType; } elseif ('collection' === $type->getName()) { if (is_string($config->getOption('type')) && isset($this->mapTypes[$config->getOption('type')])) { - $bestType = sprintf('array of %ss', $this->mapTypes[$config->getOption('type')]); + $subType = $this->mapTypes[$config->getOption('type')]; + $actualType = DataTypes::COLLECTION; + $bestType = sprintf('array of %ss', $subType); } else { // Embedded form collection $subParameters = $this->parseForm($this->formFactory->create($config->getOption('type'), null, $config->getOption('options', array())), $name . '[]'); @@ -139,6 +146,7 @@ class FormTypeParser implements ParserInterface if ($addDefault) { $parameters[$name] = array( 'dataType' => 'string', + 'actualType' => 'string', 'required' => $config->getRequired(), 'description' => $config->getAttribute('description'), 'readonly' => $config->getDisabled(), @@ -152,13 +160,15 @@ class FormTypeParser implements ParserInterface $parameters[$name] = array( 'dataType' => $bestType, + 'actualType' => $actualType, + 'subType' => $subType, 'required' => $config->getRequired(), 'description' => $config->getAttribute('description'), 'readonly' => $config->getDisabled(), ); - switch ($bestType) { - case 'datetime': + switch ($actualType) { + case DataTypes::DATETIME: if (($format = $config->getOption('date_format')) && is_string($format)) { $parameters[$name]['format'] = $format; } elseif ('single_text' == $config->getOption('widget') && $format = $config->getOption('format')) { @@ -166,15 +176,17 @@ class FormTypeParser implements ParserInterface } break; - case 'date': + case DataTypes::DATE: if (($format = $config->getOption('format')) && is_string($format)) { $parameters[$name]['format'] = $format; } break; - case 'choice': + case DataTypes::ENUM: if ($config->getOption('multiple')) { $parameters[$name]['dataType'] = sprintf('array of %ss', $parameters[$name]['dataType']); + $parameters[$name]['actualType'] = DataTypes::COLLECTION; + $parameters[$name]['subType'] = DataTypes::ENUM; } if (($choices = $config->getOption('choices')) && is_array($choices) && count($choices)) { diff --git a/Parser/JmsMetadataParser.php b/Parser/JmsMetadataParser.php index 8af8432..5429769 100644 --- a/Parser/JmsMetadataParser.php +++ b/Parser/JmsMetadataParser.php @@ -14,6 +14,7 @@ namespace Nelmio\ApiDocBundle\Parser; use JMS\Serializer\Exclusion\GroupsExclusionStrategy; use JMS\Serializer\SerializationContext; use Metadata\MetadataFactoryInterface; +use Nelmio\ApiDocBundle\DataTypes; use Nelmio\ApiDocBundle\Util\DocCommentExtractor; use JMS\Serializer\Metadata\PropertyMetadata; use JMS\Serializer\Metadata\VirtualPropertyMetadata; @@ -39,6 +40,15 @@ class JmsMetadataParser implements ParserInterface */ private $commentExtractor; + private $typeMap = array( + 'integer' => DataTypes::INTEGER, + 'boolean' => DataTypes::BOOLEAN, + 'string' => DataTypes::STRING, + 'float' => DataTypes::FLOAT, + 'double' => DataTypes::FLOAT, + 'array' => DataTypes::COLLECTION, + 'DateTime' => DataTypes::DATETIME, + ); /** * Constructor, requires JMS Metadata factory */ @@ -120,6 +130,8 @@ class JmsMetadataParser implements ParserInterface $params[$name] = array( 'dataType' => $dataType['normalized'], + 'actualType' => $dataType['actualType'], + 'subType' => $dataType['class'], 'required' => false, //TODO: can't think of a good way to specify this one, JMS doesn't have a setting for this 'description' => $this->getDescription($item), @@ -128,7 +140,7 @@ class JmsMetadataParser implements ParserInterface 'untilVersion' => $item->untilVersion, ); - if (!is_null($dataType['class'])) { + if (!is_null($dataType['class']) && false === $dataType['primitive']) { $params[$name]['class'] = $dataType['class']; } @@ -138,7 +150,7 @@ class JmsMetadataParser implements ParserInterface } // check for nested classes with JMS metadata - if ($dataType['class'] && null !== $this->factory->getMetadataForClass($dataType['class'])) { + if ($dataType['class'] && false === $dataType['primitive'] && null !== $this->factory->getMetadataForClass($dataType['class'])) { $visited[] = $dataType['class']; $params[$name]['children'] = $this->doParse($dataType['class'], $visited, $groups); } @@ -162,7 +174,9 @@ class JmsMetadataParser implements ParserInterface if ($this->isPrimitive($nestedType)) { return array( 'normalized' => sprintf("array of %ss", $nestedType), - 'class' => null + 'actualType' => DataTypes::COLLECTION, + 'class' => $this->typeMap[$nestedType], + 'primitive' => true, ); } @@ -170,7 +184,9 @@ class JmsMetadataParser implements ParserInterface return array( 'normalized' => sprintf("array of objects (%s)", end($exp)), - 'class' => $nestedType + 'actualType' => DataTypes::COLLECTION, + 'class' => $nestedType, + 'primitive' => false, ); } @@ -180,7 +196,9 @@ class JmsMetadataParser implements ParserInterface if ($this->isPrimitive($type)) { return array( 'normalized' => $type, - 'class' => null + 'actualType' => $this->typeMap[$type], + 'class' => null, + 'primitive' => true, ); } @@ -188,7 +206,9 @@ class JmsMetadataParser implements ParserInterface if (!class_exists($type)) { return array( 'normalized' => sprintf("custom handler result for (%s)", $type), - 'class' => null + 'class' => $type, + 'actualType' => DataTypes::MODEL, + 'primitive' => false, ); } @@ -197,7 +217,9 @@ class JmsMetadataParser implements ParserInterface return array( 'normalized' => sprintf("object (%s)", end($exp)), - 'class' => $type + 'class' => $type, + 'actualType' => DataTypes::MODEL, + 'primitive' => false, ); } diff --git a/Parser/ValidationParser.php b/Parser/ValidationParser.php index 1d9e4b8..386b0f9 100644 --- a/Parser/ValidationParser.php +++ b/Parser/ValidationParser.php @@ -11,6 +11,7 @@ namespace Nelmio\ApiDocBundle\Parser; +use Nelmio\ApiDocBundle\DataTypes; use Symfony\Component\Validator\Exception\ConstraintDefinitionException; use Symfony\Component\Validator\MetadataFactoryInterface; use Symfony\Component\Validator\Constraint; @@ -26,6 +27,21 @@ class ValidationParser implements ParserInterface, PostParserInterface */ protected $factory; + protected $typeMap = array( + 'integer' => DataTypes::INTEGER, + 'int' => DataTypes::INTEGER, + 'scalar' => DataTypes::STRING, + 'numeric' => DataTypes::INTEGER, + 'boolean' => DataTypes::BOOLEAN, + 'string' => DataTypes::STRING, + 'float' => DataTypes::FLOAT, + 'double' => DataTypes::FLOAT, + 'long' => DataTypes::INTEGER, + 'object' => DataTypes::MODEL, + 'array' => DataTypes::COLLECTION, + 'DateTime' => DataTypes::DATETIME, + ); + /** * Requires a validation MetadataFactory. * @@ -142,6 +158,9 @@ class ValidationParser implements ParserInterface, PostParserInterface { $class = substr(get_class($constraint), strlen('Symfony\\Component\\Validator\\Constraints\\')); + $vparams['actualType'] = DataTypes::STRING; + $vparams['subType'] = null; + switch ($class) { case 'NotBlank': $vparams['format'][] = '{not blank}'; @@ -149,6 +168,9 @@ class ValidationParser implements ParserInterface, PostParserInterface $vparams['required'] = true; break; case 'Type': + if (isset($this->typeMap[$constraint->type])) { + $vparams['actualType'] = $this->typeMap[$constraint->type]; + } $vparams['dataType'] = $constraint->type; break; case 'Email': @@ -162,12 +184,15 @@ class ValidationParser implements ParserInterface, PostParserInterface break; case 'Date': $vparams['format'][] = '{Date YYYY-MM-DD}'; + $vparams['actualType'] = DataTypes::DATE; break; case 'DateTime': $vparams['format'][] = '{DateTime YYYY-MM-DD HH:MM:SS}'; + $vparams['actualType'] = DataTypes::DATETIME; break; case 'Time': $vparams['format'][] = '{Time HH:MM:SS}'; + $vparams['actualType'] = DataTypes::TIME; break; case 'Length': $messages = array(); @@ -183,6 +208,8 @@ class ValidationParser implements ParserInterface, PostParserInterface $choices = $this->getChoices($constraint, $className); $format = '[' . join('|', $choices) . ']'; if ($constraint->multiple) { + $vparams['actualType'] = DataTypes::COLLECTION; + $vparams['subType'] = DataTypes::ENUM; $messages = array(); if (isset($constraint->min)) { $messages[] = "min: {$constraint->min} "; @@ -192,6 +219,7 @@ class ValidationParser implements ParserInterface, PostParserInterface } $vparams['format'][] = '{' . join ('', $messages) . 'choice of ' . $format . '}'; } else { + $vparams['actualType'] = DataTypes::ENUM; $vparams['format'][] = $format; } break; @@ -216,6 +244,8 @@ class ValidationParser implements ParserInterface, PostParserInterface } $vparams['dataType'] = sprintf("array of objects (%s)", end($exp)); + $vparams['actualType'] = DataTypes::COLLECTION; + $vparams['subType'] = $nestedType; $vparams['class'] = $nestedType; if (!in_array($nestedType, $visited)) { diff --git a/Tests/Formatter/SimpleFormatterTest.php b/Tests/Formatter/SimpleFormatterTest.php index dfa5b5e..6d8918e 100644 --- a/Tests/Formatter/SimpleFormatterTest.php +++ b/Tests/Formatter/SimpleFormatterTest.php @@ -11,6 +11,7 @@ namespace Nelmio\ApiDocBundle\Tests\Formatter; +use Nelmio\ApiDocBundle\DataTypes; use Nelmio\ApiDocBundle\Tests\WebTestCase; class SimpleFormatterTest extends WebTestCase @@ -108,18 +109,24 @@ class SimpleFormatterTest extends WebTestCase array( 'a' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => 'A nice description', 'readonly' => false, ), 'b' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, ), 'c' => array( 'dataType' => 'boolean', + 'actualType' => DataTypes::BOOLEAN, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, @@ -149,18 +156,24 @@ class SimpleFormatterTest extends WebTestCase array( 'a' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => 'A nice description', 'readonly' => false, ), 'b' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, ), 'c' => array( 'dataType' => 'boolean', + 'actualType' => DataTypes::BOOLEAN, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, @@ -193,6 +206,8 @@ class SimpleFormatterTest extends WebTestCase 'dependency_type[a]' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => 'A nice description', 'readonly' => false, @@ -251,6 +266,8 @@ class SimpleFormatterTest extends WebTestCase 'foo' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -260,6 +277,8 @@ class SimpleFormatterTest extends WebTestCase 'bar' => array( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => true, @@ -269,6 +288,8 @@ class SimpleFormatterTest extends WebTestCase 'number' => array( 'dataType' => 'double', + 'actualType' => DataTypes::FLOAT, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -278,6 +299,8 @@ class SimpleFormatterTest extends WebTestCase 'arr' => array( 'dataType' => 'array', + 'actualType' => DataTypes::COLLECTION, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -287,6 +310,8 @@ class SimpleFormatterTest extends WebTestCase 'nested' => array( 'dataType' => 'object (JmsNested)', + 'actualType' => DataTypes::MODEL, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested', 'required' => false, 'description' => '', 'readonly' => false, @@ -297,6 +322,8 @@ class SimpleFormatterTest extends WebTestCase 'foo' => array( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => true, @@ -306,6 +333,8 @@ class SimpleFormatterTest extends WebTestCase 'bar' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -315,6 +344,8 @@ class SimpleFormatterTest extends WebTestCase 'baz' => array( 'dataType' => 'array of integers', + 'actualType' => DataTypes::COLLECTION, + 'subType' => DataTypes::INTEGER, 'required' => false, 'description' => 'Epic description. @@ -326,6 +357,8 @@ With multiple lines.', 'circular' => array( 'dataType' => 'object (JmsNested)', + 'actualType' => DataTypes::MODEL, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested', 'required' => false, 'description' => '', 'readonly' => false, @@ -335,6 +368,8 @@ With multiple lines.', 'parent' => array( 'dataType' => 'object (JmsTest)', + 'actualType' => DataTypes::MODEL, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsTest', 'required' => false, 'description' => '', 'readonly' => false, @@ -345,6 +380,8 @@ With multiple lines.', 'foo' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -354,6 +391,8 @@ With multiple lines.', 'bar' => array( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => true, @@ -363,6 +402,8 @@ With multiple lines.', 'number' => array( 'dataType' => 'double', + 'actualType' => DataTypes::FLOAT, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -372,6 +413,8 @@ With multiple lines.', 'arr' => array( 'dataType' => 'array', + 'actualType' => DataTypes::COLLECTION, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -381,6 +424,8 @@ With multiple lines.', 'nested' => array( 'dataType' => 'object (JmsNested)', + 'actualType' => DataTypes::MODEL, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested', 'required' => false, 'description' => '', 'readonly' => false, @@ -390,6 +435,8 @@ With multiple lines.', 'nested_array' => array( 'dataType' => 'array of objects (JmsNested)', + 'actualType' => DataTypes::COLLECTION, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested', 'required' => false, 'description' => '', 'readonly' => false, @@ -401,6 +448,8 @@ With multiple lines.', 'since' => array ( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -410,6 +459,8 @@ With multiple lines.', 'until' => array ( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -419,6 +470,8 @@ With multiple lines.', 'since_and_until' => array ( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -430,6 +483,8 @@ With multiple lines.', 'nested_array' => array( 'dataType' => 'array of objects (JmsNested)', + 'actualType' => DataTypes::COLLECTION, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested', 'required' => false, 'description' => '', 'readonly' => false, @@ -452,6 +507,8 @@ With multiple lines.', 'dependency_type[a]' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => 'A nice description', 'readonly' => false, @@ -516,6 +573,8 @@ And, it supports multilines until the first \'@\' char.', 'foo' => array ( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -525,6 +584,8 @@ And, it supports multilines until the first \'@\' char.', 'bar' => array ( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => true, @@ -534,6 +595,8 @@ And, it supports multilines until the first \'@\' char.', 'number' => array ( 'dataType' => 'double', + 'actualType' => DataTypes::FLOAT, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -543,6 +606,8 @@ And, it supports multilines until the first \'@\' char.', 'arr' => array ( 'dataType' => 'array', + 'actualType' => DataTypes::COLLECTION, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -552,6 +617,8 @@ And, it supports multilines until the first \'@\' char.', 'nested' => array ( 'dataType' => 'object (JmsNested)', + 'actualType' => DataTypes::MODEL, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested', 'required' => false, 'description' => '', 'readonly' => false, @@ -562,6 +629,8 @@ And, it supports multilines until the first \'@\' char.', 'foo' => array ( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => true, @@ -571,6 +640,8 @@ And, it supports multilines until the first \'@\' char.', 'bar' => array ( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -580,6 +651,8 @@ And, it supports multilines until the first \'@\' char.', 'baz' => array ( 'dataType' => 'array of integers', + 'actualType' => DataTypes::COLLECTION, + 'subType' => DataTypes::INTEGER, 'required' => false, 'description' => 'Epic description. @@ -591,6 +664,8 @@ With multiple lines.', 'circular' => array ( 'dataType' => 'object (JmsNested)', + 'actualType' => DataTypes::MODEL, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested', 'required' => false, 'description' => '', 'readonly' => false, @@ -600,6 +675,8 @@ With multiple lines.', 'parent' => array ( 'dataType' => 'object (JmsTest)', + 'actualType' => DataTypes::MODEL, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsTest', 'required' => false, 'description' => '', 'readonly' => false, @@ -610,6 +687,8 @@ With multiple lines.', 'foo' => array ( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -619,6 +698,8 @@ With multiple lines.', 'bar' => array ( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => true, @@ -628,6 +709,8 @@ With multiple lines.', 'number' => array ( 'dataType' => 'double', + 'actualType' => DataTypes::FLOAT, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -637,6 +720,8 @@ With multiple lines.', 'arr' => array ( 'dataType' => 'array', + 'actualType' => DataTypes::COLLECTION, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -646,6 +731,8 @@ With multiple lines.', 'nested' => array ( 'dataType' => 'object (JmsNested)', + 'actualType' => DataTypes::MODEL, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested', 'required' => false, 'description' => '', 'readonly' => false, @@ -655,6 +742,8 @@ With multiple lines.', 'nested_array' => array ( 'dataType' => 'array of objects (JmsNested)', + 'actualType' => DataTypes::COLLECTION, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested', 'required' => false, 'description' => '', 'readonly' => false, @@ -666,6 +755,8 @@ With multiple lines.', 'since' => array ( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -675,6 +766,8 @@ With multiple lines.', 'until' => array ( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -684,6 +777,8 @@ With multiple lines.', 'since_and_until' => array ( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -695,6 +790,8 @@ With multiple lines.', 'nested_array' => array ( 'dataType' => 'array of objects (JmsNested)', + 'actualType' => DataTypes::COLLECTION, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested', 'required' => false, 'description' => '', 'readonly' => false, @@ -802,6 +899,8 @@ With multiple lines.', array( 'required' => true, 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'description' => 'Param1 description.', 'readonly' => false, ), @@ -821,11 +920,15 @@ With multiple lines.', 'response' => array ( 'bar' => array( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => null, 'readonly' => null ), 'number' => array( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -834,17 +937,23 @@ With multiple lines.', ), 'objects' => array( 'dataType' => 'array of objects (Test)', + 'actualType' => DataTypes::COLLECTION, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\Test', 'readonly' => null, 'required' => null, 'children' => array( 'a' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'format' => '{length: min: foo}, {not blank}', 'required' => true, 'readonly' => null ), 'b' => array( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => null, 'readonly' => null ) @@ -865,18 +974,24 @@ With multiple lines.', array( 'a' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => 'A nice description', 'readonly' => false, ), 'b' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, ), 'c' => array( 'dataType' => 'boolean', + 'actualType' => DataTypes::BOOLEAN, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, @@ -893,11 +1008,15 @@ With multiple lines.', 'response' => array ( 'bar' => array( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => null, 'readonly' => null ), 'number' => array( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => false, 'description' => '', 'readonly' => false, @@ -906,17 +1025,23 @@ With multiple lines.', ), 'objects' => array( 'dataType' => 'array of objects (Test)', + 'actualType' => DataTypes::COLLECTION, + 'subType' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\Test', 'readonly' => null, 'required' => null, 'children' => array( 'a' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'format' => '{length: min: foo}, {not blank}', 'required' => true, 'readonly' => null ), 'b' => array( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => null, 'readonly' => null ) diff --git a/Tests/Parser/FormTypeParserTest.php b/Tests/Parser/FormTypeParserTest.php index eb7bdb0..cf9c872 100644 --- a/Tests/Parser/FormTypeParserTest.php +++ b/Tests/Parser/FormTypeParserTest.php @@ -1,6 +1,7 @@ array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => 'A nice description', 'readonly' => false ), 'b' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false ), 'c' => array( 'dataType' => 'boolean', + 'actualType' => DataTypes::BOOLEAN, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false @@ -60,24 +67,33 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase array( 'collection_type[a]' => array( 'dataType' => 'array of strings', + 'actualType' => DataTypes::COLLECTION, + + 'subType' => DataTypes::STRING, 'required' => true, 'description' => '', 'readonly' => false ), 'collection_type[b][][a]' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => 'A nice description', 'readonly' => false ), 'collection_type[b][][b]' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false ), 'collection_type[b][][c]' => array( 'dataType' => 'boolean', + 'actualType' => DataTypes::BOOLEAN, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false @@ -92,24 +108,32 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase array( 'a' => array( 'dataType' => 'array of strings', + 'actualType' => DataTypes::COLLECTION, + 'subType' => DataTypes::STRING, 'required' => true, 'description' => '', 'readonly' => false ), 'b[][a]' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => 'A nice description', 'readonly' => false ), 'b[][b]' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false ), 'b[][c]' => array( 'dataType' => 'boolean', + 'actualType' => DataTypes::BOOLEAN, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false @@ -124,24 +148,32 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase array( 'a' => array( 'dataType' => 'array of strings', + 'actualType' => DataTypes::COLLECTION, + 'subType' => DataTypes::STRING, 'required' => true, 'description' => '', 'readonly' => false ), 'b[][a]' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => 'A nice description', 'readonly' => false ), 'b[][b]' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false ), 'b[][c]' => array( 'dataType' => 'boolean', + 'actualType' => DataTypes::BOOLEAN, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false @@ -153,6 +185,8 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase array( 'dt1' => array( 'dataType' => 'datetime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => true, 'description' => 'A nice description', 'readonly' => false, @@ -160,6 +194,8 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase ), 'dt2' => array( 'dataType' => 'datetime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, @@ -167,6 +203,8 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase ), 'dt3' => array( 'dataType' => 'datetime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, @@ -174,24 +212,32 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase ), 'dt4' => array( 'dataType' => 'datetime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, ), 'dt5' => array( 'dataType' => 'datetime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, ), 'd1' => array( 'dataType' => 'date', + 'actualType' => DataTypes::DATE, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, ), 'd2' => array( 'dataType' => 'date', + 'actualType' => DataTypes::DATE, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, @@ -199,6 +245,8 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase ), 'c1' => array( 'dataType' => 'choice', + 'actualType' => DataTypes::ENUM, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, @@ -206,6 +254,8 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase ), 'c2' => array( 'dataType' => 'array of choices', + 'actualType' => DataTypes::COLLECTION, + 'subType' => DataTypes::ENUM, 'required' => true, 'description' => '', 'readonly' => false, @@ -213,12 +263,16 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase ), 'c3' => array( 'dataType' => 'choice', + 'actualType' => DataTypes::ENUM, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, ), 'c4' => array( 'dataType' => 'choice', + 'actualType' => DataTypes::ENUM, + 'subType' => null, 'required' => true, 'description' => '', 'readonly' => false, diff --git a/Tests/Parser/JmsMetadataParserTest.php b/Tests/Parser/JmsMetadataParserTest.php index 880596f..d4640d5 100644 --- a/Tests/Parser/JmsMetadataParserTest.php +++ b/Tests/Parser/JmsMetadataParserTest.php @@ -1,6 +1,7 @@ array( 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -90,6 +93,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase ), 'bar' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -98,6 +103,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase ), 'baz' => array( 'dataType' => 'array of integers', + 'actualType' => DataTypes::COLLECTION, + 'subType' => DataTypes::INTEGER, 'required' => false, 'description' => null, 'readonly' => false, @@ -155,6 +162,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase array( 'foo' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -163,6 +172,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase ), 'bar' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -171,6 +182,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase ), 'baz' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -193,6 +206,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase array( 'foo' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -201,6 +216,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase ), 'bar' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -223,6 +240,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase array( 'bar' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -231,6 +250,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase ), 'baz' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -253,6 +274,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase array( 'foo' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -261,6 +284,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase ), 'bar' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -269,6 +294,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase ), 'baz' => array( 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, 'required' => false, 'description' => null, 'readonly' => false, @@ -325,26 +352,32 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase $this->assertEquals( array( 'foo' => array( - 'dataType' => 'string', - 'required' => false, - 'description' => null, - 'readonly' => false, + 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, + 'required' => false, + 'description' => null, + 'readonly' => false, 'sinceVersion' => null, 'untilVersion' => null, ), 'bar' => array( - 'dataType' => 'string', - 'required' => false, - 'description' => null, - 'readonly' => false, + 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, + 'required' => false, + 'description' => null, + 'readonly' => false, 'sinceVersion' => '2.0', 'untilVersion' => null, ), 'baz' => array( - 'dataType' => 'string', - 'required' => false, - 'description' => null, - 'readonly' => false, + 'dataType' => 'string', + 'actualType' => DataTypes::STRING, + 'subType' => null, + 'required' => false, + 'description' => null, + 'readonly' => false, 'sinceVersion' => null, 'untilVersion' => '3.0', ) diff --git a/Tests/Parser/ValidationParserTest.php b/Tests/Parser/ValidationParserTest.php index 13885b7..0bca5b5 100644 --- a/Tests/Parser/ValidationParserTest.php +++ b/Tests/Parser/ValidationParserTest.php @@ -1,6 +1,7 @@ parser->parse(array('class' => 'Nelmio\ApiDocBundle\Tests\Fixtures\Model\ValidatorTest')); - foreach ($expected as $name => $value) { $this->assertArrayHasKey($property, $result); $this->assertArrayHasKey($name, $result[$property]); @@ -66,25 +66,29 @@ class ValidationParserTest extends WebTestCase array( 'property' => 'type', 'expected' => array( - 'dataType' => 'DateTime' + 'dataType' => 'DateTime', + 'actualType' => DataTypes::DATETIME, ) ), array( 'property' => 'date', 'expected' => array( - 'format' => '{Date YYYY-MM-DD}' + 'format' => '{Date YYYY-MM-DD}', + 'actualType' => DataTypes::DATE, ) ), array( 'property' => 'dateTime', 'expected' => array( - 'format' => '{DateTime YYYY-MM-DD HH:MM:SS}' + 'format' => '{DateTime YYYY-MM-DD HH:MM:SS}', + 'actualType' => DataTypes::DATETIME, ) ), array( 'property' => 'time', 'expected' => array( - 'format' => '{Time HH:MM:SS}' + 'format' => '{Time HH:MM:SS}', + 'actualType' => DataTypes::TIME, ) ), array( @@ -108,19 +112,24 @@ class ValidationParserTest extends WebTestCase array( 'property' => 'singlechoice', 'expected' => array( - 'format' => '[a|b]' + 'format' => '[a|b]', + 'actualType' => DataTypes::ENUM, ) ), array( 'property' => 'multiplechoice', 'expected' => array( - 'format' => '{choice of [x|y|z]}' + 'format' => '{choice of [x|y|z]}', + 'actualType' => DataTypes::COLLECTION, + 'subType' => DataTypes::ENUM, ) ), array( 'property' => 'multiplerangechoice', 'expected' => array( - 'format' => '{min: 2 max: 3 choice of [foo|bar|baz|qux]}' + 'format' => '{min: 2 max: 3 choice of [foo|bar|baz|qux]}', + 'actualType' => DataTypes::COLLECTION, + 'subType' => DataTypes::ENUM, ) ), array(