Merge pull request #7 from lsmith77/support_controllers_as_services

also support services as controller in ApiDocExtractor::get()
This commit is contained in:
Jordi Boggiano 2012-04-14 01:24:17 -07:00
commit 18a70b09f5
7 changed files with 247 additions and 42 deletions

View File

@ -56,19 +56,7 @@ class ApiDocExtractor
$resources = array();
foreach ($this->router->getRouteCollection()->all() as $route) {
$method = false;
if (preg_match('#(.+)::([\w]+)#', $route->getDefault('_controller'), $matches)) {
$method = new \ReflectionMethod($matches[1], $matches[2]);
} elseif (preg_match('#(.+):([\w]+)#', $route->getDefault('_controller'), $matches)) {
$controller = $matches[1];
if ($this->container->has($controller)) {
$this->container->enterScope('request');
$this->container->set('request', new Request);
$class = get_class($this->container->get($controller));
$this->container->leaveScope('request');
$method = new \ReflectionMethod($class, $matches[2]);
}
}
$method = $this->getReflectionMethod($route->getDefault('_controller'));
if ($method) {
$annot = $this->reader->getMethodAnnotation($method, self::ANNOTATION_CLASS);
@ -125,6 +113,38 @@ class ApiDocExtractor
return $array;
}
/**
* Returns the ReflectionMethod for the given controller string
*
* @param string $controller
* @return ReflectionMethod|null
*/
public function getReflectionMethod($controller)
{
if (preg_match('#(.+)::([\w]+)#', $controller, $matches)) {
$class = $matches[1];
$method = $matches[2];
} elseif (preg_match('#(.+):([\w]+)#', $controller, $matches)) {
$controller = $matches[1];
$method = $matches[2];
if ($this->container->has($controller)) {
$this->container->enterScope('request');
$this->container->set('request', new Request);
$class = get_class($this->container->get($controller));
$this->container->leaveScope('request');
}
}
if (isset($class) && isset($method)) {
try {
return new \ReflectionMethod($class, $method);
} catch (\ReflectionException $e) {
}
}
return null;
}
/**
* Returns an array containing two values with the following keys:
* - annotation
@ -136,13 +156,8 @@ class ApiDocExtractor
*/
public function get($controller, $route)
{
if (!preg_match('#(.+)::([\w]+)#', $controller, $matches)) {
return null;
}
try {
$method = new \ReflectionMethod($matches[1], $matches[2]);
} catch (\ReflectionException $e) {
$method = $this->getReflectionMethod($controller);
if (!$method) {
return null;
}

View File

@ -22,7 +22,7 @@ class ApiDocExtractorTest extends WebTestCase
$data = $extractor->all();
$this->assertTrue(is_array($data));
$this->assertCount(3, $data);
$this->assertCount(6, $data);
foreach ($data as $d) {
$this->assertTrue(is_array($d));
@ -41,7 +41,19 @@ class ApiDocExtractorTest extends WebTestCase
$this->assertTrue(is_array($a1->getFilters()));
$this->assertNull($a1->getFormType());
$a2 = $data[1]['annotation'];
$a1 = $data[1]['annotation'];
$this->assertTrue($a1->isResource());
$this->assertEquals('index action', $a1->getDescription());
$this->assertTrue(is_array($a1->getFilters()));
$this->assertNull($a1->getFormType());
$a2 = $data[2]['annotation'];
$this->assertFalse($a2->isResource());
$this->assertEquals('create test', $a2->getDescription());
$this->assertTrue(is_array($a2->getFilters()));
$this->assertEquals('Nelmio\ApiDocBundle\Tests\Fixtures\Form\TestType', $a2->getFormType());
$a2 = $data[3]['annotation'];
$this->assertFalse($a2->isResource());
$this->assertEquals('create test', $a2->getDescription());
$this->assertTrue(is_array($a2->getFilters()));
@ -62,6 +74,10 @@ class ApiDocExtractorTest extends WebTestCase
$this->assertEquals('index action', $a->getDescription());
$this->assertTrue(is_array($a->getFilters()));
$this->assertNull($a->getFormType());
$data2 = $extractor->get('nemlio.test.controller:indexAction', 'test_service_route_1');
$data2['route']->setDefault('_controller', $data['route']->getDefault('_controller'));
$this->assertEquals($data, $data2);
}
public function testGetWithBadController()
@ -71,6 +87,10 @@ class ApiDocExtractorTest extends WebTestCase
$data = $extractor->get('Undefined\Controller::indexAction', 'test_route_1');
$this->assertNull($data);
$data = $extractor->get('undefined_service:index', 'test_service_route_1');
$this->assertNull($data);
}
public function testGetWithBadRoute()
@ -80,6 +100,10 @@ class ApiDocExtractorTest extends WebTestCase
$data = $extractor->get('Nelmio\ApiDocBundle\Tests\Fixtures\Controller\TestController::indexAction', 'invalid_route');
$this->assertNull($data);
$data = $extractor->get('nemlio.test.controller:indexAction', 'invalid_route');
$this->assertNull($data);
}
public function testGetWithInvalidPattern()
@ -89,6 +113,10 @@ class ApiDocExtractorTest extends WebTestCase
$data = $extractor->get('Nelmio\ApiDocBundle\Tests\Fixtures\Controller\TestController', 'test_route_1');
$this->assertNull($data);
$data = $extractor->get('nemlio.test.controller', 'test_service_route_1');
$this->assertNull($data);
}
public function testGetWithMethodWithoutApiDocAnnotation()
@ -98,5 +126,9 @@ class ApiDocExtractorTest extends WebTestCase
$data = $extractor->get('Nelmio\ApiDocBundle\Tests\Fixtures\Controller\TestController::anotherAction', 'test_route_3');
$this->assertNull($data);
$data = $extractor->get('nemlio.test.controller:anotherAction', 'test_service_route_1');
$this->assertNull($data);
}
}

