From 21f4a7291ec88dd541850ec22795f1e6cf9c3e15 Mon Sep 17 00:00:00 2001 From: Paul Mitchum Date: Tue, 31 Jan 2023 11:39:23 -0800 Subject: [PATCH 1/3] added fromYamlRaw --- README.md | 4 ++-- composer.json | 1 + src/ValidatorBuilder.php | 26 +++++++++++++++++++++-- src/ValidatorBuilderInterface.php | 20 ++++++++++++++++-- tests/ValidatorBuilderSpeedTest.php | 32 +++++++++++++++++++++++++++++ tests/ValidatorBuilderTest.php | 2 ++ 6 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 tests/ValidatorBuilderSpeedTest.php diff --git a/README.md b/README.md index 59e663c..acd5fc9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# OpenAPI HttpFoundation Testing + # OpenAPI HttpFoundation Testing [![Build Status](https://github.com/osteel/php-cli-demo/workflows/CI/badge.svg)](https://github.com/osteel/php-cli-demo/actions) [![Latest Stable Version](https://poser.pugx.org/osteel/openapi-httpfoundation-testing/v)](//packagist.org/packages/osteel/openapi-httpfoundation-testing) @@ -53,7 +53,7 @@ $validator = ValidatorBuilder::fromYaml('my-definition.yaml')->getValidator(); $validator = ValidatorBuilder::fromJson('my-definition.json')->getValidator(); ``` -💡 _Instead of a file, you can also pass a YAML or JSON string directly._ +💡 _Instead of a file, you can also pass a YAML or JSON string directly into `fromJson` or `fromYaml`, or you can use `fromJsonRaw` or `fromYamlRaw`._ You can now validate `\Symfony\Component\HttpFoundation\Request` and `\Symfony\Component\HttpFoundation\Response` objects for a given [path](https://swagger.io/specification/#paths-object) and method: diff --git a/composer.json b/composer.json index b2ebc2c..cc36bc3 100644 --- a/composer.json +++ b/composer.json @@ -47,6 +47,7 @@ }, "scripts": { "test": "phpunit", + "test-speed": "phpunit --filter ValidatorBuilderSpeedTest --repeat 10000", "check-style": "phpcs src tests", "fix-style": "phpcbf src tests" }, diff --git a/src/ValidatorBuilder.php b/src/ValidatorBuilder.php index 0a2eef7..835743a 100644 --- a/src/ValidatorBuilder.php +++ b/src/ValidatorBuilder.php @@ -38,7 +38,7 @@ public function __construct(BaseValidatorBuilder $builder) /** * {@inheritdoc} * - * @param string $definition The OpenAPI definition. + * @param string $definition The OpenAPI definition or a file name. * @return ValidatorBuilderInterface */ public static function fromYaml(string $definition): ValidatorBuilderInterface @@ -51,7 +51,7 @@ public static function fromYaml(string $definition): ValidatorBuilderInterface /** * {@inheritdoc} * - * @param string $definition The OpenAPI definition. + * @param string $definition The OpenAPI definition or a file name. * @return ValidatorBuilderInterface */ public static function fromJson(string $definition): ValidatorBuilderInterface @@ -61,6 +61,28 @@ public static function fromJson(string $definition): ValidatorBuilderInterface return static::fromMethod($method, $definition); } + /** + * {@inheritdoc} + * + * @param string $definition The OpenAPI definition as YAML text. + * @return ValidatorBuilderInterface + */ + public static function fromYamlRaw(string $definition): ValidatorBuilderInterface + { + return static::fromMethod('fromYaml', $definition); + } + + /** + * {@inheritdoc} + * + * @param string $definition The OpenAPI definition as JSON text. + * @return ValidatorBuilderInterface + */ + public static function fromJsonRaw(string $definition): ValidatorBuilderInterface + { + return static::fromMethod('fromJson', $definition); + } + /** * Create a Validator object based on an OpenAPI definition. * diff --git a/src/ValidatorBuilderInterface.php b/src/ValidatorBuilderInterface.php index 2998d3f..4914c2f 100644 --- a/src/ValidatorBuilderInterface.php +++ b/src/ValidatorBuilderInterface.php @@ -9,7 +9,7 @@ interface ValidatorBuilderInterface /** * Create a ValidatorBuilderInterface object based on a YAML OpenAPI definition. * - * @param string $definition The OpenAPI definition. + * @param string $definition The OpenAPI definition or a file name. * @return ValidatorBuilderInterface */ public static function fromYaml(string $definition): ValidatorBuilderInterface; @@ -17,11 +17,27 @@ public static function fromYaml(string $definition): ValidatorBuilderInterface; /** * Create a ValidatorBuilderInterface object based on a JSON OpenAPI definition. * - * @param string $definition The OpenAPI definition. + * @param string $definition The OpenAPI definition or a file name. * @return ValidatorBuilderInterface */ public static function fromJson(string $definition): ValidatorBuilderInterface; + /** + * Create a ValidatorBuilderInterface object based on a YAML OpenAPI definition. + * + * @param string $definition The OpenAPI definition as YAML text. + * @return ValidatorBuilderInterface + */ + public static function fromYamlRaw(string $definition): ValidatorBuilderInterface; + + /** + * Create a ValidatorBuilderInterface object based on a JSON OpenAPI definition. + * + * @param string $definition The OpenAPI definition as JSON text. + * @return ValidatorBuilderInterface + */ + public static function fromJsonRaw(string $definition): ValidatorBuilderInterface; + /** * Return the validator. * diff --git a/tests/ValidatorBuilderSpeedTest.php b/tests/ValidatorBuilderSpeedTest.php new file mode 100644 index 0000000..5828582 --- /dev/null +++ b/tests/ValidatorBuilderSpeedTest.php @@ -0,0 +1,32 @@ +getValidator(); + + $this->assertInstanceOf(Validator::class, $result); + } +} diff --git a/tests/ValidatorBuilderTest.php b/tests/ValidatorBuilderTest.php index 2df74e5..1f74af7 100644 --- a/tests/ValidatorBuilderTest.php +++ b/tests/ValidatorBuilderTest.php @@ -17,8 +17,10 @@ public function definitionProvider(): array return [ ['fromYaml', self::$yamlDefinition], ['fromYaml', file_get_contents(self::$yamlDefinition)], + ['fromYamlRaw', file_get_contents(self::$yamlDefinition)], ['fromJson', self::$jsonDefinition], ['fromJson', file_get_contents(self::$jsonDefinition)], + ['fromJsonRaw', file_get_contents(self::$jsonDefinition)], ]; } From 88681a4c806a8bb5b640123bf546381bf7d2d416 Mon Sep 17 00:00:00 2001 From: Paul Mitchum Date: Wed, 1 Feb 2023 09:41:21 -0800 Subject: [PATCH 2/3] renamed to fromYamlString, added fromYamlFile, other fixes from review --- README.md | 15 +++++++++----- composer.json | 1 - src/ValidatorBuilder.php | 28 +++++++++++++++++++++++-- src/ValidatorBuilderInterface.php | 22 ++++++++++++++++++-- tests/ValidatorBuilderSpeedTest.php | 32 ----------------------------- tests/ValidatorBuilderTest.php | 6 ++++-- 6 files changed, 60 insertions(+), 44 deletions(-) delete mode 100644 tests/ValidatorBuilderSpeedTest.php diff --git a/README.md b/README.md index acd5fc9..0d27e19 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - # OpenAPI HttpFoundation Testing +# OpenAPI HttpFoundation Testing [![Build Status](https://github.com/osteel/php-cli-demo/workflows/CI/badge.svg)](https://github.com/osteel/php-cli-demo/actions) [![Latest Stable Version](https://poser.pugx.org/osteel/openapi-httpfoundation-testing/v)](//packagist.org/packages/osteel/openapi-httpfoundation-testing) @@ -43,17 +43,22 @@ Import the builder class: use Osteel\OpenApi\Testing\ValidatorBuilder; ``` -Use the builder to create a `\Osteel\OpenApi\Testing\Validator` object, feeding it a YAML or JSON OpenAPI definition: +Use the builder to create a `\Osteel\OpenApi\Testing\Validator` object, using one of the many factory methods for YAML or JSON: ```php +// Choose one: + $validator = ValidatorBuilder::fromYaml('my-definition.yaml')->getValidator(); +$validator = ValidatorBuilder::fromJson('my-definition.json')->getValidator(); -// or +$validator = ValidatorBuilder::fromYamlFile('my-definition.yaml')->getValidator(); +$validator = ValidatorBuilder::fromJsonFile('my-definition.json')->getValidator(); -$validator = ValidatorBuilder::fromJson('my-definition.json')->getValidator(); +$validator = ValidatorBuilder::fromYamlString($already_loaded_yaml_string)->getValidator(); +$validator = ValidatorBuilder::fromJsonString($already_loaded_json_string)->getValidator(); ``` -💡 _Instead of a file, you can also pass a YAML or JSON string directly into `fromJson` or `fromYaml`, or you can use `fromJsonRaw` or `fromYamlRaw`._ +💡 _`ValidatorBuilder::fromYaml` and `ValidatorBuilder::fromJson` can take either a file name or the contents of the file._ You can now validate `\Symfony\Component\HttpFoundation\Request` and `\Symfony\Component\HttpFoundation\Response` objects for a given [path](https://swagger.io/specification/#paths-object) and method: diff --git a/composer.json b/composer.json index cc36bc3..b2ebc2c 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,6 @@ }, "scripts": { "test": "phpunit", - "test-speed": "phpunit --filter ValidatorBuilderSpeedTest --repeat 10000", "check-style": "phpcs src tests", "fix-style": "phpcbf src tests" }, diff --git a/src/ValidatorBuilder.php b/src/ValidatorBuilder.php index 835743a..f9e5568 100644 --- a/src/ValidatorBuilder.php +++ b/src/ValidatorBuilder.php @@ -61,13 +61,37 @@ public static function fromJson(string $definition): ValidatorBuilderInterface return static::fromMethod($method, $definition); } + /** + * {@inheritdoc} + * + * @param string $file The OpenAPI definition file name. + * + * @return ValidatorBuilderInterface + */ + public static function fromYamlFile(string $file): ValidatorBuilderInterface + { + return static::fromMethod('fromYamlFile', $file); + } + + /** + * {@inheritdoc} + * + * @param string $file The OpenAPI definition file name. + * + * @return ValidatorBuilderInterface + */ + public static function fromJsonFile(string $file): ValidatorBuilderInterface + { + return static::fromMethod('fromJsonFile', $file); + } + /** * {@inheritdoc} * * @param string $definition The OpenAPI definition as YAML text. * @return ValidatorBuilderInterface */ - public static function fromYamlRaw(string $definition): ValidatorBuilderInterface + public static function fromYamlString(string $definition): ValidatorBuilderInterface { return static::fromMethod('fromYaml', $definition); } @@ -78,7 +102,7 @@ public static function fromYamlRaw(string $definition): ValidatorBuilderInterfac * @param string $definition The OpenAPI definition as JSON text. * @return ValidatorBuilderInterface */ - public static function fromJsonRaw(string $definition): ValidatorBuilderInterface + public static function fromJsonString(string $definition): ValidatorBuilderInterface { return static::fromMethod('fromJson', $definition); } diff --git a/src/ValidatorBuilderInterface.php b/src/ValidatorBuilderInterface.php index 4914c2f..d66ab00 100644 --- a/src/ValidatorBuilderInterface.php +++ b/src/ValidatorBuilderInterface.php @@ -22,13 +22,31 @@ public static function fromYaml(string $definition): ValidatorBuilderInterface; */ public static function fromJson(string $definition): ValidatorBuilderInterface; + /** + * Create a ValidatorBuilderInterface object based on a YAML OpenAPI definition. + * + * @param string $file The OpenAPI definition file name. + * + * @return ValidatorBuilderInterface + */ + public static function fromYamlFile(string $file): ValidatorBuilderInterface; + + /** + * Create a ValidatorBuilderInterface object based on a JSON OpenAPI definition. + * + * @param string $file The OpenAPI definition file name. + * + * @return ValidatorBuilderInterface + */ + public static function fromJsonFile(string $file): ValidatorBuilderInterface; + /** * Create a ValidatorBuilderInterface object based on a YAML OpenAPI definition. * * @param string $definition The OpenAPI definition as YAML text. * @return ValidatorBuilderInterface */ - public static function fromYamlRaw(string $definition): ValidatorBuilderInterface; + public static function fromYamlString(string $definition): ValidatorBuilderInterface; /** * Create a ValidatorBuilderInterface object based on a JSON OpenAPI definition. @@ -36,7 +54,7 @@ public static function fromYamlRaw(string $definition): ValidatorBuilderInterfac * @param string $definition The OpenAPI definition as JSON text. * @return ValidatorBuilderInterface */ - public static function fromJsonRaw(string $definition): ValidatorBuilderInterface; + public static function fromJsonString(string $definition): ValidatorBuilderInterface; /** * Return the validator. diff --git a/tests/ValidatorBuilderSpeedTest.php b/tests/ValidatorBuilderSpeedTest.php deleted file mode 100644 index 5828582..0000000 --- a/tests/ValidatorBuilderSpeedTest.php +++ /dev/null @@ -1,32 +0,0 @@ -getValidator(); - - $this->assertInstanceOf(Validator::class, $result); - } -} diff --git a/tests/ValidatorBuilderTest.php b/tests/ValidatorBuilderTest.php index 1f74af7..92ddb49 100644 --- a/tests/ValidatorBuilderTest.php +++ b/tests/ValidatorBuilderTest.php @@ -17,10 +17,12 @@ public function definitionProvider(): array return [ ['fromYaml', self::$yamlDefinition], ['fromYaml', file_get_contents(self::$yamlDefinition)], - ['fromYamlRaw', file_get_contents(self::$yamlDefinition)], + ['fromYamlFile', self::$yamlDefinition], + ['fromYamlString', file_get_contents(self::$yamlDefinition)], ['fromJson', self::$jsonDefinition], ['fromJson', file_get_contents(self::$jsonDefinition)], - ['fromJsonRaw', file_get_contents(self::$jsonDefinition)], + ['fromJsonFile', self::$jsonDefinition], + ['fromJsonString', file_get_contents(self::$jsonDefinition)], ]; } From fd7a276916ee09371f0f4d0763cfd984b8643fc4 Mon Sep 17 00:00:00 2001 From: osteel Date: Wed, 1 Feb 2023 19:20:03 +0000 Subject: [PATCH 3/3] polishing up --- README.md | 33 ++++++++++++++++++------------- src/ValidatorBuilder.php | 18 ++++++++--------- src/ValidatorBuilderInterface.php | 10 ++++------ 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 0d27e19..4055153 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ Validate HttpFoundation requests and responses against OpenAPI (3.0.x) definitio See [this post](https://tech.osteel.me/posts/openapi-backed-api-testing-in-php-projects-a-laravel-example "OpenAPI-backed API testing in PHP projects – a Laravel example") for more details and [this repository](https://github.com/osteel/openapi-httpfoundation-testing-laravel-example) for an example use in a Laravel project. -💡 _While you can safely use this package for your projects, as long as version `1.0` has not been released "minor" version patches can contain breaking changes. Make sure to check the [release section](../../releases) before you upgrade._ +> **Note** +> While you can safely use this package for your projects, as long as version `1.0` has not been released "minor" version patches can contain breaking changes. Make sure to check the [release section](../../releases) before you upgrade. ## Why? @@ -25,7 +26,7 @@ This package is built upon the [OpenAPI PSR-7 Message Validator](https://github. It converts HttpFoundation request and response objects to PSR-7 messages using Symfony's [PSR-7 Bridge](https://symfony.com/doc/current/components/psr7.html) and [Tobias Nyholm](https://github.com/Nyholm)'s [PSR-7 implementation](https://github.com/Nyholm/psr7), before passing them on to OpenAPI PSR-7 Message Validator. -## Install +## Installation Via Composer: @@ -33,7 +34,8 @@ Via Composer: $ composer require --dev osteel/openapi-httpfoundation-testing ``` -💡 _This package is mostly intended to be used as part of an API test suite._ +> **Note** +> This package is mostly intended to be used as part of an API test suite. ## Usage @@ -43,22 +45,24 @@ Import the builder class: use Osteel\OpenApi\Testing\ValidatorBuilder; ``` -Use the builder to create a `\Osteel\OpenApi\Testing\Validator` object, using one of the many factory methods for YAML or JSON: +Use the builder to create a `\Osteel\OpenApi\Testing\Validator` object, using one of the available factory methods for YAML or JSON: ```php -// Choose one: +// From a file: -$validator = ValidatorBuilder::fromYaml('my-definition.yaml')->getValidator(); -$validator = ValidatorBuilder::fromJson('my-definition.json')->getValidator(); +$validator = ValidatorBuilder::fromYamlFile($yamlFile)->getValidator(); +$validator = ValidatorBuilder::fromJsonFile($jsonFile)->getValidator(); -$validator = ValidatorBuilder::fromYamlFile('my-definition.yaml')->getValidator(); -$validator = ValidatorBuilder::fromJsonFile('my-definition.json')->getValidator(); +// From a string: -$validator = ValidatorBuilder::fromYamlString($already_loaded_yaml_string)->getValidator(); -$validator = ValidatorBuilder::fromJsonString($already_loaded_json_string)->getValidator(); -``` +$validator = ValidatorBuilder::fromYamlString($yamlString)->getValidator(); +$validator = ValidatorBuilder::fromJsonString($jsonString)->getValidator(); + +// Automatic detection (slower): -💡 _`ValidatorBuilder::fromYaml` and `ValidatorBuilder::fromJson` can take either a file name or the contents of the file._ +$validator = ValidatorBuilder::fromYaml($yamlFileOrString)->getValidator(); +$validator = ValidatorBuilder::fromJson($jsonFileOrString)->getValidator(); +``` You can now validate `\Symfony\Component\HttpFoundation\Request` and `\Symfony\Component\HttpFoundation\Response` objects for a given [path](https://swagger.io/specification/#paths-object) and method: @@ -66,7 +70,8 @@ You can now validate `\Symfony\Component\HttpFoundation\Request` and `\Symfony\C $validator->validate($response, '/users', 'post'); ``` -💡 _For convenience, objects implementing `\Psr\Http\Message\ServerRequestInterface` or `\Psr\Http\Message\ResponseInterface` are also accepted._ +> **Note** +> For convenience, objects implementing `\Psr\Http\Message\ServerRequestInterface` or `\Psr\Http\Message\ResponseInterface` are also accepted. In the example above, we check that the response matches the OpenAPI definition for a `POST` request on the `/users` path. diff --git a/src/ValidatorBuilder.php b/src/ValidatorBuilder.php index f9e5568..8622fad 100644 --- a/src/ValidatorBuilder.php +++ b/src/ValidatorBuilder.php @@ -38,7 +38,7 @@ public function __construct(BaseValidatorBuilder $builder) /** * {@inheritdoc} * - * @param string $definition The OpenAPI definition or a file name. + * @param string $definition The OpenAPI definition. * @return ValidatorBuilderInterface */ public static function fromYaml(string $definition): ValidatorBuilderInterface @@ -51,7 +51,7 @@ public static function fromYaml(string $definition): ValidatorBuilderInterface /** * {@inheritdoc} * - * @param string $definition The OpenAPI definition or a file name. + * @param string $definition The OpenAPI definition. * @return ValidatorBuilderInterface */ public static function fromJson(string $definition): ValidatorBuilderInterface @@ -64,25 +64,23 @@ public static function fromJson(string $definition): ValidatorBuilderInterface /** * {@inheritdoc} * - * @param string $file The OpenAPI definition file name. - * + * @param string $definition The OpenAPI definition's file. * @return ValidatorBuilderInterface */ - public static function fromYamlFile(string $file): ValidatorBuilderInterface + public static function fromYamlFile(string $definition): ValidatorBuilderInterface { - return static::fromMethod('fromYamlFile', $file); + return static::fromMethod('fromYamlFile', $definition); } /** * {@inheritdoc} * - * @param string $file The OpenAPI definition file name. - * + * @param string $definition The OpenAPI definition's file. * @return ValidatorBuilderInterface */ - public static function fromJsonFile(string $file): ValidatorBuilderInterface + public static function fromJsonFile(string $definition): ValidatorBuilderInterface { - return static::fromMethod('fromJsonFile', $file); + return static::fromMethod('fromJsonFile', $definition); } /** diff --git a/src/ValidatorBuilderInterface.php b/src/ValidatorBuilderInterface.php index d66ab00..c078b44 100644 --- a/src/ValidatorBuilderInterface.php +++ b/src/ValidatorBuilderInterface.php @@ -9,7 +9,7 @@ interface ValidatorBuilderInterface /** * Create a ValidatorBuilderInterface object based on a YAML OpenAPI definition. * - * @param string $definition The OpenAPI definition or a file name. + * @param string $definition The OpenAPI definition. * @return ValidatorBuilderInterface */ public static function fromYaml(string $definition): ValidatorBuilderInterface; @@ -17,7 +17,7 @@ public static function fromYaml(string $definition): ValidatorBuilderInterface; /** * Create a ValidatorBuilderInterface object based on a JSON OpenAPI definition. * - * @param string $definition The OpenAPI definition or a file name. + * @param string $definition The OpenAPI definition. * @return ValidatorBuilderInterface */ public static function fromJson(string $definition): ValidatorBuilderInterface; @@ -25,8 +25,7 @@ public static function fromJson(string $definition): ValidatorBuilderInterface; /** * Create a ValidatorBuilderInterface object based on a YAML OpenAPI definition. * - * @param string $file The OpenAPI definition file name. - * + * @param string $file The OpenAPI definition's file. * @return ValidatorBuilderInterface */ public static function fromYamlFile(string $file): ValidatorBuilderInterface; @@ -34,8 +33,7 @@ public static function fromYamlFile(string $file): ValidatorBuilderInterface; /** * Create a ValidatorBuilderInterface object based on a JSON OpenAPI definition. * - * @param string $file The OpenAPI definition file name. - * + * @param string $file The OpenAPI definition's file. * @return ValidatorBuilderInterface */ public static function fromJsonFile(string $file): ValidatorBuilderInterface;