Skip to content

Commit 1d82def

Browse files
authored
Encapsulate diff options into an object (#5)
1 parent aa5cf8e commit 1d82def

File tree

17 files changed

+197
-101
lines changed

17 files changed

+197
-101
lines changed

build.sbt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import sbtrelease.ReleasePlugin.autoImport._
55
inThisBuild(
66
Seq(
77
organization := "software.purpledragon.xml",
8-
scalaVersion := "2.13.1",
9-
crossScalaVersions := Seq(scalaVersion.value, "2.11.12", "2.12.10"),
8+
scalaVersion := "2.13.2",
9+
crossScalaVersions := Seq(scalaVersion.value, "2.11.12", "2.12.11"),
1010
licenses += ("Apache-2.0", url("https://opensource.org/licenses/Apache-2.0")),
1111
developers := List(
1212
Developer("stringbean", "Michael Stringer", "@the_stringbean", url("https://github.com/stringbean"))
@@ -24,7 +24,7 @@ inThisBuild(
2424
scalacOptions ++= Seq(s"-target:jvm-$javaVersion", "-deprecation", "-feature", "-unchecked"),
2525
// dependencies common for all sub-projects
2626
libraryDependencies ++= Seq(
27-
"org.scala-lang.modules" %% "scala-xml" % "1.2.0"
27+
"org.scala-lang.modules" %% "scala-xml" % "1.3.0"
2828
),
2929
))
3030

@@ -70,6 +70,7 @@ lazy val root = Project("scala-xml-compare", file("."))
7070
),
7171
// sbt-release settings
7272
releaseCrossBuild := true,
73+
releaseVcsSign := true,
7374
releaseProcess := Seq[ReleaseStep](
7475
checkSnapshotDependencies,
7576
inquireVersions,

project/build.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=1.3.2
1+
sbt.version=1.3.12

project/plugins.sbt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// code style
22
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0")
3-
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.0")
4-
addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.15")
5-
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.0.0")
3+
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.1")
4+
addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.16")
5+
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.6.0")
66

77
// artifact publishing
8-
addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.4")
9-
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.0")
10-
addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.11")
8+
addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.6")
9+
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.1")
10+
addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.13")
1111

1212
// documentation
13-
addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.2")
13+
addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.3")
1414
addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.3")
1515
addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.4.0")
16-
addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.6.5")
16+
addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.8.0")
1717
addSbtPlugin("com.thoughtworks.sbt-api-mappings" % "sbt-api-mappings" % "3.0.0")

xml-compare/build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name := "xml-compare"
22

33
libraryDependencies ++= Seq(
4-
"org.scalatest" %% "scalatest" % "3.0.8" % Test
4+
"org.scalatest" %% "scalatest" % "3.1.2" % Test
55
)

xml-compare/src/main/scala/software/purpledragon/xml/compare/XmlCompare.scala

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,10 @@ import scala.xml._
2828
object XmlCompare {
2929
private type Check = (Node, Node, DiffOptions, Seq[String]) => XmlDiff
3030

31-
private implicit val NodeOrdering = NormalisedNodeOrdering
31+
private implicit val NodeOrdering: NormalisedNodeOrdering.type = NormalisedNodeOrdering
3232

33-
/**
34-
* Default [[software.purpledragon.xml.compare.options.DiffOption.DiffOption DiffOption]]s to use during XML comparison.
35-
*
36-
* Currently these are:
37-
* - [[software.purpledragon.xml.compare.options.DiffOption.IgnoreNamespacePrefix IgnoreNamespacePrefix]]
38-
*/
39-
val DefaultOptions: DiffOptions = Set(IgnoreNamespacePrefix)
33+
@deprecated(message = "use DiffOptions.Default", since = "2.0.0")
34+
val DefaultOptions: DiffOptions = DiffOptions.default
4035

4136
/**
4237
* Compares two XML documents. This will perform a recursive scan of all the nodes in each document, checking each
@@ -47,7 +42,7 @@ object XmlCompare {
4742
* @param options configuration options to control the way the comparison is performed.
4843
* @return results of the XML comparison.
4944
*/
50-
def compare(left: Node, right: Node, options: DiffOptions = DefaultOptions): XmlDiff = {
45+
def compare(left: Node, right: Node, options: DiffOptions = DiffOptions.default): XmlDiff = {
5146
compareNodes(left, right, options, Nil)
5247
}
5348

@@ -72,10 +67,10 @@ object XmlCompare {
7267
private def compareNamespace(left: Node, right: Node, options: DiffOptions, path: Seq[String]): XmlDiff = {
7368
if (left.label != right.label) {
7469
XmlDiffers("different label", left.label, right.label, extendPath(path, left))
75-
} else if (left.namespace != right.namespace && !options.contains(IgnoreNamespace)) {
70+
} else if (left.namespace != right.namespace && options.isDisabled(IgnoreNamespace)) {
7671
XmlDiffers("different namespace", left.namespace, right.namespace, extendPath(path, left))
77-
} else if (left.prefix != right.prefix && !options.contains(IgnoreNamespacePrefix) &&
78-
!options.contains(IgnoreNamespace)) {
72+
} else if (left.prefix != right.prefix && options.isDisabled(IgnoreNamespacePrefix) &&
73+
options.isDisabled(IgnoreNamespace)) {
7974
XmlDiffers("different namespace prefix", left.prefix, right.prefix, extendPath(path, left))
8075
} else {
8176
XmlEqual
@@ -88,7 +83,7 @@ object XmlCompare {
8883

8984
if (leftKeys.sorted != rightKeys.sorted) {
9085
XmlDiffers("different attribute names", leftKeys.sorted, rightKeys.sorted, extendPath(path, left))
91-
} else if (options.contains(StrictAttributeOrdering) && leftKeys != rightKeys) {
86+
} else if (options.isEnabled(StrictAttributeOrdering) && leftKeys != rightKeys) {
9287
XmlDiffers("different attribute ordering", leftKeys, rightKeys, extendPath(path, left))
9388
} else {
9489
leftKeys.sorted collectFirst {
@@ -134,7 +129,7 @@ object XmlCompare {
134129
}
135130

136131
private def normalise(nodes: Seq[Node], options: DiffOptions): Seq[Node] = {
137-
val sort = options.contains(DiffOption.IgnoreChildOrder)
132+
val sort = options.isEnabled(DiffOption.IgnoreChildOrder)
138133
val filtered = nodes.filterNot(n => n.isInstanceOf[Atom[_]])
139134

140135
if (sort) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2017 Michael Stringer
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package software.purpledragon.xml.compare.options
18+
19+
object DiffOptions {
20+
21+
/**
22+
* Default [[DiffOption DiffOption]]s to use during XML comparison.
23+
*
24+
* Currently these are:
25+
* - [[DiffOption.IgnoreNamespacePrefix IgnoreNamespacePrefix]]
26+
*/
27+
val default: DiffOptions = DiffOptions(DiffOption.IgnoreNamespacePrefix)
28+
val empty: DiffOptions = DiffOptions()
29+
30+
def apply(options: DiffOption.DiffOption*): DiffOptions = DiffOptions(options.toSet)
31+
}
32+
33+
case class DiffOptions(options: Set[DiffOption.DiffOption]) {
34+
def &(option: DiffOption.DiffOption): DiffOptions = copy(options = options + option)
35+
def &!(option: DiffOption.DiffOption): DiffOptions = copy(options = options - option)
36+
37+
def +(option: DiffOption.DiffOption): DiffOptions = copy(options = options + option)
38+
def -(option: DiffOption.DiffOption): DiffOptions = copy(options = options - option)
39+
40+
def isEnabled(option: DiffOption.DiffOption): Boolean = options.contains(option)
41+
def isDisabled(option: DiffOption.DiffOption): Boolean = !options.contains(option)
42+
}

xml-compare/src/main/scala/software/purpledragon/xml/compare/options/package.scala

Lines changed: 0 additions & 27 deletions
This file was deleted.

xml-compare/src/test/scala/software/purpledragon/xml/XmlUtilsSpec.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616

1717
package software.purpledragon.xml
1818

19-
import org.scalatest.{FlatSpec, Matchers}
19+
import org.scalatest.flatspec.AnyFlatSpec
20+
import org.scalatest.matchers.should.Matchers
2021

21-
class XmlUtilsSpec extends FlatSpec with Matchers {
22+
class XmlUtilsSpec extends AnyFlatSpec with Matchers {
2223
"XmlUtils.extractAttributes" should "return empty values for no attributes" in {
2324
XmlUtils.extractAttributes(<empty/>) shouldBe (Nil, Map.empty[String, String])
2425
}

xml-compare/src/test/scala/software/purpledragon/xml/compare/NormalisedNodeOrderingSpec.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616

1717
package software.purpledragon.xml.compare
1818

19-
import org.scalatest.{FlatSpec, Matchers}
19+
import org.scalatest.flatspec.AnyFlatSpec
20+
import org.scalatest.matchers.should.Matchers
2021

2122
import scala.xml.{Comment, Node, PCData, Text}
2223

23-
class NormalisedNodeOrderingSpec extends FlatSpec with Matchers {
24+
class NormalisedNodeOrderingSpec extends AnyFlatSpec with Matchers {
2425
private implicit val ordering: Ordering[Node] = NormalisedNodeOrdering
2526

2627
"NormalisedNodeOrdering" should "order nodes by type" in {

xml-compare/src/test/scala/software/purpledragon/xml/compare/XmlCompareSpec.scala

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616

1717
package software.purpledragon.xml.compare
1818

19-
import org.scalatest.{FlatSpec, Matchers}
19+
import org.scalatest.flatspec.AnyFlatSpec
20+
import org.scalatest.matchers.should.Matchers
2021
import software.purpledragon.xml.compare.options.DiffOption._
22+
import software.purpledragon.xml.compare.options.DiffOptions
2123

22-
class XmlCompareSpec extends FlatSpec with Matchers {
24+
class XmlCompareSpec extends AnyFlatSpec with Matchers {
2325

2426
"compare with defaults" should "match same empty element" in {
2527
XmlCompare.compare(<test/>, <test/>) shouldBe XmlEqual
@@ -152,47 +154,47 @@ class XmlCompareSpec extends FlatSpec with Matchers {
152154
XmlCompare.compare(
153155
<t:test xmlns:t="http://example.com"/>,
154156
<e:test xmlns:e="http://example.com"/>,
155-
Set.empty
157+
DiffOptions.empty
156158
) shouldBe XmlDiffers("different namespace prefix", "t", "e", Seq("t:test"))
157159
}
158160

159161
it should "match same namespaces" in {
160162
XmlCompare.compare(
161163
<t:test xmlns:t="http://example.com"/>,
162164
<t:test xmlns:t="http://example.com"/>,
163-
Set.empty
165+
DiffOptions.empty
164166
) shouldBe XmlEqual
165167
}
166168

167169
"compare with IgnoreNamespace" should "match different namespace prefix" in {
168170
XmlCompare.compare(
169171
<t:test xmlns:t="http://example.com"/>,
170172
<e:test xmlns:e="http://example.com"/>,
171-
Set(IgnoreNamespace)
173+
DiffOptions(IgnoreNamespace)
172174
) shouldBe XmlEqual
173175
}
174176

175177
it should "match different namespace" in {
176178
XmlCompare.compare(
177179
<t:test xmlns:t="http://example.com"/>,
178180
<t:test xmlns:e="http://example.org"/>,
179-
Set(IgnoreNamespace)
181+
DiffOptions(IgnoreNamespace)
180182
) shouldBe XmlEqual
181183
}
182184

183185
"compare with StrictAttributeOrder" should "match with same attributes" in {
184186
XmlCompare.compare(
185187
<test first="a" second="b" />,
186188
<test first="a" second="b" />,
187-
Set(StrictAttributeOrdering)
189+
DiffOptions(StrictAttributeOrdering)
188190
) shouldBe XmlEqual
189191
}
190192

191193
it should "not-match with attributes in different order" in {
192194
XmlCompare.compare(
193195
<test first="a" second="b"/>,
194196
<test second="b" first="a"/>,
195-
Set(StrictAttributeOrdering)
197+
DiffOptions(StrictAttributeOrdering)
196198
) shouldBe XmlDiffers(
197199
"different attribute ordering",
198200
Seq("first", "second"),
@@ -205,31 +207,31 @@ class XmlCompareSpec extends FlatSpec with Matchers {
205207
XmlCompare.compare(
206208
<test><child-a/><child-b/><child-a/></test>,
207209
<test><child-a/><child-b/><child-a/></test>,
208-
Set(IgnoreChildOrder)
210+
DiffOptions(IgnoreChildOrder)
209211
) shouldBe XmlEqual
210212
}
211213

212214
it should "match XML with children in different order" in {
213215
XmlCompare.compare(
214216
<test><child-a/><child-b/><child-a/></test>,
215217
<test><child-b/><child-a/><child-a/></test>,
216-
Set(IgnoreChildOrder)
218+
DiffOptions(IgnoreChildOrder)
217219
) shouldBe XmlEqual
218220
}
219221

220222
it should "match XML with children in different order with attributes" in {
221223
XmlCompare.compare(
222224
<test><child value="a"/><child value="b"/><child value="c"/></test>,
223225
<test><child value="b"/><child value="a"/><child value="c"/></test>,
224-
Set(IgnoreChildOrder)
226+
DiffOptions(IgnoreChildOrder)
225227
) shouldBe XmlEqual
226228
}
227229

228230
it should "match XML with children in different order with multiple attributes" in {
229231
XmlCompare.compare(
230232
<test><child first="a" second="b"/><child second="1" first="2"/></test>,
231233
<test><child second="1" first="2"/><child second="b" first="a"/></test>,
232-
Set(IgnoreChildOrder)
234+
DiffOptions(IgnoreChildOrder)
233235
) shouldBe XmlEqual
234236
}
235237
}

0 commit comments

Comments
 (0)