From 7576c8c438e1f3c4ac878a174c696f6d842e5f3c Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Thu, 3 Apr 2025 00:29:57 +0100 Subject: [PATCH 1/2] [TASK] Add and implement `CSSElement` interface Also add tests to confirm that the supplanted types in the DocBlock actually implement the new interface. And correct a DocBlock type to also allow `string`, which is currently possible. cf. #1230 --- CHANGELOG.md | 1 + README.md | 10 ++++++-- src/CSSElement.php | 17 +++++++++++++ src/CSSList/CSSBlockList.php | 3 ++- src/CSSList/CSSList.php | 3 ++- src/CSSList/Document.php | 3 ++- src/Rule/Rule.php | 4 +-- src/RuleSet/RuleSet.php | 3 ++- src/Value/Value.php | 4 +-- tests/Unit/CSSList/CSSListTest.php | 11 ++++++++ tests/Unit/Rule/RuleTest.php | 11 ++++++++ .../Unit/RuleSet/Fixtures/ConcreteRuleSet.php | 16 ++++++++++++ tests/Unit/RuleSet/RuleSetTest.php | 25 +++++++++++++++++++ tests/Unit/Value/Fixtures/ConcreteValue.php | 16 ++++++++++++ tests/Unit/Value/ValueTest.php | 12 +++++++++ 15 files changed, 129 insertions(+), 10 deletions(-) create mode 100644 src/CSSElement.php create mode 100644 tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php create mode 100644 tests/Unit/RuleSet/RuleSetTest.php create mode 100644 tests/Unit/Value/Fixtures/ConcreteValue.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 0549f23ab..1192c93aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Please also have a look at our ### Added +- Interface `CSSElement` (#1231) - Methods `getLineNumber` and `getColumnNumber` which return a nullable `int` for the following classes: `Comment`, `CSSList`, `SourceException`, `Charset`, `CSSNamespace`, `Import`, diff --git a/README.md b/README.md index e5dd70db2..b69cb6d28 100644 --- a/README.md +++ b/README.md @@ -624,6 +624,9 @@ classDiagram %% Start of the part originally generated from the PHP code using tasuku43/mermaid-class-diagram + class CSSElement { + <> + } class Renderable { <> } @@ -721,9 +724,11 @@ classDiagram } RuleSet <|-- DeclarationBlock: inheritance + Renderable <|-- CSSElement: inheritance Renderable <|-- CSSListItem: inheritance Commentable <|-- CSSListItem: inheritance Positionable <|.. RuleSet: realization + CSSElement <|.. RuleSet: realization CSSListItem <|.. RuleSet: realization RuleSet <|-- AtRuleSet: inheritance AtRule <|.. AtRuleSet: realization @@ -736,7 +741,7 @@ classDiagram AtRule <|.. Import: realization Positionable <|.. CSSNamespace: realization AtRule <|.. CSSNamespace: realization - Renderable <|.. Rule: realization + CSSElement <|.. Rule: realization Positionable <|.. Rule: realization Commentable <|.. Rule: realization SourceException <|-- OutputException: inheritance @@ -746,6 +751,7 @@ classDiagram SourceException <|-- UnexpectedTokenException: inheritance CSSList <|-- CSSBlockList: inheritance CSSBlockList <|-- Document: inheritance + CSSElement <|.. CSSList: realization Positionable <|.. CSSList: realization CSSListItem <|.. CSSList: realization CSSList <|-- KeyFrame: inheritance @@ -758,7 +764,7 @@ classDiagram Value <|-- ValueList: inheritance CSSFunction <|-- CalcFunction: inheritance ValueList <|-- LineName: inheritance - Renderable <|.. Value: realization + CSSElement <|.. Value: realization Positionable <|.. Value: realization PrimitiveValue <|-- Size: inheritance PrimitiveValue <|-- CSSString: inheritance diff --git a/src/CSSElement.php b/src/CSSElement.php new file mode 100644 index 000000000..944aabe2c --- /dev/null +++ b/src/CSSElement.php @@ -0,0 +1,17 @@ + $result */ protected function allValues( diff --git a/src/CSSList/CSSList.php b/src/CSSList/CSSList.php index 45deccddb..1942d8c95 100644 --- a/src/CSSList/CSSList.php +++ b/src/CSSList/CSSList.php @@ -5,6 +5,7 @@ namespace Sabberworm\CSS\CSSList; use Sabberworm\CSS\Comment\CommentContainer; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\OutputFormat; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\SourceException; @@ -34,7 +35,7 @@ * Note that `CSSListItem` extends both `Commentable` and `Renderable`, * so those interfaces must also be implemented by concrete subclasses. */ -abstract class CSSList implements CSSListItem, Positionable +abstract class CSSList implements CSSElement, CSSListItem, Positionable { use CommentContainer; use Position; diff --git a/src/CSSList/Document.php b/src/CSSList/Document.php index 10370dc0e..f061b427d 100644 --- a/src/CSSList/Document.php +++ b/src/CSSList/Document.php @@ -4,6 +4,7 @@ namespace Sabberworm\CSS\CSSList; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\OutputFormat; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\SourceException; @@ -33,7 +34,7 @@ public static function parse(ParserState $parserState): Document /** * Returns all `Value` objects found recursively in `Rule`s in the tree. * - * @param CSSList|RuleSet|string $element + * @param CSSElement|string $element * the `CSSList` or `RuleSet` to start the search from (defaults to the whole document). * If a string is given, it is used as rule name filter. * @param bool $searchInFunctionArguments whether to also return Value objects used as Function arguments. diff --git a/src/Rule/Rule.php b/src/Rule/Rule.php index af93dcde9..304e66283 100644 --- a/src/Rule/Rule.php +++ b/src/Rule/Rule.php @@ -7,13 +7,13 @@ use Sabberworm\CSS\Comment\Comment; use Sabberworm\CSS\Comment\Commentable; use Sabberworm\CSS\Comment\CommentContainer; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\OutputFormat; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\UnexpectedEOFException; use Sabberworm\CSS\Parsing\UnexpectedTokenException; use Sabberworm\CSS\Position\Position; use Sabberworm\CSS\Position\Positionable; -use Sabberworm\CSS\Renderable; use Sabberworm\CSS\Value\RuleValueList; use Sabberworm\CSS\Value\Value; @@ -22,7 +22,7 @@ * * In CSS, `Rule`s are expressed as follows: “key: value[0][0] value[0][1], value[1][0] value[1][1];” */ -class Rule implements Commentable, Positionable, Renderable +class Rule implements Commentable, CSSElement, Positionable { use CommentContainer; use Position; diff --git a/src/RuleSet/RuleSet.php b/src/RuleSet/RuleSet.php index 1d5b2b4c5..3a7552e32 100644 --- a/src/RuleSet/RuleSet.php +++ b/src/RuleSet/RuleSet.php @@ -5,6 +5,7 @@ namespace Sabberworm\CSS\RuleSet; use Sabberworm\CSS\Comment\CommentContainer; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\CSSList\CSSListItem; use Sabberworm\CSS\OutputFormat; use Sabberworm\CSS\Parsing\ParserState; @@ -26,7 +27,7 @@ * Note that `CSSListItem` extends both `Commentable` and `Renderable`, * so those interfaces must also be implemented by concrete subclasses. */ -abstract class RuleSet implements CSSListItem, Positionable +abstract class RuleSet implements CSSElement, CSSListItem, Positionable { use CommentContainer; use Position; diff --git a/src/Value/Value.php b/src/Value/Value.php index 3e51d8d04..e33a2949f 100644 --- a/src/Value/Value.php +++ b/src/Value/Value.php @@ -4,19 +4,19 @@ namespace Sabberworm\CSS\Value; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Parsing\SourceException; use Sabberworm\CSS\Parsing\UnexpectedEOFException; use Sabberworm\CSS\Parsing\UnexpectedTokenException; use Sabberworm\CSS\Position\Position; use Sabberworm\CSS\Position\Positionable; -use Sabberworm\CSS\Renderable; /** * Abstract base class for specific classes of CSS values: `Size`, `Color`, `CSSString` and `URL`, and another * abstract subclass `ValueList`. */ -abstract class Value implements Positionable, Renderable +abstract class Value implements CSSElement, Positionable { use Position; diff --git a/tests/Unit/CSSList/CSSListTest.php b/tests/Unit/CSSList/CSSListTest.php index 69ee4d05d..abe87dd6f 100644 --- a/tests/Unit/CSSList/CSSListTest.php +++ b/tests/Unit/CSSList/CSSListTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use Sabberworm\CSS\Comment\Commentable; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\Renderable; use Sabberworm\CSS\RuleSet\DeclarationBlock; use Sabberworm\CSS\Tests\Unit\CSSList\Fixtures\ConcreteCSSList; @@ -15,6 +16,16 @@ */ final class CSSListTest extends TestCase { + /** + * @test + */ + public function implementsCSSElement(): void + { + $subject = new ConcreteCSSList(); + + self::assertInstanceOf(CSSElement::class, $subject); + } + /** * @test */ diff --git a/tests/Unit/Rule/RuleTest.php b/tests/Unit/Rule/RuleTest.php index b803c6853..008bcfc18 100644 --- a/tests/Unit/Rule/RuleTest.php +++ b/tests/Unit/Rule/RuleTest.php @@ -5,6 +5,7 @@ namespace Sabberworm\CSS\Tests\Unit\Rule; use PHPUnit\Framework\TestCase; +use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\Parsing\ParserState; use Sabberworm\CSS\Rule\Rule; use Sabberworm\CSS\Settings; @@ -17,6 +18,16 @@ */ final class RuleTest extends TestCase { + /** + * @test + */ + public function implementsCSSElement(): void + { + $subject = new Rule('beverage-container'); + + self::assertInstanceOf(CSSElement::class, $subject); + } + /** * @return array}> */ diff --git a/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php b/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php new file mode 100644 index 000000000..5938c1d66 --- /dev/null +++ b/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php @@ -0,0 +1,16 @@ + */ From 92b0ebfc32945441febe9d63e58275e83e23955b Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Tue, 8 Apr 2025 16:49:08 +0100 Subject: [PATCH 2/2] Changes suggested in review --- CHANGELOG.md | 2 +- tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php | 3 +++ tests/Unit/Value/Fixtures/ConcreteValue.php | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1192c93aa..a74924aa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Please also have a look at our ### Added -- Interface `CSSElement` (#1231) +- Add Interface `CSSElement` (#1231) - Methods `getLineNumber` and `getColumnNumber` which return a nullable `int` for the following classes: `Comment`, `CSSList`, `SourceException`, `Charset`, `CSSNamespace`, `Import`, diff --git a/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php b/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php index 5938c1d66..9c79c09dc 100644 --- a/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php +++ b/tests/Unit/RuleSet/Fixtures/ConcreteRuleSet.php @@ -9,6 +9,9 @@ final class ConcreteRuleSet extends RuleSet { + /** + * @return never + */ public function render(OutputFormat $outputFormat): string { throw new \BadMethodCallException('Nothing to see here :/', 1744067015); diff --git a/tests/Unit/Value/Fixtures/ConcreteValue.php b/tests/Unit/Value/Fixtures/ConcreteValue.php index 4f95b86ae..b6e924805 100644 --- a/tests/Unit/Value/Fixtures/ConcreteValue.php +++ b/tests/Unit/Value/Fixtures/ConcreteValue.php @@ -9,6 +9,9 @@ final class ConcreteValue extends Value { + /** + * @return never + */ public function render(OutputFormat $outputFormat): string { throw new \BadMethodCallException('Nothing to see here :/', 1744067951);