fix: consolidate essence formatting into single shared function (Closes #80) (#122)

This commit was merged in pull request #122.
This commit is contained in:
2026-04-04 22:28:55 +02:00
parent d823c9b507
commit ca0e17c89d
4 changed files with 78 additions and 21 deletions
@@ -11,6 +11,7 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import org.shahondin1624.lib.components.TestTags
import org.shahondin1624.lib.functions.formatEssence
import org.shahondin1624.model.characterdata.CharacterData
import org.shahondin1624.model.characterdata.Metatype
@@ -31,7 +32,7 @@ fun CharacterDataEditDialog(
var metatype by remember { mutableStateOf(characterData.metatype) }
var ageText by remember { mutableStateOf(characterData.age.toString()) }
var nuyenText by remember { mutableStateOf(characterData.nuyen.toString()) }
var essenceText by remember { mutableStateOf(formatEssenceForEdit(characterData.essence)) }
var essenceText by remember { mutableStateOf(formatEssence(characterData.essence)) }
var totalKarmaText by remember { mutableStateOf(characterData.totalKarma.toString()) }
var currentKarmaText by remember { mutableStateOf(characterData.currentKarma.toString()) }
@@ -229,12 +230,3 @@ fun CharacterDataEditDialog(
}
)
}
/**
* Format essence float for editing, showing one decimal place.
*/
private fun formatEssenceForEdit(essence: Float): String {
val wholePart = essence.toInt()
val decimalPart = ((essence - wholePart) * 10 + 0.5f).toInt()
return "$wholePart.$decimalPart"
}
@@ -12,20 +12,10 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import org.shahondin1624.lib.components.TestTags
import org.shahondin1624.lib.components.UiConstants
import org.shahondin1624.lib.functions.formatEssence
import org.shahondin1624.model.characterdata.CharacterData
import org.shahondin1624.theme.LocalWindowSizeClass
import org.shahondin1624.theme.WindowSizeClass
import kotlin.math.roundToInt
/**
* Formats a float to one decimal place without platform-specific String.format.
*/
private fun formatEssence(value: Float): String {
val rounded = (value * 10).roundToInt() / 10.0
val intPart = rounded.toInt()
val decPart = ((rounded - intPart) * 10).roundToInt()
return "$intPart.$decPart"
}
/**
* Displays resource trackers: Karma (current/total), Nuyen, Essence, and Edge.
@@ -0,0 +1,16 @@
package org.shahondin1624.lib.functions
import kotlin.math.roundToInt
/**
* Formats a float to one decimal place without platform-specific String.format.
* Uses integer rounding to avoid floating-point precision artifacts.
*
* Examples: 5.7f -> "5.7", 6.0f -> "6.0", 0.0f -> "0.0"
*/
fun formatEssence(value: Float): String {
val rounded = (value * 10).roundToInt() / 10.0
val intPart = rounded.toInt()
val decPart = ((rounded - intPart) * 10).roundToInt()
return "$intPart.$decPart"
}
@@ -0,0 +1,59 @@
package org.shahondin1624
import org.shahondin1624.lib.functions.formatEssence
import kotlin.test.Test
import kotlin.test.assertEquals
class FormatEssenceTest {
@Test
fun formatsWholeNumber() {
assertEquals("6.0", formatEssence(6.0f))
}
@Test
fun formatsZero() {
assertEquals("0.0", formatEssence(0.0f))
}
@Test
fun formatsTypicalEssenceValue() {
assertEquals("5.7", formatEssence(5.7f))
}
@Test
fun formatsOneDecimalPlace() {
assertEquals("3.5", formatEssence(3.5f))
}
@Test
fun roundsFloatingPointPrecisionArtifacts() {
// 5.7f may be stored as 5.6999998 internally
assertEquals("5.7", formatEssence(5.6999998f))
}
@Test
fun formatsSmallFractionalValue() {
assertEquals("0.1", formatEssence(0.1f))
}
@Test
fun formatsLargeFractionalValue() {
assertEquals("5.9", formatEssence(5.9f))
}
@Test
fun roundsUpCorrectly() {
assertEquals("2.3", formatEssence(2.25f))
}
@Test
fun roundsDownCorrectly() {
assertEquals("2.2", formatEssence(2.24f))
}
@Test
fun formatsMaxEssence() {
assertEquals("6.0", formatEssence(6.0f))
}
}