From c57611670307f411f425d50f398d42dc1f0bb8d6 Mon Sep 17 00:00:00 2001 From: uniumuniu Date: Sun, 14 Jan 2024 21:57:14 +0100 Subject: [PATCH] Add unit tests for serializers --- .../com/featurevisor/sdk/Instance+Feature.kt | 3 - .../com/featurevisor/sdk/InstanceTest.kt | 66 +++++----- .../serializers/ConditionSerializerTest.kt | 115 ++++++++++++++++++ .../sdk/serializers/ConditionValueTest.kt | 72 +++++++++++ .../sdk/serializers/GroupSegmentTest.kt | 68 +++++++++++ 5 files changed, 293 insertions(+), 31 deletions(-) create mode 100644 src/test/kotlin/com/featurevisor/sdk/serializers/ConditionSerializerTest.kt create mode 100644 src/test/kotlin/com/featurevisor/sdk/serializers/ConditionValueTest.kt create mode 100644 src/test/kotlin/com/featurevisor/sdk/serializers/GroupSegmentTest.kt diff --git a/src/main/kotlin/com/featurevisor/sdk/Instance+Feature.kt b/src/main/kotlin/com/featurevisor/sdk/Instance+Feature.kt index 2dbd173..e9fbe20 100644 --- a/src/main/kotlin/com/featurevisor/sdk/Instance+Feature.kt +++ b/src/main/kotlin/com/featurevisor/sdk/Instance+Feature.kt @@ -38,7 +38,6 @@ internal fun FeaturevisorInstance.getMatchedTraffic( ): Traffic? { return traffic.firstOrNull { trafficItem -> -// logger?.debug("trafficItem.segments: ${trafficItem.segments}") allGroupSegmentsAreMatched(trafficItem.segments, context, datafileReader) } } @@ -71,11 +70,9 @@ internal fun FeaturevisorInstance.getMatchedTrafficAndAllocation( var matchedAllocation: Allocation? = null val matchedTraffic = traffic.firstOrNull { trafficItem -> if (allGroupSegmentsAreMatched(trafficItem.segments, context, datafileReader)) { -// logger?.debug("getMatchedTrafficAndAllocation, traffic: $trafficItem, allGroupSegmentsAreMatched") matchedAllocation = getMatchedAllocation(trafficItem, bucketValue) true } else { -// logger?.debug("getMatchedTrafficAndAllocation, traffic: $trafficItem, allGroupSegmentsAreMatched.not()") false } } diff --git a/src/test/kotlin/com/featurevisor/sdk/InstanceTest.kt b/src/test/kotlin/com/featurevisor/sdk/InstanceTest.kt index c7590af..d3403e3 100644 --- a/src/test/kotlin/com/featurevisor/sdk/InstanceTest.kt +++ b/src/test/kotlin/com/featurevisor/sdk/InstanceTest.kt @@ -3,31 +3,41 @@ */ package com.featurevisor.sdk -//TODO: Add unit tests for Instance.kt later -//class InstanceTest { -// -// private val systemUnderTest = FeaturevisorInstance.createInstance( -// options = InstanceOptions( -// bucketKeySeparator = "", -// configureBucketKey = { feature: Feature, map: Map, s: String -> }, -// configureBucketValue = { feature: Feature, map: Map, i: Int -> }, -// datafile = null, -// datafileUrl = null, -// handleDatafileFetch = {}, -// initialFeatures = mapOf(), -// interceptContext = {}, -// logger = null, -// onActivation = {}, -// onReady = {}, -// onRefresh = {}, -// onUpdate = {}, -// refreshInterval = null, -// stickyFeatures = mapOf() -// ) -// ) -// -// @Test -// fun `instance initialised properly`() { -// -// } -//} +import com.featurevisor.types.DatafileContent +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test + +class InstanceTest { + + private val systemUnderTest = FeaturevisorInstance.createInstance( + options = InstanceOptions( + bucketKeySeparator = "", + configureBucketKey = null, + configureBucketValue = null, + datafile = DatafileContent( + schemaVersion = "0", + revision = "0", + attributes = listOf(), + segments = listOf(), + features = listOf() + ), + datafileUrl = null, + handleDatafileFetch = null, + initialFeatures = mapOf(), + interceptContext = null, + logger = null, + onActivation = {}, + onReady = {}, + onRefresh = {}, + onUpdate = {}, + refreshInterval = null, + stickyFeatures = mapOf(), + onError = {}, + ) + ) + + @Test + fun `instance initialised properly`() { + systemUnderTest.statuses.ready shouldBe true + } +} diff --git a/src/test/kotlin/com/featurevisor/sdk/serializers/ConditionSerializerTest.kt b/src/test/kotlin/com/featurevisor/sdk/serializers/ConditionSerializerTest.kt new file mode 100644 index 0000000..02fcc40 --- /dev/null +++ b/src/test/kotlin/com/featurevisor/sdk/serializers/ConditionSerializerTest.kt @@ -0,0 +1,115 @@ +package com.featurevisor.sdk.serializers + +import com.featurevisor.types.Condition +import com.featurevisor.types.ConditionValue +import com.featurevisor.types.Operator +import io.kotest.matchers.shouldBe +import io.kotest.matchers.types.shouldBeTypeOf +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import org.junit.jupiter.api.Test + +class ConditionSerializerTest { + + @Test + fun `decode PLAIN condition`() { + val element = """ + { + "attribute": "version", + "operator": "equals", + "value": "1.2.3" + } + """.trimIndent() + + val condition = Json.decodeFromString(element) + + condition.shouldBeTypeOf() + condition.attributeKey shouldBe "version" + condition.operator shouldBe Operator.EQUALS + condition.value shouldBe ConditionValue.StringValue("1.2.3") + } + + @Test + fun `decode AND condition`() { + val element = """ + { + "and": [{ + "attribute": "version", + "operator": "equals", + "value": "1.2.3" + }, { + "attribute": "age", + "operator": "greaterThanOrEqual", + "value": "18" + }] + } + """.trimIndent() + + val condition = Json.decodeFromString(element) + + condition.shouldBeTypeOf() + (condition.and[0] as Condition.Plain).run { + attributeKey shouldBe "version" + operator shouldBe Operator.EQUALS + value shouldBe ConditionValue.StringValue("1.2.3") + } + (condition.and[1] as Condition.Plain).run { + attributeKey shouldBe "age" + operator shouldBe Operator.GREATER_THAN_OR_EQUAL + value shouldBe ConditionValue.IntValue(18) + } + } + + @Test + fun `decode OR condition`() { + val element = """ + { + "or": [{ + "attribute": "version", + "operator": "equals", + "value": "1.2.3" + }, { + "attribute": "age", + "operator": "greaterThanOrEqual", + "value": "18" + }] + } + """.trimIndent() + + val condition = Json.decodeFromString(element) + + condition.shouldBeTypeOf() + (condition.or[0] as Condition.Plain).run { + attributeKey shouldBe "version" + operator shouldBe Operator.EQUALS + value shouldBe ConditionValue.StringValue("1.2.3") + } + (condition.or[1] as Condition.Plain).run { + attributeKey shouldBe "age" + operator shouldBe Operator.GREATER_THAN_OR_EQUAL + value shouldBe ConditionValue.IntValue(18) + } + } + + @Test + fun `decode NOT condition`() { + val element = """ + { + "not": [{ + "attribute": "version", + "operator": "equals", + "value": "1.2.3" + }] + } + """.trimIndent() + + val condition = Json.decodeFromString(element) + + condition.shouldBeTypeOf() + (condition.not[0] as Condition.Plain).run { + attributeKey shouldBe "version" + operator shouldBe Operator.EQUALS + value shouldBe ConditionValue.StringValue("1.2.3") + } + } +} diff --git a/src/test/kotlin/com/featurevisor/sdk/serializers/ConditionValueTest.kt b/src/test/kotlin/com/featurevisor/sdk/serializers/ConditionValueTest.kt new file mode 100644 index 0000000..9857555 --- /dev/null +++ b/src/test/kotlin/com/featurevisor/sdk/serializers/ConditionValueTest.kt @@ -0,0 +1,72 @@ +package com.featurevisor.sdk.serializers + +import com.featurevisor.types.ConditionValue +import io.kotest.matchers.shouldBe +import io.kotest.matchers.types.shouldBeTypeOf +import kotlinx.serialization.json.Json +import org.junit.jupiter.api.Test +import kotlinx.serialization.decodeFromString + +class ConditionValueTest { + + @Test + fun `decode int value with correct type`() { + val element = """ + 1 + """.trimIndent() + + val result = Json.decodeFromString(element) + + result.shouldBeTypeOf() + result.value shouldBe 1 + } + + @Test + fun `decode boolean value with correct type`() { + val element = """ + true + """.trimIndent() + + val result = Json.decodeFromString(element) + + result.shouldBeTypeOf() + result.value shouldBe true + } + + @Test + fun `decode double value with correct type`() { + val element = """ + 1.2 + """.trimIndent() + + val result = Json.decodeFromString(element) + + result.shouldBeTypeOf() + result.value shouldBe 1.2 + } + + @Test + fun `decode string value with correct type`() { + val element = """ + test + """.trimIndent() + + val result = Json.decodeFromString(element) + + result.shouldBeTypeOf() + result.value shouldBe "test" + } + + @Test + fun `decode array value with correct type`() { + val element = """ + [ "test1", "test2"] + """.trimIndent() + + val result = Json.decodeFromString(element) + + result.shouldBeTypeOf() + result.values[0] shouldBe "test1" + result.values[1] shouldBe "test2" + } +} diff --git a/src/test/kotlin/com/featurevisor/sdk/serializers/GroupSegmentTest.kt b/src/test/kotlin/com/featurevisor/sdk/serializers/GroupSegmentTest.kt new file mode 100644 index 0000000..486d24d --- /dev/null +++ b/src/test/kotlin/com/featurevisor/sdk/serializers/GroupSegmentTest.kt @@ -0,0 +1,68 @@ +package com.featurevisor.sdk.serializers + +import com.featurevisor.types.GroupSegment +import io.kotest.matchers.shouldBe +import io.kotest.matchers.types.shouldBeTypeOf +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import org.junit.jupiter.api.Test + +class GroupSegmentTest { + + @Test + fun `decode PLAIN segment`() { + val element = """ + testSegment + """.trimIndent() + + val groupSegment = Json.decodeFromString(element) + + groupSegment.shouldBeTypeOf() + groupSegment.segment shouldBe "testSegment" + } + + @Test + fun `decode AND group segment`() { + val element = """ + { + "and": ["testSegment1", "testSegment2"] + } + """.trimIndent() + + val groupSegment = Json.decodeFromString(element) + + groupSegment.shouldBeTypeOf() + groupSegment.segment.and[0] shouldBe GroupSegment.Plain("testSegment1") + groupSegment.segment.and[1] shouldBe GroupSegment.Plain("testSegment2") + } + + @Test + fun `decode OR group segment`() { + val element = """ + { + "or": ["testSegment1", "testSegment2"] + } + """.trimIndent() + + val groupSegment = Json.decodeFromString(element) + + groupSegment.shouldBeTypeOf() + groupSegment.segment.or[0] shouldBe GroupSegment.Plain("testSegment1") + groupSegment.segment.or[1] shouldBe GroupSegment.Plain("testSegment2") + } + + @Test + fun `decode NOT group segment`() { + val element = """ + { + "not": ["testSegment1", "testSegment2"] + } + """.trimIndent() + + val groupSegment = Json.decodeFromString(element) + + groupSegment.shouldBeTypeOf() + groupSegment.segment.not[0] shouldBe GroupSegment.Plain("testSegment1") + groupSegment.segment.not[1] shouldBe GroupSegment.Plain("testSegment2") + } +}