Skip to content

Commit

Permalink
Introduce value object to represent version_compare() operator
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbergmann committed Feb 8, 2020
1 parent d440690 commit c4e1e53
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/Util/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ private function satisfiesPhpVersion(DOMElement $node): bool
$phpVersionOperator = (string) $node->getAttribute('phpVersionOperator');
}

return \version_compare(\PHP_VERSION, $phpVersion, $phpVersionOperator);
return \version_compare(\PHP_VERSION, $phpVersion, (new VersionComparisonOperator($phpVersionOperator))->asString());
}

/**
Expand Down
39 changes: 9 additions & 30 deletions src/Util/Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,10 @@ public static function getMissingRequirements(string $className, string $methodN
$hint = null;

if (!empty($required['PHP'])) {
$operator = empty($required['PHP']['operator']) ? '>=' : $required['PHP']['operator'];
$operator = new VersionComparisonOperator(empty($required['PHP']['operator']) ? '>=' : $required['PHP']['operator']);

self::ensureOperatorIsValid($operator);

if (!\version_compare(\PHP_VERSION, $required['PHP']['version'], $operator)) {
$missing[] = \sprintf('PHP %s %s is required.', $operator, $required['PHP']['version']);
if (!\version_compare(\PHP_VERSION, $required['PHP']['version'], $operator->asString())) {
$missing[] = \sprintf('PHP %s %s is required.', $operator->asString(), $required['PHP']['version']);
$hint = $hint ?? 'PHP';
}
} elseif (!empty($required['PHP_constraint'])) {
Expand All @@ -182,12 +180,10 @@ public static function getMissingRequirements(string $className, string $methodN
if (!empty($required['PHPUnit'])) {
$phpunitVersion = Version::id();

$operator = empty($required['PHPUnit']['operator']) ? '>=' : $required['PHPUnit']['operator'];

self::ensureOperatorIsValid($operator);
$operator = new VersionComparisonOperator(empty($required['PHPUnit']['operator']) ? '>=' : $required['PHPUnit']['operator']);

if (!\version_compare($phpunitVersion, $required['PHPUnit']['version'], $operator)) {
$missing[] = \sprintf('PHPUnit %s %s is required.', $operator, $required['PHPUnit']['version']);
if (!\version_compare($phpunitVersion, $required['PHPUnit']['version'], $operator->asString())) {
$missing[] = \sprintf('PHPUnit %s %s is required.', $operator->asString(), $required['PHPUnit']['version']);
$hint = $hint ?? 'PHPUnit';
}
} elseif (!empty($required['PHPUnit_constraint'])) {
Expand Down Expand Up @@ -260,12 +256,10 @@ public static function getMissingRequirements(string $className, string $methodN
foreach ($required['extension_versions'] as $extension => $req) {
$actualVersion = \phpversion($extension);

$operator = empty($req['operator']) ? '>=' : $req['operator'];

self::ensureOperatorIsValid($operator);
$operator = new VersionComparisonOperator(empty($req['operator']) ? '>=' : $req['operator']);

if ($actualVersion === false || !\version_compare($actualVersion, $req['version'], $operator)) {
$missing[] = \sprintf('Extension %s %s %s is required.', $extension, $operator, $req['version']);
if ($actualVersion === false || !\version_compare($actualVersion, $req['version'], $operator->asString())) {
$missing[] = \sprintf('Extension %s %s %s is required.', $extension, $operator->asString(), $req['version']);
$hint = $hint ?? 'extension_' . $extension;
}
}
Expand Down Expand Up @@ -897,19 +891,4 @@ private static function mergeArraysRecursively(array $a, array $b): array

return $a;
}

/**
* @throws Exception
*/
private static function ensureOperatorIsValid(string $operator): void
{
if (!\in_array($operator, ['<', 'lt', '<=', 'le', '>', 'gt', '>=', 'ge', '==', '=', 'eq', '!=', '<>', 'ne'])) {
throw new Exception(
\sprintf(
'"%s" is not a valid version_compare() operator',
$operator
)
);
}
}
}
54 changes: 54 additions & 0 deletions src/Util/VersionComparisonOperator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\Util;

/**
* @internal This class is not covered by the backward compatibility promise for PHPUnit
* @psalm-immutable
*/
final class VersionComparisonOperator
{
/**
* @var '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne'
*/
private $operator;

This comment has been minimized.

Copy link
@muglug

muglug Feb 9, 2020

Contributor

If this is internal, the property doesn't need to be private – all immutable classes have typechecker-ensured readonly properties, allowing you to remove the getter method (if you wish)

This comment has been minimized.

Copy link
@sebastianbergmann

sebastianbergmann Feb 10, 2020

Author Owner

I know. :) I prefer it this way, though.


public function __construct(string $operator)
{
$this->ensureOperatorIsValid($operator);

$this->operator = $operator;
}

/**
* @return '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne'
*/
public function asString(): string
{
return $this->operator;
}

/**
* @throws Exception
*
* @psalm-assert '<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne' $operator
*/
private function ensureOperatorIsValid(string $operator): void
{
if (!\in_array($operator, ['<', 'lt', '<=', 'le', '>', 'gt', '>=', 'ge', '==', '=', 'eq', '!=', '<>', 'ne'])) {
throw new Exception(
\sprintf(
'"%s" is not a valid version_compare() operator',
$operator
)
);
}
}
}

0 comments on commit c4e1e53

Please sign in to comment.