Merge pull request #413 from bezhermoso/unified_data_types

This commit is contained in:
William DURAND 2014-06-25 09:06:32 +02:00
commit 607d031051
11 changed files with 467 additions and 44 deletions

63
DataTypes.php Normal file
View File

@ -0,0 +1,63 @@
<?php
/*
* This file is part of the NelmioApiDocBundle.
*
* (c) Nelmio <hello@nelm.io>
*
* 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 <bez@activelamp.com>
*/
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,
));
}
}

View File

@ -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'])) {

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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)) {

View File

@ -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,
);
}

View File

@ -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)) {

View File

@ -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
)

View File

@ -1,6 +1,7 @@
<?php
namespace NelmioApiDocBundle\Tests\Parser;
use Nelmio\ApiDocBundle\DataTypes;
use Nelmio\ApiDocBundle\Form\Extension\DescriptionFormTypeExtension;
use Nelmio\ApiDocBundle\Parser\FormTypeParser;
use Nelmio\ApiDocBundle\Tests\Fixtures;
@ -37,18 +38,24 @@ class FormTypeParserTest extends \PHPUnit_Framework_TestCase
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' => 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,

View File

@ -1,6 +1,7 @@
<?php
namespace NelmioApiDocBundle\Tests\Parser;
use Nelmio\ApiDocBundle\DataTypes;
use Nelmio\ApiDocBundle\Tests\Fixtures\Model\JmsNested;
use Nelmio\ApiDocBundle\Parser\JmsMetadataParser;
use JMS\Serializer\Metadata\ClassMetadata;
@ -82,6 +83,8 @@ class JmsMetadataParserTest extends \PHPUnit_Framework_TestCase
array(
'foo' => 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',
)

View File

@ -1,6 +1,7 @@
<?php
namespace NelmioApiDocBundle\Tests\Parser;
use Nelmio\ApiDocBundle\DataTypes;
use Nelmio\ApiDocBundle\Tests\WebTestCase;
use Nelmio\ApiDocBundle\Parser\ValidationParser;
use Nelmio\ApiDocBundle\Parser\ValidationParserLegacy;
@ -28,7 +29,6 @@ class ValidationParserTest extends WebTestCase
public function testParser($property, $expected)
{
$result = $this->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(