From 054d229b979394d9ae687f016ce8fe675f41643c Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Sun, 12 Oct 2025 16:19:02 +0200 Subject: [PATCH] Add test for clue parser --- .../kotlin/ch/dissem/yaep/domain/clues.kt | 2 +- .../ch/dissem/yaep/domain/ClueParserTest.kt | 88 +++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 domain/src/commonTest/kotlin/ch/dissem/yaep/domain/ClueParserTest.kt diff --git a/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/clues.kt b/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/clues.kt index b1c0e88..24e1d59 100644 --- a/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/clues.kt +++ b/domain/src/commonMain/kotlin/ch/dissem/yaep/domain/clues.kt @@ -438,7 +438,7 @@ class PositionClue>(val item: Item, val index: Int) : Clue() line: String, mapper: (ItemClass<*>) -> Item ): Clue? { - val regex = Regex("^(?:\\* )?(?[A-Z_]+) is at position (?\\d)$") + val regex = Regex("^(?:\\* )?(?[A-Z_]+) is at position (?\\d+)$") val matchResult = regex.matchEntire(line) ?: return null val type = ItemClass.parse(matchResult.groups["type"]!!.value) diff --git a/domain/src/commonTest/kotlin/ch/dissem/yaep/domain/ClueParserTest.kt b/domain/src/commonTest/kotlin/ch/dissem/yaep/domain/ClueParserTest.kt new file mode 100644 index 0000000..1f4cdda --- /dev/null +++ b/domain/src/commonTest/kotlin/ch/dissem/yaep/domain/ClueParserTest.kt @@ -0,0 +1,88 @@ +package ch.dissem.yaep.domain + +import ch.dissem.yaep.domain.Animal.DOG +import ch.dissem.yaep.domain.Animal.SNAIL +import ch.dissem.yaep.domain.Profession.ASTRONAUT +import ch.tutteli.atrium.api.fluent.en_GB.message +import ch.tutteli.atrium.api.fluent.en_GB.toBeAnInstanceOf +import ch.tutteli.atrium.api.fluent.en_GB.toContain +import ch.tutteli.atrium.api.fluent.en_GB.toEqual +import ch.tutteli.atrium.api.fluent.en_GB.toThrow +import ch.tutteli.atrium.api.verbs.expect +import kotlin.test.Test + +class ClueParserTest { + val mapper = { itemClass: ItemClass<*> -> Item(itemClass) } + + @Test + fun `ensure parser throws exception when line isn't recognized`() { + expect { + Clue.parse("dummy clue", mapper) + }.toThrow { + message { + toContain("dummy clue") + } + } + } + + @Test + fun `ensure neighbour clue can be parsed`() { + val clueString = "SNAIL is next to DOG" + val clue = Clue.parse(clueString, mapper) + expect(clue).toBeAnInstanceOf>() + expect(clue.toString()).toEqual(clueString) + + val neighbourClue = clue as NeighbourClue<*, *> + expect(neighbourClue.a.itemType).toEqual(SNAIL) + expect(neighbourClue.b.itemType).toEqual(DOG) + } + + @Test + fun `expect order clue can be parsed`() { + val clueString = "ASTRONAUT is left of SNAIL" + val clue = Clue.parse(clueString, mapper) + expect(clue).toBeAnInstanceOf>() + expect(clue.toString()).toEqual(clueString) + + val orderClue = clue as OrderClue<*, *> + expect(orderClue.left.itemType).toEqual(ASTRONAUT) + expect(orderClue.right.itemType).toEqual(SNAIL) + } + + @Test + fun `expect triplet clue can be parsed`() { + val clueString = "SNAIL is between the neighbours ASTRONAUT and DOG to both sides" + val clue = Clue.parse(clueString, mapper) + expect(clue).toBeAnInstanceOf>() + expect(clue.toString()).toEqual(clueString) + + val tripletClue = clue as TripletClue<*, *, *> + expect(tripletClue.a.itemType).toEqual(ASTRONAUT) + expect(tripletClue.b.itemType).toEqual(SNAIL) + expect(tripletClue.c.itemType).toEqual(DOG) + } + + @Test + fun `expect same column clue can be parsed`() { + val clueString = "ASTRONAUT and SNAIL are in the same column" + val clue = Clue.parse(clueString, mapper) + expect(clue).toBeAnInstanceOf>() + expect(clue.toString()).toEqual(clueString) + + val sameColumnClue = clue as SameColumnClue<*, *> + expect(sameColumnClue.a.itemType).toEqual(ASTRONAUT) + expect(sameColumnClue.b.itemType).toEqual(SNAIL) + } + + @Test + fun `expect position clue can be parsed`() { + val clueString = "ASTRONAUT is at position 42" + val clue = Clue.parse(clueString, mapper) + expect(clue).toBeAnInstanceOf>() + expect(clue.toString()).toEqual(clueString) + + val positionClue = clue as PositionClue<*> + expect(positionClue.item.itemType).toEqual(ASTRONAUT) + expect(positionClue.index).toEqual(42) + } +} \ No newline at end of file