From 1d4934f8949a6c45eb79c9a3cb82071dea68b7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Sun, 3 Dec 2023 12:48:09 +0100 Subject: [PATCH] Fix: Detect PHPUnit version based on series instead of identifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Andreas Möller Co-authored-by: Michael Voříšek --- CHANGELOG.md | 5 + src/Extension.php | 14 +- src/Version/Minor.php | 47 --- src/Version/Patch.php | 47 --- src/Version/Series.php | 54 ++++ src/Version/Version.php | 183 ------------ test/Unit/Version/MinorTest.php | 49 ---- test/Unit/Version/PatchTest.php | 49 ---- test/Unit/Version/SeriesTest.php | 206 +++++++++++++ test/Unit/Version/VersionTest.php | 465 ------------------------------ 10 files changed, 272 insertions(+), 847 deletions(-) delete mode 100644 src/Version/Minor.php delete mode 100644 src/Version/Patch.php create mode 100644 src/Version/Series.php delete mode 100644 src/Version/Version.php delete mode 100644 test/Unit/Version/MinorTest.php delete mode 100644 test/Unit/Version/PatchTest.php create mode 100644 test/Unit/Version/SeriesTest.php delete mode 100644 test/Unit/Version/VersionTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index ec9df66e..9c77b5dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ For a full diff see [`2.4.0...main`][2.4.0...main]. - Added support for PHP 8.0 ([#375]), by [@localheinz] and [@mvorisek] - Added support for PHP 7.4 ([#390]), by [@localheinz] and [@mvorisek] +### Changed + +- Improved detection of PHPUnit version ([#393]), by [@localheinz] and [@mvorisek] + ## [`2.4.0`][2.4.0] For a full diff see [`2.3.2...2.4.0`][2.3.2...2.4.0]. @@ -204,6 +208,7 @@ For a full diff see [`7afa59c...1.0.0`][7afa59c...1.0.0]. [#367]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/367 [#375]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/375 [#390]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/390 +[#393]: https://github.com/ergebnis/phpunit-slow-test-detector/pull/393 [@HypeMC]: https://github.com/HypeMC [@localheinz]: https://github.com/localheinz diff --git a/src/Extension.php b/src/Extension.php index 3182ea52..8ec339a9 100644 --- a/src/Extension.php +++ b/src/Extension.php @@ -18,15 +18,15 @@ use PHPUnit\Util; try { - $phpUnitVersion = Version\Version::fromString(Runner\Version::id()); + $phpUnitVersionSeries = Version\Series::fromString(Runner\Version::series()); } catch (\InvalidArgumentException $exception) { throw new \RuntimeException(\sprintf( - 'Unable to determine PHPUnit version from version identifier "%s".', - Runner\Version::id(), + 'Unable to determine PHPUnit version from version series "%s".', + Runner\Version::series(), )); } -if ($phpUnitVersion->major()->equals(Version\Major::fromInt(9))) { +if ($phpUnitVersionSeries->major()->equals(Version\Major::fromInt(9))) { /** * @internal */ @@ -170,7 +170,7 @@ private function resolveMaximumDuration(string $test): Duration return; } -if ($phpUnitVersion->major()->equals(Version\Major::fromInt(10))) { +if ($phpUnitVersionSeries->major()->equals(Version\Major::fromInt(10))) { /** * @internal */ @@ -224,6 +224,6 @@ public function bootstrap( } throw new \RuntimeException(\sprintf( - 'Unable to select extension for PHPUnit version with version identifier "%s".', - Runner\Version::id(), + 'Unable to select extension for PHPUnit version with version series "%s".', + Runner\Version::series(), )); diff --git a/src/Version/Minor.php b/src/Version/Minor.php deleted file mode 100644 index 9687a02f..00000000 --- a/src/Version/Minor.php +++ /dev/null @@ -1,47 +0,0 @@ -value = $value; - } - - /** - * @throws \InvalidArgumentException - */ - public static function fromInt(int $value): self - { - if (0 > $value) { - throw new \InvalidArgumentException(\sprintf( - 'Value "%d" does not appear to be a valid value for a minor version.', - $value, - )); - } - - return new self($value); - } - - public function toInt(): int - { - return $this->value; - } -} diff --git a/src/Version/Patch.php b/src/Version/Patch.php deleted file mode 100644 index 1e63fd6e..00000000 --- a/src/Version/Patch.php +++ /dev/null @@ -1,47 +0,0 @@ -value = $value; - } - - /** - * @throws \InvalidArgumentException - */ - public static function fromInt(int $value): self - { - if (0 > $value) { - throw new \InvalidArgumentException(\sprintf( - 'Value "%d" does not appear to be a valid value for a patch version.', - $value, - )); - } - - return new self($value); - } - - public function toInt(): int - { - return $this->value; - } -} diff --git a/src/Version/Series.php b/src/Version/Series.php new file mode 100644 index 00000000..206acde8 --- /dev/null +++ b/src/Version/Series.php @@ -0,0 +1,54 @@ +major = $major; + } + + public static function create(Major $major): self + { + return new self($major); + } + + /** + * @throws \InvalidArgumentException + */ + public static function fromString(string $value): self + { + if (0 === \preg_match('/^(?P(0|[1-9]\d*))\.(?P(0|[1-9]\d*))?$/', $value, $matches)) { + throw new \InvalidArgumentException(\sprintf( + 'Value "%s" does not appear to be a valid value for a semantic version.', + $value, + )); + } + + $major = Major::fromInt((int) $matches['major']); + + return self::create($major); + } + + public function major(): Major + { + return $this->major; + } +} diff --git a/src/Version/Version.php b/src/Version/Version.php deleted file mode 100644 index ff195215..00000000 --- a/src/Version/Version.php +++ /dev/null @@ -1,183 +0,0 @@ -major = $major; - $this->minor = $minor; - $this->patch = $patch; - } - - /** - * @throws \InvalidArgumentException - */ - public static function create( - Major $major, - ?Minor $minor = null, - ?Patch $patch = null - ): self { - if ( - $patch instanceof Patch - && !$minor instanceof Minor - ) { - throw new \InvalidArgumentException('Patch version requires minor version.'); - } - - return new self( - $major, - $minor, - $patch, - ); - } - - /** - * @throws \InvalidArgumentException - */ - public static function fromString(string $value): self - { - if (0 === \preg_match('/^(?P(0|[1-9]\d*))(\.(?P(0|[1-9]\d*))(\.(?P(0|[1-9]\d*)))?)?$/', $value, $matches)) { - throw new \InvalidArgumentException(\sprintf( - 'Value "%s" does not appear to be a valid value for a semantic version.', - $value, - )); - } - - $major = Major::fromInt((int) $matches['major']); - $minor = null; - $patch = null; - - if (\array_key_exists('minor', $matches)) { - $minor = Minor::fromInt((int) $matches['minor']); - } - - if (\array_key_exists('patch', $matches)) { - $patch = Patch::fromInt((int) $matches['patch']); - } - - return self::create( - $major, - $minor, - $patch, - ); - } - - public function major(): Major - { - return $this->major; - } - - public function minor(): ?Minor - { - return $this->minor; - } - - public function patch(): ?Patch - { - return $this->patch; - } - - public function toString(): string - { - if (!$this->minor instanceof Minor) { - return (string) $this->major->toInt(); - } - - if (!$this->patch instanceof Patch) { - return \sprintf( - '%d.%d', - $this->major->toInt(), - $this->minor->toInt(), - ); - } - - return \sprintf( - '%d.%d.%d', - $this->major->toInt(), - $this->minor->toInt(), - $this->patch->toInt(), - ); - } - - public function compare(self $other): int - { - $normalizedThis = self::normalize($this); - $normalizedOther = self::normalize($other); - - if ($normalizedThis->major->toInt() < $normalizedOther->major->toInt()) { - return -1; - } - - if ($normalizedThis->major->toInt() > $normalizedOther->major->toInt()) { - return 1; - } - - \assert($normalizedThis->minor instanceof Minor); - \assert($normalizedOther->minor instanceof Minor); - - if ($normalizedThis->minor->toInt() < $normalizedOther->minor->toInt()) { - return -1; - } - - if ($normalizedThis->minor->toInt() > $normalizedOther->minor->toInt()) { - return 1; - } - - \assert($normalizedThis->patch instanceof Patch); - \assert($normalizedOther->patch instanceof Patch); - - if ($normalizedThis->patch->toInt() < $normalizedOther->patch->toInt()) { - return -1; - } - - if ($normalizedThis->patch->toInt() > $normalizedOther->patch->toInt()) { - return 1; - } - - return 0; - } - - private static function normalize(self $version): self - { - if (!$version->minor instanceof Minor) { - return new self( - $version->major, - Minor::fromInt(0), - Patch::fromInt(0), - ); - } - - if (!$version->patch instanceof Patch) { - return new self( - $version->major, - $version->minor, - Patch::fromInt(0), - ); - } - - return $version; - } -} diff --git a/test/Unit/Version/MinorTest.php b/test/Unit/Version/MinorTest.php deleted file mode 100644 index 45afb947..00000000 --- a/test/Unit/Version/MinorTest.php +++ /dev/null @@ -1,49 +0,0 @@ -expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage(\sprintf( - 'Value "%d" does not appear to be a valid value for a minor version.', - $value, - )); - - Version\Minor::fromInt($value); - } - - /** - * @dataProvider \Ergebnis\DataProvider\IntProvider::greaterThanZero - * @dataProvider \Ergebnis\DataProvider\IntProvider::zero - */ - public function testFromStringReturnsMinor(int $value): void - { - $minor = Version\Minor::fromInt($value); - - self::assertSame($value, $minor->toInt()); - } -} diff --git a/test/Unit/Version/PatchTest.php b/test/Unit/Version/PatchTest.php deleted file mode 100644 index df000c12..00000000 --- a/test/Unit/Version/PatchTest.php +++ /dev/null @@ -1,49 +0,0 @@ -expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage(\sprintf( - 'Value "%d" does not appear to be a valid value for a patch version.', - $value, - )); - - Version\Patch::fromInt($value); - } - - /** - * @dataProvider \Ergebnis\DataProvider\IntProvider::greaterThanZero - * @dataProvider \Ergebnis\DataProvider\IntProvider::zero - */ - public function testFromStringReturnsPatch(int $value): void - { - $patch = Version\Patch::fromInt($value); - - self::assertSame($value, $patch->toInt()); - } -} diff --git a/test/Unit/Version/SeriesTest.php b/test/Unit/Version/SeriesTest.php new file mode 100644 index 00000000..472c2311 --- /dev/null +++ b/test/Unit/Version/SeriesTest.php @@ -0,0 +1,206 @@ +numberBetween(0)); + + $series = Version\Series::create($major); + + self::assertSame($major, $series->major()); + } + + /** + * @dataProvider \Ergebnis\DataProvider\StringProvider::arbitrary() + * @dataProvider provideInvalidValue + */ + public function testFromStringRejectsInvalidValue(string $value): void + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage(\sprintf( + 'Value "%s" does not appear to be a valid value for a semantic version.', + $value, + )); + + Version\Series::fromString($value); + } + + /** + * @return \Generator + */ + public static function provideInvalidValue(): iterable + { + $faker = self::faker(); + + $invalidMajors = [ + 'major-minus-one' => '-1', + 'major-letter' => $faker->randomLetter(), + 'major-word' => $faker->word(), + ]; + + foreach ($invalidMajors as $key => $invalidMajor) { + yield $key => [ + $invalidMajor, + ]; + } + + $invalidMinors = [ + 'minor-minus-one' => '-1', + 'minor-letter' => $faker->randomLetter(), + 'minor-word' => $faker->word(), + ]; + + foreach ($invalidMajors as $invalidMajorKey => $invalidMajor) { + foreach ($invalidMinors as $invalidMinorKey => $invalidMinor) { + $key = \sprintf( + '%s-%s', + $invalidMajorKey, + $invalidMinorKey, + ); + + yield $key => [ + \sprintf( + '%s.%s', + $invalidMajor, + $invalidMinor, + ), + ]; + } + } + + $invalidSeparators = [ + 'separator-space' => ' ', + 'separator-dash' => ' ', + 'separator-dots-two' => '..', + ]; + + $majors = [ + 'major-zero' => '0', + 'major-one' => '1', + 'major-greater-than-one' => (string) $faker->numberBetween(2), + ]; + + $minors = [ + 'minor-zero' => '0', + 'minor-one' => '1', + 'minor-greater-than-one' => (string) $faker->numberBetween(2), + ]; + + foreach ($invalidSeparators as $invalidSeparatorKey => $invalidSeparator) { + foreach ($majors as $majorKey => $major) { + foreach ($minors as $minorKey => $minor) { + $key = \sprintf( + '%s-%s-%s', + $invalidSeparatorKey, + $majorKey, + $minorKey, + ); + + yield $key => [ + \implode( + $invalidSeparator, + [ + $major, + $minor, + ], + ), + ]; + } + } + } + + $patches = [ + 'minor-zero' => '0', + 'minor-one' => '1', + 'minor-greater-than-one' => (string) $faker->numberBetween(2), + ]; + + foreach ($majors as $majorKey => $major) { + foreach ($minors as $minorKey => $minor) { + foreach ($patches as $patchKey => $patch) { + $key = \sprintf( + '%s-%s-%s', + $majorKey, + $minorKey, + $patchKey, + ); + + yield $key => [ + \sprintf( + '%s.%s.%s', + $major, + $minor, + $patch, + ), + ]; + } + } + } + } + + /** + * @dataProvider provideValidValueAndMajor + */ + public function testFromStringReturnsSeries( + string $value, + Version\Major $major + ): void { + $series = Version\Series::fromString($value); + + self::assertEquals($major, $series->major()); + } + + /** + * @return \Generator + */ + public static function provideValidValueAndMajor(): iterable + { + $values = [ + 'major-zero-minor-zero' => [ + '0.0', + Version\Major::fromInt(0), + ], + 'major-one-minor-zero' => [ + '1.0', + Version\Major::fromInt(1), + ], + 'major-minor' => [ + '123.456', + Version\Major::fromInt(123), + ], + ]; + + foreach ($values as $key => [$value, $major]) { + yield $key => [ + $value, + $major, + ]; + } + } +} diff --git a/test/Unit/Version/VersionTest.php b/test/Unit/Version/VersionTest.php deleted file mode 100644 index 9139bcb6..00000000 --- a/test/Unit/Version/VersionTest.php +++ /dev/null @@ -1,465 +0,0 @@ -numberBetween(0)); - - $version = Version\Version::create($major); - - self::assertSame($major, $version->major()); - self::assertNull($version->minor()); - self::assertNull($version->patch()); - - $expected = (string) $major->toInt(); - - self::assertSame($expected, $version->toString()); - } - - public function testCreateReturnsVersionWithMajorAndMinor(): void - { - $faker = self::faker(); - - $major = Version\Major::fromInt($faker->numberBetween(0)); - $minor = Version\Minor::fromInt($faker->numberBetween(0)); - - $version = Version\Version::create( - $major, - $minor, - ); - - self::assertSame($major, $version->major()); - self::assertSame($minor, $version->minor()); - self::assertNull($version->patch()); - - $expected = \sprintf( - '%d.%d', - $major->toInt(), - $minor->toInt(), - ); - - self::assertSame($expected, $version->toString()); - } - - public function testCreateRejectsPatchWhenMinorIsNull(): void - { - $faker = self::faker(); - - $major = Version\Major::fromInt($faker->numberBetween(0)); - $patch = Version\Patch::fromInt($faker->numberBetween(0)); - - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage('Patch version requires minor version.'); - - Version\Version::create( - $major, - null, - $patch, - ); - } - - public function testCreateReturnsVersionWithMajorMinorAndPatch(): void - { - $faker = self::faker(); - - $major = Version\Major::fromInt($faker->numberBetween(0)); - $minor = Version\Minor::fromInt($faker->numberBetween(0)); - $patch = Version\Patch::fromInt($faker->numberBetween(0)); - - $version = Version\Version::create( - $major, - $minor, - $patch, - ); - - self::assertSame($major, $version->major()); - self::assertSame($minor, $version->minor()); - self::assertSame($patch, $version->patch()); - - $expected = \sprintf( - '%d.%d.%d', - $major->toInt(), - $minor->toInt(), - $patch->toInt(), - ); - - self::assertSame($expected, $version->toString()); - } - - /** - * @dataProvider \Ergebnis\DataProvider\StringProvider::arbitrary() - * @dataProvider provideInvalidValue - */ - public function testFromStringRejectsInvalidValue(string $value): void - { - $this->expectException(\InvalidArgumentException::class); - $this->expectExceptionMessage(\sprintf( - 'Value "%s" does not appear to be a valid value for a semantic version.', - $value, - )); - - Version\Version::fromString($value); - } - - /** - * @return \Generator - */ - public static function provideInvalidValue(): iterable - { - $faker = self::faker(); - - $invalidMajors = [ - 'major-minus-one' => '-1', - 'major-letter' => $faker->randomLetter(), - 'major-word' => $faker->word(), - ]; - - foreach ($invalidMajors as $key => $invalidMajor) { - yield $key => [ - $invalidMajor, - ]; - } - - $invalidMinors = [ - 'minor-minus-one' => '-1', - 'minor-letter' => $faker->randomLetter(), - 'minor-word' => $faker->word(), - ]; - - foreach ($invalidMajors as $invalidMajorKey => $invalidMajor) { - foreach ($invalidMinors as $invalidMinorKey => $invalidMinor) { - $key = \sprintf( - '%s-%s', - $invalidMajorKey, - $invalidMinorKey, - ); - - yield $key => [ - \sprintf( - '%s.%s', - $invalidMajor, - $invalidMinor, - ), - ]; - } - } - - $invalidPatches = [ - 'patch-minus-one' => '-1', - 'patch-letter' => $faker->randomLetter(), - 'patch-word' => $faker->word(), - ]; - - foreach ($invalidMajors as $invalidMajorKey => $invalidMajor) { - foreach ($invalidMinors as $invalidMinorKey => $invalidMinor) { - foreach ($invalidPatches as $invalidPatchKey => $invalidPatch) { - $key = \sprintf( - '%s-%s-%s', - $invalidMajorKey, - $invalidMinorKey, - $invalidPatchKey, - ); - - yield $key => [ - \sprintf( - '%s.%s.%s', - $invalidMajor, - $invalidMinor, - $invalidPatch, - ), - ]; - } - } - } - - $separators = [ - 'separator-space' => ' ', - 'separator-dash' => ' ', - 'separator-dots-two' => '..', - ]; - - $majors = [ - 'major-zero' => '0', - 'major-one' => '1', - 'major-greater-than-one' => (string) $faker->numberBetween(2), - ]; - - $minors = [ - 'minor-zero' => '0', - 'minor-one' => '1', - 'minor-greater-than-one' => (string) $faker->numberBetween(2), - ]; - - $patches = [ - 'minor-zero' => '0', - 'minor-one' => '1', - 'minor-greater-than-one' => (string) $faker->numberBetween(2), - ]; - - foreach ($separators as $separatorKey => $separator) { - foreach ($majors as $majorKey => $major) { - foreach ($minors as $minorKey => $minor) { - foreach ($patches as $patchKey => $patch) { - $key = \sprintf( - '%s-%s-%s-%s', - $separatorKey, - $majorKey, - $minorKey, - $patchKey, - ); - - yield $key => [ - \implode( - $separator, - [ - $major, - $minor, - $patch, - ], - ), - ]; - } - } - } - } - } - - /** - * @dataProvider provideValidValue - */ - public function testFromStringReturnsVersion(string $value): void - { - $version = Version\Version::fromString($value); - - self::assertSame($value, $version->toString()); - } - - /** - * @return \Generator - */ - public static function provideValidValue(): iterable - { - $faker = self::faker(); - - $majors = [ - 'major-zero' => '0', - 'major-one' => '1', - 'major-greater-than-one' => (string) $faker->numberBetween(2), - ]; - - foreach ($majors as $key => $major) { - yield $key => [ - $major, - ]; - } - - $minors = [ - 'minor-zero' => '0', - 'minor-one' => '1', - 'minor-greater-than-one' => (string) $faker->numberBetween(2), - ]; - - foreach ($majors as $majorKey => $major) { - foreach ($minors as $minorKey => $minor) { - $key = \sprintf( - '%s-%s', - $majorKey, - $minorKey, - ); - - yield $key => [ - \sprintf( - '%s.%s', - $major, - $minor, - ), - ]; - } - } - - $patches = [ - 'minor-zero' => '0', - 'minor-one' => '1', - 'minor-greater-than-one' => (string) $faker->numberBetween(2), - ]; - - foreach ($majors as $majorKey => $major) { - foreach ($minors as $minorKey => $minor) { - foreach ($patches as $patchKey => $patch) { - $key = \sprintf( - '%s-%s-%s', - $majorKey, - $minorKey, - $patchKey, - ); - - yield $key => [ - \sprintf( - '%s.%s.%s', - $major, - $minor, - $patch, - ), - ]; - } - } - } - } - - /** - * @dataProvider provideVersion - */ - public function testCompareReturnsZeroWhenOtherVersionIsIdentical(Version\Version $version): void - { - self::assertSame(0, $version->compare($version)); - } - - /** - * @return \Generator - */ - public static function provideVersion(): iterable - { - $values = [ - 'major' => Version\Version::fromString('1'), - 'major-minor' => Version\Version::fromString('1.0'), - 'major-minor-patch' => Version\Version::fromString('1.0.0'), - ]; - - foreach ($values as $key => $version) { - yield $key => [ - $version, - ]; - } - } - - /** - * @dataProvider provideSmallerVersionAndGreaterVersion - */ - public function testCompareReturnsMinusOneWhenOtherVersionIsGreater( - Version\Version $smaller, - Version\Version $greater - ): void { - self::assertSame(-1, $smaller->compare($greater)); - } - - /** - * @return \Generator - */ - public static function provideSmallerVersionAndGreaterVersion(): iterable - { - foreach (self::smallerVersionAndGreaterVersion() as [$smaller, $greater]) { - $key = \sprintf( - '%s-is-smaller-than-%s', - $smaller->toString(), - $greater->toString(), - ); - - yield $key => [ - $smaller, - $greater, - ]; - } - } - - /** - * @dataProvider provideGreaterVersionAndSmallerVersion - */ - public function testCompareReturnsPlusOneWhenOtherVersionIsSmaller( - Version\Version $smaller, - Version\Version $greater - ): void { - self::assertSame(1, $smaller->compare($greater)); - } - - /** - * @return \Generator - */ - public static function provideGreaterVersionAndSmallerVersion(): iterable - { - foreach (self::smallerVersionAndGreaterVersion() as [$smaller, $greater]) { - $key = \sprintf( - '%s-is-greater-than-%s', - $greater->toString(), - $smaller->toString(), - ); - - yield $key => [ - $greater, - $smaller, - ]; - } - } - - /** - * @return array - */ - private static function smallerVersionAndGreaterVersion(): array - { - return [ - [ - Version\Version::fromString('1'), - Version\Version::fromString('2'), - ], - [ - Version\Version::fromString('1'), - Version\Version::fromString('1.1'), - ], - [ - Version\Version::fromString('1'), - Version\Version::fromString('1.0.1'), - ], - [ - Version\Version::fromString('1.0'), - Version\Version::fromString('1.1'), - ], - [ - Version\Version::fromString('1.0'), - Version\Version::fromString('2'), - ], - [ - Version\Version::fromString('1.0'), - Version\Version::fromString('1.0.1'), - ], - [ - Version\Version::fromString('1.0.0'), - Version\Version::fromString('1.0.1'), - ], - [ - Version\Version::fromString('1.0.0'), - Version\Version::fromString('2'), - ], - [ - Version\Version::fromString('1.0.0'), - Version\Version::fromString('1.1'), - ], - ]; - } -}