diff --git a/src/Parser/Attribute.php b/src/Parser/Attribute.php index cc9cb98..bd75400 100644 --- a/src/Parser/Attribute.php +++ b/src/Parser/Attribute.php @@ -31,20 +31,43 @@ public function bound(): bool */ public function isStaticValue(): bool { - return $this->dynamic === false || in_array($this->value, ['true', 'false', 'null'], true); + return $this->dynamic === false || $this->hasConstantDynamicValue(); } + /** + * Resolve the compile time value of this attribute. + */ public function getStaticValue(): mixed { - if (! $this->isStaticValue()) { + if ($this->hasConstantDynamicValue()) { + return $this->getConstantValue(); + } + + if ($this->dynamic) { throw new \LogicException("Cannot get static value of dynamic attribute '{$this->name}'."); } + return $this->value; + } + + /** + * Check if this attribute is dynamic and has a constant value (true, false, or null). + */ + protected function hasConstantDynamicValue(): bool + { + return $this->dynamic && in_array($this->value, ['true', 'false', 'null'], true); + } + + /** + * Resolve the constant value of this attribute (true, false, or null). + */ + protected function getConstantValue() + { return match ($this->value) { 'true' => true, 'false' => false, 'null' => null, - default => $this->value, + default => throw new \LogicException("Invalid constant value '{$this->value}'."), }; } } diff --git a/src/Support/AttributeParser.php b/src/Support/AttributeParser.php index 8a09649..f5663df 100644 --- a/src/Support/AttributeParser.php +++ b/src/Support/AttributeParser.php @@ -49,7 +49,7 @@ public function parse(string $attributesString): array $valueless = is_null($value); if ($valueless) { - $value = 'true'; + $value = true; } $quotes = ''; diff --git a/tests/ComparisonTest.php b/tests/ComparisonTest.php index eb594de..155bd2a 100644 --- a/tests/ComparisonTest.php +++ b/tests/ComparisonTest.php @@ -58,6 +58,13 @@ ['readonly' => false], )); +test('foldable literal string attributes matching PHP constants', fn () => compare(<<<'BLADE' + + + + BLADE +)); + test('same component in a slot doesnt affect parents attributes', fn () => compare(<<<'BLADE' @@ -115,4 +122,4 @@ BLADE -)); \ No newline at end of file +)); diff --git a/tests/Parser/AttributeTest.php b/tests/Parser/AttributeTest.php new file mode 100644 index 0000000..f380d5e --- /dev/null +++ b/tests/Parser/AttributeTest.php @@ -0,0 +1,30 @@ +parse(':foo="true"')['foo']; + + expect($attribute->isStaticValue())->toBeTrue(); + expect($attribute->getStaticValue())->toBeTrue(); +}); + +test('getStaticValue returns strings for static constant values', function () { + $attribute = app(AttributeParser::class)->parse('foo="true"')['foo']; + + expect($attribute->isStaticValue())->toBeTrue(); + expect($attribute->getStaticValue())->toBe('true'); +}); + +test('getStaticValue returns true for valueless attributes', function () { + $attribute = app(AttributeParser::class)->parse('foo')['foo']; + + expect($attribute->isStaticValue())->toBeTrue(); + expect($attribute->getStaticValue())->toBeTrue(); +}); + +test('getStaticValue throws for dynamic attributes', function () { + $attribute = app(AttributeParser::class)->parse(':foo="$bar"')['foo']; + + $attribute->getStaticValue(); +})->throws(LogicException::class); diff --git a/tests/Support/AttributeParserTest.php b/tests/Support/AttributeParserTest.php index b9f1737..a2fdceb 100644 --- a/tests/Support/AttributeParserTest.php +++ b/tests/Support/AttributeParserTest.php @@ -30,7 +30,7 @@ expect($attrs)->toHaveKey('disabled'); expect($attrs['disabled']) ->name->toBe('disabled') - ->value->toBe('true') + ->value->toBeTrue() ->valueless->toBeTrue() ->dynamic->toBeFalse() ->quotes->toBe('');