Skip to content

Commit

Permalink
Add support for php 8.1 features without breaking older php versions
Browse files Browse the repository at this point in the history
 - Refactor unit tests in order to remove php 8.1 specific tests from
 older php versions
 - Conditionally remove or add code to static analysis based on the
 current php version
 - Update minimum phpunit version
  • Loading branch information
xico42 committed Nov 11, 2021
1 parent 969d8f7 commit f349ff5
Show file tree
Hide file tree
Showing 29 changed files with 451 additions and 174 deletions.
7 changes: 7 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
->in(['src', 'test'])
;

if (version_compare(PHP_VERSION, '8.1') < 0) {
$finder = $finder
->notPath('Objects/Schema/Generation/Attributes')
->notPath('Objects/Schema/Generation/AttributeReader.php')
->notPath('Objects/Schema/Generation/Fixture/Attributes');
}

return (new PhpCsFixer\Config())
->setRules([
'@Symfony' => true,
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
ARG PHP_VERSION=7.4

FROM php:${PHP_VERSION}-cli-alpine
FROM php:${PHP_VERSION}-cli-alpine3.13

ARG XDEBUG_VERSION=3.1.1

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ ZOOKEEPER_IPV4 ?= 192.168.104.101
COMPOSER ?= bin/composer.phar
COMPOSER_VERSION ?= 2.1.9
PHP_STAN ?= bin/phpstan.phar
PHP_STAN_VERSION ?= 0.12.99
PHP_STAN_VERSION ?= 1.0.1
PHP_CS_FIXER ?= bin/php-cs-fixer.phar
PHP_CS_FIXER_VERSION ?= 3.2.1
PHPUNIT ?= vendor/bin/phpunit
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"widmogrod/php-functional": "^6.0"
},
"require-dev": {
"phpunit/phpunit": "^8.2.3|^9.4.2",
"phpunit/phpunit": "^9.5.10",
"phpbench/phpbench": "1.0.0-alpha2",
"vlucas/phpdotenv": "~2.4",
"symfony/serializer": "^3.4|^4.3",
Expand Down
15 changes: 15 additions & 0 deletions phpstan-conditional.config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
declare(strict_types = 1);

$config = [];

if (version_compare(PHP_VERSION, '8.1') < 0) {
$config['parameters']['excludePaths'] = [
'analyseAndScan' => [
'src/Objects/Schema/Generation/Attributes/',
'src/Objects/Schema/Generation/AttributeReader.php'
],
];
}

return $config;
2 changes: 2 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
includes:
- phpstan-conditional.config.php
parameters:
level: 8
paths: [ src ]
16 changes: 16 additions & 0 deletions src/Objects/Exceptions/Exceptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ final class Exceptions
{
public const ERROR_ENCODING = 501;
public const ERROR_DECODING = 502;
public const ERROR_PHP_VERSION = 503;

/**
* @param mixed $record
Expand Down Expand Up @@ -41,4 +42,19 @@ public static function forDecode(string $binaryMessage, \Exception $previous = n

return new AvroDecodingException($message, self::ERROR_DECODING, $previous);
}

public static function forPhpVersion(string $currentVersion, string $minimumVersion): UnsupportedPhpVersionException
{
$message = sprintf(
'The current php version \'%s\' is not supported for this feature. ' .
'Minimum supported version is \'%s\'',
$currentVersion,
$minimumVersion,
);

return new UnsupportedPhpVersionException(
$message,
self::ERROR_PHP_VERSION
);
}
}
11 changes: 11 additions & 0 deletions src/Objects/Exceptions/UnsupportedPhpVersionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace FlixTech\AvroSerializer\Objects\Exceptions;

use RuntimeException;

class UnsupportedPhpVersionException extends RuntimeException
{
}
5 changes: 4 additions & 1 deletion src/Objects/Schema/Generation/Annotations/AvroItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
*/
final class AvroItems implements TypeOnlyAttribute
{
/**
* @var mixed
*/
public $value;

public function value(): array
{
$value = is_array($this->value) ? $this->value : [$this->value];
$value = \is_array($this->value) ? $this->value : [$this->value];

return array_map(function ($value) {
if ($value instanceof AvroType) {
Expand Down
5 changes: 4 additions & 1 deletion src/Objects/Schema/Generation/Annotations/AvroValues.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
*/
final class AvroValues implements TypeOnlyAttribute
{
/**
* @var mixed
*/
public $value;

public function value(): array
{
$value = is_array($this->value) ? $this->value : [$this->value];
$value = \is_array($this->value) ? $this->value : [$this->value];

return array_map(function ($value) {
if ($value instanceof AvroType) {
Expand Down
13 changes: 13 additions & 0 deletions src/Objects/Schema/Generation/AttributeReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,25 @@

namespace FlixTech\AvroSerializer\Objects\Schema\Generation;

use FlixTech\AvroSerializer\Objects\Exceptions\Exceptions;
use ReflectionAttribute;
use ReflectionClass;
use ReflectionProperty;

class AttributeReader implements SchemaAttributeReader
{
private const MINIMUM_REQUIRED_VERSION = '8.1';

public function __construct()
{
if (version_compare(PHP_VERSION, self::MINIMUM_REQUIRED_VERSION) < 0) {
throw Exceptions::forPhpVersion(
PHP_VERSION,
self::MINIMUM_REQUIRED_VERSION,
);
}
}

public function readClassAttributes(ReflectionClass $class): SchemaAttributes
{
$attributes = $class->getAttributes();
Expand Down
35 changes: 35 additions & 0 deletions test/Objects/Schema/Generation/AnnotationSchemaGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
use Doctrine\Common\Annotations\AnnotationRegistry;
use FlixTech\AvroSerializer\Objects\Schema\Generation\AnnotationReader as SchemaAnnotationReader;
use FlixTech\AvroSerializer\Objects\Schema\Generation\SchemaAttributeReader;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Annotations\ArraysWithComplexType;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Annotations\EmptyRecord;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Annotations\MapsWithComplexType;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Annotations\PrimitiveTypes;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Annotations\RecordWithComplexTypes;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Annotations\RecordWithRecordType;

class AnnotationSchemaGeneratorTest extends SchemaGeneratorTest
{
Expand All @@ -20,4 +26,33 @@ protected function makeSchemaAttributeReader(): SchemaAttributeReader
);
}

protected function getEmptyRecordClass(): string
{
return EmptyRecord::class;
}

protected function getPrimitiveTypesClass(): string
{
return PrimitiveTypes::class;
}

protected function getRecordWithComplexTypesClass(): string
{
return RecordWithComplexTypes::class;
}

protected function getRecordWithRecordTypeClass(): string
{
return RecordWithRecordType::class;
}

protected function getArraysWithComplexTypeClass(): string
{
return ArraysWithComplexType::class;
}

protected function getMapsWithComplexTypeClass(): string
{
return MapsWithComplexType::class;
}
}
23 changes: 23 additions & 0 deletions test/Objects/Schema/Generation/AttributeReaderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace FlixTech\AvroSerializer\Test\Objects\Schema\Generation;

use FlixTech\AvroSerializer\Objects\Exceptions\UnsupportedPhpVersionException;
use FlixTech\AvroSerializer\Objects\Schema\Generation\AttributeReader;
use PHPUnit\Framework\TestCase;

class AttributeReaderTest extends TestCase
{
/**
* @test
* @requires PHP < 8.1
*/
public function it_should_throw_exception_when_the_php_version_is_not_supported(): void
{
$this->expectException(UnsupportedPhpVersionException::class);

new AttributeReader();
}
}
39 changes: 39 additions & 0 deletions test/Objects/Schema/Generation/AttributeSchemaGeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,50 @@

use FlixTech\AvroSerializer\Objects\Schema\Generation\AttributeReader;
use FlixTech\AvroSerializer\Objects\Schema\Generation\SchemaAttributeReader;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Attributes\ArraysWithComplexType;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Attributes\EmptyRecord;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Attributes\MapsWithComplexType;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Attributes\PrimitiveTypes;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Attributes\RecordWithComplexTypes;
use FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Attributes\RecordWithRecordType;

/**
* @requires PHP >= 8.1
*/
class AttributeSchemaGeneratorTest extends SchemaGeneratorTest
{
protected function makeSchemaAttributeReader(): SchemaAttributeReader
{
return new AttributeReader();
}

protected function getEmptyRecordClass(): string
{
return EmptyRecord::class;
}

protected function getPrimitiveTypesClass(): string
{
return PrimitiveTypes::class;
}

protected function getRecordWithComplexTypesClass(): string
{
return RecordWithComplexTypes::class;
}

protected function getRecordWithRecordTypeClass(): string
{
return RecordWithRecordType::class;
}

protected function getArraysWithComplexTypeClass(): string
{
return ArraysWithComplexType::class;
}

protected function getMapsWithComplexTypeClass(): string
{
return MapsWithComplexType::class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Annotations;

use FlixTech\AvroSerializer\Objects\Schema\Generation\Annotations as SerDe;

/**
* @SerDe\AvroType("record")
* @SerDe\AvroName("ArraysWithComplexType")
*/
class ArraysWithComplexType
{
/**
* @SerDe\AvroType("array", attributes={
* @SerDe\AvroItems({
* "string",
* @SerDe\AvroType("array", attributes={@SerDe\AvroItems(@SerDe\AvroType("string"))})
* })
* })
*/
private $arrayWithUnion;

/**
* @SerDe\AvroType("array", attributes={
* @SerDe\AvroItems(
* @SerDe\AvroType("map", attributes={@SerDe\AvroValues(@SerDe\AvroType("string"))})
* )
* })
*/
private $arrayWithMap;
}
16 changes: 16 additions & 0 deletions test/Objects/Schema/Generation/Fixture/Annotations/EmptyRecord.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Annotations;

use FlixTech\AvroSerializer\Objects\Schema\Generation\Annotations as SerDe;

/**
* @SerDe\AvroName("EmptyRecord")
* @SerDe\AvroNamespace("org.acme")
* @SerDe\AvroType("record")
*/
class EmptyRecord
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace FlixTech\AvroSerializer\Test\Objects\Schema\Generation\Fixture\Annotations;

use FlixTech\AvroSerializer\Objects\Schema\Generation\Annotations as SerDe;

/**
* @SerDe\AvroType("record")
* @SerDe\AvroName("MapsWithComplexType")
*/
class MapsWithComplexType
{
/**
* @SerDe\AvroType("map", attributes={
* @SerDe\AvroValues({
* "string",
* @SerDe\AvroType("array", attributes={@SerDe\AvroItems("string")})
* })
* })
*/
private $mapWithUnion;

/**
* @SerDe\AvroType("map", attributes={
* @SerDe\AvroValues(
* @SerDe\AvroType("array", attributes={@SerDe\AvroItems("string")})
* )
* })
*/
private $mapWithArray;
}
Loading

0 comments on commit f349ff5

Please sign in to comment.