Files
tez-utils-enum/tests/BitFlagTraitTest.php

184 lines
5.4 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\BitFlagTrait;
enum Permission: int
{
use BackedEnumTrait;
use BitFlagTrait;
case Read = 1;
case Write = 2;
case Delete = 4;
case Admin = 8;
}
final class BitFlagTraitTest extends TestCase
{
// -------------------------------------------------------------------------
// combine()
// -------------------------------------------------------------------------
public function testCombineWithNoArgumentsReturnsZero(): void
{
self::assertSame(0, Permission::combine());
}
public function testCombineWithSingleCase(): void
{
self::assertSame(1, Permission::combine(Permission::Read));
}
public function testCombineWithTwoCases(): void
{
self::assertSame(3, Permission::combine(Permission::Read, Permission::Write));
}
public function testCombineWithAllCases(): void
{
self::assertSame(15, Permission::combine(
Permission::Read,
Permission::Write,
Permission::Delete,
Permission::Admin,
));
}
public function testCombineIsDeduplicated(): void
{
self::assertSame(1, Permission::combine(Permission::Read, Permission::Read));
}
// -------------------------------------------------------------------------
// fromBitmask()
// -------------------------------------------------------------------------
public function testFromBitmaskWithZeroReturnsEmptyArray(): void
{
self::assertSame([], Permission::fromBitmask(0));
}
public function testFromBitmaskWithSingleBitReturnsSingleCase(): void
{
self::assertSame([Permission::Read], Permission::fromBitmask(1));
}
public function testFromBitmaskWithCombinedMaskReturnsMatchingCases(): void
{
$mask = Permission::combine(Permission::Read, Permission::Write);
self::assertSame([Permission::Read, Permission::Write], Permission::fromBitmask($mask));
}
public function testFromBitmaskWithAllBitsReturnsAllCases(): void
{
$mask = Permission::combine(
Permission::Read,
Permission::Write,
Permission::Delete,
Permission::Admin,
);
self::assertSame(
[Permission::Read, Permission::Write, Permission::Delete, Permission::Admin],
Permission::fromBitmask($mask),
);
}
// -------------------------------------------------------------------------
// isSetIn()
// -------------------------------------------------------------------------
public function testIsSetInReturnsTrueWhenBitIsPresent(): void
{
$mask = Permission::combine(Permission::Read, Permission::Write);
self::assertTrue(Permission::Read->isSetIn($mask));
self::assertTrue(Permission::Write->isSetIn($mask));
}
public function testIsSetInReturnsFalseWhenBitIsAbsent(): void
{
$mask = Permission::combine(Permission::Read, Permission::Write);
self::assertFalse(Permission::Delete->isSetIn($mask));
self::assertFalse(Permission::Admin->isSetIn($mask));
}
public function testIsSetInReturnsFalseForZeroMask(): void
{
self::assertFalse(Permission::Read->isSetIn(0));
}
// -------------------------------------------------------------------------
// addTo()
// -------------------------------------------------------------------------
public function testAddToSetsBit(): void
{
$mask = Permission::combine(Permission::Read);
$mask = Permission::Write->addTo($mask);
self::assertSame(3, $mask);
self::assertTrue(Permission::Write->isSetIn($mask));
}
public function testAddToIsIdempotent(): void
{
$mask = Permission::combine(Permission::Read);
$mask = Permission::Read->addTo($mask);
self::assertSame(1, $mask);
}
public function testAddToOnEmptyMask(): void
{
self::assertSame(4, Permission::Delete->addTo(0));
}
// -------------------------------------------------------------------------
// removeFrom()
// -------------------------------------------------------------------------
public function testRemoveFromClearsBit(): void
{
$mask = Permission::combine(Permission::Read, Permission::Write);
$mask = Permission::Write->removeFrom($mask);
self::assertSame(1, $mask);
self::assertFalse(Permission::Write->isSetIn($mask));
}
public function testRemoveFromIsIdempotent(): void
{
$mask = Permission::combine(Permission::Read);
$mask = Permission::Write->removeFrom($mask);
self::assertSame(1, $mask);
}
public function testRemoveFromOnZeroMaskReturnsZero(): void
{
self::assertSame(0, Permission::Read->removeFrom(0));
}
// -------------------------------------------------------------------------
// Workflow: add then remove
// -------------------------------------------------------------------------
public function testAddThenRemoveRestoresOriginalMask(): void
{
$original = Permission::combine(Permission::Read, Permission::Delete);
$modified = Permission::Write->addTo($original);
$restored = Permission::Write->removeFrom($modified);
self::assertSame($original, $restored);
}
}