mirror of https://github.com/sbt/sbt.git
Merge pull request #221 from dwijnand/cleanup/VersionNumberSpec
Cleanup VersionNumberSpec
This commit is contained in:
commit
c6b2b626c8
|
|
@ -1,128 +1,155 @@
|
|||
package sbt.librarymanagement
|
||||
|
||||
import sbt.internal.librarymanagement.UnitSpec
|
||||
import org.scalatest.{ FreeSpec, Inside, Matchers }
|
||||
|
||||
// This is a specification to check the version number parsing.
|
||||
class VersionNumberSpec extends UnitSpec {
|
||||
"1" should "be parsed" in beParsedAs("1", Seq(1), Seq(), Seq())
|
||||
it should "breakdown" in breakDownTo("1", Some(1))
|
||||
it should "cascade" in generateCorrectCascadingNumbers("1", Seq("1"))
|
||||
// This is a specification to check VersionNumber and VersionNumberCompatibility.
|
||||
class VersionNumberSpec extends FreeSpec with Matchers with Inside {
|
||||
import VersionNumber.{ SemVer, SecondSegment }
|
||||
|
||||
"1.0" should "be parsed" in beParsedAs("1.0", Seq(1, 0), Seq(), Seq())
|
||||
it should "breakdown" in breakDownTo("1.0", Some(1), Some(0))
|
||||
it should "cascade" in generateCorrectCascadingNumbers("1.0", Seq("1.0"))
|
||||
|
||||
"1.0.0" should "be parsed" in beParsedAs("1.0.0", Seq(1, 0, 0), Seq(), Seq())
|
||||
it should "breakdown" in breakDownTo("1.0.0", Some(1), Some(0), Some(0))
|
||||
it should "cascade" in generateCorrectCascadingNumbers("1.0.0", Seq("1.0.0", "1.0"))
|
||||
it should "be SemVer compat with 1.0.1" in beSemVerCompatWith("1.0.0", "1.0.1")
|
||||
it should "be SemVer compat with 1.1.1" in beSemVerCompatWith("1.0.0", "1.1.1")
|
||||
it should "not be SemVer compat with 2.0.0" in notBeSemVerCompatWith("1.0.0", "2.0.0")
|
||||
it should "not be SemVer compat with 1.0.0-M1" in notBeSemVerCompatWith("1.0.0", "1.0.0-M1")
|
||||
it should "be SecSeg compat with 1.0.1" in beSecSegCompatWith("1.0.0", "1.0.1")
|
||||
it should "not be SecSeg compat with 1.1.1" in notBeSecSegCompatWith("1.0.0", "1.1.1")
|
||||
it should "not be SecSeg compat with 2.0.0" in notBeSecSegCompatWith("1.0.0", "2.0.0")
|
||||
it should "not be SecSeg compat with 1.0.0-M1" in notBeSecSegCompatWith("1.0.0", "1.0.0-M1")
|
||||
|
||||
"1.0.0.0" should "be parsed" in beParsedAs("1.0.0.0", Seq(1, 0, 0, 0), Seq(), Seq())
|
||||
it should "breakdown" in breakDownTo("1.0.0.0", Some(1), Some(0), Some(0), Some(0))
|
||||
it should "cascade" in generateCorrectCascadingNumbers("1.0.0.0", Seq("1.0.0.0", "1.0.0", "1.0"))
|
||||
|
||||
"0.12.0" should "be parsed" in beParsedAs("0.12.0", Seq(0, 12, 0), Seq(), Seq())
|
||||
it should "breakdown" in breakDownTo("0.12.0", Some(0), Some(12), Some(0))
|
||||
it should "cascade" in generateCorrectCascadingNumbers("0.12.0", Seq("0.12.0", "0.12"))
|
||||
it should "not be SemVer compat with 0.12.0-RC1" in notBeSemVerCompatWith("0.12.0", "0.12.0-RC1")
|
||||
it should "not be SemVer compat with 0.12.1" in notBeSemVerCompatWith("0.12.0", "0.12.1")
|
||||
it should "not be SemVer compat with 0.12.1-M1" in notBeSemVerCompatWith("0.12.0", "0.12.1-M1")
|
||||
it should "not be SecSeg compat with 0.12.0-RC1" in notBeSecSegCompatWith("0.12.0", "0.12.0-RC1")
|
||||
it should "be SecSeg compat with 0.12.1" in beSecSegCompatWith("0.12.0", "0.12.1")
|
||||
it should "be SecSeg compat with 0.12.1-M1" in beSecSegCompatWith("0.12.0", "0.12.1-M1")
|
||||
|
||||
"0.1.0-SNAPSHOT" should "be parsed" in beParsedAs("0.1.0-SNAPSHOT",
|
||||
Seq(0, 1, 0),
|
||||
Seq("SNAPSHOT"),
|
||||
Seq())
|
||||
it should "cascade" in generateCorrectCascadingNumbers("0.1.0-SNAPSHOT",
|
||||
Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1"))
|
||||
it should "be SemVer compat with 0.1.0-SNAPSHOT" in beSemVerCompatWith("0.1.0-SNAPSHOT",
|
||||
"0.1.0-SNAPSHOT")
|
||||
it should "not be SemVer compat with 0.1.0" in notBeSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0")
|
||||
it should "be SemVer compat with 0.1.0-SNAPSHOT+001" in beSemVerCompatWith("0.1.0-SNAPSHOT",
|
||||
"0.1.0-SNAPSHOT+001")
|
||||
it should "be SecSeg compat with 0.1.0-SNAPSHOT" in beSecSegCompatWith("0.1.0-SNAPSHOT",
|
||||
"0.1.0-SNAPSHOT")
|
||||
it should "be not SecSeg compat with 0.1.0" in notBeSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0")
|
||||
it should "be SecSeg compat with 0.1.0-SNAPSHOT+001" in beSecSegCompatWith("0.1.0-SNAPSHOT",
|
||||
"0.1.0-SNAPSHOT+001")
|
||||
|
||||
"0.1.0-M1" should "be parsed" in beParsedAs("0.1.0-M1", Seq(0, 1, 0), Seq("M1"), Seq())
|
||||
it should "cascade" in generateCorrectCascadingNumbers("0.1.0-M1",
|
||||
Seq("0.1.0-M1", "0.1.0", "0.1"))
|
||||
|
||||
"0.1.0-RC1" should "be parsed" in beParsedAs("0.1.0-RC1", Seq(0, 1, 0), Seq("RC1"), Seq())
|
||||
it should "cascade" in generateCorrectCascadingNumbers("0.1.0-RC1",
|
||||
Seq("0.1.0-RC1", "0.1.0", "0.1"))
|
||||
|
||||
"0.1.0-MSERVER-1" should "be parsed" in beParsedAs("0.1.0-MSERVER-1",
|
||||
Seq(0, 1, 0),
|
||||
Seq("MSERVER", "1"),
|
||||
Seq())
|
||||
it should "cascade" in generateCorrectCascadingNumbers("0.1.0-MSERVER-1",
|
||||
Seq("0.1.0-MSERVER-1", "0.1.0", "0.1"))
|
||||
|
||||
"2.10.4-20140115-000117-b3a-sources" should "be parsed" in {
|
||||
beParsedAs("2.10.4-20140115-000117-b3a-sources",
|
||||
Seq(2, 10, 4),
|
||||
Seq("20140115", "000117", "b3a", "sources"),
|
||||
Seq())
|
||||
version("1") { v =>
|
||||
assertParsesTo(v, Seq(1), Seq(), Seq())
|
||||
assertBreaksDownTo(v, Some(1))
|
||||
assertCascadesTo(v, Seq("1"))
|
||||
}
|
||||
it should "cascade" in generateCorrectCascadingNumbers(
|
||||
"2.10.4-20140115-000117-b3a-sources",
|
||||
Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10"))
|
||||
it should "be SemVer compat with 2.0.0" in beSemVerCompatWith(
|
||||
"2.10.4-20140115-000117-b3a-sources",
|
||||
"2.0.0")
|
||||
it should "be not SecSeg compat with 2.0.0" in notBeSecSegCompatWith(
|
||||
"2.10.4-20140115-000117-b3a-sources",
|
||||
"2.0.0")
|
||||
|
||||
"20140115000117-b3a-sources" should "be parsed" in {
|
||||
beParsedAs("20140115000117-b3a-sources", Seq(20140115000117L), Seq("b3a", "sources"), Seq())
|
||||
version("1.0") { v =>
|
||||
assertParsesTo(v, Seq(1, 0), Seq(), Seq())
|
||||
assertBreaksDownTo(v, Some(1), Some(0))
|
||||
assertCascadesTo(v, Seq("1.0"))
|
||||
}
|
||||
it should "cascade" in generateCorrectCascadingNumbers("20140115000117-b3a-sources",
|
||||
Seq("20140115000117-b3a-sources"))
|
||||
|
||||
"1.0.0-alpha+001+002" should "be parsed" in {
|
||||
beParsedAs("1.0.0-alpha+001+002", Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002"))
|
||||
version("1.0.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"))
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
}
|
||||
it should "cascade" in generateCorrectCascadingNumbers(
|
||||
"1.0.0-alpha+001+002",
|
||||
Seq("1.0.0-alpha+001+002", "1.0.0", "1.0")
|
||||
)
|
||||
|
||||
"non.space.!?string" should "be parsed" in {
|
||||
beParsedAs("non.space.!?string", Seq(), Seq(), Seq("non.space.!?string"))
|
||||
version("1.0.0.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"))
|
||||
}
|
||||
it should "cascade" in generateCorrectCascadingNumbers("non.space.!?string",
|
||||
Seq("non.space.!?string"))
|
||||
|
||||
"space !?string" should "be parsed as an error" in beParsedAsError("space !?string")
|
||||
"blank string" should "be parsed as an error" in beParsedAsError("")
|
||||
version("0.12.0") { 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"))
|
||||
|
||||
def beParsedAs(s: String, ns: Seq[Long], ts: Seq[String], es: Seq[String]) =
|
||||
s match {
|
||||
case VersionNumber(ns1, ts1, es1) if (ns1 == ns && ts1 == ts && es1 == es) =>
|
||||
(VersionNumber(ns, ts, es).toString shouldBe s)
|
||||
(VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es))
|
||||
case VersionNumber(ns1, ts1, es1) =>
|
||||
sys.error(s"$ns1, $ts1, $es1")
|
||||
assertIsNotCompatibleWith(v, "0.12.0-RC1", SemVer)
|
||||
assertIsNotCompatibleWith(v, "0.12.1", SemVer)
|
||||
assertIsNotCompatibleWith(v, "0.12.1-M1", SemVer)
|
||||
|
||||
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 =>
|
||||
assertParsesTo(v, Seq(0, 1, 0), Seq("SNAPSHOT"), Seq())
|
||||
assertCascadesTo(v, Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1"))
|
||||
|
||||
assertIsCompatibleWith(v, "0.1.0-SNAPSHOT", SemVer)
|
||||
assertIsNotCompatibleWith(v, "0.1.0", SemVer)
|
||||
assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SemVer)
|
||||
|
||||
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 =>
|
||||
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 =>
|
||||
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 =>
|
||||
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 =>
|
||||
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 =>
|
||||
assertParsesTo(v, Seq(20140115000117L), Seq("b3a", "sources"), Seq())
|
||||
assertCascadesTo(v, Seq("20140115000117-b3a-sources"))
|
||||
}
|
||||
|
||||
version("1.0.0-alpha+001+002") { 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 =>
|
||||
assertParsesTo(v, Seq(), Seq(), Seq("non.space.!?string"))
|
||||
assertCascadesTo(v, Seq("non.space.!?string"))
|
||||
}
|
||||
|
||||
version("space !?string") { v =>
|
||||
assertParsesToError(v)
|
||||
}
|
||||
version("") { v =>
|
||||
assertParsesToError(v)
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
private[this] final class VersionString(val value: String)
|
||||
|
||||
private[this] def version(s: String)(f: VersionString => Unit) =
|
||||
s"""Version "$s"""" - {
|
||||
f(new VersionString(s))
|
||||
}
|
||||
def breakDownTo(s: String,
|
||||
major: Option[Long],
|
||||
minor: Option[Long] = None,
|
||||
patch: Option[Long] = None,
|
||||
buildNumber: Option[Long] = None) =
|
||||
s match {
|
||||
|
||||
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)
|
||||
(es1 shouldBe es)
|
||||
(VersionNumber(ns, ts, es).toString shouldBe v.value)
|
||||
(VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es))
|
||||
}
|
||||
|
||||
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 assertBreaksDownTo(
|
||||
v: VersionString,
|
||||
major: Option[Long],
|
||||
minor: Option[Long] = None,
|
||||
patch: Option[Long] = None,
|
||||
buildNumber: Option[Long] = None
|
||||
): 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)
|
||||
|
|
@ -130,21 +157,42 @@ class VersionNumberSpec extends UnitSpec {
|
|||
(v._3 shouldBe patch)
|
||||
(v._4 shouldBe buildNumber)
|
||||
}
|
||||
def beParsedAsError(s: String): Unit =
|
||||
s match {
|
||||
case VersionNumber(_, _, _) => sys.error(s)
|
||||
case _ => ()
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
private[this] def assertIsCompatibleWith(
|
||||
v1: VersionString,
|
||||
v2: String,
|
||||
vnc: VersionNumberCompatibility
|
||||
): Unit =
|
||||
checkCompat(true, vnc, v1, 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
|
||||
) = {
|
||||
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
|
||||
}
|
||||
s"$prefix be $compatibilityStrategy compatible with $v2" in {
|
||||
vnc.isCompatible(VersionNumber(v1.value), VersionNumber(v2)) shouldBe expectOutcome
|
||||
}
|
||||
def beSemVerCompatWith(v1: String, v2: String) =
|
||||
VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe true
|
||||
def notBeSemVerCompatWith(v1: String, v2: String) =
|
||||
VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe false
|
||||
def beSecSegCompatWith(v1: String, v2: String) =
|
||||
VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe true
|
||||
def notBeSecSegCompatWith(v1: String, v2: String) =
|
||||
VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe false
|
||||
def generateCorrectCascadingNumbers(s: String, ns: Seq[String]) = {
|
||||
val versionNumbers = ns.toVector map VersionNumber.apply
|
||||
VersionNumber(s).cascadingVersions shouldBe versionNumbers
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue