@@ -29,7 +29,7 @@ public function expandBorderShorthand($sCss, $sExpected)
2929 foreach ($ oDoc ->getAllDeclarationBlocks () as $ oDeclaration ) {
3030 $ oDeclaration ->expandBorderShorthand ();
3131 }
32- self ::assertSame (trim ((string )$ oDoc ), $ sExpected );
32+ self ::assertDeclarationBlockEquals (trim ((string )$ oDoc ), $ sExpected );
3333 }
3434
3535 /**
@@ -62,7 +62,7 @@ public function expandFontShorthand($sCss, $sExpected)
6262 foreach ($ oDoc ->getAllDeclarationBlocks () as $ oDeclaration ) {
6363 $ oDeclaration ->expandFontShorthand ();
6464 }
65- self ::assertSame (trim ((string )$ oDoc ), $ sExpected );
65+ self ::assertDeclarationBlockEquals (trim ((string )$ oDoc ), $ sExpected );
6666 }
6767
6868 /**
@@ -118,7 +118,7 @@ public function expandBackgroundShorthand($sCss, $sExpected)
118118 foreach ($ oDoc ->getAllDeclarationBlocks () as $ oDeclaration ) {
119119 $ oDeclaration ->expandBackgroundShorthand ();
120120 }
121- self ::assertSame (trim ((string )$ oDoc ), $ sExpected );
121+ self ::assertDeclarationBlockEquals (trim ((string )$ oDoc ), $ sExpected );
122122 }
123123
124124 /**
@@ -171,7 +171,7 @@ public function expandDimensionsShorthand($sCss, $sExpected)
171171 foreach ($ oDoc ->getAllDeclarationBlocks () as $ oDeclaration ) {
172172 $ oDeclaration ->expandDimensionsShorthand ();
173173 }
174- self ::assertSame (trim ((string )$ oDoc ), $ sExpected );
174+ self ::assertDeclarationBlockEquals (trim ((string )$ oDoc ), $ sExpected );
175175 }
176176
177177 /**
@@ -505,4 +505,50 @@ public function canRemoveCommentsFromRulesUsingStrictParsing(
505505
506506 self ::assertSame ($ cssWithoutComments , $ renderedDocument );
507507 }
508+
509+ /**
510+ * Asserts two declaration blocks are equivalent, allowing the rules to be in any order.
511+ *
512+ * @param string $expected
513+ * @param string $actual
514+ */
515+ public static function assertDeclarationBlockEquals ($ expected , $ actual )
516+ {
517+ $ normalizedExpected = self ::sortRulesInDeclarationBlock ($ expected );
518+ $ normalizedActual = self ::sortRulesInDeclarationBlock ($ actual );
519+
520+ self ::assertSame ($ normalizedExpected , $ normalizedActual );
521+ }
522+
523+ /**
524+ * Sorts the rules within a declaration block by property name.
525+ *
526+ * @param string $declarationBlock
527+ *
528+ * @return string
529+ */
530+ private static function sortRulesInDeclarationBlock ($ declarationBlock )
531+ {
532+ // Match everything between `{` and `}`.
533+ return \preg_replace_callback (
534+ '/(?<= \\{)[^ \\}]*+(?= \\})/ ' ,
535+ [self ::class, 'sortDeclarationBlockRules ' ],
536+ $ declarationBlock
537+ );
538+ }
539+
540+ /**
541+ * Sorts rules from within a declaration block by property name.
542+ *
543+ * @param array{0: string} $rulesMatches
544+ * This method is intended as a callback for `preg_replace_callback`.
545+ *
546+ * @return string
547+ */
548+ private static function sortDeclarationBlockRules ($ rulesMatches )
549+ {
550+ $ rules = \explode ('; ' , $ rulesMatches [0 ]);
551+ \sort ($ rules );
552+ return \implode ('; ' , $ rules );
553+ }
508554}
0 commit comments