summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/util/Properties.scala68
-rw-r--r--test/junit/scala/util/SpecVersionTest.scala52
2 files changed, 91 insertions, 29 deletions
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
index 1bdf50bac2..8722294dde 100644
--- a/src/library/scala/util/Properties.scala
+++ b/src/library/scala/util/Properties.scala
@@ -168,33 +168,59 @@ private[scala] trait PropertiesTrait {
/** Compares the given specification version to the specification version of the platform.
*
- * @param version a specification version number (legacy forms acceptable)
- * @return `true` iff the specification version of the current runtime
- * is equal to or higher than the version denoted by the given string.
- * @throws NumberFormatException if the given string is not a version string
+ * @param version a specification version number (legacy forms acceptable)
+ * @return `true` if the specification version of the current runtime
+ * is equal to or higher than the version denoted by the given string.
+ * @throws NumberFormatException if the given string is not a version string
*
- * @example {{{
- * // In this example, the runtime's Java specification is assumed to be at version 8.
- * isJavaAtLeast("1.6") // true
- * isJavaAtLeast("1.8") // true
- * isJavaAtLeast("8") // true
- * isJavaAtLeast("9") // false
- * isJavaAtLeast("1.9") // throws
- * }}}
+ * @example {{{
+ * // In this example, the runtime's Java specification is assumed to be at version 8.
+ * isJavaAtLeast("1.8") // true
+ * isJavaAtLeast("8") // true
+ * isJavaAtLeast("9") // false
+ * isJavaAtLeast("9.1") // false
+ * isJavaAtLeast("1.9") // throws
+ * }}}
*/
def isJavaAtLeast(version: String): Boolean = {
- def versionOf(s: String): Int = s.indexOf('.') match {
- case 1 if s.charAt(0) == '1' =>
- val v = s.substring(2).toInt
- if (v < 9) v else -1
- case -1 => s.toInt
- case _ => -1
+ def versionOf(s: String, depth: Int): (Int, String) =
+ s.indexOf('.') match {
+ case 0 =>
+ (-2, s.substring(1))
+ case 1 if depth == 0 && s.charAt(0) == '1' =>
+ val r0 = s.substring(2)
+ val (v, r) = versionOf(r0, 1)
+ val n = if (v > 8 || r0.isEmpty) -2 else v // accept 1.8, not 1.9 or 1.
+ (n, r)
+ case -1 =>
+ val n = if (!s.isEmpty) s.toInt else if (depth == 0) -2 else 0
+ (n, "")
+ case i =>
+ val r = s.substring(i + 1)
+ val n = if (depth < 2 && r.isEmpty) -2 else s.substring(0, i).toInt
+ (n, r)
+ }
+ def compareVersions(s: String, v: String, depth: Int): Int = {
+ if (depth >= 3) 0
+ else {
+ val (sn, srest) = versionOf(s, depth)
+ val (vn, vrest) = versionOf(v, depth)
+ if (vn < 0) -2
+ else if (sn < vn) -1
+ else if (sn > vn) 1
+ else compareVersions(srest, vrest, depth + 1)
+ }
+ }
+ compareVersions(javaSpecVersion, version, 0) match {
+ case -2 => throw new NumberFormatException(s"Not a version: $version")
+ case i => i >= 0
}
- val v = versionOf(version)
- if (v < 0) throw new NumberFormatException(s"Not a version: $version")
- versionOf(javaSpecVersion) >= v
}
+ /** Tests whether the major version of the platform specification is at least the given value.
+ *
+ * @param version a major version number
+ */
def isJavaAtLeast(version: Int): Boolean = isJavaAtLeast(version.toString)
// provide a main method so version info can be obtained by running this
diff --git a/test/junit/scala/util/SpecVersionTest.scala b/test/junit/scala/util/SpecVersionTest.scala
index 9232c4721b..4639389dd9 100644
--- a/test/junit/scala/util/SpecVersionTest.scala
+++ b/test/junit/scala/util/SpecVersionTest.scala
@@ -34,6 +34,8 @@ class SpecVersionTest {
assert(sut9 isJavaAtLeast "8")
assert(sut9 isJavaAtLeast "9")
assert(sut9.isJavaAtLeast(9))
+ assertFalse(sut9.isJavaAtLeast(10))
+ assertFalse(sut9.isJavaAtLeast("10"))
}
// SI-7265
@@ -53,15 +55,49 @@ class SpecVersionTest {
}
@Test def variousBadVersionStrings(): Unit = {
- val sut7 = new TestProperties("1.7")
- val sut9 = new TestProperties("9")
- assertThrows[NumberFormatException](sut7.isJavaAtLeast("1.9"), _ == "Not a version: 1.9")
- assertThrows[NumberFormatException] { sut9 isJavaAtLeast "1.9" }
- assertThrows[NumberFormatException] { sut7 isJavaAtLeast "9.1" }
- assertThrows[NumberFormatException] { sut9 isJavaAtLeast "9.1" }
+ val sut = new TestProperties("9")
+ assertThrows[NumberFormatException](sut.isJavaAtLeast("1.9"), _ == "Not a version: 1.9")
+ assertThrows[NumberFormatException](sut.isJavaAtLeast("1."))
+ assertThrows[NumberFormatException](sut.isJavaAtLeast("1.8."))
+ assertThrows[NumberFormatException](sut.isJavaAtLeast("1.a"))
+ assertThrows[NumberFormatException](sut.isJavaAtLeast(""))
+ assertThrows[NumberFormatException](sut.isJavaAtLeast("."))
+ assertThrows[NumberFormatException](sut.isJavaAtLeast(".."))
+ assertThrows[NumberFormatException](sut.isJavaAtLeast(".5"))
+ assertThrows[NumberFormatException](sut.isJavaAtLeast("9-ea")) //version number, not version string
+ }
- val badvs = List("1.1.8", "1.", "1.a", "", ".", ".5", "1.7.1")
+ @Test def `spec has minor or more`(): Unit = {
+ val sut = new TestProperties("9.2.5")
+ assert(sut.isJavaAtLeast(9))
+ assert(sut.isJavaAtLeast("9"))
+ assert(sut.isJavaAtLeast("9.0.1"))
+ assert(sut.isJavaAtLeast("9.2.1"))
+ assert(sut.isJavaAtLeast("8.3.1"))
+ assert(sut.isJavaAtLeast("8.3.1.1.1"))
+ assertFalse(sut.isJavaAtLeast("9.3.1"))
+ assertFalse(sut.isJavaAtLeast("10.3.1"))
+ }
+
+ @Test def `compares only major minor security`(): Unit = {
+ val sut = new TestProperties("9.2.5.1.2.3")
+ assert(sut.isJavaAtLeast(9))
+ assert(sut.isJavaAtLeast("9"))
+ assert(sut.isJavaAtLeast("9.0.1"))
+ assert(sut.isJavaAtLeast("9.2.5.9.9.9"))
+ assertFalse(sut.isJavaAtLeast("9.2.6"))
+ }
- for (v <- badvs) assertThrows[NumberFormatException](sut7.isJavaAtLeast(v))
+ @Test def `futurely proofed`(): Unit = {
+ val sut = new TestProperties("10.2.5")
+ assert(sut.isJavaAtLeast(9))
+ assert(sut.isJavaAtLeast(10))
+ assert(sut.isJavaAtLeast("9"))
+ assert(sut.isJavaAtLeast("9.0.1"))
+ assert(sut.isJavaAtLeast("9.2.1"))
+ assert(sut.isJavaAtLeast("8.3.1"))
+ assert(sut.isJavaAtLeast("8.3.1.1.1"))
+ assert(sut.isJavaAtLeast("9.3.1"))
+ assertFalse(sut.isJavaAtLeast("10.3.1"))
}
}