add('a', $a); $registry->add('b', $b); $this->assertSame($a, $registry->get('a')); $this->assertTrue($registry->has('b')); $this->assertFalse($registry->has('c')); $this->assertNull($registry->get('c')); $this->assertCount(2, $registry); $this->assertSame(['a', 'b'], $registry->ids()); } public function test_remove_is_idempotent_and_fires_listeners_once(): void { $registry = new ConnectionRegistry; $removed = []; $registry->onRemove(function (string $id) use (&$removed) { $removed[] = $id; }); $registry->add('a', new \stdClass); $registry->remove('a'); $registry->remove('a'); // no-op — must not fire again $this->assertSame(['a'], $removed); $this->assertCount(0, $registry); } public function test_on_add_listener_fires(): void { $registry = new ConnectionRegistry; $added = []; $registry->onAdd(function (string $id) use (&$added) { $added[] = $id; }); $registry->add('x', new \stdClass); $this->assertSame(['x'], $added); } public function test_numeric_string_ids_survive_ids_each_and_clear(): void { // PHP coerces numeric-string array keys ("1") to int keys internally, which // used to hand ints to remove(string) during clear(). Regression guard. $registry = new ConnectionRegistry; $registry->add('1', new \stdClass); $registry->add('2', new \stdClass); $this->assertSame(['1', '2'], $registry->ids()); $seen = []; $registry->each(function (object $conn, string $id) use (&$seen) { $seen[] = $id; // must receive strings, not ints }); $this->assertSame(['1', '2'], $seen); $registry->clear(); // must not TypeError $this->assertCount(0, $registry); } public function test_each_visits_every_connection(): void { $registry = new ConnectionRegistry; $registry->add('a', new \stdClass); $registry->add('b', new \stdClass); $seen = []; $registry->each(function (object $conn, string $id) use (&$seen) { $seen[] = $id; }); $this->assertSame(['a', 'b'], $seen); } public function test_clear_removes_all_and_fires_remove_for_each(): void { $registry = new ConnectionRegistry; $removed = []; $registry->onRemove(function (string $id) use (&$removed) { $removed[] = $id; }); $registry->add('a', new \stdClass); $registry->add('b', new \stdClass); $registry->clear(); $this->assertCount(0, $registry); $this->assertSame(['a', 'b'], $removed); } }