Repository: jhy/jsoup
Pull request #1909 (2023-02-27 23:56:44)

Bump jetty-server from 9.4.50.v20221201 to 9.4.51.v20230217
Bumps [jetty-server](https://github.com/eclipse/jetty.project) from 9.4.50.v20221201 to 9.4.51.v20230217.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/eclipse/jetty.project/releases">jetty-server's releases</a>.</em></p>
<blockquote>
<h2>9.4.51.v20230217</h2>
<h1>Sponsored Release</h1>
<p>This is a release of the <a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/7958">End of Community Support Jetty 9.x series</a> that was sponsored by a <a href="https://github.com/eclipse/jetty.project/blob/HEAD/mailto:sales@webtide.com">support contract from Webtide.com</a></p>
<h1>Changelog</h1>
<ul>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9352">#9352</a> - Update / Fix CookieCutter</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9345">#9345</a> - Multipart Cleanups</li>
</ul>
<h1>Dependencies</h1>
<ul>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9269">#9269</a> - Bump ant.version to 1.10.13</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9370">#9370</a> - Bump asciidoctorj-diagram to 2.2.4</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9364">#9364</a> - Bump eclipse-jarsigner-plugin to 1.4.2</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9251">#9251</a> - Bump infinispan.version to 11.0.17.Final</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9247">#9247</a> - Bump maven-checkstyle-plugin to 3.2.1</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9267">#9267</a> - Bump maven-dependency-plugin to 3.5.0</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9365">#9365</a> - Bump maven-deploy-plugin to 3.1.0</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9252">#9252</a> - Bump maven-enforcer-plugin to 3.2.1</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9363">#9363</a> - Bump maven-invoker-plugin to 3.5.0</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9266">#9266</a> - Bump maven-plugin-plugin to 3.7.1</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9263">#9263</a> - Bump maven.plugin-tools.version to 3.7.1</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9256">#9256</a> - Bump maven.resolver.version to 1.9.4</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9368">#9368</a> - Bump maven.surefire.plugin.version to 3.0.0-M9</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9362">#9362</a> - Bump maven.version to 3.9.0</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9100">#9100</a> - Bump org.apache.aries.spifly.dynamic.bundle to 1.3.6</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9103">#9103</a> - Bump org.eclipse.osgi to 3.18.200</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9110">#9110</a> - Bump org.eclipse.osgi.services to 3.11.100</li>
<li><a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9262">#9262</a> - Bump spring-beans to 5.3.25</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/eclipse/jetty.project/commit/b45c405e4544384de066f814ed42ae3dceacdd49"><code>b45c405</code></a> Updating to version 9.4.51.v20230217</li>
<li><a href="https://github.com/eclipse/jetty.project/commit/3beaa8158c589da77ff35af90a52225b938abdb8"><code>3beaa81</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9368">#9368</a> from eclipse/dependabot/maven/jetty-9.4.x/maven.sure...</li>
<li><a href="https://github.com/eclipse/jetty.project/commit/d382683e2be1dc7527bd628df988b3e27147a94a"><code>d382683</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9370">#9370</a> from eclipse/dependabot/maven/jetty-9.4.x/org.asciid...</li>
<li><a href="https://github.com/eclipse/jetty.project/commit/d52d1336da67fac3a2f7a5889d5207c78d33c389"><code>d52d133</code></a> Bump maven.surefire.plugin.version from 3.0.0-M8 to 3.0.0-M9</li>
<li><a href="https://github.com/eclipse/jetty.project/commit/1bc959a9c3be3769ec59660df74663ceaf586ea7"><code>1bc959a</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9365">#9365</a> from eclipse/dependabot/maven/jetty-9.4.x/org.apache...</li>
<li><a href="https://github.com/eclipse/jetty.project/commit/08c89c797abef55c0a500e4440c6055e1f97ed90"><code>08c89c7</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9364">#9364</a> from eclipse/dependabot/maven/jetty-9.4.x/org.eclips...</li>
<li><a href="https://github.com/eclipse/jetty.project/commit/2a30acaffef584a11c1a53b371ee6ee7535d0566"><code>2a30aca</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9363">#9363</a> from eclipse/dependabot/maven/jetty-9.4.x/org.apache...</li>
<li><a href="https://github.com/eclipse/jetty.project/commit/6ab783d9c810f1a1e4469244e8194111c19345f4"><code>6ab783d</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9362">#9362</a> from eclipse/dependabot/maven/jetty-9.4.x/maven.vers...</li>
<li><a href="https://github.com/eclipse/jetty.project/commit/722781d7517c8d769764941af14ade9cb649a41a"><code>722781d</code></a> Issue <a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9181">#9181</a> NPE in SessionHandler  (<a href="https://github-redirect.dependabot.com/eclipse/jetty.project/issues/9346">#9346</a>)</li>
<li><a href="https://github.com/eclipse/jetty.project/commit/922b84b1d8e795f74aa026e952335f525b3f622b"><code>922b84b</code></a> Bump asciidoctorj-diagram from 2.2.3 to 2.2.4</li>
<li>Additional commits viewable in <a href="https://github.com/eclipse/jetty.project/compare/jetty-9.4.50.v20221201...jetty-9.4.51.v20230217">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=org.eclipse.jetty:jetty-server&package-manager=maven&previous-version=9.4.50.v20221201&new-version=9.4.51.v20230217)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/CHANGES b/CHANGES
index 6b3e0a9b..5fd3b451 100644
--- a/CHANGES
+++ b/CHANGES
@@ -15,6 +15,20 @@ Release 1.16.1 [PENDING]
     again, causing errors when fetched.
     <https://github.com/jhy/jsoup/issues/1902>
 