View File

@ -0,0 +1,19 @@
<?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\Tests\Fixtures\Controller;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Symfony\Component\HttpFoundation\Response;
class TestServiceController extends TestController
{
}

View File

@ -18,3 +18,7 @@ framework:
twig:
debug: %kernel.debug%
strict_variables: %kernel.debug%
services:
nemlio.test.controller:
class: Nelmio\ApiDocBundle\Tests\Fixtures\Controller\TestServiceController

View File

@ -18,6 +18,26 @@ test_route_4:
pattern: /any
defaults: { _controller: NelmioApiDocTestBundle:Test:any, _format: json }
test_service_route_1:
pattern: /tests
defaults: { _controller: nemlio.test.controller:indexAction, _format: json }
requirements:
_method: GET
test_service_route_2:
pattern: /tests
defaults: { _controller: nemlio.test.controller:postTestAction, _format: json }
requirements:
_method: POST
test_service_route_3:
pattern: /another
defaults: { _controller: nemlio.test.controller:anotherAction }
test_service_route_4:
pattern: /any
defaults: { _controller: nemlio.test.controller:anyAction, _format: json }
NelmioApiDocBundle:
resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
prefix: /

View File

@ -42,6 +42,40 @@ b:
* arbitrary: ["arg1","arg2"]
### `GET` /tests ###
_index action_
#### Filters ####
a:
* dataType: integer
b:
* dataType: string
* arbitrary: ["arg1","arg2"]
### `POST` /tests ###
_create test_
#### Parameters ####
a:
* type: string
* required: true
* description: A nice description
b:
* type: string
* required: true
### `POST` /tests ###
_create test_
@ -63,6 +97,11 @@ b:
# others #
### `ANY` /any ###
_Action without HTTP verb_
### `ANY` /any ###
_Action without HTTP verb_

View File

@ -24,44 +24,75 @@ class SimpleFormatterTest extends WebTestCase
$result = $container->get('nelmio_api_doc.formatter.simple_formatter')->format($data);
$expected = array(
'others' => array(
array(
'method' => 'ANY',
'uri' => '/any',
'requirements' => array(),
'description' => 'Action without HTTP verb'
)
),
'/tests' => array(
'/tests' =>
array(
0 =>
array(
'method' => 'GET',
'uri' => '/tests',
'requirements' => array(),
'filters' => array(
'a' => array(
'requirements' =>
array(
),
'filters' =>
array(
'a' =>
array(
'dataType' => 'integer',
),
'b' => array(
'b' =>
array(
'dataType' => 'string',
'arbitrary' => array(
'arg1',
'arg2',
'arbitrary' =>
array(
0 => 'arg1',
1 => 'arg2',
),
),
),
'description' => 'index action',
),
1 =>
array(
'method' => 'GET',
'uri' => '/tests',
'requirements' =>
array(
),
'filters' =>
array(
'a' =>
array(
'dataType' => 'integer',
),
'b' =>
array(
'dataType' => 'string',
'arbitrary' =>
array(
0 => 'arg1',
1 => 'arg2',
),
),
),
'description' => 'index action',
),
2 =>
array(
'method' => 'POST',
'uri' => '/tests',
'requirements' => array(),
'parameters' => array(
'a' => array(
'requirements' =>
array(
),
'parameters' =>
array(
'a' =>
array(
'dataType' => 'string',
'required' => true,
'description' => 'A nice description',
),
'b' => array(
'b' =>
array(
'dataType' => 'string',
'required' => true,
'description' => '',
@ -69,6 +100,51 @@ class SimpleFormatterTest extends WebTestCase
),
'description' => 'create test',
),
3 =>
array(
'method' => 'POST',
'uri' => '/tests',
'requirements' =>
array(
),
'parameters' =>
array(
'a' =>
array(
'dataType' => 'string',
'required' => true,
'description' => 'A nice description',
),
'b' =>
array(
'dataType' => 'string',
'required' => true,
'description' => '',
),
),
'description' => 'create test',
),
),
'others' =>
array(
0 =>
array(
'method' => 'ANY',
'uri' => '/any',
'requirements' =>
array(
),
'description' => 'Action without HTTP verb',
),
1 =>
array(
'method' => 'ANY',
'uri' => '/any',
'requirements' =>
array(
),
'description' => 'Action without HTTP verb',
),
),
);