Add tests
This commit is contained in:
@@ -3,7 +3,6 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.jetbrainsKotlinJvm)
|
|
||||||
alias(libs.plugins.kotlinMultiplatform)
|
alias(libs.plugins.kotlinMultiplatform)
|
||||||
alias(libs.plugins.androidApplication)
|
alias(libs.plugins.androidApplication)
|
||||||
alias(libs.plugins.jetbrainsCompose)
|
alias(libs.plugins.jetbrainsCompose)
|
||||||
@@ -20,6 +19,7 @@ kotlin {
|
|||||||
androidTarget()
|
androidTarget()
|
||||||
jvm("desktop")
|
jvm("desktop")
|
||||||
|
|
||||||
|
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
|
||||||
sourceSets {
|
sourceSets {
|
||||||
val androidUnitTest by getting
|
val androidUnitTest by getting
|
||||||
val desktopMain by getting
|
val desktopMain by getting
|
||||||
@@ -42,18 +42,16 @@ kotlin {
|
|||||||
implementation(compose.desktop.currentOs)
|
implementation(compose.desktop.currentOs)
|
||||||
}
|
}
|
||||||
androidUnitTest.dependencies {
|
androidUnitTest.dependencies {
|
||||||
implementation(kotlin("test"))
|
implementation(libs.kotlin.test)
|
||||||
|
implementation(compose.uiTest)
|
||||||
implementation(libs.atrium)
|
implementation(libs.atrium)
|
||||||
}
|
}
|
||||||
commonTest.dependencies {
|
commonTest.dependencies {
|
||||||
implementation(kotlin("test"))
|
implementation(libs.kotlin.test)
|
||||||
implementation(libs.atrium)
|
implementation(libs.atrium)
|
||||||
|
|
||||||
@OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
|
|
||||||
implementation(compose.uiTest)
|
|
||||||
}
|
}
|
||||||
desktopTest.dependencies {
|
desktopTest.dependencies {
|
||||||
implementation(kotlin("test"))
|
implementation(libs.kotlin.test)
|
||||||
implementation(libs.atrium)
|
implementation(libs.atrium)
|
||||||
implementation(compose.desktop.uiTestJUnit4)
|
implementation(compose.desktop.uiTestJUnit4)
|
||||||
implementation(compose.desktop.currentOs)
|
implementation(compose.desktop.currentOs)
|
||||||
|
|||||||
@@ -56,14 +56,16 @@ class TripletClue<C : ItemClass<C>>(val a: Item<C>, val b: Item<C>, val c: Item<
|
|||||||
val ib = grid.indexOf(bType)
|
val ib = grid.indexOf(bType)
|
||||||
val ic = grid.indexOf(cType)
|
val ic = grid.indexOf(cType)
|
||||||
|
|
||||||
|
if (ib == 0 || ib == grid.size) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
if (ia == -1 && ic == -1) {
|
if (ia == -1 && ic == -1) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ia != -1 && ic != -1) {
|
if (ia != -1 && ic != -1) {
|
||||||
if (ia + 2 == ic || ia == ic + 2) {
|
return !(ia + 2 == ic || ia == ic + 2)
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNeighbourRuleViolated(ia, ib) || isNeighbourRuleViolated(ib, ic)) {
|
if (isNeighbourRuleViolated(ia, ib) || isNeighbourRuleViolated(ib, ic)) {
|
||||||
|
|||||||
25
composeApp/src/commonTest/kotlin/domain/ClueTest.kt
Normal file
25
composeApp/src/commonTest/kotlin/domain/ClueTest.kt
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package domain
|
||||||
|
|
||||||
|
abstract class ClueTest {
|
||||||
|
protected val size = 6
|
||||||
|
|
||||||
|
protected fun createGrid(selection: (Item<ItemClass<*>>) -> Item<ItemClass<*>>? = { it }) = Grid(
|
||||||
|
ItemClass.randomClasses(size)
|
||||||
|
.map {
|
||||||
|
it.randomItems(size).map { item -> Item(item) }
|
||||||
|
}
|
||||||
|
.map { row ->
|
||||||
|
GameRow(
|
||||||
|
category = row.first().itemType.companion,
|
||||||
|
options = row,
|
||||||
|
cells = row.map {
|
||||||
|
GameCell(
|
||||||
|
selection = selection(it),
|
||||||
|
solution = it,
|
||||||
|
options = mutableListOf()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,36 +1,94 @@
|
|||||||
package domain
|
package domain
|
||||||
|
|
||||||
import ch.tutteli.atrium.api.fluent.en_GB.feature
|
|
||||||
import ch.tutteli.atrium.api.fluent.en_GB.size
|
|
||||||
import ch.tutteli.atrium.api.fluent.en_GB.toBeLessThan
|
|
||||||
import ch.tutteli.atrium.api.fluent.en_GB.toEqual
|
import ch.tutteli.atrium.api.fluent.en_GB.toEqual
|
||||||
import ch.tutteli.atrium.api.fluent.en_GB.toHaveSize
|
|
||||||
import ch.tutteli.atrium.api.verbs.expect
|
import ch.tutteli.atrium.api.verbs.expect
|
||||||
import domain.Item
|
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
|
|
||||||
class NeighbourClueTest {
|
class NeighbourClueTest : ClueTest() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `ensure actual neighbours are valid`() {
|
fun `ensure actual neighbours are valid`() {
|
||||||
val size = 5
|
val grid = createGrid()
|
||||||
val grid = ItemClass.randomClasses(size)
|
for (ia in 0 until size) {
|
||||||
.map {
|
for (ib in 0 until size) {
|
||||||
it.randomItems(size).map { item -> Item(item) }
|
for (j in 1 until size) {
|
||||||
}
|
val a = grid[ia][j - 1]
|
||||||
.map { row ->
|
val b = grid[ib][j]
|
||||||
GameRow(
|
|
||||||
category = row.first().itemType.companion,
|
|
||||||
options = row,
|
|
||||||
cells = row.map {
|
|
||||||
GameCell(
|
|
||||||
selection = it,
|
|
||||||
solution = it,
|
|
||||||
options = mutableListOf()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
NeighbourClue(Item(Animals.ANT), Item(Profession.ASTRONAUT))
|
expect(NeighbourClue(a.solution, b.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(false)
|
||||||
|
expect(NeighbourClue(b.solution, a.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `ensure non-neighbours are invalid`() {
|
||||||
|
val grid = createGrid()
|
||||||
|
for (ia in 0 until size) {
|
||||||
|
for (ib in 0 until size) {
|
||||||
|
for (ja in 0 until size) {
|
||||||
|
for (jb in 0 until size) {
|
||||||
|
if (ja == jb + 1 || ja == jb - 1) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val a = grid[ia][ja]
|
||||||
|
val b = grid[ib][jb]
|
||||||
|
|
||||||
|
expect(NeighbourClue(a.solution, b.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(true)
|
||||||
|
expect(NeighbourClue(b.solution, a.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `ensure grid with one neighbour not set is considered valid`() {
|
||||||
|
val grid = createGrid()
|
||||||
|
for (ia in 0 until size) {
|
||||||
|
for (ib in 0 until size) {
|
||||||
|
for (j in 1 until size) {
|
||||||
|
val a = grid[ia][j - 1]
|
||||||
|
val b = grid[ib][j]
|
||||||
|
|
||||||
|
a.selection = null
|
||||||
|
b.selection = b.solution
|
||||||
|
|
||||||
|
expect(NeighbourClue(a.solution, b.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(false)
|
||||||
|
expect(NeighbourClue(b.solution, a.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(false)
|
||||||
|
|
||||||
|
a.selection = a.solution
|
||||||
|
b.selection = null
|
||||||
|
|
||||||
|
expect(NeighbourClue(a.solution, b.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(false)
|
||||||
|
expect(NeighbourClue(b.solution, a.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `ensure grid with a and c more than one cell between is not considered valid`() {
|
||||||
|
val grid = createGrid { null }
|
||||||
|
val a = grid[2][1]
|
||||||
|
val b = grid[0][2]
|
||||||
|
|
||||||
|
a.selection = a.solution
|
||||||
|
grid[0][3].selection = b.solution
|
||||||
|
|
||||||
|
expect(NeighbourClue(a.solution, b.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(true)
|
||||||
|
expect(NeighbourClue(b.solution, a.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(true)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
28
composeApp/src/commonTest/kotlin/domain/OrderClueTest.kt
Normal file
28
composeApp/src/commonTest/kotlin/domain/OrderClueTest.kt
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package domain
|
||||||
|
|
||||||
|
import ch.tutteli.atrium.api.fluent.en_GB.toEqual
|
||||||
|
import ch.tutteli.atrium.api.verbs.expect
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
class OrderClueTest : ClueTest() {
|
||||||
|
@Test
|
||||||
|
fun `ensure items in correct order are valid`() {
|
||||||
|
val grid = createGrid()
|
||||||
|
for (ia in 0 until size) {
|
||||||
|
for (ib in 0 until size) {
|
||||||
|
for (ic in 0 until size) {
|
||||||
|
for (ja in 0 until size - 1) {
|
||||||
|
for (jb in ja + 1 until size) {
|
||||||
|
val a = grid[ia][ja]
|
||||||
|
val b = grid[ib][jb]
|
||||||
|
|
||||||
|
expect(OrderClue(a.solution, b.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
46
composeApp/src/commonTest/kotlin/domain/TripletClueTest.kt
Normal file
46
composeApp/src/commonTest/kotlin/domain/TripletClueTest.kt
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package domain
|
||||||
|
|
||||||
|
import ch.tutteli.atrium.api.fluent.en_GB.toEqual
|
||||||
|
import ch.tutteli.atrium.api.verbs.expect
|
||||||
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
class TripletClueTest : ClueTest() {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `ensure actual triplets are valid`() {
|
||||||
|
val grid = createGrid()
|
||||||
|
for (ia in 0 until size) {
|
||||||
|
for (ib in 0 until size) {
|
||||||
|
for (ic in 0 until size) {
|
||||||
|
for (j in 2 until size) {
|
||||||
|
val a = grid[ia][j - 2]
|
||||||
|
val b = grid[ib][j - 1]
|
||||||
|
val c = grid[ic][j]
|
||||||
|
|
||||||
|
expect(TripletClue(a.solution, b.solution, c.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(false)
|
||||||
|
expect(TripletClue(a.solution, b.solution, c.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `ensure grid with a and c more than one cell between is not considered valid`() {
|
||||||
|
val grid = createGrid { null }
|
||||||
|
val a = grid[2][1]
|
||||||
|
val b = grid[0][2]
|
||||||
|
val c = grid[1][3]
|
||||||
|
|
||||||
|
a.selection = a.solution
|
||||||
|
grid[1][4].selection = c.solution
|
||||||
|
|
||||||
|
expect(TripletClue(a.solution, b.solution, c.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(true)
|
||||||
|
expect(TripletClue(a.solution, b.solution, c.solution).isRuleViolated(grid))
|
||||||
|
.toEqual(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,11 +9,12 @@ compose-plugin = "1.6.11"
|
|||||||
kotlin = "2.0.0"
|
kotlin = "2.0.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
atrium = { module = "ch.tutteli.atrium:atrium-fluent", version = "1.2.0" }
|
|
||||||
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
|
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
|
||||||
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
|
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
|
||||||
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
|
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
|
||||||
compose-ui-text-googlefonts = { module = "androidx.compose.ui:ui-text-google-fonts", version.ref = "compose" }
|
compose-ui-text-googlefonts = { module = "androidx.compose.ui:ui-text-google-fonts", version.ref = "compose" }
|
||||||
|
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||||
|
atrium = { module = "ch.tutteli.atrium:atrium-fluent", version = "1.2.0" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
androidApplication = { id = "com.android.application", version.ref = "agp" }
|
androidApplication = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|||||||
Reference in New Issue
Block a user