Skip to content

Commit

Permalink
In VersionNumberSpec switch to FreeSpec, add "assert" prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
dwijnand committed Mar 19, 2018
1 parent f159846 commit 4b9eb38
Showing 1 changed file with 93 additions and 79 deletions.
172 changes: 93 additions & 79 deletions core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala
Original file line number Diff line number Diff line change
@@ -1,128 +1,132 @@
package sbt.librarymanagement

import sbt.internal.librarymanagement.UnitSpec
import org.scalatest.Inside
import org.scalatest.{ FreeSpec, Inside, Matchers }

// This is a specification to check VersionNumber and VersionNumberCompatibility.
class VersionNumberSpec extends UnitSpec with Inside {
class VersionNumberSpec extends FreeSpec with Matchers with Inside {
import VersionNumber.{ SemVer, SecondSegment }

version("1") { v =>
parsesTo(Seq(1), Seq(), Seq())(v)
breaksDownTo(Some(1))(v)
cascadesTo(Seq("1"))(v)
assertParsesTo(v, Seq(1), Seq(), Seq())
assertBreaksDownTo(v, Some(1))
assertCascadesTo(v, Seq("1"))
}

version("1.0") { v =>
parsesTo(Seq(1, 0), Seq(), Seq())(v)
breaksDownTo(Some(1), Some(0))(v)
cascadesTo(Seq("1.0"))(v)
assertParsesTo(v, Seq(1, 0), Seq(), Seq())
assertBreaksDownTo(v, Some(1), Some(0))
assertCascadesTo(v, Seq("1.0"))
}

version("1.0.0") { v =>
parsesTo(Seq(1, 0, 0), Seq(), Seq())(v)
breaksDownTo(Some(1), Some(0), Some(0))(v)
cascadesTo(Seq("1.0.0", "1.0"))(v)
assertParsesTo(v, Seq(1, 0, 0), Seq(), Seq())
assertBreaksDownTo(v, Some(1), Some(0), Some(0))
assertCascadesTo(v, Seq("1.0.0", "1.0"))

isCompatibleWith("1.0.1", SemVer)(v)
isCompatibleWith("1.1.1", SemVer)(v)
isNotCompatibleWith("2.0.0", SemVer)(v)
isNotCompatibleWith("1.0.0-M1", SemVer)(v)
assertIsCompatibleWith(v, "1.0.1", SemVer)
assertIsCompatibleWith(v, "1.1.1", SemVer)
assertIsNotCompatibleWith(v, "2.0.0", SemVer)
assertIsNotCompatibleWith(v, "1.0.0-M1", SemVer)

isCompatibleWith("1.0.1", SecondSegment)(v)
isNotCompatibleWith("1.1.1", SecondSegment)(v)
isNotCompatibleWith("2.0.0", SecondSegment)(v)
isNotCompatibleWith("1.0.0-M1", SecondSegment)(v)
assertIsCompatibleWith(v, "1.0.1", SecondSegment)
assertIsNotCompatibleWith(v, "1.1.1", SecondSegment)
assertIsNotCompatibleWith(v, "2.0.0", SecondSegment)
assertIsNotCompatibleWith(v, "1.0.0-M1", SecondSegment)
}

version("1.0.0.0") { v =>
parsesTo(Seq(1, 0, 0, 0), Seq(), Seq())(v)
breaksDownTo(Some(1), Some(0), Some(0), Some(0))(v)
cascadesTo(Seq("1.0.0.0", "1.0.0", "1.0"))(v)
assertParsesTo(v, Seq(1, 0, 0, 0), Seq(), Seq())
assertBreaksDownTo(v, Some(1), Some(0), Some(0), Some(0))
assertCascadesTo(v, Seq("1.0.0.0", "1.0.0", "1.0"))
}

version("0.12.0") { v =>
parsesTo(Seq(0, 12, 0), Seq(), Seq())(v)
breaksDownTo(Some(0), Some(12), Some(0))(v)
cascadesTo(Seq("0.12.0", "0.12"))(v)
assertParsesTo(v, Seq(0, 12, 0), Seq(), Seq())
assertBreaksDownTo(v, Some(0), Some(12), Some(0))
assertCascadesTo(v, Seq("0.12.0", "0.12"))

isNotCompatibleWith("0.12.0-RC1", SemVer)(v)
isNotCompatibleWith("0.12.1", SemVer)(v)
isNotCompatibleWith("0.12.1-M1", SemVer)(v)
assertIsNotCompatibleWith(v, "0.12.0-RC1", SemVer)
assertIsNotCompatibleWith(v, "0.12.1", SemVer)
assertIsNotCompatibleWith(v, "0.12.1-M1", SemVer)

isNotCompatibleWith("0.12.0-RC1", SecondSegment)(v)
isCompatibleWith("0.12.1", SecondSegment)(v)
isCompatibleWith("0.12.1-M1", SecondSegment)(v)
assertIsNotCompatibleWith(v, "0.12.0-RC1", SecondSegment)
assertIsCompatibleWith(v, "0.12.1", SecondSegment)
assertIsCompatibleWith(v, "0.12.1-M1", SecondSegment)
}

version("0.1.0-SNAPSHOT") { v =>
parsesTo(Seq(0, 1, 0), Seq("SNAPSHOT"), Seq())(v)
cascadesTo(Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1"))(v)
assertParsesTo(v, Seq(0, 1, 0), Seq("SNAPSHOT"), Seq())
assertCascadesTo(v, Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1"))

isCompatibleWith("0.1.0-SNAPSHOT", SemVer)(v)
isNotCompatibleWith("0.1.0", SemVer)(v)
isCompatibleWith("0.1.0-SNAPSHOT+001", SemVer)(v)
assertIsCompatibleWith(v, "0.1.0-SNAPSHOT", SemVer)
assertIsNotCompatibleWith(v, "0.1.0", SemVer)
assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SemVer)

isCompatibleWith("0.1.0-SNAPSHOT", SecondSegment)(v)
isNotCompatibleWith("0.1.0", SecondSegment)(v)
isCompatibleWith("0.1.0-SNAPSHOT+001", SecondSegment)(v)
assertIsCompatibleWith(v, "0.1.0-SNAPSHOT", SecondSegment)
assertIsNotCompatibleWith(v, "0.1.0", SecondSegment)
assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SecondSegment)
}

version("0.1.0-M1") { v =>
parsesTo(Seq(0, 1, 0), Seq("M1"), Seq())(v)
cascadesTo(Seq("0.1.0-M1", "0.1.0", "0.1"))(v)
assertParsesTo(v, Seq(0, 1, 0), Seq("M1"), Seq())
assertCascadesTo(v, Seq("0.1.0-M1", "0.1.0", "0.1"))
}

version("0.1.0-RC1") { v =>
parsesTo(Seq(0, 1, 0), Seq("RC1"), Seq())(v)
cascadesTo(Seq("0.1.0-RC1", "0.1.0", "0.1"))(v)
assertParsesTo(v, Seq(0, 1, 0), Seq("RC1"), Seq())
assertCascadesTo(v, Seq("0.1.0-RC1", "0.1.0", "0.1"))
}

version("0.1.0-MSERVER-1") { v =>
parsesTo(Seq(0, 1, 0), Seq("MSERVER", "1"), Seq())(v)
cascadesTo(Seq("0.1.0-MSERVER-1", "0.1.0", "0.1"))(v)
assertParsesTo(v, Seq(0, 1, 0), Seq("MSERVER", "1"), Seq())
assertCascadesTo(v, Seq("0.1.0-MSERVER-1", "0.1.0", "0.1"))
}

version("2.10.4-20140115-000117-b3a-sources") { v =>
parsesTo(Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq())(v)
cascadesTo(Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10"))(v)
isCompatibleWith("2.0.0", SemVer)(v)
isNotCompatibleWith("2.0.0", SecondSegment)(v)
assertParsesTo(v, Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq())
assertCascadesTo(v, Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10"))
assertIsCompatibleWith(v, "2.0.0", SemVer)
assertIsNotCompatibleWith(v, "2.0.0", SecondSegment)
}

version("20140115000117-b3a-sources") { v =>
parsesTo(Seq(20140115000117L), Seq("b3a", "sources"), Seq())(v)
cascadesTo(Seq("20140115000117-b3a-sources"))(v)
assertParsesTo(v, Seq(20140115000117L), Seq("b3a", "sources"), Seq())
assertCascadesTo(v, Seq("20140115000117-b3a-sources"))
}

version("1.0.0-alpha+001+002") { v =>
parsesTo(Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002"))(v)
cascadesTo(Seq("1.0.0-alpha+001+002", "1.0.0", "1.0"))(v)
assertParsesTo(v, Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002"))
assertCascadesTo(v, Seq("1.0.0-alpha+001+002", "1.0.0", "1.0"))
}

version("non.space.!?string") { v =>
parsesTo(Seq(), Seq(), Seq("non.space.!?string"))(v)
cascadesTo(Seq("non.space.!?string"))(v)
assertParsesTo(v, Seq(), Seq(), Seq("non.space.!?string"))
assertCascadesTo(v, Seq("non.space.!?string"))
}

version("space !?string") { v =>
parsesToError(v)
assertParsesToError(v)
}
version("") { v =>
parsesToError(v)
assertParsesToError(v)
}

////

final class VersionString(val value: String)
private[this] final class VersionString(val value: String)

private[this] def version[A](s: String)(f: VersionString => A) = {
behavior of s"""Version "$s""""
f(new VersionString(s))
}
private[this] def version(s: String)(f: VersionString => Unit) =
s"""Version "$s"""" - {
f(new VersionString(s))
}

def parsesTo(ns: Seq[Long], ts: Seq[String], es: Seq[String])(implicit v: VersionString): Unit =
it should s"parse to ($ns, $ts, $es)" in inside(v.value) {
private[this] def assertParsesTo(
v: VersionString,
ns: Seq[Long],
ts: Seq[String],
es: Seq[String]
): Unit =
s"should parse to ($ns, $ts, $es)" in inside(v.value) {
case VersionNumber(ns1, ts1, es1) =>
(ns1 shouldBe ns)
(ts1 shouldBe ts)
Expand All @@ -131,20 +135,21 @@ class VersionNumberSpec extends UnitSpec with Inside {
(VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es))
}

private[this] def parsesToError(implicit v: VersionString): Unit =
it should "parse as an error" in {
private[this] def assertParsesToError(v: VersionString): Unit =
"should parse as an error" in {
v.value should not matchPattern {
case s: String if VersionNumber.unapply(s).isDefined => // because of unapply overloading
}
}

private[this] def breaksDownTo(
private[this] def assertBreaksDownTo(
v: VersionString,
major: Option[Long],
minor: Option[Long] = None,
patch: Option[Long] = None,
buildNumber: Option[Long] = None
)(implicit v: VersionString): Unit =
it should s"breakdown to ($major, $minor, $patch, $buildNumber)" in inside(v.value) {
): Unit =
s"should breakdown to ($major, $minor, $patch, $buildNumber)" in inside(v.value) {
case VersionNumber(ns, ts, es) =>
val v = VersionNumber(ns, ts, es)
(v._1 shouldBe major)
Expand All @@ -153,31 +158,40 @@ class VersionNumberSpec extends UnitSpec with Inside {
(v._4 shouldBe buildNumber)
}

private[this] def cascadesTo(ns: Seq[String])(implicit v: VersionString) = {
it should s"cascade to $ns" in {
private[this] def assertCascadesTo(v: VersionString, ns: Seq[String]): Unit = {
s"should cascade to $ns" in {
val versionNumbers = ns.toVector map VersionNumber.apply
VersionNumber(v.value).cascadingVersions shouldBe versionNumbers
}
}

def isCompatibleWith(v2: String, vnc: VersionNumberCompatibility)(implicit v1: VersionString) =
checkCompat(true, vnc, v2)
private[this] def assertIsCompatibleWith(
v1: VersionString,
v2: String,
vnc: VersionNumberCompatibility
): Unit =
checkCompat(true, vnc, v1, v2)

def isNotCompatibleWith(v2: String, vnc: VersionNumberCompatibility)(implicit v1: VersionString) =
checkCompat(false, vnc, v2)
private[this] def assertIsNotCompatibleWith(
v1: VersionString,
v2: String,
vnc: VersionNumberCompatibility
): Unit =
checkCompat(false, vnc, v1, v2)

private[this] def checkCompat(
expectOutcome: Boolean,
vnc: VersionNumberCompatibility,
v1: VersionString,
v2: String
)(implicit v1: VersionString) = {
val prefix = if (expectOutcome) "" else "NOT "
) = {
val prefix = if (expectOutcome) "should" else "should NOT"
val compatibilityStrategy = vnc match {
case SemVer => "SemVer"
case SecondSegment => "SecondSegment"
case _ => val s = vnc.name; if (s contains " ") s""""$s"""" else s
}
it should s"${prefix}be $compatibilityStrategy compatible with $v2" in {
s"$prefix be $compatibilityStrategy compatible with $v2" in {
vnc.isCompatible(VersionNumber(v1.value), VersionNumber(v2)) shouldBe expectOutcome
}
}
Expand Down

0 comments on commit 4b9eb38

Please sign in to comment.