From 3e255707a815e32a8285e7b5e9077311b01e0710 Mon Sep 17 00:00:00 2001
From: Jan-Niclas Struewer <j.n.struewer@gmail.com>
Date: Tue, 30 Jul 2024 17:37:21 +0200
Subject: [PATCH] feature: added data classes for hierarchy serialization

---
 kpi-calculator/core/build.gradle.kts          |  1 +
 .../model/kpi/{KpiKind.kt => KpiId.kt}        |  2 +-
 .../kpiCalculator/model/kpi/KpiStrategyId.kt  |  8 ++++
 .../model/kpi/hierarchy/KpiHierarchy.kt       | 22 +++++++++
 .../model/kpi/hierarchy/KpiNodeTest.kt        | 46 +++++++++++++++++++
 5 files changed, 78 insertions(+), 1 deletion(-)
 rename kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/{KpiKind.kt => KpiId.kt} (96%)
 create mode 100644 kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/KpiStrategyId.kt
 create mode 100644 kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/hierarchy/KpiHierarchy.kt
 create mode 100644 kpi-calculator/model/src/test/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/hierarchy/KpiNodeTest.kt

diff --git a/kpi-calculator/core/build.gradle.kts b/kpi-calculator/core/build.gradle.kts
index f18ba4f7..aa309758 100644
--- a/kpi-calculator/core/build.gradle.kts
+++ b/kpi-calculator/core/build.gradle.kts
@@ -10,6 +10,7 @@ repositories {
 }
 
 dependencies {
+    implementation(project(":model"))
     testImplementation(libs.kotlin.test)
 }
 
diff --git a/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/KpiKind.kt b/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/KpiId.kt
similarity index 96%
rename from kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/KpiKind.kt
rename to kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/KpiId.kt
index 6b8eb5fd..b9b60a9f 100644
--- a/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/KpiKind.kt
+++ b/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/KpiId.kt
@@ -1,7 +1,7 @@
 package de.fraunhofer.iem.kpiCalculator.model.kpi
 
 
-enum class KpiKind {
+enum class KpiId {
     // Raw Value KPIs
     CHECKED_IN_BINARIES,
     NUMBER_OF_COMMITS,
diff --git a/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/KpiStrategyId.kt b/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/KpiStrategyId.kt
new file mode 100644
index 00000000..270a4308
--- /dev/null
+++ b/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/KpiStrategyId.kt
@@ -0,0 +1,8 @@
+package de.fraunhofer.iem.kpiCalculator.model.kpi
+
+enum class KpiStrategyId {
+    RAW_VALUE_STRATEGY,
+    AGGREGATION_STRATEGY,
+    MAXIMUM_STRATEGY,
+    RATIO_STRATEGY,
+}
diff --git a/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/hierarchy/KpiHierarchy.kt b/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/hierarchy/KpiHierarchy.kt
new file mode 100644
index 00000000..a7ce187e
--- /dev/null
+++ b/kpi-calculator/model/src/main/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/hierarchy/KpiHierarchy.kt
@@ -0,0 +1,22 @@
+package de.fraunhofer.iem.kpiCalculator.model.kpi.hierarchy
+
+import de.fraunhofer.iem.kpiCalculator.model.kpi.KpiId
+import de.fraunhofer.iem.kpiCalculator.model.kpi.KpiStrategyId
+import kotlinx.serialization.Serializable
+
+val SCHEMA_VERSIONS: Array<String> = arrayOf(
+    "1.0.0"
+).sortedArray()
+
+@Serializable
+data class KpiHierarchy private constructor(val rootNode: KpiNode, val schemaVersion: String) {
+    companion object {
+        fun create(rootNode: KpiNode) = KpiHierarchy(rootNode, SCHEMA_VERSIONS.last())
+    }
+}
+
+@Serializable
+data class KpiNode(val kpiId: KpiId, val strategyType: KpiStrategyId, val children: List<KpiEdge>)
+
+@Serializable
+data class KpiEdge(val target: KpiNode, val weight: Double)
diff --git a/kpi-calculator/model/src/test/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/hierarchy/KpiNodeTest.kt b/kpi-calculator/model/src/test/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/hierarchy/KpiNodeTest.kt
new file mode 100644
index 00000000..c2872514
--- /dev/null
+++ b/kpi-calculator/model/src/test/kotlin/de/fraunhofer/iem/kpiCalculator/model/kpi/hierarchy/KpiNodeTest.kt
@@ -0,0 +1,46 @@
+package de.fraunhofer.iem.kpiCalculator.model.kpi.hierarchy
+
+import de.fraunhofer.iem.kpiCalculator.model.kpi.KpiId
+import de.fraunhofer.iem.kpiCalculator.model.kpi.KpiStrategyId
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.assertDoesNotThrow
+import kotlin.test.assertEquals
+
+class KpiNodeTest {
+    @Test
+    fun constructHierarchy() {
+        // This test doesn't really test any functionality. It's mainly here as a reminder to fail whenever we change something
+        // related to our external data model (the KpiHierarchy), as this is what the library users store and use to call the
+        // library with.
+        // TLDR; Whenever this test fails we have a breaking change in how we construct our KPI hierarchy meaning we potentially
+        // break our clients code.
+        assertDoesNotThrow {
+            val childNodes = listOf(
+                KpiEdge(
+                    KpiNode(kpiId = KpiId.SECURITY, KpiStrategyId.AGGREGATION_STRATEGY, listOf()),
+                    weight = 0.3
+                ),
+                KpiEdge(
+                    KpiNode(kpiId = KpiId.PROCESS_COMPLIANCE, KpiStrategyId.AGGREGATION_STRATEGY, listOf()),
+                    weight = 0.3
+                ),
+                KpiEdge(
+                    KpiNode(kpiId = KpiId.INTERNAL_QUALITY, KpiStrategyId.AGGREGATION_STRATEGY, listOf()),
+                    weight = 0.3
+                ),
+            )
+            val root = KpiNode(kpiId = KpiId.ROOT, strategyType = KpiStrategyId.AGGREGATION_STRATEGY, childNodes)
+            val hierarchy = KpiHierarchy.create(root)
+
+            val json = Json {
+                prettyPrint = true
+            }
+            val jsonResult = json.encodeToString(hierarchy)
+
+            println(jsonResult)
+            assertEquals(hierarchy.schemaVersion, "1.0.0")
+        }
+    }
+}
-- 
GitLab