Skip to content
5 changes: 4 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,14 @@ lazy val xml = crossProject(JSPlatform, JVMPlatform)
libraryDependencies += "junit" % "junit" % "4.12" % Test,
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test,
libraryDependencies += "org.apache.commons" % "commons-lang3" % "3.9" % Test,
libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.14.0" % Test,
libraryDependencies += ("org.scala-lang" % "scala-compiler" % scalaVersion.value % Test).exclude("org.scala-lang.modules", s"scala-xml_${scalaBinaryVersion.value}")
)
.jsSettings(
// Scala.js cannot run forked tests
fork in Test := false
fork in Test := false,

libraryDependencies += "org.scalacheck" %%% "scalacheck" % "1.14.0" % Test
)
.jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin))

Expand Down
161 changes: 161 additions & 0 deletions jvm/src/test/scala/scala/xml/NodeSeqSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2018, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */

package scala.xml

import org.scalacheck.Prop
import org.scalacheck.{ Properties => PropertiesFor }
import org.scalacheck.Prop.AnyOperators

object NodeSeqSpec extends PropertiesFor("NodeSeq")
with NodeSeqGen {

property("theSeq") = {
Prop.forAll { n: NodeSeq =>
n.theSeq ne null
}
}

property("length") = {
Prop.forAll { n: NodeSeq =>
n.length >= 0
}
}

property("\\ \"\".throws[Exception]") = {
Prop.forAll { n: NodeSeq =>
Prop.throws(classOf[IllegalArgumentException]) {
(n \ "")
}
}
}

property("\\ _.throws[Exception]") = {
Prop.forAll { n: NodeSeq =>
Prop.iff[NodeSeq](n, {
// FIXME: Exception thrown in NodeSeq.\.makeSeq
case g @ Group(_) =>
Prop.throws(classOf[UnsupportedOperationException]) {
(g \ "_")
}
case _ => {
(n \ "_")
Prop.passed
}
})
}
}

property("\\ @.throws[Exception]") = {
Prop.forAll { n: NodeSeq =>
Prop.iff[NodeSeq](n, {
case n: NodeSeq =>
Prop.throws(classOf[IllegalArgumentException]) {
(n \ "@")
}
})
}
}

property("\\") = {
Prop.forAll { (n: NodeSeq, s: String) =>
Prop.iff[String](s, {
// FIXME: Should be IllegalArgumentException, regardless of theSeq.
case "" =>
Prop.throws(classOf[IllegalArgumentException]) {
(n \ s)
}
case "@" =>
Prop.throws(classOf[IllegalArgumentException]) {
(n \ s)
}
case s =>
(n \ s)
Prop.passed
})
}
}

property("\\\\ \"\".throws[Exception]") = {
Prop.forAll { n: NodeSeq =>
Prop.throws(classOf[IllegalArgumentException]) {
(n \\ "")
}
}
}

property("\\\\ @.throws[Exception]") = {
Prop.forAll { n: NodeSeq =>
Prop.iff[NodeSeq](n, {
// FIXME: Should be IllegalArgumentException, regardless of theSeq
case n if n.filter(!_.isAtom).length == 0 =>
(n \\ "@") ?= NodeSeq.Empty
case n =>
Prop.throws(classOf[IllegalArgumentException]) {
(n \\ "@")
}
})
}
}

property("\\\\") = {
Prop.forAll { (n: NodeSeq, s: String) =>
Prop.iff[String](s, {
case "" | "@" =>
Prop.throws(classOf[IllegalArgumentException]) {
(n \\ s)
}
case s =>
(n \\ s)
Prop.passed
})
}
}

property("\\@ \"\".throws[Exception]") = {
Prop.forAll { n: NodeSeq =>
Prop.iff[NodeSeq](n, {
case s =>
Prop.throws(classOf[IllegalArgumentException]) {
(n \@ "")
}
})
}
}

property("\\@ _.throws[Exception]") = {
Prop.forAll { n: NodeSeq =>
Prop.iff[NodeSeq](n, {
// FIXME: Exception thrown in NodeSeq.\.makeSeq
case g @ Group(_) =>
Prop.throws(classOf[UnsupportedOperationException]) {
(g \@ "_")
}
case _ => {
(n \@ "_")
Prop.passed
}
})
}
}

property("\\@") = {
Prop.forAll { (n: NodeSeq, s: String) =>
// FIXME: Should be IllegalArgumentException, regardless of theSeq.
Prop.throws(classOf[IllegalArgumentException]) {
(n \@ s)
} || Prop.passed // FIXME: Error conditions are too complex.
}
}

property("text") = {
Prop.forAll { n: NodeSeq =>
n.text.length >= 0
}
}
}
27 changes: 27 additions & 0 deletions jvm/src/test/scala/scala/xml/NodeSerializationSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2018, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */

