@@ -79,7 +79,20 @@ public function renderRendersDocumentProvidedToFromDomDocument()
7979 /**
8080 * @test
8181 */
82- public function reformatsHtml ()
82+ public function renderPreservesBodyContentProvidedToFromHtml ()
83+ {
84+ $ innerHtml = '<p>Hello world!</p> ' ;
85+ $ subject = TestingHtmlProcessor::fromHtml ('<html> ' . $ innerHtml . '</html> ' );
86+
87+ $ html = $ subject ->render ();
88+
89+ self ::assertContains ($ innerHtml , $ html );
90+ }
91+
92+ /**
93+ * @test
94+ */
95+ public function renderPreservesOuterHtmlProvidedToFromHtml ()
8396 {
8497 $ rawHtml = '<!DOCTYPE HTML> ' .
8598 '<html> ' .
@@ -93,8 +106,9 @@ public function reformatsHtml()
93106 "</html> \n" ;
94107
95108 $ subject = TestingHtmlProcessor::fromHtml ($ rawHtml );
109+ $ html = $ subject ->render ();
96110
97- self ::assertSame ($ formattedHtml , $ subject -> render () );
111+ self ::assertEqualsHtml ($ formattedHtml , $ html );
98112 }
99113
100114 /**
@@ -706,7 +720,7 @@ public function getDomDocumentWithNormalizedHtmlRepresentsTheGivenHtml()
706720
707721 $ domDocument = $ subject ->getDomDocument ();
708722
709- self ::assertSame ($ html , $ domDocument ->saveHTML ());
723+ self ::assertEqualsHtml ($ html , $ domDocument ->saveHTML ());
710724 }
711725
712726 /**
@@ -732,4 +746,42 @@ public function getDomDocumentVoidElementNotHasChildNodes(string $htmlWithNonXml
732746 self ::assertFalse ($ element ->hasChildNodes ());
733747 }
734748 }
749+
750+ /**
751+ * Asserts that two HTML strings are equal, allowing for whitespace differences in the HTML element itself (but not
752+ * its descendants) and after its closing tag.
753+ *
754+ * @param string $expected
755+ * @param string $actual
756+ * @param string $message
757+ */
758+ private static function assertEqualsHtml (string $ expected , string $ actual , string $ message = '' )
759+ {
760+ $ normalizedExpected = self ::normalizeHtml ($ expected );
761+ $ normalizedActual = self ::normalizeHtml ($ actual );
762+
763+ self ::assertSame ($ normalizedExpected , $ normalizedActual , $ message );
764+ }
765+
766+ /**
767+ * Normalizes whitespace in the HTML element itself (but not its descendants) and after its closing tag, with a
768+ * single newline inserted or replacing whitespace at positions where whitespace may occur but is superfluous.
769+ *
770+ * @param string $html
771+ *
772+ * @return string
773+ */
774+ private static function normalizeHtml (string $ html )
775+ {
776+ return \preg_replace (
777+ [
778+ '%(<html(?=[ \\s>])[^>]*+>) \\s*+(<head[ \\s>])% ' ,
779+ '%(</head>) \\s*+(<body[ \\s>])% ' ,
780+ '%(</body>) \\s*+(</html>)% ' ,
781+ '%(</html>) \\s*+($)% ' ,
782+ ],
783+ "$1 \n$2 " ,
784+ $ html
785+ );
786+ }
735787}
0 commit comments