Skip to content

Commit

Permalink
Merge pull request #4 from petrknap/of-and-of-nullable
Browse files Browse the repository at this point in the history
Implemented `of` and `ofNullable` methods
  • Loading branch information
petrknap authored May 11, 2024
2 parents ab9b47b + 9ed33c7 commit c40db7b
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 8 deletions.
26 changes: 24 additions & 2 deletions src/Optional.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ final class Optional
private bool|null $wasPresent = null;

/**
* @deprecated will be changed to protected - use {@see self::ofNullable()}/{@see self::of()}/{@see self::empty()}
*
* @param T|null $value
*/
public function __construct(
Expand All @@ -24,11 +26,31 @@ public function __construct(
}

/**
* @return self<null>
* @return self<T>
*/
public static function empty(): self
{
return new self(null);
return self::ofNullable(null);
}

/**
* @param T $value
*
* @return self<T>
*/
public static function of(mixed $value): self
{
return $value !== null ? self::ofNullable($value) : throw new LogicException('Value must not be null.');
}

/**
* @param T|null $value
*
* @return self<T>
*/
public static function ofNullable(mixed $value): self
{
return new self($value);
}

public function equals(mixed $obj): bool
Expand Down
45 changes: 39 additions & 6 deletions tests/OptionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,39 @@ class OptionalTest extends TestCase
private const VALUE = 'value';
private const OTHER = 'other';

public function testMethodEmptyReturnsEmptyOptional(): void
{
self::assertFalse(Optional::empty()->isPresent());
}

public function testMethodOfReturnsOptionalWithValue(): void
{
$optional = Optional::of(self::VALUE);

self::assertTrue($optional->isPresent());
self::assertSame(self::VALUE, $optional->get());
}

public function testMethodOfThrowsWhenCalledWithNull(): void
{
self::expectException(LogicException::class);
Optional::of(null);
}

#[DataProvider('dataMethodOfNullableWorks')]
public function testMethodOfNullableWorks(Optional $expectedOptional, mixed $value): void
{
self::assertTrue(Optional::ofNullable($value)->equals($expectedOptional));
}

public static function dataMethodOfNullableWorks(): array
{
return self::makeDataSet([
[self::VALUE],
[null],
]);
}

#[DataProvider('dataMethodEqualsWorks')]
public function testMethodEqualsWorks(Optional $optional, mixed $obj, bool $expectedResult): void
{
Expand All @@ -21,22 +54,22 @@ public function testMethodEqualsWorks(Optional $optional, mixed $obj, bool $expe

public static function dataMethodEqualsWorks(): array
{
$optionalValue = new Optional(self::VALUE);
$optionalValue = Optional::of(self::VALUE);
$optionalEmpty = Optional::empty();
return [
'equal (value)' => [$optionalValue, self::VALUE, true],
'equal (optional)' => [$optionalValue, new Optional(self::VALUE), true],
'equal (optional)' => [$optionalValue, Optional::of(self::VALUE), true],
'equal (empty)' => [$optionalEmpty, Optional::empty(), true],
'not equal (value)' => [$optionalValue, self::OTHER, false],
'not equal (optional)' => [$optionalValue, new Optional(self::OTHER), false],
'not equal (optional)' => [$optionalValue, Optional::of(self::OTHER), false],
'not equal (empty-present)' => [$optionalEmpty, $optionalValue, false],
'not equal (present-empty)' => [$optionalValue, $optionalEmpty, false],
];
}

public function testMethodGetReturnsValueWhenValueIsPresent(): void
{
$optional = new Optional(self::VALUE);
$optional = Optional::of(self::VALUE);

self::assertTrue($optional->isPresent());
self::assertSame(self::VALUE, $optional->get());
Expand All @@ -53,7 +86,7 @@ public function testMethodGetThrowsWhenValueIsNotPresent(): void

public function testMethodGetThrowsWhenCalledSeparately(): void
{
$optional = new Optional(self::VALUE);
$optional = Optional::of(self::VALUE);

self::expectException(LogicException::class);
$optional->get();
Expand Down Expand Up @@ -110,7 +143,7 @@ public static function dataMethodOrElseWorks(): array
private static function makeDataSet(array $args): array
{
return [
'present value' => [new Optional(self::VALUE), ...$args[0]],
'present value' => [Optional::of(self::VALUE), ...$args[0]],
'not present value' => [Optional::empty(), ...$args[1]],
];
}
Expand Down

0 comments on commit c40db7b

Please sign in to comment.