All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonTest.SemanticVersionTest.kt Maven / Gradle / Ivy

package com.amplitude.experiment.evaluation

import kotlin.test.Test
import kotlin.test.assertTrue
import kotlin.test.fail

class SemanticVersionTest {

    @Test
    fun testInvalidVersions() {
        // just major
        assertInvalidVersion("10")
        // trailing dots
        assertInvalidVersion("10.")
        assertInvalidVersion("10..")
        assertInvalidVersion("10.2.")
        assertInvalidVersion("10.2.33.")
        // trailing dots on prerelease tags are not handled because prerelease tags are considered
        // strings anyway for comparison which should be fine - e.g. "10.2.33-alpha1.2."

        // dots in the middle
        assertInvalidVersion("10..2.33")
        assertInvalidVersion("102...33")

        // invalid characters
        assertInvalidVersion("a.2.3")
        assertInvalidVersion("23!")
        assertInvalidVersion("23.#5")
        assertInvalidVersion("")
        assertInvalidVersion(null)

        // more numbers
        assertInvalidVersion("2.3.4.567")
        assertInvalidVersion("2.3.4.5.6.7")

        // prerelease if provided should always have major, minor, patch
        assertInvalidVersion("10.2.alpha")
        assertInvalidVersion("10.alpha")
        assertInvalidVersion("alpha-1.2.3")

        // prerelease should be separated by a hyphen after patch
        assertInvalidVersion("10.2.3alpha")
        assertInvalidVersion("10.2.3alpha-1.2.3")

        // negative numbers
        assertInvalidVersion("-10.1")
        assertInvalidVersion("10.-1")
    }

    @Test
    fun testValidVersions() {
        assertValidVersions("100.2")
        assertValidVersions("0.102.39")
        assertValidVersions("0.0.0")

        // versions with leading 0s would be converted to int
        assertValidVersions("01.02")
        assertValidVersions("001.001100.000900")

        // prerelease tags
        assertValidVersions("10.20.30-alpha")
        assertValidVersions("10.20.30-1.x.y")
        assertValidVersions("10.20.30-aslkjd")
        assertValidVersions("10.20.30-b894")
        assertValidVersions("10.20.30-b8c9")
    }

    @Test
    fun testVersionComparison() {
        // EQUALS case
        assertVersionComparison("66.12.23", EvaluationOperator.IS, "66.12.23")
        // patch if not specified equals 0
        assertVersionComparison("5.6", EvaluationOperator.IS, "5.6.0")
        // leading 0s are not stored when parsed
        assertVersionComparison("06.007.0008", EvaluationOperator.IS, "6.7.8")
        // with pre release
        assertVersionComparison("1.23.4-b-1.x.y", EvaluationOperator.IS, "1.23.4-b-1.x.y")

        // DOES NOT EQUAL case
        assertVersionComparison("1.23.4-alpha-1.2", EvaluationOperator.IS_NOT, "1.23.4-alpha-1")
        // trailing 0s aren't stripped
        assertVersionComparison("1.2.300", EvaluationOperator.IS_NOT, "1.2.3")
        assertVersionComparison("1.20.3", EvaluationOperator.IS_NOT, "1.2.3")

        // LESS THAN case
        // patch of .1 makes it greater
        assertVersionComparison("50.2", EvaluationOperator.VERSION_LESS_THAN, "50.2.1")
        // minor 9 > minor 20
        assertVersionComparison("20.9", EvaluationOperator.VERSION_LESS_THAN, "20.20")
        // same version with pre release should be lesser
        assertVersionComparison("20.9.4-alpha1", EvaluationOperator.VERSION_LESS_THAN, "20.9.4")
        // compare prerelease as strings
        assertVersionComparison("20.9.4-a-1.2.3", EvaluationOperator.VERSION_LESS_THAN, "20.9.4-a-1.3")
        // since prerelease is compared as strings a1.23 < a1.5 because 2 < 5
        assertVersionComparison("20.9.4-a1.23", EvaluationOperator.VERSION_LESS_THAN, "20.9.4-a1.5")

        // GREATER THAN case
        assertVersionComparison("12.30.2", EvaluationOperator.VERSION_GREATER_THAN, "12.4.1")
        // 100 > 1
        assertVersionComparison("7.100", EvaluationOperator.VERSION_GREATER_THAN, "7.1")
        // 10 > 9
        assertVersionComparison("7.10", EvaluationOperator.VERSION_GREATER_THAN, "7.9")
        // converts to 7.10.20 > 7.9.1
        assertVersionComparison("07.010.0020", EvaluationOperator.VERSION_GREATER_THAN, "7.009.1")
        // patch comparison comes first
        assertVersionComparison("20.5.6-b1.2.x", EvaluationOperator.VERSION_GREATER_THAN, "20.5.5")
    }

    private fun assertInvalidVersion(ver: String?) {
        SemanticVersion.parse(ver) ?: return // expect null
        fail("Should have failed creating a semantic version for $ver")
    }

    private fun assertValidVersions(ver: String) {
        SemanticVersion.parse(ver) ?: fail("expected a non null semantic version for $ver")
    }

    private fun assertVersionComparison(v1: String, op: String, v2: String) {
        val sv1 = SemanticVersion.parse(v1) ?: fail("parsing should succeed: $v1")
        val sv2 = SemanticVersion.parse(v2) ?: fail("parsing should succeed: $v2")
        when (op) {
            EvaluationOperator.IS -> assertTrue(sv1.compareTo(sv2) == 0)
            EvaluationOperator.IS_NOT -> assertTrue(sv1.compareTo(sv2) != 0)
            EvaluationOperator.VERSION_LESS_THAN -> assertTrue(sv1 < sv2)
            EvaluationOperator.VERSION_GREATER_THAN -> assertTrue(sv1 > sv2)
            else -> fail("Invalid operator $op")
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy