Skip to content

Commit 219d5b0

Browse files
committed
Initial XML diff
1 parent 3fbb9e3 commit 219d5b0

File tree

5 files changed

+102
-0
lines changed

5 files changed

+102
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package software.purpledragon.xml.compare
2+
3+
import software.purpledragon.xml.compare.options.DiffOption._
4+
import software.purpledragon.xml.compare.options.DiffOptions
5+
6+
import scala.xml.Node
7+
8+
object XmlCompare {
9+
private type Check = (Node, Node, DiffOptions) => XmlDiff
10+
11+
val DefaultOptions: DiffOptions = Set(IgnorePrefix)
12+
13+
def compare(left: Node, right: Node, options: DiffOptions = DefaultOptions): XmlDiff = {
14+
val checks: Seq[Check] = Seq(compareNamespace)
15+
16+
checks.foldLeft[XmlDiff](XmlEqual) { (status, check) =>
17+
if (!status.isEqual) {
18+
// already failed
19+
status
20+
} else {
21+
check(left, right, options)
22+
}
23+
}
24+
}
25+
26+
private def compareNamespace(left: Node, right: Node, options: DiffOptions): XmlDiff = {
27+
if (left.label != right.label) {
28+
XmlDiffers("different label")
29+
} else if (left.namespace != right.namespace) {
30+
XmlDiffers("different namespace")
31+
} else if (left.prefix != right.prefix && !options.contains(IgnorePrefix)) {
32+
XmlDiffers("different prefix")
33+
} else {
34+
XmlEqual
35+
}
36+
}
37+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package software.purpledragon.xml.compare
2+
3+
sealed trait XmlDiff {
4+
def isEqual: Boolean
5+
}
6+
7+
object XmlEqual extends XmlDiff {
8+
override def isEqual: Boolean = true
9+
}
10+
11+
case class XmlDiffers(reason: String) extends XmlDiff {
12+
override def isEqual: Boolean = false
13+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package software.purpledragon.xml.compare.options
2+
3+
object DiffOption extends Enumeration {
4+
type DiffOption = Value
5+
6+
val IgnorePrefix = DiffOption
7+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package software.purpledragon.xml.compare
2+
3+
package object options {
4+
type DiffOptions = Set[DiffOption.type]
5+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package software.purpledragon.xml.compare
2+
3+
import org.scalatest.{FlatSpec, Matchers}
4+
5+
class XmlCompareSpec extends FlatSpec with Matchers {
6+
7+
"comparing empty" should "match same element name" in {
8+
XmlCompare.compare(<test/>, <test/>) shouldBe XmlEqual
9+
}
10+
11+
it should "blah" in {
12+
XmlCompare.compare(<test/>, <test></test>) shouldBe XmlEqual
13+
}
14+
15+
it should "not-match" in {
16+
XmlCompare.compare(<test/>, <foo/>) shouldBe XmlDiffers("different label")
17+
}
18+
19+
it should "match same namespaces" in {
20+
XmlCompare.compare(<t:test xmlns:t="http://example.com"/>, <t:test xmlns:t="http://example.com"/>) shouldBe XmlEqual
21+
}
22+
23+
it should "match different namespace prefix" in {
24+
XmlCompare.compare(
25+
<t:test xmlns:t="http://example.com"/>,
26+
<e:test xmlns:e="http://example.com"/>) shouldBe XmlEqual
27+
}
28+
29+
it should "not-match different namespace prefix (with IgnorePrefix disabled)" in {
30+
XmlCompare.compare(
31+
<t:test xmlns:t="http://example.com"/>,
32+
<e:test xmlns:e="http://example.com"/>, Set.empty) shouldBe XmlDiffers("different prefix")
33+
}
34+
35+
it should "not-match different namespace url" in {
36+
XmlCompare.compare(
37+
<t:test xmlns:t="http://example.com"/>,
38+
<t:test xmlns:t="http://foo.com"/>) shouldBe XmlDiffers("different namespace")
39+
}
40+
}

0 commit comments

Comments
 (0)