From 9b4e969b69f289311823e613c017e9ad009a1c31 Mon Sep 17 00:00:00 2001 From: Ethan Joachim Eldridge Date: Wed, 5 Oct 2016 23:46:51 -0400 Subject: [PATCH 1/3] Unit tests for Issue #73 --- .../test/scala/scala/xml/UtilityTest.scala | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/shared/src/test/scala/scala/xml/UtilityTest.scala b/shared/src/test/scala/scala/xml/UtilityTest.scala index 44db70d67..a27fb0b1a 100644 --- a/shared/src/test/scala/scala/xml/UtilityTest.scala +++ b/shared/src/test/scala/scala/xml/UtilityTest.scala @@ -194,4 +194,27 @@ class UtilityTest { ).toMap.withDefault { key: Char => key.toString } + + def issue73StartsWithAndEndsWithWSInFirst: Unit = { + val x =
{Text(" My name is ")}{Text("Harry")}
+ assertEquals(
My name is Harry
, Utility.trim(x)) + } + + @Test + def issue73EndsWithWSInLast: Unit = { + val x =
{Text("My name is ")}{Text("Harry ")}
+ assertEquals(
My name is Harry
, Utility.trim(x)) + } + + @Test + def issue73HasWSInMiddle: Unit = { + val x =
{Text("My name is")}{Text(" ")}{Text("Harry")}
+ assertEquals(
My name is Harry
, Utility.trim(x)) + } + + @Test + def issue73HasWSEverywhere: Unit = { + val x =
{Text(" My name ")}{Text(" is ")}{Text(" Harry ")}
+ assertEquals(
My name is Harry
, Utility.trim(x)) + } } From 1e3b2883c88f8824f71194072348bc59f23561fd Mon Sep 17 00:00:00 2001 From: Ethan Joachim Eldridge Date: Thu, 6 Oct 2016 00:10:47 -0400 Subject: [PATCH 2/3] Unit tests for #73 passing --- shared/src/main/scala/scala/xml/Utility.scala | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/shared/src/main/scala/scala/xml/Utility.scala b/shared/src/main/scala/scala/xml/Utility.scala index b40adf2d8..2f528e1eb 100755 --- a/shared/src/main/scala/scala/xml/Utility.scala +++ b/shared/src/main/scala/scala/xml/Utility.scala @@ -46,17 +46,28 @@ object Utility extends AnyRef with parsing.TokenTests { */ def trim(x: Node): Node = x match { case Elem(pre, lab, md, scp, child@_*) => - val children = child flatMap trimProper + val children = combineAdjacentTextNodes(child:_*) flatMap trimProper Elem(pre, lab, md, scp, children.isEmpty, children: _*) } + private def combineAdjacentTextNodes(children: Node*): Seq[Node] = { + children.foldLeft(Seq.empty[Node]) { (acc, n) => + (acc.lastOption, n) match { + case (Some(Text(l)), Text(r)) => { + acc.dropRight(1) :+ Text(l + r) + } + case _ => acc :+ n + } + } + } + /** * trim a child of an element. `Attribute` values and `Atom` nodes that * are not `Text` nodes are unaffected. */ def trimProper(x: Node): Seq[Node] = x match { case Elem(pre, lab, md, scp, child@_*) => - val children = child flatMap trimProper + val children = combineAdjacentTextNodes(child:_*) flatMap trimProper Elem(pre, lab, md, scp, children.isEmpty, children: _*) case Text(s) => new TextBuffer().append(s).toText From 361d02e1f18984e353e6eaf8df6ec40ea2e3da51 Mon Sep 17 00:00:00 2001 From: Ethan Eldridge Date: Fri, 11 May 2018 10:16:40 -0400 Subject: [PATCH 3/3] Improve combineAdjacentTextNodes logic Remove lastOption and Option matching in favor of a more elegant foldRight solution proposed by ashawley. --- shared/src/main/scala/scala/xml/Utility.scala | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/shared/src/main/scala/scala/xml/Utility.scala b/shared/src/main/scala/scala/xml/Utility.scala index 2f528e1eb..88f6e8cd0 100755 --- a/shared/src/main/scala/scala/xml/Utility.scala +++ b/shared/src/main/scala/scala/xml/Utility.scala @@ -51,13 +51,9 @@ object Utility extends AnyRef with parsing.TokenTests { } private def combineAdjacentTextNodes(children: Node*): Seq[Node] = { - children.foldLeft(Seq.empty[Node]) { (acc, n) => - (acc.lastOption, n) match { - case (Some(Text(l)), Text(r)) => { - acc.dropRight(1) :+ Text(l + r) - } - case _ => acc :+ n - } + children.foldRight(Seq.empty[Node]) { + case (Text(left), Text(right) +: accMinusLast) => Text(left + right) +: accMinusLast + case (n, acc) => n +: acc } }