Skip to content

Commit

Permalink
Enhancement: Implement BuildMetaData
Browse files Browse the repository at this point in the history
  • Loading branch information
localheinz committed Dec 25, 2023
1 parent eca4e26 commit 8d189ae
Show file tree
Hide file tree
Showing 9 changed files with 347 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ For a full diff see [`64ced12...main`][64ced12...main].
- Added `Minor` as a value object ([#4]), by [@localheinz]
- Added `Patch` as a value object ([#5]), by [@localheinz]
- Added `PreRelease` as a value object ([#8]), by [@localheinz]
- Added `BuildMetaData` as a value object ([#9]), by [@localheinz]

[64ced12...main]: https://github.com/ergebnis/version/compare/64ced12...main

Expand All @@ -23,5 +24,6 @@ For a full diff see [`64ced12...main`][64ced12...main].
[#4]: https://github.com/ergebnis/version/pull/4
[#5]: https://github.com/ergebnis/version/pull/5
[#8]: https://github.com/ergebnis/version/pull/8
[#9]: https://github.com/ergebnis/version/pull/9

[@localheinz]: https://github.com/localheinz
50 changes: 49 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@ declare(strict_types=1);

use Ergebnis\Version;

$version = Version\Version::fromString('1.2.3-alpha');
$version = Version\Version::fromString('1.2.3-alpha+build.9001');

echo $version->toString(); // 1.2.3

echo $version->major()->toString(); // 1
echo $version->minor()->toString(); // 2
echo $version->patch()->toString(); // 3
echo $version->preRelease()->toString(); // alpha
echo $version->buildMetaData()->toString(); // build.9001
```

### Compare a `Version` with another `Version`
Expand Down Expand Up @@ -206,6 +207,53 @@ $one->equals($three); // false
$one->equals($two); // true
```

### Create a `BuildMetaData` from a `string`

```php
<?php

declare(strict_types=1);

use Ergebnis\Version;

$buildMetaData = Version\BuildMetaData::fromString('build.9001');

echo $buildMetaData->toString(); // build.9001
```

### Create an empty `BuildMetaData`

```php
<?php

declare(strict_types=1);

use Ergebnis\Version;

$buildMetaData = Version\BuildMetaData::empty();

echo $buildMetaData->toString(); // empty
```

### Compare a `BuildMetaData` with another `BuildMetaData`

```php
<?php

declare(strict_types=1);

use Ergebnis\Version;

$one = Version\BuildMetaData::::fromString('build.9001');
$two = Version\BuildMetaData::fromString('build.9001');
$three = Version\BuildMetaData::fromString('build.9000');

$one->equals($two); // true
$one->equals($three); // false

$one->equals($two); // true
```

## Changelog

The maintainers of this project record notable changes to this project in a [changelog](CHANGELOG.md).
Expand Down
8 changes: 7 additions & 1 deletion psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.18.0@b113f3ed0259fd6e212d87c3df80eec95a6abf19">
<file src="test/Unit/BuildMetaDataTest.php">
<PossiblyUnusedMethod>
<code>provideInvalidValue</code>
<code>provideValidValue</code>
</PossiblyUnusedMethod>
</file>
<file src="test/Unit/MajorTest.php">
<PossiblyUnusedMethod>
<code>provideInvalidValue</code>
Expand Down Expand Up @@ -27,7 +33,7 @@
<file src="test/Unit/VersionTest.php">
<PossiblyUnusedMethod>
<code>provideInvalidValue</code>
<code>provideValidValueMajorMinorPatchAndPreRelease</code>
<code>provideValidValueMajorMinorPatchPreReleaseAndBuildMetaData</code>
</PossiblyUnusedMethod>
</file>
</files>
54 changes: 54 additions & 0 deletions src/BuildMetaData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/version
*/

namespace Ergebnis\Version;

final class BuildMetaData
{
/**
* @see https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
* @see https://regex101.com/r/Ly7O1x/3/
*/
private const REGEX = '/^(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)$/';

private function __construct(private readonly string $value)
{
}

/**
* @throws Exception\InvalidBuildMetaData
*/
public static function fromString(string $value): self
{
if (1 !== \preg_match(self::REGEX, $value)) {
throw Exception\InvalidBuildMetaData::fromString($value);
}

return new self($value);
}

public static function empty(): self
{
return new self('');
}

public function toString(): string
{
return $this->value;
}

public function equals(self $other): bool
{
return $this->value === $other->value;
}
}
25 changes: 25 additions & 0 deletions src/Exception/InvalidBuildMetaData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/version
*/

namespace Ergebnis\Version\Exception;

final class InvalidBuildMetaData extends \InvalidArgumentException
{
public static function fromString(string $value): self
{
return new self(\sprintf(
'Value "%s" does not appear to be valid.',
$value,
));
}
}
16 changes: 16 additions & 0 deletions src/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ private function __construct(
private readonly Minor $minor,
private readonly Patch $patch,
private readonly PreRelease $preRelease,
private readonly BuildMetaData $buildMetaData,
) {
}

Expand All @@ -48,12 +49,22 @@ public static function fromString(string $value): self
$preRelease = PreRelease::fromString($matches['prerelease']);
}

$buildMetaData = BuildMetaData::empty();

if (
\array_key_exists('buildmetadata', $matches)
&& '' !== $matches['buildmetadata']
) {
$buildMetaData = BuildMetaData::fromString($matches['buildmetadata']);
}

return new self(
$value,
Major::fromString($matches['major']),
Minor::fromString($matches['minor']),
Patch::fromString($matches['patch']),
$preRelease,
$buildMetaData,
);
}

Expand Down Expand Up @@ -86,4 +97,9 @@ public function preRelease(): PreRelease
{
return $this->preRelease;
}

public function buildMetaData(): BuildMetaData
{
return $this->buildMetaData;
}
}
116 changes: 116 additions & 0 deletions test/Unit/BuildMetaDataTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/version
*/

namespace Ergebnis\Version\Test\Unit;

use Ergebnis\Version\BuildMetaData;
use Ergebnis\Version\Exception;
use Ergebnis\Version\Test;
use PHPUnit\Framework;

#[Framework\Attributes\CoversClass(BuildMetaData::class)]
#[Framework\Attributes\UsesClass(Exception\InvalidBuildMetaData::class)]
final class BuildMetaDataTest extends Framework\TestCase
{
use Test\Util\Helper;

#[Framework\Attributes\DataProvider('provideInvalidValue')]
public function testFromStringRejectsInvalidValue(string $value): void
{
$this->expectException(Exception\InvalidBuildMetaData::class);

BuildMetaData::fromString($value);
}

/**
* @see https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
* @see https://regex101.com/r/Ly7O1x/3/
*
* @return \Generator<string, array{0: string}>
*/
public static function provideInvalidValue(): \Generator
{
$values = [
'meta+meta',
'whatever+meta+meta',
];

foreach ($values as $value) {
yield $value => [
$value,
];
}
}

#[Framework\Attributes\DataProvider('provideValidValue')]
public function testFromStringReturnsBuildMetaData(string $value): void
{
$buildMetaData = BuildMetaData::fromString($value);

self::assertSame($value, $buildMetaData->toString());
}

/**
* @see https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
* @see https://regex101.com/r/Ly7O1x/3/
*
* @return \Generator<string, array{0: string}>
*/
public static function provideValidValue(): \Generator
{
$values = [
'meta',
'meta-valid',
'build.1-aef.1-its-okay',
'build.1',
'build.123',
'build.1848',
'beta',
'788',
'0.build.1-rc.10000aaa-kk-0.1',
];

foreach ($values as $value) {
yield $value => [
$value,
];
}
}

public function testEmptyReturnsBuildMetaData(): void
{
$buildMetaData = BuildMetaData::empty();

self::assertSame('', $buildMetaData->toString());
}

public function testEqualsReturnsFalseWhenValuesAreDifferent(): void
{
$faker = self::faker()->unique();

$one = BuildMetaData::fromString($faker->word());
$two = BuildMetaData::fromString($faker->word());

self::assertFalse($one->equals($two));
}

public function testEqualsReturnsTrueWhenValueIsSame(): void
{
$value = self::faker()->word();

$one = BuildMetaData::fromString($value);
$two = BuildMetaData::fromString($value);

self::assertTrue($one->equals($two));
}
}
38 changes: 38 additions & 0 deletions test/Unit/Exception/InvalidBuildMetaDataTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/version
*/

namespace Ergebnis\Version\Test\Unit\Exception;

use Ergebnis\Version\Exception;
use Ergebnis\Version\Test;
use PHPUnit\Framework;

#[Framework\Attributes\CoversClass(Exception\InvalidBuildMetaData::class)]
final class InvalidBuildMetaDataTest extends Framework\TestCase
{
use Test\Util\Helper;

public function testFromStringReturnsException(): void
{
$value = self::faker()->word();

$exception = Exception\InvalidBuildMetaData::fromString($value);

$message = \sprintf(
'Value "%s" does not appear to be valid.',
$value,
);

self::assertSame($message, $exception->getMessage());
}
}
Loading

0 comments on commit 8d189ae

Please sign in to comment.