diff --git a/lib/Context/RootContext.php b/lib/Context/RootContext.php index 950a867..3b938e8 100644 --- a/lib/Context/RootContext.php +++ b/lib/Context/RootContext.php @@ -6,7 +6,7 @@ declare(strict_types=1); namespace JKingWeb\Arsse\Context; -class RootContext extends AbstractContext { +abstract class RootContext extends AbstractContext { public $limit = 0; public $offset = 0; diff --git a/lib/Context/UnionContext.php b/lib/Context/UnionContext.php index 257e501..db5a98f 100644 --- a/lib/Context/UnionContext.php +++ b/lib/Context/UnionContext.php @@ -10,7 +10,7 @@ class UnionContext extends RootContext implements \ArrayAccess, \Countable, \Ite protected $contexts = []; public function offsetExists(mixed $offset): bool { - return array_key_exists($offset, $this->contexts); + return isset($this->contexts[$offset]); } public function offsetGet(mixed $offset): mixed { @@ -18,7 +18,12 @@ class UnionContext extends RootContext implements \ArrayAccess, \Countable, \Ite } public function offsetSet(mixed $offset, mixed $value): void { - $this->contexts[$offset ?? count($this->contexts)] = $value; + assert($value instanceof RootContext, new \Exception("Union contexts may only contain other non-exclusion contexts")); + if (isset($offset)) { + $this->contexts[$offset] = $value; + } else { + $this->contexts[] = $value; + } } public function offsetUnset(mixed $offset): void { @@ -35,7 +40,7 @@ class UnionContext extends RootContext implements \ArrayAccess, \Countable, \Ite } } - public function __construct(Context ...$context) { + public function __construct(RootContext ...$context) { $this->contexts = $context; } } diff --git a/tests/cases/Misc/TestContext.php b/tests/cases/Misc/TestContext.php index 1f8b638..f02f6fa 100644 --- a/tests/cases/Misc/TestContext.php +++ b/tests/cases/Misc/TestContext.php @@ -8,12 +8,14 @@ namespace JKingWeb\Arsse\TestCase\Misc; use JKingWeb\Arsse\Context\Context; use JKingWeb\Arsse\Context\ExclusionContext; +use JKingWeb\Arsse\Context\UnionContext; use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\ValueInfo; /** * @covers \JKingWeb\Arsse\Context\Context * @covers \JKingWeb\Arsse\Context\ExclusionContext + * @covers \JKingWeb\Arsse\Context\UnionContext */ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest { protected $ranges = ['modifiedRange', 'markedRange', 'articleRange', 'editionRange']; @@ -150,4 +152,27 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest { $this->assertSame($c1, $c1->not->article(null)); $this->assertSame($c2, $c2->not->article(null)); } + + public function testExerciseAUnionContext(): void { + $c1 = new UnionContext; + $c2 = new Context; + $c3 = new UnionContext; + $this->assertSame(0, sizeof($c1)); + $c1[] = $c2; + $c1[2] = $c3; + $this->assertSame(2, sizeof($c1)); + $this->assertSame($c2, $c1[0]); + $this->assertSame($c3, $c1[2]); + $this->assertSame(null, $c1[1]); + unset($c1[0]); + $this->assertFalse(isset($c1[0])); + $this->assertTrue(isset($c1[2])); + $c1[] = $c2; + $act = []; + foreach($c1 as $k => $v) { + $act[$k] = $v; + } + $exp = [2 => $c3, $c2]; + $this->assertSame($exp, $act); + } }