├── .circleci └── config.yml ├── .gitignore ├── .lgtm ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENCE.md ├── LICENSE.txt ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── bin └── swaggerize ├── composer.json ├── config └── swaggerConfig.dist.php ├── src ├── Command │ └── Scan.php ├── OperationParser │ ├── LumenControllerOperationParser.php │ └── OperationParserInterface.php └── functions.php └── tests ├── OperationParser └── LumenControllerOperationParserTest.php └── phpunit.xml /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | working_directory: ~/php-swaggerize-fastroute-library 5 | docker: 6 | - image: circleci/php:5 7 | steps: 8 | - checkout 9 | - run: 10 | name: Install dependencies 11 | command: composer install && ./vendor/bin/phpcs --config-set installed_paths $PWD/vendor/escapestudios/symfony2-coding-standard,$PWD/vendor/iadvize/php-convention/phpcs >> /dev/null 12 | - run: 13 | name: Run phpunit 14 | command: ./vendor/bin/phpunit --configuration tests/phpunit.xml 15 | - run: 16 | name: Run phpcs 17 | command: ./vendor/bin/phpcs --standard=Iadvize src 18 | - run: 19 | name: Run phpmd 20 | command: ./vendor/bin/phpmd src text vendor/iadvize/php-convention/phpmd/phpmd.xml 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | vendor 3 | composer.lock 4 | -------------------------------------------------------------------------------- /.lgtm: -------------------------------------------------------------------------------- 1 | approvals = 1 2 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @TidyMaze 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 7 | 8 | ## Our Standards 9 | 10 | Examples of behavior that contributes to creating a positive environment include: 11 | 12 | * Using welcoming and inclusive language 13 | * Being respectful of differing viewpoints and experiences 14 | * Gracefully accepting constructive criticism 15 | * Focusing on what is best for the community 16 | * Showing empathy towards other community members 17 | 18 | Examples of unacceptable behavior by participants include: 19 | 20 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 21 | * Trolling, insulting/derogatory comments, and personal or political attacks 22 | * Public or private harassment 23 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 24 | * Other conduct which could reasonably be considered inappropriate in a professional setting 25 | 26 | ## Our Responsibilities 27 | 28 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 29 | 30 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 31 | 32 | ## Scope 33 | 34 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 35 | 36 | ## Enforcement 37 | 38 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at opensource@iadvize.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 39 | 40 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 41 | 42 | ## Attribution 43 | 44 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 45 | 46 | [homepage]: http://contributor-covenant.org 47 | [version]: http://contributor-covenant.org/version/1/4/ 48 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to iAdvize Projects 2 | 3 | Please take a moment to review this document in order to make the contribution 4 | process easy and effective for everyone involved. 5 | 6 | Following these guidelines helps to communicate that you respect the time of 7 | the developers managing and developing this open source project. In return, 8 | they should reciprocate that respect in addressing your issue or assessing 9 | patches and features. 10 | 11 | 12 | ## Using the issue tracker 13 | 14 | The issue tracker is the preferred channel for [bug reports](#bugs), 15 | [features requests](#features) and [submitting pull 16 | requests](#pull-requests), but please respect the following restrictions: 17 | 18 | * Please **do not** use the issue tracker for personal support requests. 19 | 20 | * Please **do not** derail or troll issues. Keep the discussion on topic and 21 | respect the opinions of others. 22 | 23 | 24 | 25 | ## Bug reports 26 | 27 | A bug is a _demonstrable problem_ that is caused by the code in the repository. 28 | Good bug reports are extremely helpful - thank you! 29 | 30 | Guidelines for bug reports: 31 | 32 | 1. **Use the GitHub issue search** — check if the issue has already been 33 | reported. 34 | 35 | 2. **Check if the issue has been fixed** — try to reproduce it using the 36 | latest `master` or development branch in the repository. 37 | 38 | 3. **Isolate the problem** — make sure that the code in the repository is 39 | _definitely_ responsible for the issue. 40 | 41 | A good bug report shouldn't leave others needing to chase you up for more 42 | information. Please try to be as detailed as possible in your report. 43 | 44 | 45 | 46 | ## Feature requests 47 | 48 | Feature requests are welcome. But take a moment to find out whether your idea 49 | fits with the scope and aims of the project. It's up to *you* to make a strong 50 | case to convince the Roots developers of the merits of this feature. Please 51 | provide as much detail and context as possible. 52 | 53 | 54 | 55 | ## Pull requests 56 | 57 | Good pull requests - patches, improvements, new features - are a fantastic 58 | help. They should remain focused in scope and avoid containing unrelated 59 | commits. 60 | 61 | **Please ask first** before embarking on any significant pull request (e.g. 62 | implementing features, refactoring code), otherwise you risk spending a lot of 63 | time working on something that the developers might not want to merge into the 64 | project. 65 | 66 | Please adhere to the coding conventions used throughout the project (indentation, 67 | comments, etc.). 68 | 69 | Adhering to the following this process is the best way to get your work 70 | merged: 71 | 72 | 1. [Fork](http://help.github.com/fork-a-repo/) the repo, clone your fork, 73 | and configure the remotes: 74 | 75 | ```bash 76 | # Clone your fork of the repo into the current directory 77 | git clone https://github.com// 78 | # Navigate to the newly cloned directory 79 | cd 80 | # Assign the original repo to a remote called "upstream" 81 | git remote add upstream https://github.com// 82 | ``` 83 | 84 | 2. If you cloned a while ago, get the latest changes from upstream: 85 | 86 | ```bash 87 | git checkout 88 | git pull upstream 89 | ``` 90 | 91 | 3. Create a new topic branch (off the main project development branch) to 92 | contain your feature, change, or fix: 93 | 94 | ```bash 95 | git checkout -b 96 | ``` 97 | 98 | 4. Commit your changes in logical chunks. Please adhere to these [git commit 99 | message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) 100 | or your code is unlikely be merged into the main project. Use Git's 101 | [interactive rebase](https://help.github.com/articles/interactive-rebase) 102 | feature to tidy up your commits before making them public. 103 | 104 | 5. Locally merge (or rebase) the upstream development branch into your topic branch: 105 | 106 | ```bash 107 | git pull [--rebase] upstream 108 | ``` 109 | 110 | 6. Push your topic branch up to your fork: 111 | 112 | ```bash 113 | git push origin 114 | ``` 115 | 116 | 10. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) 117 | with a clear title and description. 118 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Please answer these questions before submitting your issue. Thanks! 2 | 3 | ### What is your configuration, please give as much details as possible ? 4 | 5 | ### Does this issue reproduce with the latest release ? 6 | 7 | ### What did you do ? 8 | 9 | If possible, provide a recipe for reproducing the error. 10 | 11 | ### What did you expect to see ? 12 | 13 | ### What did you see instead ? 14 | -------------------------------------------------------------------------------- /LICENCE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 iAdvize 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 iAdvize 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | What this PR does / why we need it: 2 | 3 | Which issue(s) this PR fixes (optional, in fixes #(, fixes #, ...) format, will close the issue(s) when PR gets merged): Fixes # -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | php-swaggerize-fastroute-library [![CircleCI](https://circleci.com/gh/iadvize/php-swaggerize-fastroute-library.svg?style=svg)](https://circleci.com/gh/iadvize/php-swaggerize-fastroute-library) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/iadvize/php-swaggerize-fastroute-library/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/iadvize/php-swaggerize-fastroute-library/?branch=master) 2 | ================================= 3 | 4 | > **⚠️ WARNING**: This repository is deprecated and no longer maintained since 2015. See removal guide [here](#removal-guide). 5 | 6 | A library to automatically create FastRoute routes based on swagger JSON documentation 7 | 8 | ## Removal guide 9 | 10 | This library is deprecated and no longer maintained since 2015. Here is a guide to remove it from your project: 11 | 12 | - check that your app uses this library `iadvize/php-swaggerize-fastroute-library` (search for `Iadvize\SwaggerizeFastRoute` package import in php code). If it does not, you can safely remove it from your `composer.json` and skip the next steps. 13 | - if your CI/CD or dockerfile uses the `swaggerize swagger:scan` command, you should: 14 | - run it manually once (use your full existing command, eg: `./vendor/bin/swaggerize swagger:scan storage/docs/definition.json "path/to/controllers" --routeFile somewhere/routeFile.php`) 15 | - remove the `swaggerize swagger:scan` command from your CI/CD or dockerfile 16 | - convert the generated route file to a standard FastRoute setup (see [FastRoute documentation](https://github.com/nikic/FastRoute?tab=readme-ov-file#usage)), usually the same file as the one using the `Iadvize\SwaggerizeFastRoute` package. 17 | - remove the `Iadvize\SwaggerizeFastRoute` package import from your php code and all usage. 18 | - remove the `iadvize/php-swaggerize-fastroute-library` from your `composer.json` (eg: `composer remove iadvize/php-swaggerize-fastroute-library`) 19 | - delete the routeFile.php file (not needed anymore) 20 | 21 | ## Examples 22 | 23 | ### Generate route File (FastRoute compatible) 24 | 25 | ``` 26 | vendor/bin/swaggerize swagger:scan path/to/swagger/json controllers\namespace [--routeFile=route/file/path] 27 | ``` 28 | 29 | ## Install 30 | 31 | To install with composer: 32 | ``` 33 | composer require iadvize/php-swaggerize-fastroute-library 34 | ``` 35 | 36 | ## Documentation 37 | 38 | ### Generate route File (FastRoute compatible) 39 | 40 | ``` 41 | vendor/bin/swaggerize swagger:scan path/to/swagger/json controllers\namespace [--routeFile=route/file/path] 42 | ``` 43 | 44 | ### Dispatch generated file or simply use cache 45 | 46 | You can then use FastRoute cached dispatcher to use generated file or directly use a cache dispatcher (file will be generated at first call). 47 | 48 | ```PHP 49 | 'route/file/path']) { 56 | \Iadvize\SwaggerizeFastRoute\addRoutes( 57 | 'path/to/swagger/json', 58 | $r, 59 | $lumenOperationParser, 60 | ['routeFile' => 'path/to/generated/route/file', 'cacheEnabled' => false] 61 | ); 62 | }); 63 | 64 | // Fetch method and URI from somewhere 65 | // ... see FastRoute Dispatcher 66 | ``` 67 | 68 | Alternatively to generate routes, you can simply cache first parse by setting `'cacheEnabled' => true` in addRoute function. 69 | 70 | ### Apply this to Lumen application 71 | 72 | To use this swagger routes in a Lumen Application (which use FastRoute as route library), you need to extends `Laravel\Lumen\Application` and override `createDispatcher` method. 73 | 74 | ```PHP 75 | 76 | dispatcher ?: \FastRoute\simpleDispatcher(function ($r) { 95 | foreach ($this->routes as $route) { 96 | $r->addRoute($route['method'], $route['uri'], $route['action']); 97 | } 98 | 99 | $operationParser = new \Iadvize\SwaggerizeFastRoute\OperationParser\LumenControllerOperationParser('My\Application\Http\Controllers'); 100 | 101 | \Iadvize\SwaggerizeFastRoute\addRoutes(storage_path('docs/definition.json'), $r, $operationParser, ['routeFile' => 'route/file/path']); 102 | }); 103 | } 104 | } 105 | ``` 106 | 107 | ### How handler is formed 108 | 109 | Handlers are formed from route defined in swagger as [Lumen](http://lumen.laravel.com/docs/routing#named-routes) define it for controller class : `Controller@method` 110 | 111 | #### Controller class generation 112 | 113 | Controller class is determined from path route with first character uppercased and with Controller at the end of file name 114 | 115 | This swagger JSON : 116 | 117 | ```JSON 118 | { 119 | // ... 120 | "paths": { 121 | "/pets": { 122 | "get": { 123 | // ... 124 | } 125 | "put": { 126 | // ... 127 | } 128 | } 129 | "/store": { 130 | "post": { 131 | // ... 132 | } 133 | } 134 | } 135 | // ... 136 | } 137 | ``` 138 | 139 | will generates respectively this handlers: 140 | 141 | * `PetsController@get` 142 | * `PetsController@update` 143 | * `StoreController@create` 144 | 145 | #### Method generation 146 | 147 | Controller method is mapped from HTTP method : 148 | * `GET` => `get`, 149 | * `POST` => `create`, 150 | * `PUT` => `update`, 151 | * `HEAD` => `head`, 152 | * `OPTIONS` => `options`, 153 | * `PATCH` => `patch`, 154 | * `DELETE` => `delete`, 155 | 156 | ## Contribute 157 | 158 | Look at contribution guidelines here : [CONTRIBUTING.md](CONTRIBUTING.md) 159 | -------------------------------------------------------------------------------- /bin/swaggerize: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | add(new \Iadvize\SwaggerizeFastRoute\Command\Scan()); 7 | $app->run(); 8 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "iadvize/php-swaggerize-fastroute-library", 3 | "description": "A library to automatically create FastRoute routes based on swagger JSON documentation", 4 | "authors": [ 5 | { 6 | "name": "Marc FRICOU", 7 | "email": "marc.fricou@iadvize.com" 8 | } 9 | ], 10 | "repositories": [ 11 | { 12 | "type": "git", 13 | "url": "git@github.com:iadvize/php-convention.git" 14 | } 15 | ], 16 | "require": { 17 | "php": ">=5.5.21", 18 | "nikic/fast-route": "0.*", 19 | "thefrozenfire/swagger": "^2.0", 20 | "symfony/console": "^2.7" 21 | }, 22 | "require-dev": { 23 | "phpunit/phpunit": "~4.8", 24 | "iadvize/php-convention": "dev-master", 25 | "mockery/mockery": "~0.9" 26 | }, 27 | "autoload": { 28 | "psr-4": { 29 | "Iadvize\\SwaggerizeFastRoute\\": "src/", 30 | "IadvizeTest\\SwaggerizeFastRoute\\": "tests/" 31 | }, 32 | "files": ["src/functions.php"] 33 | }, 34 | "bin": [ 35 | "bin/swaggerize" 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /config/swaggerConfig.dist.php: -------------------------------------------------------------------------------- 1 | 'path/to/route/file', 5 | 'cacheEnabled' => true, 6 | 'namespace' => 'Iadvize\ServiceNamespace', 7 | ]; -------------------------------------------------------------------------------- /src/Command/Scan.php: -------------------------------------------------------------------------------- 1 | setName('swagger:scan') 26 | ->setDescription('Scan swagger JSON file ') 27 | ->addArgument( 28 | 'swaggerFile', 29 | InputArgument::REQUIRED, 30 | 'Give JSON file to scan' 31 | ) 32 | ->addArgument( 33 | 'controllerNamespace', 34 | InputArgument::REQUIRED, 35 | 'Controllers namespace that will handle route' 36 | ) 37 | ->addOption( 38 | 'routeFile', 39 | null, 40 | InputOption::VALUE_REQUIRED, 41 | 'Where FastRoute cache file should be write ? Default to output' 42 | ); 43 | } 44 | 45 | /** 46 | * {@inheritdoc} 47 | */ 48 | protected function execute(InputInterface $input, OutputInterface $output) 49 | { 50 | $controllerNamespace = $input->getArgument('controllerNamespace'); 51 | $swaggerFile = $input->getArgument('swaggerFile'); 52 | $routeStream = $input->getOption('routeFile'); 53 | 54 | if (!$routeStream) { 55 | $routeStream = 'php://output'; 56 | } 57 | 58 | $operationParser = new LumenControllerOperationParser($controllerNamespace); 59 | 60 | $routes = \Iadvize\SwaggerizeFastRoute\scan($swaggerFile, $operationParser); 61 | 62 | \Iadvize\SwaggerizeFastRoute\cacheRoutes($routes, $routeStream); 63 | 64 | if ($routeStream !== 'php://output') { 65 | $output->writeln('route file available at ' . $routeStream); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/OperationParser/LumenControllerOperationParser.php: -------------------------------------------------------------------------------- 1 | 'get', 21 | 'POST' => 'create', 22 | 'PUT' => 'update', 23 | 'HEAD' => 'head', 24 | 'OPTIONS' => 'options', 25 | 'PATCH' => 'patch', 26 | 'DELETE' => 'delete', 27 | ]; 28 | 29 | /** 30 | * Constructor 31 | * 32 | * @param string $controllerNamespace 33 | */ 34 | public function __construct($controllerNamespace) 35 | { 36 | if (substr('$controllerNamespace', -1) !== '\\') { 37 | $controllerNamespace .= '\\'; 38 | } 39 | 40 | $this->namespace = $controllerNamespace; 41 | } 42 | 43 | /** 44 | * Get Handler 45 | * 46 | * @param OperationReference $operation 47 | * 48 | * @return array 49 | */ 50 | public function getHandler(OperationReference $operation) 51 | { 52 | // remove route parameters 53 | $path = preg_replace('/\/\{.*\}/', '', $operation->getPath()); 54 | 55 | // lowerCamelCase to UpperCamelCase 56 | $paths = explode('/', $path); 57 | // path start with a / 58 | unset($paths[0]); 59 | $paths = array_map(function ($path) { 60 | return ucfirst($path); 61 | }, $paths); 62 | // path to 'relative' namespace 63 | $path = implode('\\', $paths); 64 | 65 | $controller = $this->namespace . $path . 'Controller'; 66 | 67 | return ['uses' => $controller . '@' . $this->httpVerbToControllerMethod[strtoupper($operation->getMethod())], 'as' => $operation->getOperationId()]; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/OperationParser/OperationParserInterface.php: -------------------------------------------------------------------------------- 1 | getOperationsById(); 38 | 39 | $routes = []; 40 | 41 | foreach ($operations as $operation) { 42 | $routes[] = [ 43 | 'method' => $operation->getMethod(), 44 | 'uri' => $operation->getPath(), 45 | 'action' => $operationParser->getHandler($operation), 46 | ]; 47 | } 48 | 49 | return $routes; 50 | } 51 | 52 | /** 53 | * Add route to route collector 54 | * 55 | * @param string $swaggerJson Swagger json file path (can be an URL) 56 | * @param RouteCollector $routeCollector FastRoute route collector 57 | * @param OperationParserInterface $operationParser Swagger operation parser. 58 | * @param array $options Options (@see config/swaggerConfig.dist.php) 59 | */ 60 | function addRoutes($swaggerJson, RouteCollector $routeCollector, OperationParserInterface $operationParser, $options = []) 61 | { 62 | if (!isset($options['routeFile']) || !file_exists($options['routeFile'])) { 63 | $routes = scan($swaggerJson, $operationParser); 64 | } else { 65 | $routes = require $options['routeFile']; 66 | } 67 | 68 | if (isset($options['routeFile']) && isset($options['cacheEnabled']) && $options['cacheEnabled']) { 69 | cacheRoutes($routes, $options['routeFile']); 70 | } 71 | 72 | foreach ($routes as $route) { 73 | $routeCollector->addRoute($route['method'], $route['uri'], $route['action']); 74 | } 75 | } 76 | 77 | /** 78 | * Write routes array into a file 79 | * 80 | * @param array $routes Routes 81 | * @param string $stream File name or stream in which write routes. 82 | */ 83 | function cacheRoutes(array $routes, $stream) 84 | { 85 | if (is_writable($stream)) { 86 | throw new \LogicException($stream . ' is not writable'); 87 | } 88 | 89 | $routeResource = fopen($stream, 'w'); 90 | 91 | $serializedRoutes = var_export($routes, true); 92 | 93 | fwrite($routeResource, 'operationParser = new LumenControllerOperationParser('Iadvize\Test'); 24 | } 25 | 26 | /** 27 | * Test: Get handler should return an Lumen compatible Array with controller@method 28 | */ 29 | public function testGetHandler() 30 | { 31 | $operationMock = \Mockery::mock(OperationReference::class); 32 | $operationMock->shouldReceive('getPath')->andReturn('/marco'); 33 | $operationMock->shouldReceive('getMethod')->andReturn('GET'); 34 | $operationMock->shouldReceive('getOperationId')->andReturn('operationID'); 35 | 36 | $this->assertEquals(['uses' => 'Iadvize\Test\MarcoController@get', 'as' => 'operationID'], $this->operationParser->getHandler($operationMock)); 37 | } 38 | 39 | /** 40 | * Test: Get handler should return an Lumen compatible Array with controller@method 41 | */ 42 | public function testGetHandlerWithRouteParameter() 43 | { 44 | $operationMock = \Mockery::mock(OperationReference::class); 45 | $operationMock->shouldReceive('getPath')->andReturn('/marco/{id}'); 46 | $operationMock->shouldReceive('getMethod')->andReturn('PUT'); 47 | $operationMock->shouldReceive('getOperationId')->andReturn('operationID'); 48 | 49 | $this->assertEquals(['uses' => 'Iadvize\Test\MarcoController@update', 'as' => 'operationID'], $this->operationParser->getHandler($operationMock)); 50 | } 51 | 52 | /** 53 | * Test: Get handler should return an Lumen compatible Array with controller@method 54 | */ 55 | public function testGetHandlerWithDeepPath() 56 | { 57 | $operationMock = \Mockery::mock(OperationReference::class); 58 | $operationMock->shouldReceive('getPath')->andReturn('/marco/{id}/name/first'); 59 | $operationMock->shouldReceive('getMethod')->andReturn('POST'); 60 | $operationMock->shouldReceive('getOperationId')->andReturn('operationID'); 61 | 62 | $this->assertEquals(['uses' => 'Iadvize\Test\Marco\Name\FirstController@create', 'as' => 'operationID'], $this->operationParser->getHandler($operationMock)); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | ./ 13 | 14 | 15 | 16 | --------------------------------------------------------------------------------