Files

212 lines
6.0 KiB
PHP

<?php
declare(strict_types=1);
namespace Tez\Utils\Tests\Enum;
use PHPUnit\Framework\TestCase;
use Tez\Utils\Enum\BackedEnumTrait;
use Tez\Utils\Enum\EnumTrait;
// Pure (unit) enum used across all EnumTrait tests
enum Season
{
use EnumTrait;
case Spring;
case Summer;
case Autumn;
case Winter;
}
// Backed enum to verify backed paths of EnumTrait (toArray, is, find)
enum Direction: string
{
use BackedEnumTrait;
case North = 'north';
case South = 'south';
case East = 'east';
case West = 'west';
}
final class EnumTraitTest extends TestCase
{
// -------------------------------------------------------------------------
// is()
// -------------------------------------------------------------------------
public function testIsReturnsTrueForSameInstance(): void
{
self::assertTrue(Season::Summer->is(Season::Summer));
}
public function testIsReturnsFalseForNull(): void
{
self::assertFalse(Season::Summer->is(null));
}
public function testIsReturnsFalseForDifferentCase(): void
{
self::assertFalse(Season::Summer->is(Season::Winter));
}
public function testIsReturnsTrueForMatchingStringName(): void
{
self::assertTrue(Season::Autumn->is('Autumn'));
}
public function testIsReturnsFalseForNonMatchingStringName(): void
{
self::assertFalse(Season::Autumn->is('Spring'));
}
public function testIsReturnsTrueForBackedEnumByValue(): void
{
self::assertTrue(Direction::North->is('north'));
}
public function testIsReturnsFalseForBackedEnumWithWrongValue(): void
{
self::assertFalse(Direction::North->is('south'));
}
// -------------------------------------------------------------------------
// isOneOf() / isNoneOf()
// -------------------------------------------------------------------------
public function testIsOneOfReturnsTrueWhenMatchFound(): void
{
self::assertTrue(Season::Winter->isOneOf([Season::Autumn, Season::Winter]));
}
public function testIsOneOfReturnsFalseWhenNoMatch(): void
{
self::assertFalse(Season::Spring->isOneOf([Season::Autumn, Season::Winter]));
}
public function testIsOneOfReturnsFalseForNull(): void
{
self::assertFalse(Season::Spring->isOneOf(null));
}
public function testIsNoneOfIsInverseOfIsOneOf(): void
{
self::assertTrue(Season::Spring->isNoneOf([Season::Autumn, Season::Winter]));
self::assertFalse(Season::Winter->isNoneOf([Season::Autumn, Season::Winter]));
}
// -------------------------------------------------------------------------
// toArray()
// -------------------------------------------------------------------------
public function testToArrayForPureEnumReturnsNameToNameMapping(): void
{
$expected = [
'Spring' => 'Spring',
'Summer' => 'Summer',
'Autumn' => 'Autumn',
'Winter' => 'Winter',
];
self::assertSame($expected, Season::toArray());
}
public function testToArrayForBackedEnumReturnsValueToNameMapping(): void
{
$expected = [
'north' => 'North',
'south' => 'South',
'east' => 'East',
'west' => 'West',
];
self::assertSame($expected, Direction::toArray());
}
// -------------------------------------------------------------------------
// find()
// -------------------------------------------------------------------------
public function testFindReturnsNullForNull(): void
{
self::assertNull(Season::find(null));
}
public function testFindReturnsEnumInstanceWhenPassedItself(): void
{
self::assertSame(Season::Spring, Season::find(Season::Spring));
}
public function testFindByNameForPureEnum(): void
{
self::assertSame(Season::Summer, Season::find('Summer'));
}
public function testFindReturnsNullForUnknownName(): void
{
self::assertNull(Season::find('Unknown'));
}
public function testFindIgnoreCasePureEnum(): void
{
self::assertSame(Season::Winter, Season::find('winter', ignoreCase: true));
}
public function testFindByValueForBackedEnum(): void
{
self::assertSame(Direction::East, Direction::find('east'));
}
public function testFindIgnoreCaseBackedEnum(): void
{
self::assertSame(Direction::West, Direction::find('WEST', ignoreCase: true));
}
// -------------------------------------------------------------------------
// filter()
// -------------------------------------------------------------------------
public function testFilterReturnsCasesMatchingCallback(): void
{
$result = Season::filter(fn(Season $c) => in_array($c, [Season::Spring, Season::Summer], true));
self::assertCount(2, $result);
self::assertContains(Season::Spring, $result);
self::assertContains(Season::Summer, $result);
}
public function testFilterReturnsEmptyArrayWhenNothingMatches(): void
{
$result = Season::filter(fn() => false);
self::assertSame([], $result);
}
// -------------------------------------------------------------------------
// ordinal()
// -------------------------------------------------------------------------
public function testOrdinalReturnsZeroBasedPosition(): void
{
self::assertSame(0, Season::Spring->ordinal());
self::assertSame(1, Season::Summer->ordinal());
self::assertSame(2, Season::Autumn->ordinal());
self::assertSame(3, Season::Winter->ordinal());
}
// -------------------------------------------------------------------------
// first() / last()
// -------------------------------------------------------------------------
public function testFirstReturnsFirstCase(): void
{
self::assertSame(Season::Spring, Season::first());
}
public function testLastReturnsLastCase(): void
{
self::assertSame(Season::Winter, Season::last());
}
}