Added minimal static analysis test suite to ensure purity/immutability of UUID API

This covers most of the commonly used `Uuid` and `UuidInterface` API, and allows us
to pass around `UuidInterface` references as if they were pure.

Note that this only verifies the *contract* of a `UuidInterface`: it is still very
much possible to write mutable `UuidInterface` implementations (and `Uuid` itself
has such an edge-case, allowing for replacement of the static `UuidFactory` reference),
but if you really do mutate UUIDs at runtime, then your code is very much hurting your
project, and you should get rid of that detail.
This commit is contained in:
Marco Pivetta
2019-12-27 17:29:33 +01:00
committed by Ben Ramsey
parent 17b390cc9c
commit c935fbb0d9
4 changed files with 105 additions and 0 deletions
+1
View File
@@ -8,4 +8,5 @@ phpstan-tests.neon export-ignore
phpstan.neon export-ignore
phpunit.xml.dist export-ignore
resources/ export-ignore
static-analysis/ export-ignore
tests/ export-ignore
+1
View File
@@ -12,6 +12,7 @@
<!-- Source and tests must follow the coding standard. -->
<file>./src</file>
<file>./static-analysis</file>
<file>./tests</file>
<!-- Arguments for the command line runner. -->
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<psalm
totallyTyped="true"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="static-analysis" />
</projectFiles>
</psalm>
+91
View File
@@ -0,0 +1,91 @@
<?php
/**
* This file is part of the ramsey/uuid library
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @copyright Copyright (c) Ben Ramsey <ben@benramsey.com>
* @license http://opensource.org/licenses/MIT MIT
*/
declare(strict_types=1);
namespace Ramsey\Uuid\StaticAnalysis;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
/**
* This is a static analysis fixture to verify that the API signature
* of a UUID allows for pure operations. Almost all methods will seem to be
* redundant or trivial: that's normal, we're just verifying the
* transitivity of immutable type signatures.
*
* Please note that this does not guarantee that the internals of the UUID
* library are pure/safe, but just that the declared API to the outside world
* is seen as immutable.
*/
final class UuidIsImmutable
{
/** @psalm-pure */
public static function pureCompareTo(UuidInterface $a, UuidInterface $b): int
{
return $a->compareTo($b);
}
/** @psalm-pure */
public static function pureEquals(UuidInterface $a, ?object $b): bool
{
return $a->equals($b);
}
/**
* @return mixed[]
*
* @psalm-pure
*/
public static function pureGetters(UuidInterface $a): array
{
return [
$a->getBytes(),
$a->getNumberConverter(),
$a->getHex(),
$a->getFieldsHex(),
$a->getClockSeqHiAndReservedHex(),
$a->getClockSeqLowHex(),
$a->getClockSequenceHex(),
$a->getDateTime(),
$a->getInteger(),
$a->getLeastSignificantBitsHex(),
$a->getMostSignificantBitsHex(),
$a->getNodeHex(),
$a->getTimeHiAndVersionHex(),
$a->getTimeLowHex(),
$a->getTimeMidHex(),
$a->getTimestampHex(),
$a->getUrn(),
$a->getVariant(),
$a->getVersion(),
$a->toString(),
$a->__toString(),
];
}
/**
* @return UuidInterface[]|bool[]
*
* @psalm-pure
*/
public static function pureStaticUuidApi(): array
{
$id = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66');
return [
Uuid::fromBytes($id->getBytes()),
Uuid::fromInteger($id->getInteger()),
Uuid::isValid('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'),
];
}
}