From d4791514cb5497b2d24608d065cbe1192bd2ce03 Mon Sep 17 00:00:00 2001 From: Olivier Perez Date: Tue, 10 Oct 2023 10:31:37 +0200 Subject: [PATCH 1/5] fix(ratings): Rewrite tests to make them easier to maintain --- .../vitamin/compose/ratings/IconTest.kt | 66 +++++++------------ 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt b/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt index 67323049..45dab462 100644 --- a/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt +++ b/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt @@ -1,72 +1,54 @@ package com.decathlon.vitamin.compose.ratings -import org.junit.Assert.* +import org.junit.Assert.assertEquals import org.junit.Test class IconTest { @Test fun integer() { - val number = 3.0f - - assertEquals(Icon.Fill, Icon.get(0, number)) - assertEquals(Icon.Fill, Icon.get(1, number)) - assertEquals(Icon.Fill, Icon.get(2, number)) - assertEquals(Icon.Empty, Icon.get(3, number)) - assertEquals(Icon.Empty, Icon.get(4, number)) + assertStars(number = 3.0f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Empty, Icon.Empty) } @Test fun close_above_int() { - val number = 3.2f - - assertEquals(Icon.Fill, Icon.get(0, number)) - assertEquals(Icon.Fill, Icon.get(1, number)) - assertEquals(Icon.Fill, Icon.get(2, number)) - assertEquals(Icon.Empty, Icon.get(3, number)) - assertEquals(Icon.Empty, Icon.get(4, number)) + assertStars(number = 3.2f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Empty, Icon.Empty) } @Test fun close_below_half() { - val number = 3.4f - - assertEquals(Icon.Fill, Icon.get(0, number)) - assertEquals(Icon.Fill, Icon.get(1, number)) - assertEquals(Icon.Fill, Icon.get(2, number)) - assertEquals(Icon.Half, Icon.get(3, number)) - assertEquals(Icon.Empty, Icon.get(4, number)) + assertStars(number = 3.4f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Half, Icon.Empty) } @Test fun strictly_half() { - val number = 3.5f - - assertEquals(Icon.Fill, Icon.get(0, number)) - assertEquals(Icon.Fill, Icon.get(1, number)) - assertEquals(Icon.Fill, Icon.get(2, number)) - assertEquals(Icon.Half, Icon.get(3, number)) - assertEquals(Icon.Empty, Icon.get(4, number)) + assertStars(number = 3.5f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Half, Icon.Empty) } @Test fun close_above_half() { - val number = 3.6f - - assertEquals(Icon.Fill, Icon.get(0, number)) - assertEquals(Icon.Fill, Icon.get(1, number)) - assertEquals(Icon.Fill, Icon.get(2, number)) - assertEquals(Icon.Half, Icon.get(3, number)) - assertEquals(Icon.Empty, Icon.get(4, number)) + assertStars(number = 3.6f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Half, Icon.Empty) } @Test fun close_below_int() { - val number = 3.8f + assertStars(number = 3.8f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Empty) + } - assertEquals(Icon.Fill, Icon.get(0, number)) - assertEquals(Icon.Fill, Icon.get(1, number)) - assertEquals(Icon.Fill, Icon.get(2, number)) - assertEquals(Icon.Fill, Icon.get(3, number)) - assertEquals(Icon.Empty, Icon.get(4, number)) + /** + * Asserts that a given [number] produces an expected list of icons. + */ + private fun assertStars( + number: Float, + icon1: Icon, + icon2: Icon, + icon3: Icon, + icon4: Icon, + icon5: Icon + ) { + assertEquals("1st star of $number should be ${icon1::class.simpleName}", icon1, Icon.get(0, number)) + assertEquals("2nd star of $number should be ${icon2::class.simpleName}", icon2, Icon.get(1, number)) + assertEquals("3rd star of $number should be ${icon3::class.simpleName}", icon3, Icon.get(2, number)) + assertEquals("4th star of $number should be ${icon4::class.simpleName}", icon4, Icon.get(3, number)) + assertEquals("5th star of $number should be ${icon5::class.simpleName}", icon5, Icon.get(4, number)) } } From 00d18ee83618fbfa1c07dc9344456da601aacc80 Mon Sep 17 00:00:00 2001 From: Olivier Perez Date: Tue, 10 Oct 2023 10:34:44 +0200 Subject: [PATCH 2/5] fix(ratings): Add test for 3.755 showing algorithm flaws --- .../kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt b/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt index 45dab462..48979e05 100644 --- a/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt +++ b/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt @@ -34,6 +34,11 @@ class IconTest { assertStars(number = 3.8f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Empty) } + @Test + fun close_edge_case_below_int() { + assertStars(number = 3.751f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Empty) + } + /** * Asserts that a given [number] produces an expected list of icons. */ From 4a72cbe8141dc99eaccf0f56e48b3fc12a0c1ab4 Mon Sep 17 00:00:00 2001 From: Olivier Perez Date: Tue, 10 Oct 2023 10:36:00 +0200 Subject: [PATCH 3/5] fix(ratings): Fix the edge case --- .../java/com/decathlon/vitamin/compose/ratings/Icon.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/ratings/src/main/java/com/decathlon/vitamin/compose/ratings/Icon.kt b/ratings/src/main/java/com/decathlon/vitamin/compose/ratings/Icon.kt index 668e0d8e..84ca88e0 100644 --- a/ratings/src/main/java/com/decathlon/vitamin/compose/ratings/Icon.kt +++ b/ratings/src/main/java/com/decathlon/vitamin/compose/ratings/Icon.kt @@ -15,11 +15,8 @@ internal sealed class Icon(val imageVector: ImageVector) { object Fill : Icon(imageVector = VitaminIcons.Fill.Star) companion object { - private const val EMPTY_LOWER_BOUND = 0f - private const val EMPTY_UPPER_BOUND = 0.24f private const val HALF_LOWER_BOUND = 0.25f private const val HALF_UPPER_BOUND = 0.75f - private const val FILL_LOWER_BOUND = 0.76f private const val FILL_UPPER_BOUND = 1f fun get(index: Int, number: Float): Icon { @@ -27,9 +24,9 @@ internal sealed class Icon(val imageVector: ImageVector) { val decimal = number - index return when { index < floor -> Fill - decimal in EMPTY_LOWER_BOUND..EMPTY_UPPER_BOUND -> Empty - decimal in HALF_LOWER_BOUND..HALF_UPPER_BOUND -> Half - decimal in FILL_LOWER_BOUND..FILL_UPPER_BOUND -> Fill + decimal < HALF_LOWER_BOUND -> Empty + decimal <= HALF_UPPER_BOUND -> Half + decimal <= FILL_UPPER_BOUND -> Fill else -> Empty } } From 0e06ef3b01319581ca0646960bb1603f87e38bea Mon Sep 17 00:00:00 2001 From: Olivier Perez Date: Tue, 10 Oct 2023 14:49:18 +0200 Subject: [PATCH 4/5] fix(ratings): Add more tests --- .../com/decathlon/vitamin/compose/ratings/IconTest.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt b/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt index 48979e05..78246874 100644 --- a/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt +++ b/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt @@ -14,6 +14,11 @@ class IconTest { assertStars(number = 3.2f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Empty, Icon.Empty) } + @Test + fun lower_limit_of_half() { + assertStars(number = 3.25f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Half, Icon.Empty) + } + @Test fun close_below_half() { assertStars(number = 3.4f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Half, Icon.Empty) @@ -29,6 +34,11 @@ class IconTest { assertStars(number = 3.6f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Half, Icon.Empty) } + @Test + fun high_limit_of_half() { + assertStars(number = 3.75f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Half, Icon.Empty) + } + @Test fun close_below_int() { assertStars(number = 3.8f, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Fill, Icon.Empty) From f670a6cc94c6daf5fe38c1870a2312efeb4ffed5 Mon Sep 17 00:00:00 2001 From: ManonPolle Date: Tue, 10 Oct 2023 15:30:12 +0200 Subject: [PATCH 5/5] fix(ratings): Ignore LongParameterList warning on private test function --- .../kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt b/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt index 78246874..6240c241 100644 --- a/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt +++ b/ratings/src/test/kotlin/com/decathlon/vitamin/compose/ratings/IconTest.kt @@ -52,13 +52,14 @@ class IconTest { /** * Asserts that a given [number] produces an expected list of icons. */ + @Suppress("LongParameterList") private fun assertStars( number: Float, icon1: Icon, icon2: Icon, icon3: Icon, icon4: Icon, - icon5: Icon + icon5: Icon, ) { assertEquals("1st star of $number should be ${icon1::class.simpleName}", icon1, Icon.get(0, number)) assertEquals("2nd star of $number should be ${icon2::class.simpleName}", icon2, Icon.get(1, number))