+  * Bugfix: If the Document.OutputSettings class was initialized, and then Entities.escape(String) called, an NPE may be
+    thrown due to a class loading circular dependency.
+    <https://github.com/jhy/jsoup/issues/1910>
+
+  * Bugfix: when pretty-printing, the first inline Element or Comment in a block would not be wrap-indented if it were
+    preceded by a blank text node.
+    <https://github.com/jhy/jsoup/issues/1906>
+
+  * Bugfix: when pretty-printing a <pre> containing block tags, those tags were incorrectly indented.
+    <https://github.com/jhy/jsoup/issues/1891>
+
+  * Bugfix: <br> tags should be wrap-indented when in block tags (and not when in inline tags).
+    <https://github.com/jhy/jsoup/issues/1911>
+
 Release 1.15.4 [18-Feb-2023]
   * Improvement: added the ability to escape CSS selectors (tags, IDs, classes) to match elements that don't follow
     regular CSS syntax. For example, to match by classname <p class="one.two">, use document.select("p.one\\.two");
diff --git a/pom.xml b/pom.xml
index 94a4409b..27771139 100644
--- a/pom.xml
+++ b/pom.xml
@@ -341,7 +341,7 @@
       <!-- jetty for webserver integration tests. 9.x is last with Java7 support -->
       <groupId>org.eclipse.jetty</groupId>
       <artifactId>jetty-server</artifactId>
-      <version>9.4.50.v20221201</version>
+      <version>9.4.51.v20230217</version>
       <scope>test</scope>
     </dependency>
 
