From 1602e389e20fa17a92ababa2838d5902e94908a6 Mon Sep 17 00:00:00 2001 From: Jake Hotson Date: Tue, 4 Mar 2025 12:08:28 +0000 Subject: [PATCH 1/2] Allow rules to be in any order in shorthand tests This is a pre-patch for #1062. --- tests/ParserTest.php | 5 ++- tests/RuleSet/DeclarationBlockTest.php | 54 ++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/tests/ParserTest.php b/tests/ParserTest.php index c8e8ac76..59f1bd64 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -19,6 +19,7 @@ use Sabberworm\CSS\RuleSet\DeclarationBlock; use Sabberworm\CSS\RuleSet\RuleSet; use Sabberworm\CSS\Settings; +use Sabberworm\CSS\Tests\RuleSet\DeclarationBlockTest; use Sabberworm\CSS\Value\Color; use Sabberworm\CSS\Value\Size; use Sabberworm\CSS\Value\URL; @@ -511,7 +512,7 @@ public function expandShorthands() . 'font-family: "Trebuchet MS",Georgia,serif;background-color: #ccc;' . 'background-image: url("/images/foo.png");background-repeat: no-repeat;background-attachment: scroll;' . 'background-position: left top;}'; - self::assertSame($sExpected, $oDoc->render()); + DeclarationBlockTest::assertDeclarationBlockEquals($sExpected, $oDoc->render()); } /** @@ -528,7 +529,7 @@ public function createShorthands() $oDoc->createShorthands(); $sExpected = 'body {background: #fff url("foobar.png") repeat-y;margin: 2px 5px 4px 3px;' . 'border: 2px dotted #999;font: bold 2em Helvetica,Arial,sans-serif;}'; - self::assertSame($sExpected, $oDoc->render()); + DeclarationBlockTest::assertDeclarationBlockEquals($sExpected, $oDoc->render()); } /** diff --git a/tests/RuleSet/DeclarationBlockTest.php b/tests/RuleSet/DeclarationBlockTest.php index d37ece18..9726bcc0 100644 --- a/tests/RuleSet/DeclarationBlockTest.php +++ b/tests/RuleSet/DeclarationBlockTest.php @@ -29,7 +29,7 @@ public function expandBorderShorthand($sCss, $sExpected) foreach ($oDoc->getAllDeclarationBlocks() as $oDeclaration) { $oDeclaration->expandBorderShorthand(); } - self::assertSame(trim((string)$oDoc), $sExpected); + self::assertDeclarationBlockEquals(trim((string)$oDoc), $sExpected); } /** @@ -62,7 +62,7 @@ public function expandFontShorthand($sCss, $sExpected) foreach ($oDoc->getAllDeclarationBlocks() as $oDeclaration) { $oDeclaration->expandFontShorthand(); } - self::assertSame(trim((string)$oDoc), $sExpected); + self::assertDeclarationBlockEquals(trim((string)$oDoc), $sExpected); } /** @@ -118,7 +118,7 @@ public function expandBackgroundShorthand($sCss, $sExpected) foreach ($oDoc->getAllDeclarationBlocks() as $oDeclaration) { $oDeclaration->expandBackgroundShorthand(); } - self::assertSame(trim((string)$oDoc), $sExpected); + self::assertDeclarationBlockEquals(trim((string)$oDoc), $sExpected); } /** @@ -171,7 +171,7 @@ public function expandDimensionsShorthand($sCss, $sExpected) foreach ($oDoc->getAllDeclarationBlocks() as $oDeclaration) { $oDeclaration->expandDimensionsShorthand(); } - self::assertSame(trim((string)$oDoc), $sExpected); + self::assertDeclarationBlockEquals(trim((string)$oDoc), $sExpected); } /** @@ -505,4 +505,50 @@ public function canRemoveCommentsFromRulesUsingStrictParsing( self::assertSame($cssWithoutComments, $renderedDocument); } + + /** + * Asserts two declaration blocks are equivalent, allowing the rules to be in any order. + * + * @param string $expected + * @param string $actual + */ + public static function assertDeclarationBlockEquals($expected, $actual) + { + $normalizedExpected = self::sortRulesInDeclarationBlock($expected); + $normalizedActual = self::sortRulesInDeclarationBlock($actual); + + self::assertSame($normalizedExpected, $normalizedActual); + } + + /** + * Sorts the rules within a declaration block by property name. + * + * @param string $declarationBlock + * + * @return string + */ + private static function sortRulesInDeclarationBlock($declarationBlock) + { + // Match everything between `{` and `}`. + return \preg_replace_callback( + '/(?<=\{)[^\}]*+(?=\})/', + [self::class, 'sortDeclarationBlockRules'], + $declarationBlock + ); + } + + /** + * Sorts rules from within a declaration block by property name. + * + * @param array{0: string} $rulesMatches + * This method is intended as a callback for `preg_replace_callback`. + * + * @return string + */ + private static function sortDeclarationBlockRules($rulesMatches) + { + $rules = \explode(';', $rulesMatches[0]); + \sort($rules); + return \implode(';', $rules); + } } From de4c2f5a4661a28ede4d7b58e7e195659f539c93 Mon Sep 17 00:00:00 2001 From: JakeQZ Date: Tue, 4 Mar 2025 12:31:37 +0000 Subject: [PATCH 2/2] Escape backslashes in PHP string. Co-authored-by: Oliver Klee --- tests/RuleSet/DeclarationBlockTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/RuleSet/DeclarationBlockTest.php b/tests/RuleSet/DeclarationBlockTest.php index 9726bcc0..d4cf31b6 100644 --- a/tests/RuleSet/DeclarationBlockTest.php +++ b/tests/RuleSet/DeclarationBlockTest.php @@ -531,7 +531,7 @@ private static function sortRulesInDeclarationBlock($declarationBlock) { // Match everything between `{` and `}`. return \preg_replace_callback( - '/(?<=\{)[^\}]*+(?=\})/', + '/(?<=\\{)[^\\}]*+(?=\\})/', [self::class, 'sortDeclarationBlockRules'], $declarationBlock );