From aea4b9bfabd33264525d873a451a3503cd1c441a Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Wed, 9 Jul 2025 22:09:04 +0100 Subject: [PATCH 1/4] [TASK] Add unit tests for selector parsing The tests broadly cover what currently works, and will be extended to cover the fixes in #1292. --- tests/Unit/RuleSet/DeclarationBlockTest.php | 78 +++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/tests/Unit/RuleSet/DeclarationBlockTest.php b/tests/Unit/RuleSet/DeclarationBlockTest.php index c84d1f9a..d918dd0e 100644 --- a/tests/Unit/RuleSet/DeclarationBlockTest.php +++ b/tests/Unit/RuleSet/DeclarationBlockTest.php @@ -8,7 +8,11 @@ use Sabberworm\CSS\CSSElement; use Sabberworm\CSS\CSSList\CSSListItem; use Sabberworm\CSS\Position\Positionable; +use Sabberworm\CSS\Parsing\ParserState; +use Sabberworm\CSS\Property\Selector; use Sabberworm\CSS\RuleSet\DeclarationBlock; +use Sabberworm\CSS\Settings; +use TRegx\PhpUnit\DataProviders\DataProvider; /** * @covers \Sabberworm\CSS\RuleSet\DeclarationBlock @@ -48,4 +52,78 @@ public function implementsPositionable(): void { self::assertInstanceOf(Positionable::class, $this->subject); } + + /** + * @return array + */ + public static function provideSelector(): array + { + return [ + 'type' => ['body'], + 'class' => ['.teapot'], + 'type & class' => ['img.teapot'], + 'id' => ['#my-mug'], + 'type & id' => ['h2#my-mug'], + 'pseudo-class' => [':hover'], + 'type & pseudo-class' => ['a:hover'], + '`not`' => [':not(#your-mug)'], + 'pseudo-element' => ['::before'], + 'attribute with `"`' => ['[alt="{}()[]\\"\'"]'], + 'attribute with `\'`' => ['[alt=\'{}()[]"\\\'\']'], + ]; + } + + /** + * @test + * + * @param non-empty-string $selector + * + * @dataProvider provideSelector + */ + public function parsesSingleSelector(string $selector): void + { + $subject = DeclarationBlock::parse(new ParserState($selector . '{}', Settings::create())); + + self::assertNotNull($subject); + self::assertSame([$selector], self::getSelectorsAsStrings($subject)); + } + + /** + * @return DataProvider + */ + public static function provideTwoSelectors(): DataProvider + { + return DataProvider::cross(self::provideSelector(), self::provideSelector()); + } + + /** + * @test + * + * @param non-empty-string $firstSelector + * @param non-empty-string $secondSelector + * + * @dataProvider provideTwoSelectors + */ + public function parsesTwoCommaSeparatedSelectors(string $firstSelector, string $secondSelector): void + { + $joinedSelectors = $firstSelector . ',' . $secondSelector; + + $subject = DeclarationBlock::parse(new ParserState($joinedSelectors . '{}', Settings::create())); + + self::assertNotNull($subject); + self::assertSame([$firstSelector, $secondSelector], self::getSelectorsAsStrings($subject)); + } + + /** + * @return array + */ + private static function getSelectorsAsStrings(DeclarationBlock $declarationBlock): array + { + return \array_map( + static function (Selector $selectorObject): string { + return $selectorObject->getSelector(); + }, + $declarationBlock->getSelectors() + ); + } } From cccf684dc69ba32ce6910cb9c4859e14174e8a43 Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Wed, 9 Jul 2025 22:41:35 +0100 Subject: [PATCH 2/4] Use `assertInstanceOf` rather than `assertNotNull` --- tests/Unit/RuleSet/DeclarationBlockTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/RuleSet/DeclarationBlockTest.php b/tests/Unit/RuleSet/DeclarationBlockTest.php index d918dd0e..990b5272 100644 --- a/tests/Unit/RuleSet/DeclarationBlockTest.php +++ b/tests/Unit/RuleSet/DeclarationBlockTest.php @@ -84,7 +84,7 @@ public function parsesSingleSelector(string $selector): void { $subject = DeclarationBlock::parse(new ParserState($selector . '{}', Settings::create())); - self::assertNotNull($subject); + self::assertInstanceOf(DeclarationBlock::class, $subject); self::assertSame([$selector], self::getSelectorsAsStrings($subject)); } @@ -110,7 +110,7 @@ public function parsesTwoCommaSeparatedSelectors(string $firstSelector, string $ $subject = DeclarationBlock::parse(new ParserState($joinedSelectors . '{}', Settings::create())); - self::assertNotNull($subject); + self::assertInstanceOf(DeclarationBlock::class, $subject); self::assertSame([$firstSelector, $secondSelector], self::getSelectorsAsStrings($subject)); } From 5907eb3185281c9d4c4304811592254eb5424f48 Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Wed, 9 Jul 2025 22:42:54 +0100 Subject: [PATCH 3/4] Add space after comma in selector list --- tests/Unit/RuleSet/DeclarationBlockTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/RuleSet/DeclarationBlockTest.php b/tests/Unit/RuleSet/DeclarationBlockTest.php index 990b5272..db06194a 100644 --- a/tests/Unit/RuleSet/DeclarationBlockTest.php +++ b/tests/Unit/RuleSet/DeclarationBlockTest.php @@ -106,7 +106,7 @@ public static function provideTwoSelectors(): DataProvider */ public function parsesTwoCommaSeparatedSelectors(string $firstSelector, string $secondSelector): void { - $joinedSelectors = $firstSelector . ',' . $secondSelector; + $joinedSelectors = $firstSelector . ', ' . $secondSelector; $subject = DeclarationBlock::parse(new ParserState($joinedSelectors . '{}', Settings::create())); From 3b55390f976a70494f8f208e1c4a8c43fec584df Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Wed, 9 Jul 2025 22:46:41 +0100 Subject: [PATCH 4/4] Add space before `{` --- tests/Unit/RuleSet/DeclarationBlockTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/RuleSet/DeclarationBlockTest.php b/tests/Unit/RuleSet/DeclarationBlockTest.php index db06194a..697b15aa 100644 --- a/tests/Unit/RuleSet/DeclarationBlockTest.php +++ b/tests/Unit/RuleSet/DeclarationBlockTest.php @@ -82,7 +82,7 @@ public static function provideSelector(): array */ public function parsesSingleSelector(string $selector): void { - $subject = DeclarationBlock::parse(new ParserState($selector . '{}', Settings::create())); + $subject = DeclarationBlock::parse(new ParserState($selector . ' {}', Settings::create())); self::assertInstanceOf(DeclarationBlock::class, $subject); self::assertSame([$selector], self::getSelectorsAsStrings($subject)); @@ -108,7 +108,7 @@ public function parsesTwoCommaSeparatedSelectors(string $firstSelector, string $ { $joinedSelectors = $firstSelector . ', ' . $secondSelector; - $subject = DeclarationBlock::parse(new ParserState($joinedSelectors . '{}', Settings::create())); + $subject = DeclarationBlock::parse(new ParserState($joinedSelectors . ' {}', Settings::create())); self::assertInstanceOf(DeclarationBlock::class, $subject); self::assertSame([$firstSelector, $secondSelector], self::getSelectorsAsStrings($subject));