diff --git a/src/main/java/org/jsoup/nodes/Comment.java b/src/main/java/org/jsoup/nodes/Comment.java
index 8ac8f702..f7fc9f3c 100644
--- a/src/main/java/org/jsoup/nodes/Comment.java
+++ b/src/main/java/org/jsoup/nodes/Comment.java
@@ -38,7 +38,7 @@ public class Comment extends LeafNode {
 
     @Override
 	void outerHtmlHead(Appendable accum, int depth, Document.OutputSettings out) throws IOException {
-        if (out.prettyPrint() && ((siblingIndex() == 0 && parentNode instanceof Element && ((Element) parentNode).tag().formatAsBlock()) || (out.outline() )))
+        if (out.prettyPrint() && ((isEffectivelyFirst() && parentNode instanceof Element && ((Element) parentNode).tag().formatAsBlock()) || (out.outline() )))
             indent(accum, depth, out);
         accum
                 .append("<!--")
diff --git a/src/main/java/org/jsoup/nodes/Element.java b/src/main/java/org/jsoup/nodes/Element.java
index 507fce96..5142fa2b 100644
--- a/src/main/java/org/jsoup/nodes/Element.java
+++ b/src/main/java/org/jsoup/nodes/Element.java
@@ -1670,7 +1670,7 @@ public class Element extends Node {
     }
 
     boolean shouldIndent(final Document.OutputSettings out) {
-        return out.prettyPrint() && isFormatAsBlock(out) && !isInlineable(out);
+        return out.prettyPrint() && isFormatAsBlock(out) && !isInlineable(out) && !preserveWhitespace(parentNode);
     }
 
     @Override
@@ -1701,7 +1701,8 @@ public class Element extends Node {
     void outerHtmlTail(Appendable accum, int depth, Document.OutputSettings out) throws IOException {
         if (!(childNodes.isEmpty() && tag.isSelfClosing())) {
             if (out.prettyPrint() && (!childNodes.isEmpty() && (
-                    tag.formatAsBlock() || (out.outline() && (childNodes.size()>1 || (childNodes.size()==1 && (childNodes.get(0) instanceof Element))))
+                (tag.formatAsBlock() && !preserveWhitespace(parentNode)) ||
+                    (out.outline() && (childNodes.size()>1 || (childNodes.size()==1 && (childNodes.get(0) instanceof Element))))
             )))
                 indent(accum, depth, out);
             accum.append("</").append(tagName()).append('>');
@@ -1846,9 +1847,11 @@ public class Element extends Node {
     }
 
     private boolean isInlineable(Document.OutputSettings out) {
-        return tag().isInline()
-            && (parent() == null || parent().isBlock())
-            && previousSibling() != null
-            && !out.outline();
+        if (!tag.isInline())
+            return false;
+        return (parent() == null || parent().isBlock())
+            && !isEffectivelyFirst()
+            && !out.outline()
+            && !isNode("br");
     }
 }
diff --git a/src/main/java/org/jsoup/nodes/Entities.java b/src/main/java/org/jsoup/nodes/Entities.java
index d330005d..be447bce 100644
--- a/src/main/java/org/jsoup/nodes/Entities.java
+++ b/src/main/java/org/jsoup/nodes/Entities.java
@@ -7,6 +7,7 @@ import org.jsoup.nodes.Document.OutputSettings;
 import org.jsoup.parser.CharacterReader;
 import org.jsoup.parser.Parser;
 
+import javax.annotation.Nullable;
 import java.io.IOException;
 import java.nio.charset.CharsetEncoder;
 import java.util.Arrays;
@@ -26,7 +27,6 @@ public class Entities {
     static final int codepointRadix = 36;
     private static final char[] codeDelims = {',', ';'};
     private static final HashMap<String, String> multipoints = new HashMap<>(); // name -> multiple character references
-    private static final OutputSettings DefaultOutput = new OutputSettings();
 
     public enum EscapeMode {
         /**
@@ -157,8 +157,11 @@ public class Entities {
      * @return the escaped string
      */
     public static String escape(String string) {
+        if (DefaultOutput == null)
+            DefaultOutput = new OutputSettings();
         return escape(string, DefaultOutput);
     }
+    private static @Nullable OutputSettings DefaultOutput; // lazy-init, to break circular dependency with OutputSettings
 
     // this method does a lot, but other breakups cause rescanning and stringbuilder generations
     static void escape(Appendable accum, String string, OutputSettings out,
diff --git a/src/main/java/org/jsoup/nodes/Node.java b/src/main/java/org/jsoup/nodes/Node.java
index fc5ac3bf..851bd8a5 100644
--- a/src/main/java/org/jsoup/nodes/Node.java
+++ b/src/main/java/org/jsoup/nodes/Node.java
@@ -762,6 +762,16 @@ public abstract class Node implements Cloneable {
         return normalName().equals(normalName);
     }
 
+    /** Test if this node is the first child, or first following blank text. */
+    final boolean isEffectivelyFirst() {
+        if (siblingIndex == 0) return true;
+        if (siblingIndex == 1) {
+            final Node prev = previousSibling();
+            return prev instanceof TextNode && (((TextNode) prev).isBlank());
+        }
+        return false;
+    }
+
     /**
      * Gets this node's outer HTML.
      * @return outer HTML.
diff --git a/src/main/java/org/jsoup/parser/Tag.java b/src/main/java/org/jsoup/parser/Tag.java
index d573033a..366bc63e 100644
--- a/src/main/java/org/jsoup/parser/Tag.java
+++ b/src/main/java/org/jsoup/parser/Tag.java
@@ -242,7 +242,7 @@ public class Tag implements Cloneable {
     };
     private static final String[] inlineTags = {
             "object", "base", "font", "tt", "i", "b", "u", "big", "small", "em", "strong", "dfn", "code", "samp", "kbd",
-            "var", "cite", "abbr", "time", "acronym", "mark", "ruby", "rt", "rp", "a", "img", "br", "wbr", "map", "q",
+            "var", "cite", "abbr", "time", "acronym", "mark", "ruby", "rt", "rp", "rtc", "a", "img", "br", "wbr", "map", "q",
             "sub", "sup", "bdo", "iframe", "embed", "span", "input", "select", "textarea", "label", "button", "optgroup",
             "option", "legend", "datalist", "keygen", "output", "progress", "meter", "area", "param", "source", "track",
             "summary", "command", "device", "area", "basefont", "bgsound", "menuitem", "param", "source", "track",


Test patch:
diff --git a/src/test/java/org/jsoup/nodes/CommentTest.java b/src/test/java/org/jsoup/nodes/CommentTest.java
index fe1c1361..c622f184 100644
--- a/src/test/java/org/jsoup/nodes/CommentTest.java
+++ b/src/test/java/org/jsoup/nodes/CommentTest.java
@@ -41,6 +41,20 @@ public class CommentTest {
         assertEquals("<!-- a simple comment -->", c1.outerHtml());
     }
 
+    @Test void stableIndentInBlock() {
+        String html = "<div><!-- comment --> Text</div><p><!-- comment --> Text</p>";
+        Document doc = Jsoup.parse(html);
+        String out = doc.body().html();
+        assertEquals("<div>\n" +
+            " <!-- comment --> Text\n" +
+            "</div>\n" +
+            "<p><!-- comment --> Text</p>", out);
+
+        Document doc2 = Jsoup.parse(out);
+        String out2 = doc2.body().html();
+        assertEquals(out, out2);
+    }
+
     @Test
     public void testClone() {
         Comment c1 = comment.clone();
diff --git a/src/test/java/org/jsoup/nodes/ElementTest.java b/src/test/java/org/jsoup/nodes/ElementTest.java
index 0887a4e7..0bb433ce 100644
--- a/src/test/java/org/jsoup/nodes/ElementTest.java
+++ b/src/test/java/org/jsoup/nodes/ElementTest.java
@@ -157,6 +157,14 @@ public class ElementTest {
         assertEquals("<pre><code><span><b>code\n\ncode</b></span></code></pre>", doc.body().html());
     }
 
+    @Test void doesNotWrapBlocksInPre() {
+        // https://github.com/jhy/jsoup/issues/1891
+        String h = "<pre><span><foo><div>TEST\n TEST</div></foo></span></pre>";
+        Document doc = Jsoup.parse(h);
+        assertEquals("TEST\n TEST", doc.wholeText());
+        assertEquals(h, doc.body().html());
+    }
+
     @Test
     public void testBrHasSpace() {
         Document doc = Jsoup.parse("<p>Hello<br>there</p>");
@@ -2306,6 +2314,17 @@ public class ElementTest {
         assertEquals("<div>\n <br>\n</div>", doc.body().html()); // not div\n br\n \n/div
     }
 
+    @Test void prettyprintBrWhenNotFirstChild() {
+        // https://github.com/jhy/jsoup/issues/1911
+        String h = "<div><p><br>Foo</p><br></div>";
+        Document doc = Jsoup.parse(h);
+        assertEquals("<div>\n" +
+            " <p><br>\n  Foo</p>\n" +
+            " <br>\n" +
+            "</div>", doc.body().html());
+        // br gets wrapped if in div, but not in p (block vs inline), but always wraps after
+    }
+
     @Test void preformatFlowsToChildTextNodes() {
         // https://github.com/jhy/jsoup/issues/1776
         String html = "<div><pre>One\n<span>\nTwo</span>\n <span>  \nThree</span>\n <span>Four <span>Five</span>\n  Six\n</pre>";
@@ -2343,6 +2362,23 @@ public class ElementTest {
         assertEquals(expectOwn, div.child(0).wholeOwnText());
     }
 
+    @Test void inlineInBlockShouldIndent() {
+        // was inconsistent between <div>\n<span> and <div><span> - former would print inline, latter would wrap(!)
+        String html = "<div>One <span>Hello</span><span>!</span></div><div>\n<span>There</span></div><div> <span>Now</span></div>";
+        Document doc = Jsoup.parse(html);
+        assertEquals(
+            "<div>\n" +
+                " One <span>Hello</span><span>!</span>\n" +
+                "</div>\n" +
+                "<div>\n" +
+                " <span>There</span>\n" +
+                "</div>\n" +
+                "<div>\n" +
+                " <span>Now</span>\n" +
+                "</div>",
+            doc.body().html());
+    }
+
     @Test void testExpectFirst() {
         Document doc = Jsoup.parse("<p>One</p><p>Two <span>Three</span> <span>Four</span>");
 
@@ -2445,7 +2481,9 @@ public class ElementTest {
     @Test void divAInlineable() {
         String html = "<body><div> <a>Text</a>";
         Document doc = Jsoup.parse(html);
-        assertEquals("<div><a>Text</a>\n</div>", doc.body().html());
+        assertEquals("<div>\n" +
+            " <a>Text</a>\n" +
+            "</div>", doc.body().html());
     }
 
     @Test void noDanglingSpaceAfterCustomElement() {
@@ -2657,4 +2695,10 @@ public class ElementTest {
         doc.body().outerHtml(builder);
         assertEquals("<body>\n <div>\n  One\n </div>\n</body>", builder.toString());
     }
-}
\ No newline at end of file
+
+    @Test void rubyInline() {
+        String html = "<ruby>T<rp>(</rp><rtc>!</rtc><rt>)</rt></ruby>";
+        Document doc = Jsoup.parse(html);
+        assertEquals(html, doc.body().html());
+    }
+}
diff --git a/src/test/java/org/jsoup/parser/HtmlParserTest.java b/src/test/java/org/jsoup/parser/HtmlParserTest.java
index 1f83518e..26b546d5 100644
--- a/src/test/java/org/jsoup/parser/HtmlParserTest.java
+++ b/src/test/java/org/jsoup/parser/HtmlParserTest.java
@@ -1247,7 +1247,7 @@ public class HtmlParserTest {
         File in = ParseTest.getFile("/htmltests/comments.html");
         Document doc = Jsoup.parse(in, "UTF-8");
 
-        assertEquals("<!--?xml version=\"1.0\" encoding=\"utf-8\"?--><!-- so --> <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><!-- what --> <html xml:lang=\"en\" lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\"><!-- now --> <head><!-- then --> <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\"> <title>A Certain Kind of Test</title> </head> <body> <h1>Hello</h1>h1&gt; (There is a UTF8 hidden BOM at the top of this file.) </body> </html>",
+        assertEquals("<!--?xml version=\"1.0\" encoding=\"utf-8\"?--><!-- so --> <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><!-- what --> <html xml:lang=\"en\" lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\"> <!-- now --> <head> <!-- then --> <meta http-equiv=\"Content-type\" content=\"text/html; charset=utf-8\"> <title>A Certain Kind of Test</title> </head> <body> <h1>Hello</h1>h1&gt; (There is a UTF8 hidden BOM at the top of this file.) </body> </html>",
             StringUtil.normaliseWhitespace(doc.html()));
 
         assertEquals("A Certain Kind of Test", doc.head().select("title").text());
diff --git a/src/test/java/org/jsoup/parser/HtmlTreeBuilderStateTest.java b/src/test/java/org/jsoup/parser/HtmlTreeBuilderStateTest.java
index f05ee268..c2dbfe31 100644
--- a/src/test/java/org/jsoup/parser/HtmlTreeBuilderStateTest.java
+++ b/src/test/java/org/jsoup/parser/HtmlTreeBuilderStateTest.java
@@ -75,7 +75,8 @@ public class HtmlTreeBuilderStateTest {
         String s = Jsoup.parse(html).toString();
         assertEquals("<html>\n" +
             " <head></head>\n" +
-            " <body><a href=\"#1\"> </a>\n" +
+            " <body>\n" +
+            "  <a href=\"#1\"> </a>\n" +
             "  <div>\n" +
             "   <a href=\"#1\"> </a><a href=\"#2\">child</a>\n" +
             "  </div>\n" +
@@ -99,7 +100,8 @@ public class HtmlTreeBuilderStateTest {
         String s = Jsoup.parse(html).toString();
         assertEquals("<html>\n" +
             " <head></head>\n" +
-            " <body><a href=\"#1\"> </a>\n" +
+            " <body>\n" +
+            "  <a href=\"#1\"> </a>\n" +
             "  <div>\n" +
             "   <a href=\"#1\"> </a>\n" +
             "   <div>\n" +
diff --git a/src/test/java/org/jsoup/parser/XmlTreeBuilderTest.java b/src/test/java/org/jsoup/parser/XmlTreeBuilderTest.java
index 227dd096..d359a528 100644
--- a/src/test/java/org/jsoup/parser/XmlTreeBuilderTest.java
+++ b/src/test/java/org/jsoup/parser/XmlTreeBuilderTest.java
@@ -94,7 +94,7 @@ public class XmlTreeBuilderTest {
     public void testDoesNotForceSelfClosingKnownTags() {
         // html will force "<br>one</br>" to logically "<br />One<br />". XML should be stay "<br>one</br> -- don't recognise tag.
         Document htmlDoc = Jsoup.parse("<br>one</br>");
-        assertEquals("<br>\none<br>", htmlDoc.body().html());
+        assertEquals("<br>\none\n<br>", htmlDoc.body().html());
 
         Document xmlDoc = Jsoup.parse("<br>one</br>", "", Parser.xmlParser());
         assertEquals("<br>one</br>", xmlDoc.html());
diff --git a/src/test/java/org/jsoup/select/ElementsTest.java b/src/test/java/org/jsoup/select/ElementsTest.java
index eab17c2c..d1895752 100644
--- a/src/test/java/org/jsoup/select/ElementsTest.java
+++ b/src/test/java/org/jsoup/select/ElementsTest.java
@@ -193,7 +193,9 @@ public class ElementsTest {
         String h = "<div><font>One</font> <font><a href=\"/\">Two</a></font></div";
         Document doc = Jsoup.parse(h);
         doc.select("font").unwrap();
-        assertEquals("<div>One <a href=\"/\">Two</a></div>", TextUtil.stripNewlines(doc.body().html()));
+        assertEquals("<div>\n" +
+            " One <a href=\"/\">Two</a>\n" +
+            "</div>", doc.body().html());
     }
 
     @Test public void unwrapP() {