package scala.xml

import org.scalacheck.Prop
import org.scalacheck.{ Properties => CheckProperties }
import org.scalacheck.Prop.AnyOperators
import org.scalacheck.Prop.BooleanOperators

object NodeSerializationSpec extends CheckProperties("NodeSerialization")
with NodeGen {

property("serialization") = {
Prop.forAll { n: Node =>
Prop.iff[Node](n, {
case n =>
JavaByteSerialization.roundTrip(n) ?= n
})
}
}
}
30 changes: 30 additions & 0 deletions jvm/src/test/scala/scala/xml/XmlStringGen.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2018, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */

package scala.xml

import org.scalacheck.Arbitrary
import org.scalacheck.Gen

trait XmlStringGen extends DocumentGen {

def xmlDeclGen(version: String, encoding: String): Gen[String] =
Gen.oneOf(
Gen.const(""),
Gen.const(s"<?xml version='$version' encoding='$encoding'?>")
)

val genXmlString: Gen[String] = for {
document <- Arbitrary.arbitrary[Document]
encoding <- Gen.const("UTF-8") // java.nio.charset.StandardCharsets.UTF_8.name
xmlDecl <- xmlDeclGen("1.0", encoding)
} yield {
val str = xmlDecl + Group(document.children ++ Seq(document.docElem)).toString
str
}
}
73 changes: 73 additions & 0 deletions jvm/src/test/scala/scala/xml/dtd/ExternalIDSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2018, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */

package scala.xml
package dtd

import org.scalacheck.Prop
import org.scalacheck.{ Properties => PropertiesFor }
import org.scalacheck.Prop.AnyOperators

object ExternalIDSpec extends PropertiesFor("dtd.ExternalID")
with ExternalIDGen {

property("PublicID.throws[Exception]") = {
Prop.forAll(genNonPubIdStr) { s: String =>
Prop.throws(classOf[IllegalArgumentException]) {
PublicID(s, s)
}
}
}

property("SystemID.throws[Exception]") = {
Prop.forAll(genNonSysIdStr) { s: String =>
Prop.throws(classOf[IllegalArgumentException]) {
SystemID(s)
}
}
}

property("SystemID(null).throws[Exception]") = {
Prop.throws(classOf[NullPointerException]) {
SystemID(null)
}
}

property("label") = {
Prop.forAll { p: PublicID =>
p.label ?= "#PI"
}
}

property("attribute") = {
Prop.forAll { p: PublicID =>
p.attribute ?= Node.NoAttributes
}
}

property("child") = {
Prop.forAll { p: PublicID =>
p.child ?= Nil
}
}

property("toString") = Prop.forAll { e: ExternalID =>
val str = e.toString
Prop.atLeastOne(
str ?= "",
str ?= s"""SYSTEM '${e.systemId}'""",
str ?= s"""SYSTEM "${e.systemId}"""",
str ?= s"""PUBLIC '${e.publicId}'""",
str ?= s"""PUBLIC "${e.publicId}"""",
str ?= s"""PUBLIC '${e.publicId}' '${e.systemId}'""",
str ?= s"""PUBLIC "${e.publicId}" "${e.systemId}"""",
str ?= s"""PUBLIC '${e.publicId}' "${e.systemId}"""",
str ?= s"""PUBLIC "${e.publicId}" '${e.systemId}'"""
)
}
}
Loading