diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..751be40 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + commit-message: + prefix: build + - package-ecosystem: gradle + directory: / + schedule: + interval: weekly + commit-message: + prefix: build diff --git a/build.gradle.kts b/build.gradle.kts index 42e324a..183dfd2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,6 +34,7 @@ version = buildString { kotlin { explicitApi() + jvm { compilations.all { kotlinOptions.jvmTarget = "1.8" @@ -42,6 +43,7 @@ kotlin { useJUnitPlatform() } } + js(IR) { browser() nodejs() @@ -175,9 +177,9 @@ publishing { } tasks.register("detektAll") { + group = "verification" dependsOn(tasks.withType()) } -fun getProperty(propertyName: String): String? { - return System.getenv()[propertyName] ?: publishingProperties.getProperty(propertyName) -} +fun getProperty(propertyName: String): String? = + providers.environmentVariable(propertyName).orNull ?: publishingProperties.getProperty(propertyName) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 7615608..f6e7be1 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -780,5 +780,3 @@ style: ignoreLateinitVar: false WildcardImport: active: true - excludeImports: - - 'java.util.*' diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6b95fe6..7ecddb9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,4 +22,4 @@ kotest-multiplatform = { id = "io.kotest.multiplatform", version.ref = "kotest" kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlinx-binaryCompatibilityValidator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "kotlinxBinaryCompatibilityValidator" } kotlinx-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } -kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } \ No newline at end of file +kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } diff --git a/src/commonMain/kotlin/net/swiftzer/semver/SemVer.kt b/src/commonMain/kotlin/net/swiftzer/semver/SemVer.kt index 24e747d..be4b041 100644 --- a/src/commonMain/kotlin/net/swiftzer/semver/SemVer.kt +++ b/src/commonMain/kotlin/net/swiftzer/semver/SemVer.kt @@ -166,9 +166,9 @@ public data class SemVer( @Suppress("DestructuringDeclarationWithTooManyEntries") public fun parse(version: String): SemVer { val (major, minor, patch, preRelease, buildMetadata) = ( - FullPattern.matchEntire(version) - ?: throw IllegalArgumentException("Invalid version string [$version]") - ).destructured + FullPattern.matchEntire(version) + ?: throw IllegalArgumentException("Invalid version string [$version]") + ).destructured return SemVer( major = major.toInt(), minor = minor.toInt(), diff --git a/src/commonTest/kotlin/net/swiftzer/semver/SemVerParseFailTest.kt b/src/commonTest/kotlin/net/swiftzer/semver/SemVerParseFailTest.kt index 542410f..5569901 100644 --- a/src/commonTest/kotlin/net/swiftzer/semver/SemVerParseFailTest.kt +++ b/src/commonTest/kotlin/net/swiftzer/semver/SemVerParseFailTest.kt @@ -5,56 +5,59 @@ import io.kotest.core.spec.style.FunSpec import io.kotest.datatest.withData import io.kotest.matchers.nulls.shouldBeNull -class SemVerParseFailTest : FunSpec({ - withData( - nameFn = { "fail case [$it]" }, - ts = sequenceOf( - "v1.2.3", - " 1.2.3", - "1.2.3 ", - "1", - "a", - "1.2", - "1.2.3-0123", - "1.2.3-0123.0123", - "1.1.2+.123", - "+invalid", - "-invalid", - "-invalid+invalid", - "-invalid.01", - "alpha", - "alpha.beta", - "alpha.beta.1", - "alpha.1", - "alpha+beta", - "alpha_beta", - "alpha.", - "alpha..", - "beta", - "1.0.0-alpha_beta", - "-alpha.", - "1.0.0-alpha..", - "1.0.0-alpha..1", - "1.0.0-alpha...1", - "1.0.0-alpha....1", - "1.0.0-alpha.....1", - "1.0.0-alpha......1", - "1.0.0-alpha.......1", - "01.1.1", - "1.01.1", - "1.1.01", - "1.2.3.DEV", - "1.2-SNAPSHOT", - "1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788", - "1.2-RC-SNAPSHOT", - "-1.0.3-gamma+b7718", - "+justmeta", - "9.8.7+meta+meta", - "9.8.7-whatever+meta+meta", - "99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12", - ), - ) { - shouldThrow { SemVer.parse(it) } - SemVer.parseOrNull(it).shouldBeNull() - } -}) +@Suppress("MaxLineLength") +class SemVerParseFailTest : FunSpec( + { + withData( + nameFn = { "fail case [$it]" }, + ts = sequenceOf( + "v1.2.3", + " 1.2.3", + "1.2.3 ", + "1", + "a", + "1.2", + "1.2.3-0123", + "1.2.3-0123.0123", + "1.1.2+.123", + "+invalid", + "-invalid", + "-invalid+invalid", + "-invalid.01", + "alpha", + "alpha.beta", + "alpha.beta.1", + "alpha.1", + "alpha+beta", + "alpha_beta", + "alpha.", + "alpha..", + "beta", + "1.0.0-alpha_beta", + "-alpha.", + "1.0.0-alpha..", + "1.0.0-alpha..1", + "1.0.0-alpha...1", + "1.0.0-alpha....1", + "1.0.0-alpha.....1", + "1.0.0-alpha......1", + "1.0.0-alpha.......1", + "01.1.1", + "1.01.1", + "1.1.01", + "1.2.3.DEV", + "1.2-SNAPSHOT", + "1.2.31.2.3----RC-SNAPSHOT.12.09.1--..12+788", + "1.2-RC-SNAPSHOT", + "-1.0.3-gamma+b7718", + "+justmeta", + "9.8.7+meta+meta", + "9.8.7-whatever+meta+meta", + "99999999999999999999999.999999999999999999.99999999999999999----RC-SNAPSHOT.12.09.1--------------------------------..12", + ), + ) { + shouldThrow { SemVer.parse(it) } + SemVer.parseOrNull(it).shouldBeNull() + } + }, +) diff --git a/src/commonTest/kotlin/net/swiftzer/semver/SemVerParseSuccessTest.kt b/src/commonTest/kotlin/net/swiftzer/semver/SemVerParseSuccessTest.kt index 97b4afe..846140f 100644 --- a/src/commonTest/kotlin/net/swiftzer/semver/SemVerParseSuccessTest.kt +++ b/src/commonTest/kotlin/net/swiftzer/semver/SemVerParseSuccessTest.kt @@ -4,161 +4,175 @@ import io.kotest.core.spec.style.FunSpec import io.kotest.datatest.withData import io.kotest.matchers.shouldBe -class SemVerParseSuccessTest : FunSpec({ - data class Param( - val version: String, - val expected: SemVer, - ) - withData( - nameFn = { "success case [${it.version}]" }, - ts = sequenceOf( - Param( - version = "0.0.4", - expected = SemVer(major = 0, minor = 0, patch = 4), - ), - Param( - version = "1.2.3", - expected = SemVer(major = 1, minor = 2, patch = 3), - ), - Param( - version = "10.20.30", - expected = SemVer(major = 10, minor = 20, patch = 30), - ), - Param( - version = "1.1.2-prerelease+meta", - expected = SemVer(major = 1, minor = 1, patch = 2, preRelease = "prerelease", buildMetadata = "meta"), - ), - Param( - version = "1.1.2+meta", - expected = SemVer(major = 1, minor = 1, patch = 2, preRelease = null, buildMetadata = "meta"), - ), - Param( - version = "1.1.2+meta-valid", - expected = SemVer(major = 1, minor = 1, patch = 2, preRelease = null, buildMetadata = "meta-valid"), - ), - Param( - version = "1.0.0-alpha", - expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha"), - ), - Param( - version = "1.0.0-beta", - expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "beta"), - ), - Param( - version = "1.0.0-alpha.beta", - expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.beta"), - ), - Param( - version = "1.0.0-alpha.beta.1", - expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.beta.1"), - ), - Param( - version = "1.0.0-alpha.1", - expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.1"), - ), - Param( - version = "1.0.0-alpha0.valid", - expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha0.valid"), - ), - Param( - version = "1.0.0-alpha.0valid", - expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.0valid"), - ), - Param( - version = "1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay", - expected = SemVer( - major = 1, - minor = 0, - patch = 0, - preRelease = "alpha-a.b-c-somethinglong", - buildMetadata = "build.1-aef.1-its-okay" +class SemVerParseSuccessTest : FunSpec( + { + data class Param( + val version: String, + val expected: SemVer, + ) + withData( + nameFn = { "success case [${it.version}]" }, + ts = sequenceOf( + Param( + version = "0.0.4", + expected = SemVer(major = 0, minor = 0, patch = 4), ), - ), - Param( - version = "1.0.0-rc.1+build.1", - expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "rc.1", buildMetadata = "build.1"), - ), - Param( - version = "2.0.0-rc.1+build.123", - expected = SemVer(major = 2, minor = 0, patch = 0, preRelease = "rc.1", buildMetadata = "build.123"), - ), - Param( - version = "1.2.3-beta", - expected = SemVer(major = 1, minor = 2, patch = 3, preRelease = "beta"), - ), - Param( - version = "10.2.3-DEV-SNAPSHOT", - expected = SemVer(major = 10, minor = 2, patch = 3, preRelease = "DEV-SNAPSHOT"), - ), - Param( - version = "1.2.3-SNAPSHOT-123", - expected = SemVer(major = 1, minor = 2, patch = 3, preRelease = "SNAPSHOT-123"), - ), - Param( - version = "1.0.0", - expected = SemVer(major = 1, minor = 0, patch = 0), - ), - Param( - version = "2.0.0", - expected = SemVer(major = 2, minor = 0, patch = 0), - ), - Param( - version = "1.1.7", - expected = SemVer(major = 1, minor = 1, patch = 7), - ), - Param( - version = "2.0.0+build.1848", - expected = SemVer(major = 2, minor = 0, patch = 0, preRelease = null, buildMetadata = "build.1848"), - ), - Param( - version = "2.0.1-alpha.1227", - expected = SemVer(major = 2, minor = 0, patch = 1, preRelease = "alpha.1227"), - ), - Param( - version = "1.0.0-alpha+beta", - expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha", buildMetadata = "beta"), - ), - Param( - version = "1.2.3----RC-SNAPSHOT.12.9.1--.12+788", - expected = SemVer( - major = 1, - minor = 2, - patch = 3, - preRelease = "---RC-SNAPSHOT.12.9.1--.12", - buildMetadata = "788" + Param( + version = "1.2.3", + expected = SemVer(major = 1, minor = 2, patch = 3), ), - ), - Param( - version = "1.2.3----R-S.12.9.1--.12+meta", - expected = SemVer( - major = 1, - minor = 2, - patch = 3, - preRelease = "---R-S.12.9.1--.12", - buildMetadata = "meta" + Param( + version = "10.20.30", + expected = SemVer(major = 10, minor = 20, patch = 30), ), - ), - Param( - version = "1.2.3----RC-SNAPSHOT.12.9.1--.12", - expected = SemVer(major = 1, minor = 2, patch = 3, preRelease = "---RC-SNAPSHOT.12.9.1--.12"), - ), - Param( - version = "1.0.0+0.build.1-rc.10000aaa-kk-0.1", - expected = SemVer( - major = 1, - minor = 0, - patch = 0, - preRelease = null, - buildMetadata = "0.build.1-rc.10000aaa-kk-0.1" + Param( + version = "1.1.2-prerelease+meta", + expected = SemVer( + major = 1, + minor = 1, + patch = 2, + preRelease = "prerelease", + buildMetadata = "meta", + ), + ), + Param( + version = "1.1.2+meta", + expected = SemVer(major = 1, minor = 1, patch = 2, preRelease = null, buildMetadata = "meta"), + ), + Param( + version = "1.1.2+meta-valid", + expected = SemVer(major = 1, minor = 1, patch = 2, preRelease = null, buildMetadata = "meta-valid"), + ), + Param( + version = "1.0.0-alpha", + expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha"), + ), + Param( + version = "1.0.0-beta", + expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "beta"), + ), + Param( + version = "1.0.0-alpha.beta", + expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.beta"), + ), + Param( + version = "1.0.0-alpha.beta.1", + expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.beta.1"), + ), + Param( + version = "1.0.0-alpha.1", + expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.1"), + ), + Param( + version = "1.0.0-alpha0.valid", + expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha0.valid"), + ), + Param( + version = "1.0.0-alpha.0valid", + expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.0valid"), + ), + Param( + version = "1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay", + expected = SemVer( + major = 1, + minor = 0, + patch = 0, + preRelease = "alpha-a.b-c-somethinglong", + buildMetadata = "build.1-aef.1-its-okay", + ), + ), + Param( + version = "1.0.0-rc.1+build.1", + expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "rc.1", buildMetadata = "build.1"), + ), + Param( + version = "2.0.0-rc.1+build.123", + expected = SemVer( + major = 2, + minor = 0, + patch = 0, + preRelease = "rc.1", + buildMetadata = "build.123", + ), + ), + Param( + version = "1.2.3-beta", + expected = SemVer(major = 1, minor = 2, patch = 3, preRelease = "beta"), + ), + Param( + version = "10.2.3-DEV-SNAPSHOT", + expected = SemVer(major = 10, minor = 2, patch = 3, preRelease = "DEV-SNAPSHOT"), + ), + Param( + version = "1.2.3-SNAPSHOT-123", + expected = SemVer(major = 1, minor = 2, patch = 3, preRelease = "SNAPSHOT-123"), + ), + Param( + version = "1.0.0", + expected = SemVer(major = 1, minor = 0, patch = 0), + ), + Param( + version = "2.0.0", + expected = SemVer(major = 2, minor = 0, patch = 0), + ), + Param( + version = "1.1.7", + expected = SemVer(major = 1, minor = 1, patch = 7), + ), + Param( + version = "2.0.0+build.1848", + expected = SemVer(major = 2, minor = 0, patch = 0, preRelease = null, buildMetadata = "build.1848"), + ), + Param( + version = "2.0.1-alpha.1227", + expected = SemVer(major = 2, minor = 0, patch = 1, preRelease = "alpha.1227"), + ), + Param( + version = "1.0.0-alpha+beta", + expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha", buildMetadata = "beta"), + ), + Param( + version = "1.2.3----RC-SNAPSHOT.12.9.1--.12+788", + expected = SemVer( + major = 1, + minor = 2, + patch = 3, + preRelease = "---RC-SNAPSHOT.12.9.1--.12", + buildMetadata = "788", + ), + ), + Param( + version = "1.2.3----R-S.12.9.1--.12+meta", + expected = SemVer( + major = 1, + minor = 2, + patch = 3, + preRelease = "---R-S.12.9.1--.12", + buildMetadata = "meta", + ), + ), + Param( + version = "1.2.3----RC-SNAPSHOT.12.9.1--.12", + expected = SemVer(major = 1, minor = 2, patch = 3, preRelease = "---RC-SNAPSHOT.12.9.1--.12"), + ), + Param( + version = "1.0.0+0.build.1-rc.10000aaa-kk-0.1", + expected = SemVer( + major = 1, + minor = 0, + patch = 0, + preRelease = null, + buildMetadata = "0.build.1-rc.10000aaa-kk-0.1", + ), + ), + Param( + version = "1.0.0-0A.is.legal", + expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "0A.is.legal"), ), ), - Param( - version = "1.0.0-0A.is.legal", - expected = SemVer(major = 1, minor = 0, patch = 0, preRelease = "0A.is.legal"), - ), - ), - ) { - SemVer.parse(it.version) shouldBe it.expected - SemVer.parseOrNull(it.version) shouldBe it.expected - } -}) + ) { + SemVer.parse(it.version) shouldBe it.expected + SemVer.parseOrNull(it.version) shouldBe it.expected + } + }, +) diff --git a/src/commonTest/kotlin/net/swiftzer/semver/SemVerSerializerTest.kt b/src/commonTest/kotlin/net/swiftzer/semver/SemVerSerializerTest.kt index 0a3ecfe..12a5c35 100644 --- a/src/commonTest/kotlin/net/swiftzer/semver/SemVerSerializerTest.kt +++ b/src/commonTest/kotlin/net/swiftzer/semver/SemVerSerializerTest.kt @@ -12,18 +12,35 @@ import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json @OptIn(ExperimentalSerializationApi::class) -class SemVerSerializerTest : FunSpec({ - val json = Json - test("descriptor") { - SemVerSerializer.descriptor.apply { - serialName shouldBe "SemVer" - kind shouldBe PrimitiveKind.STRING +class SemVerSerializerTest : FunSpec( + { + val json = Json + test("descriptor") { + SemVerSerializer.descriptor.apply { + serialName shouldBe "SemVer" + kind shouldBe PrimitiveKind.STRING + } } - } - test("serialize") { - json.encodeToString( - DummyData( + test("serialize") { + json.encodeToString( + DummyData( + semVer = SemVer( + major = 2, + minor = 0, + patch = 0, + preRelease = "rc.1", + buildMetadata = "build.123", + ), + number = 12345, + ), + ) shouldBe """{"semVer":"2.0.0-rc.1+build.123","number":12345}""" + } + + test("deserialize success") { + json.decodeFromString( + """{"semVer":"2.0.0-rc.1+build.123","number":12345}""", + ) shouldBe DummyData( semVer = SemVer( major = 2, minor = 0, @@ -33,40 +50,25 @@ class SemVerSerializerTest : FunSpec({ ), number = 12345, ) - ) shouldBe """{"semVer":"2.0.0-rc.1+build.123","number":12345}""" - } - - test("deserialize success") { - json.decodeFromString( - """{"semVer":"2.0.0-rc.1+build.123","number":12345}""", - ) shouldBe DummyData( - semVer = SemVer( - major = 2, - minor = 0, - patch = 0, - preRelease = "rc.1", - buildMetadata = "build.123", - ), - number = 12345, - ) - } + } - test("deserialize IllegalArgumentException") { - shouldThrow { - json.decodeFromString( - """{"semVer":"1.1.2+.123","number":12345}""", - ) - }.cause.shouldBeInstanceOf() - } + test("deserialize IllegalArgumentException") { + shouldThrow { + json.decodeFromString( + """{"semVer":"1.1.2+.123","number":12345}""", + ) + }.cause.shouldBeInstanceOf() + } - test("deserialize NumberFormatException") { - shouldThrow { - json.decodeFromString( - """{"semVer":"99999999999999999999999.999999999999999999.99999999999999999","number":12345}""", - ) - }.cause.shouldBeInstanceOf() - } -}) + test("deserialize NumberFormatException") { + shouldThrow { + json.decodeFromString( + """{"semVer":"99999999999999999999999.999999999999999999.99999999999999999","number":12345}""", + ) + }.cause.shouldBeInstanceOf() + } + }, +) @Serializable private data class DummyData( diff --git a/src/commonTest/kotlin/net/swiftzer/semver/SemVerTest.kt b/src/commonTest/kotlin/net/swiftzer/semver/SemVerTest.kt index 40047ed..0373013 100644 --- a/src/commonTest/kotlin/net/swiftzer/semver/SemVerTest.kt +++ b/src/commonTest/kotlin/net/swiftzer/semver/SemVerTest.kt @@ -9,174 +9,175 @@ import io.kotest.matchers.ints.shouldBePositive import io.kotest.matchers.nulls.shouldBeNull import io.kotest.matchers.shouldBe -class SemVerTest : FunSpec({ - - test("init major validation") { - SemVer(major = 0).major shouldBe 0 - SemVer(major = 1).major shouldBe 1 - shouldThrow { SemVer(major = -1) } - } - - test("init minor validation") { - SemVer(major = 0, minor = 0).minor shouldBe 0 - SemVer(major = 0, minor = 1).minor shouldBe 1 - shouldThrow { SemVer(major = 0, minor = -1) } - } - - test("init patch validation") { - SemVer(major = 0, patch = 0).patch shouldBe 0 - SemVer(major = 0, patch = 1).patch shouldBe 1 - shouldThrow { SemVer(major = 0, patch = -1) } - } - - test("init preRelease validation") { - SemVer(major = 0, preRelease = "a1B2c3").preRelease shouldBe "a1B2c3" - SemVer(major = 0, preRelease = "0").preRelease shouldBe "0" - SemVer(major = 0, preRelease = "01s").preRelease shouldBe "01s" - SemVer(major = 0, preRelease = "1").preRelease shouldBe "1" - SemVer(major = 0, preRelease = "1024").preRelease shouldBe "1024" - SemVer(major = 0, preRelease = "--a1b2C3").preRelease shouldBe "--a1b2C3" - - shouldThrow { SemVer(major = 0, preRelease = " ") } - shouldThrow { SemVer(major = 0, preRelease = "a!bc") } - shouldThrow { SemVer(major = 0, preRelease = "007") } - shouldThrow { SemVer(major = 0, preRelease = " --a1b2C3") } - shouldThrow { SemVer(major = 0, preRelease = "--a1b2C3 ") } - } - - test("init buildMetadata validation") { - SemVer(major = 0, buildMetadata = "meta-valid").buildMetadata shouldBe "meta-valid" - SemVer(major = 0, buildMetadata = "0").buildMetadata shouldBe "0" - SemVer(major = 0, buildMetadata = "1").buildMetadata shouldBe "1" - SemVer( - major = 0, buildMetadata = "0.build.1-rc.10000aaa-kk-0.1" - ).buildMetadata shouldBe "0.build.1-rc.10000aaa-kk-0.1" - SemVer(major = 0, buildMetadata = "--a1b2C3").buildMetadata shouldBe "--a1b2C3" - shouldThrow { SemVer(major = 0, buildMetadata = " ") } - shouldThrow { SemVer(major = 0, buildMetadata = "a!bc") } - shouldThrow { SemVer(major = 0, buildMetadata = "meta+meta") } - shouldThrow { SemVer(major = 0, buildMetadata = "+meta") } - shouldThrow { SemVer(major = 0, buildMetadata = " a1b2C3") } - shouldThrow { SemVer(major = 0, buildMetadata = "a1b2C3 ") } - } - - test("isInitialDevelopmentPhase") { - SemVer(0, 1, 2).isInitialDevelopmentPhase().shouldBeTrue() - SemVer(1, 2, 3).isInitialDevelopmentPhase().shouldBeFalse() - } - - test("nextMajor") { - SemVer( - major = 1, - minor = 3, - patch = 5, - preRelease = "prerelease", - buildMetadata = "meta" - ).nextMajor() shouldBe SemVer(major = 2, minor = 0, patch = 0) - } - - test("nextMinor") { - SemVer( - major = 1, - minor = 3, - patch = 5, - preRelease = "prerelease", - buildMetadata = "meta" - ).nextMinor() shouldBe SemVer(major = 1, minor = 4, patch = 0) - } - - test("nextPatch") { - SemVer( - major = 1, - minor = 3, - patch = 5, - preRelease = "prerelease", - buildMetadata = "meta" - ).nextPatch() shouldBe SemVer(major = 1, minor = 3, patch = 6) - } - - test("toString") { - SemVer(major = 0, minor = 11, patch = 222).toString() shouldBe "0.11.222" - SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.1").toString() shouldBe "1.0.0-alpha.1" - SemVer( - major = 1, minor = 1, patch = 2, preRelease = null, buildMetadata = "meta-valid" - ).toString() shouldBe "1.1.2+meta-valid" - SemVer( - major = 2, minor = 0, patch = 0, preRelease = "rc.1", buildMetadata = "build.123" - ).toString() shouldBe "2.0.0-rc.1+build.123" - } - - test("compareTo major") { - val smaller = SemVer(major = 1) - val larger = SemVer(major = 2) - smaller.compareTo(larger).shouldBeNegative() - larger.compareTo(smaller).shouldBePositive() - smaller.compareTo(smaller) shouldBe 0 - } - - test("compareTo minor") { - val smaller = SemVer(major = 1, minor = 1) - val larger = SemVer(major = 1, minor = 2) - smaller.compareTo(larger).shouldBeNegative() - larger.compareTo(smaller).shouldBePositive() - smaller.compareTo(smaller) shouldBe 0 - } - - test("compareTo patch") { - val smaller = SemVer(major = 1, minor = 1, patch = 1) - val larger = SemVer(major = 1, minor = 1, patch = 2) - smaller.compareTo(larger).shouldBeNegative() - larger.compareTo(smaller).shouldBePositive() - smaller.compareTo(smaller) shouldBe 0 - } - - test("compareTo release") { - val version1 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha") - val version2 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.1") - val version3 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.beta") - val version4 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "beta") - val version5 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "beta.2") - val version6 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "beta.11") - val version7 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "rc.1") - val version8 = SemVer(major = 1, minor = 0, patch = 0) - - version1.compareTo(version2).shouldBeNegative() - version2.compareTo(version3).shouldBeNegative() - version3.compareTo(version4).shouldBeNegative() - version4.compareTo(version5).shouldBeNegative() - version5.compareTo(version6).shouldBeNegative() - version6.compareTo(version7).shouldBeNegative() - version7.compareTo(version8).shouldBeNegative() - version1.compareTo(version8).shouldBeNegative() - - version2.compareTo(version1).shouldBePositive() - version3.compareTo(version2).shouldBePositive() - version4.compareTo(version3).shouldBePositive() - version5.compareTo(version4).shouldBePositive() - version6.compareTo(version5).shouldBePositive() - version7.compareTo(version6).shouldBePositive() - version8.compareTo(version7).shouldBePositive() - version8.compareTo(version1).shouldBePositive() - - version6.compareTo(version6) shouldBe 0 - } - - test("compare preRelease exceed Long range") { - val smaller = SemVer(1, 0, 0, "111.99999999999999999999998") - val larger = SemVer(1, 0, 0, "111.99999999999999999999999") - smaller.compareTo(larger).shouldBeNegative() - larger.compareTo(smaller).shouldBePositive() - } - - test("parse exceed Int range") { - // The type for major/minor/patch are Long, thus throw exception - shouldThrow { - SemVer.parse("99999999999999999999999.999999999999999999.99999999999999999") - } - } - - test("parseOrNull exceed Int range") { - // The type for major/minor/patch are Long, thus throw exception - SemVer.parseOrNull("99999999999999999999999.999999999999999999.99999999999999999").shouldBeNull() - } -}) +class SemVerTest : FunSpec( + { + test("init major validation") { + SemVer(major = 0).major shouldBe 0 + SemVer(major = 1).major shouldBe 1 + shouldThrow { SemVer(major = -1) } + } + + test("init minor validation") { + SemVer(major = 0, minor = 0).minor shouldBe 0 + SemVer(major = 0, minor = 1).minor shouldBe 1 + shouldThrow { SemVer(major = 0, minor = -1) } + } + + test("init patch validation") { + SemVer(major = 0, patch = 0).patch shouldBe 0 + SemVer(major = 0, patch = 1).patch shouldBe 1 + shouldThrow { SemVer(major = 0, patch = -1) } + } + + test("init preRelease validation") { + SemVer(major = 0, preRelease = "a1B2c3").preRelease shouldBe "a1B2c3" + SemVer(major = 0, preRelease = "0").preRelease shouldBe "0" + SemVer(major = 0, preRelease = "01s").preRelease shouldBe "01s" + SemVer(major = 0, preRelease = "1").preRelease shouldBe "1" + SemVer(major = 0, preRelease = "1024").preRelease shouldBe "1024" + SemVer(major = 0, preRelease = "--a1b2C3").preRelease shouldBe "--a1b2C3" + + shouldThrow { SemVer(major = 0, preRelease = " ") } + shouldThrow { SemVer(major = 0, preRelease = "a!bc") } + shouldThrow { SemVer(major = 0, preRelease = "007") } + shouldThrow { SemVer(major = 0, preRelease = " --a1b2C3") } + shouldThrow { SemVer(major = 0, preRelease = "--a1b2C3 ") } + } + + test("init buildMetadata validation") { + SemVer(major = 0, buildMetadata = "meta-valid").buildMetadata shouldBe "meta-valid" + SemVer(major = 0, buildMetadata = "0").buildMetadata shouldBe "0" + SemVer(major = 0, buildMetadata = "1").buildMetadata shouldBe "1" + SemVer( + major = 0, buildMetadata = "0.build.1-rc.10000aaa-kk-0.1", + ).buildMetadata shouldBe "0.build.1-rc.10000aaa-kk-0.1" + SemVer(major = 0, buildMetadata = "--a1b2C3").buildMetadata shouldBe "--a1b2C3" + shouldThrow { SemVer(major = 0, buildMetadata = " ") } + shouldThrow { SemVer(major = 0, buildMetadata = "a!bc") } + shouldThrow { SemVer(major = 0, buildMetadata = "meta+meta") } + shouldThrow { SemVer(major = 0, buildMetadata = "+meta") } + shouldThrow { SemVer(major = 0, buildMetadata = " a1b2C3") } + shouldThrow { SemVer(major = 0, buildMetadata = "a1b2C3 ") } + } + + test("isInitialDevelopmentPhase") { + SemVer(0, 1, 2).isInitialDevelopmentPhase().shouldBeTrue() + SemVer(1, 2, 3).isInitialDevelopmentPhase().shouldBeFalse() + } + + test("nextMajor") { + SemVer( + major = 1, + minor = 3, + patch = 5, + preRelease = "prerelease", + buildMetadata = "meta", + ).nextMajor() shouldBe SemVer(major = 2, minor = 0, patch = 0) + } + + test("nextMinor") { + SemVer( + major = 1, + minor = 3, + patch = 5, + preRelease = "prerelease", + buildMetadata = "meta", + ).nextMinor() shouldBe SemVer(major = 1, minor = 4, patch = 0) + } + + test("nextPatch") { + SemVer( + major = 1, + minor = 3, + patch = 5, + preRelease = "prerelease", + buildMetadata = "meta", + ).nextPatch() shouldBe SemVer(major = 1, minor = 3, patch = 6) + } + + test("toString") { + SemVer(major = 0, minor = 11, patch = 222).toString() shouldBe "0.11.222" + SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.1").toString() shouldBe "1.0.0-alpha.1" + SemVer( + major = 1, minor = 1, patch = 2, preRelease = null, buildMetadata = "meta-valid", + ).toString() shouldBe "1.1.2+meta-valid" + SemVer( + major = 2, minor = 0, patch = 0, preRelease = "rc.1", buildMetadata = "build.123", + ).toString() shouldBe "2.0.0-rc.1+build.123" + } + + test("compareTo major") { + val smaller = SemVer(major = 1) + val larger = SemVer(major = 2) + smaller.compareTo(larger).shouldBeNegative() + larger.compareTo(smaller).shouldBePositive() + smaller.compareTo(smaller) shouldBe 0 + } + + test("compareTo minor") { + val smaller = SemVer(major = 1, minor = 1) + val larger = SemVer(major = 1, minor = 2) + smaller.compareTo(larger).shouldBeNegative() + larger.compareTo(smaller).shouldBePositive() + smaller.compareTo(smaller) shouldBe 0 + } + + test("compareTo patch") { + val smaller = SemVer(major = 1, minor = 1, patch = 1) + val larger = SemVer(major = 1, minor = 1, patch = 2) + smaller.compareTo(larger).shouldBeNegative() + larger.compareTo(smaller).shouldBePositive() + smaller.compareTo(smaller) shouldBe 0 + } + + test("compareTo release") { + val version1 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha") + val version2 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.1") + val version3 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "alpha.beta") + val version4 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "beta") + val version5 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "beta.2") + val version6 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "beta.11") + val version7 = SemVer(major = 1, minor = 0, patch = 0, preRelease = "rc.1") + val version8 = SemVer(major = 1, minor = 0, patch = 0) + + version1.compareTo(version2).shouldBeNegative() + version2.compareTo(version3).shouldBeNegative() + version3.compareTo(version4).shouldBeNegative() + version4.compareTo(version5).shouldBeNegative() + version5.compareTo(version6).shouldBeNegative() + version6.compareTo(version7).shouldBeNegative() + version7.compareTo(version8).shouldBeNegative() + version1.compareTo(version8).shouldBeNegative() + + version2.compareTo(version1).shouldBePositive() + version3.compareTo(version2).shouldBePositive() + version4.compareTo(version3).shouldBePositive() + version5.compareTo(version4).shouldBePositive() + version6.compareTo(version5).shouldBePositive() + version7.compareTo(version6).shouldBePositive() + version8.compareTo(version7).shouldBePositive() + version8.compareTo(version1).shouldBePositive() + + version6.compareTo(version6) shouldBe 0 + } + + test("compare preRelease exceed Long range") { + val smaller = SemVer(1, 0, 0, "111.99999999999999999999998") + val larger = SemVer(1, 0, 0, "111.99999999999999999999999") + smaller.compareTo(larger).shouldBeNegative() + larger.compareTo(smaller).shouldBePositive() + } + + test("parse exceed Int range") { + // The type for major/minor/patch are Long, thus throw exception + shouldThrow { + SemVer.parse("99999999999999999999999.999999999999999999.99999999999999999") + } + } + + test("parseOrNull exceed Int range") { + // The type for major/minor/patch are Long, thus throw exception + SemVer.parseOrNull("99999999999999999999999.999999999999999999.99999999999999999").shouldBeNull() + } + }, +) diff --git a/src/jsMain/kotlin/net/swiftzer/semver/SemVerRegex.js.kt b/src/jsMain/kotlin/net/swiftzer/semver/SemVerRegex.js.kt index 77609c8..8d43a95 100644 --- a/src/jsMain/kotlin/net/swiftzer/semver/SemVerRegex.js.kt +++ b/src/jsMain/kotlin/net/swiftzer/semver/SemVerRegex.js.kt @@ -10,4 +10,6 @@ internal actual val BuildMetadataPattern: Regex @Suppress("MaxLineLength") internal actual val FullPattern: Regex get() = - Regex("""^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$""") + Regex( + """^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$""" + ) diff --git a/src/jvmMain/kotlin/net/swiftzer/semver/SemVerRegex.jvm.kt b/src/jvmMain/kotlin/net/swiftzer/semver/SemVerRegex.jvm.kt index b3e52db..dc443a2 100644 --- a/src/jvmMain/kotlin/net/swiftzer/semver/SemVerRegex.jvm.kt +++ b/src/jvmMain/kotlin/net/swiftzer/semver/SemVerRegex.jvm.kt @@ -10,4 +10,6 @@ internal actual val BuildMetadataPattern: Regex @Suppress("MaxLineLength") internal actual val FullPattern: Regex get() = - Regex("""(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?""") + Regex( + """(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?""" + ) diff --git a/src/nativeMain/kotlin/net/swiftzer/semver/SemVerRegex.native.kt b/src/nativeMain/kotlin/net/swiftzer/semver/SemVerRegex.native.kt index b3e52db..dc443a2 100644 --- a/src/nativeMain/kotlin/net/swiftzer/semver/SemVerRegex.native.kt +++ b/src/nativeMain/kotlin/net/swiftzer/semver/SemVerRegex.native.kt @@ -10,4 +10,6 @@ internal actual val BuildMetadataPattern: Regex @Suppress("MaxLineLength") internal actual val FullPattern: Regex get() = - Regex("""(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?""") + Regex( + """(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?""" + )