registry = new AttributeRegistry(); }); it('can be instantiated', function () { expect($this->registry)->toBeInstanceOf(AttributeRegistry::class); }); it('starts empty', function () { expect(count($this->registry))->toBe(0); }); it('can add attributes', function () { $attribute = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass'), attributeClass: 'Test\\Attribute', target: AttributeTarget::TARGET_CLASS ); $this->registry->add('Test\\Attribute', $attribute); expect(count($this->registry))->toBe(1); }); it('can retrieve attributes by class', function () { $attribute1 = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass1'), attributeClass: 'Test\\Attribute', target: AttributeTarget::TARGET_CLASS ); $attribute2 = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass2'), attributeClass: 'Test\\Attribute', target: AttributeTarget::TARGET_CLASS ); $this->registry->add('Test\\Attribute', $attribute1); $this->registry->add('Test\\Attribute', $attribute2); $attributes = $this->registry->get('Test\\Attribute'); expect($attributes)->toBeArray(); expect(count($attributes))->toBe(2); expect($attributes[0])->toBeInstanceOf(DiscoveredAttribute::class); expect($attributes[1])->toBeInstanceOf(DiscoveredAttribute::class); }); it('returns empty array for non-existent attribute class', function () { $attributes = $this->registry->get('NonExistent\\Attribute'); expect($attributes)->toBeArray(); expect(count($attributes))->toBe(0); }); it('can check if attribute class exists', function () { $attribute = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass'), attributeClass: 'Test\\Attribute', target: AttributeTarget::TARGET_CLASS ); expect($this->registry->has('Test\\Attribute'))->toBeFalse(); $this->registry->add('Test\\Attribute', $attribute); expect($this->registry->has('Test\\Attribute'))->toBeTrue(); }); it('can get all attribute classes', function () { $attribute1 = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass1'), attributeClass: 'Test\\Attribute1', target: AttributeTarget::TARGET_CLASS ); $attribute2 = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass2'), attributeClass: 'Test\\Attribute2', target: AttributeTarget::TARGET_CLASS ); $this->registry->add('Test\\Attribute1', $attribute1); $this->registry->add('Test\\Attribute2', $attribute2); $all = $this->registry->getAllTypes(); expect($all)->toBeArray(); expect(count($all))->toBe(2); expect($all)->toContain('Test\\Attribute1'); expect($all)->toContain('Test\\Attribute2'); }); it('can serialize and deserialize', function () { $attribute = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass'), attributeClass: 'Test\\Attribute', target: AttributeTarget::TARGET_CLASS ); $this->registry->add('Test\\Attribute', $attribute); $array = $this->registry->toArray(); expect($array)->toBeArray(); expect($array)->toHaveKey('mappings'); $restored = AttributeRegistry::fromArray($array); expect($restored)->toBeInstanceOf(AttributeRegistry::class); expect(count($restored))->toBe(1); expect($restored->has('Test\\Attribute'))->toBeTrue(); }); it('can optimize for memory', function () { $attribute = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass'), attributeClass: 'Test\\Attribute', target: AttributeTarget::TARGET_CLASS ); $this->registry->add('Test\\Attribute', $attribute); $this->registry->optimize(); // Should still contain the data after optimization expect($this->registry->has('Test\\Attribute'))->toBeTrue(); }); it('can clear cache', function () { $attribute = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass'), attributeClass: 'Test\\Attribute', target: AttributeTarget::TARGET_CLASS ); $this->registry->add('Test\\Attribute', $attribute); expect($this->registry->has('Test\\Attribute'))->toBeTrue(); $this->registry->clearCache(); // Cache clearing shouldn't remove the data expect($this->registry->has('Test\\Attribute'))->toBeTrue(); }); it('handles method attributes', function () { $attribute = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass'), attributeClass: 'Test\\MethodAttribute', target: AttributeTarget::METHOD, methodName: MethodName::create('myMethod') ); $this->registry->add('Test\\MethodAttribute', $attribute); $attributes = $this->registry->get('Test\\MethodAttribute'); expect(count($attributes))->toBe(1); expect($attributes[0]->target)->toBe(AttributeTarget::METHOD); expect($attributes[0]->methodName)->not->toBeNull(); }); it('handles property attributes', function () { $attribute = new DiscoveredAttribute( className: ClassName::create('Test\\MyClass'), attributeClass: 'Test\\PropertyAttribute', target: AttributeTarget::PROPERTY, propertyName: 'myProperty' ); $this->registry->add('Test\\PropertyAttribute', $attribute); $attributes = $this->registry->get('Test\\PropertyAttribute'); expect(count($attributes))->toBe(1); expect($attributes[0]->target)->toBe(AttributeTarget::PROPERTY); expect($attributes[0]->propertyName)->toBe('myProperty'); }); });