Skip to content

Commit

Permalink
Merge pull request #4 from ergebnis/feature/minor
Browse files Browse the repository at this point in the history
Enhancement: Implement `Minor`
  • Loading branch information
localheinz authored Dec 25, 2023
2 parents 92ff9a4 + ef9d9fb commit 83cfc70
Show file tree
Hide file tree
Showing 9 changed files with 306 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ For a full diff see [`64ced12...main`][64ced12...main].

- Added `Version` as a value object ([#1]), by [@localheinz]
- Added `Major` as a value object ([#3]), by [@localheinz]
- Added `Minor` as a value object ([#4]), by [@localheinz]

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

[#1]: https://github.com/ergebnis/version/pull/1
[#3]: https://github.com/ergebnis/version/pull/3
[#4]: https://github.com/ergebnis/version/pull/4

[@localheinz]: https://github.com/localheinz
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ $version = Version\Version::fromString('1.2.3');
echo $version->toString(); // 1.2.3

echo $version->major()->toString(); // 1
echo $version->minor()->toString(); // 2
```

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

### Create a `Minor` from a `string`

```php
<?php

declare(strict_types=1);

use Ergebnis\Version;

$minor = Version\Minor::fromString('1');

echo $minor->toString(); // 1
```

### Compare a `Minor` with another `Minor`

```php
<?php

declare(strict_types=1);

use Ergebnis\Version;

$one = Version\Minor::::fromString('1');
$two = Version\Minor::fromString('1');
$three = Version\Minor::fromString('2');

$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
6 changes: 6 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
<code>provideValidValue</code>
</PossiblyUnusedMethod>
</file>
<file src="test/Unit/MinorTest.php">
<PossiblyUnusedMethod>
<code>provideInvalidValue</code>
<code>provideValidValue</code>
</PossiblyUnusedMethod>
</file>
<file src="test/Unit/VersionTest.php">
<PossiblyUnusedMethod>
<code>provideInvalidValue</code>
Expand Down
25 changes: 25 additions & 0 deletions src/Exception/InvalidMinor.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 InvalidMinor extends \InvalidArgumentException
{
public static function fromString(string $value): self
{
return new self(\sprintf(
'Value "%s" does not appear to be valid.',
$value,
));
}
}
49 changes: 49 additions & 0 deletions src/Minor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?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 Minor
{
/**
* @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<minor>0|[1-9]\d*)$/';

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

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

return new self($value);
}

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

public function equals(self $other): bool
{
return $this->value === $other->value;
}
}
7 changes: 7 additions & 0 deletions src/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ final class Version
private function __construct(
private readonly string $value,
private readonly Major $major,
private readonly Minor $minor,
) {
}

Expand All @@ -39,6 +40,7 @@ public static function fromString(string $value): self
return new self(
$value,
Major::fromString($matches['major']),
Minor::fromString($matches['minor']),
);
}

Expand All @@ -56,4 +58,9 @@ public function major(): Major
{
return $this->major;
}

public function minor(): Minor
{
return $this->minor;
}
}
38 changes: 38 additions & 0 deletions test/Unit/Exception/InvalidMinorTest.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\InvalidMinor::class)]
final class InvalidMinorTest extends Framework\TestCase
{
use Test\Util\Helper;

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

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

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

self::assertSame($message, $exception->getMessage());
}
}
107 changes: 107 additions & 0 deletions test/Unit/MinorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?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
*/

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

#[Framework\Attributes\CoversClass(Minor::class)]
#[Framework\Attributes\UsesClass(Exception\InvalidMinor::class)]
final class MinorTest extends Framework\TestCase
{
use Test\Util\Helper;

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

Minor::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
{
$faker = self::faker();

$values = [
'leading-zero' => \sprintf(
'0%d',
$faker->numberBetween(1),
),
'word' => $faker->word(),
];

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

#[Framework\Attributes\DataProvider('provideValidValue')]
public function testFromStringReturnsMinor(string $value): void
{
$minor = Minor::fromString($value);

self::assertSame($value, $minor->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 = [
'zero' => '0',
'one' => '1',
'greater-than-one' => (string) self::faker()->numberBetween(2),
];

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

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

$one = Minor::fromString((string) $faker->numberBetween(0));
$two = Minor::fromString((string) $faker->numberBetween(0));

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

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

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

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

0 comments on commit 83cfc70

Please sign in to comment.