From c26edb1cba551d14ca46175397b359e7cda2d1c2 Mon Sep 17 00:00:00 2001 From: Joshua Gleitze Date: Tue, 18 Feb 2020 18:13:18 +0200 Subject: [PATCH] feat: Word#flatMapParts & Word#partsInNotation --- src/main/kotlin/Word.kt | 15 +++++++++++++ src/test/kotlin/WordTest.kt | 43 +++++++++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/Word.kt b/src/main/kotlin/Word.kt index 2b7bb1d..0b28d04 100644 --- a/src/main/kotlin/Word.kt +++ b/src/main/kotlin/Word.kt @@ -28,6 +28,17 @@ class Word(val parts: Sequence) { */ fun mapParts(transform: (String) -> String) = Word(parts.map(transform)) + /** + * Creates a new word, with all its parts transformed by the provided [transform] function, which may return more than one new part for + * every existing part. + */ + fun flatMapParts(transform: (String) -> Sequence) = Word(parts.flatMap(transform)) + + /** + * Creates a new words, with all its parts parsed by the provided [notation]. Allows to parse words that use a combination of notations. + */ + fun partsFromNotation(notation: StringNotation) = Word(parts.flatMap { it.fromNotation(notation).parts }) + /** * Appends a part to this word. */ @@ -39,6 +50,10 @@ class Word(val parts: Sequence) { operator fun plus(word: Word) = Word(parts + word.parts) override fun toString() = "Word(${parts.joinToString { "\"$it\"" }})" + + override fun equals(other: Any?) = this === other || (other is Word && partsList == other.partsList) + + override fun hashCode() = partsList.hashCode() } /** diff --git a/src/test/kotlin/WordTest.kt b/src/test/kotlin/WordTest.kt index be1d88b..670e85d 100644 --- a/src/test/kotlin/WordTest.kt +++ b/src/test/kotlin/WordTest.kt @@ -3,10 +3,27 @@ package de.joshuagleitze.stringnotation import ch.tutteli.atrium.api.fluent.en_GB.asIterable import ch.tutteli.atrium.api.fluent.en_GB.containsExactly import ch.tutteli.atrium.api.fluent.en_GB.feature +import ch.tutteli.atrium.api.fluent.en_GB.notToBe +import ch.tutteli.atrium.api.fluent.en_GB.toBe import ch.tutteli.atrium.api.verbs.expect import org.junit.jupiter.api.Test class WordTest { + @Test + fun `implements #equals`() { + val aInstance = Word("a") + expect(aInstance).toBe(aInstance) + expect(aInstance).toBe(Word("a")) + expect(Word("a")).notToBe(Word("A")) + } + + @Test + fun `implements #hashCode`() { + expect(Word("a")) + .feature(Word::hashCode) + .toBe(Word("a").hashCode()) + } + @Test fun `exposes parts as list`() { expect(Word("with", "parts")).feature(Word::partsList).containsExactly("with", "parts") @@ -24,22 +41,34 @@ class WordTest { @Test fun `allows to add parts`() { expect((Word("with") + "more" + "parts")) - .feature(Word::partsList) - .containsExactly("with", "more", "parts") + .toBe(Word("with", "more", "parts")) } @Test fun `allows to add words`() { expect(Word("with") + Word("more", "parts")) - .feature(Word::partsList) - .containsExactly("with", "more", "parts") + .toBe(Word("with", "more", "parts")) } @Test - fun `allows to transform parts`() { + fun `allows to map parts`() { expect(Word("a", "b", "c")) .feature(Word::mapParts, String::toUpperCase) - .feature(Word::partsList) - .containsExactly("A", "B", "C"); + .toBe(Word("A", "B", "C")) + } + + @Test + fun `allows to flatMap parts`() { + expect(Word("a", "b")) + .feature(Word::flatMapParts) { it -> sequenceOf("${it}1", "${it}2") } + .toBe(Word("a1", "a2", "b1", "b2")) + } + + @Test + fun `allows to parse parts from a notation`() { + expect("these are words with UpperCamelCase") + .feature(String::fromNotation, NormalWords) + .feature(Word::partsFromNotation, UpperCamelCase) + .toBe(Word("these", "are", "words", "with", "upper", "camel", "case")) } }