Updated on 2026-08-14
This commit is contained in:
parent
4383291669
commit
fec7986d80
16 changed files with 1322 additions and 587 deletions
|
|
@ -22,7 +22,7 @@ class AmountVisualTransformation(
|
|||
private val symbol: String? = null,
|
||||
private val currencyCode: String? = null,
|
||||
private val decimalFormat: DecimalFormat = DecimalFormat(),
|
||||
private val symbolColor: Color,
|
||||
private val symbolColor: Color = Color.Unspecified,
|
||||
) : VisualTransformation {
|
||||
|
||||
override fun filter(text: AnnotatedString): TransformedText {
|
||||
|
|
@ -31,21 +31,27 @@ class AmountVisualTransformation(
|
|||
decimals,
|
||||
)
|
||||
formattedAmount = formattedAmount.ifEmpty { decimalFormat.defaultFormat() }
|
||||
val formattedText = if (formattedAmount.isNotEmpty() && symbol != null) {
|
||||
val formattedText = if (formattedAmount.isNotEmpty()) {
|
||||
buildAnnotatedString {
|
||||
if (currencyCode != null) {
|
||||
append(
|
||||
formatFiatEditableAmount(
|
||||
fiatAmount = formattedAmount,
|
||||
fiatCurrencyCode = currencyCode,
|
||||
fiatCurrencySymbol = symbol,
|
||||
fiatCurrencySymbolColor = symbolColor,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
append(formattedAmount)
|
||||
append(CURRENCY_SPACE)
|
||||
appendColored(symbol, symbolColor)
|
||||
when {
|
||||
currencyCode != null && symbol != null -> {
|
||||
append(
|
||||
formatFiatEditableAmount(
|
||||
fiatAmount = formattedAmount,
|
||||
fiatCurrencyCode = currencyCode,
|
||||
fiatCurrencySymbol = symbol,
|
||||
fiatCurrencySymbolColor = symbolColor,
|
||||
),
|
||||
)
|
||||
}
|
||||
symbol != null -> {
|
||||
append(formattedAmount)
|
||||
append(CURRENCY_SPACE)
|
||||
appendColored(symbol, symbolColor)
|
||||
}
|
||||
else -> {
|
||||
append(formattedAmount)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
package com.tangem.core.ui.components.fields.visualtransformations
|
||||
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.core.ui.format.bigdecimal.BigDecimalFormatConstants.CURRENCY_SPACE
|
||||
import com.tangem.core.ui.utils.defaultFormat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import java.text.DecimalFormat
|
||||
import java.text.DecimalFormatSymbols
|
||||
import java.util.Locale
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
internal class AmountVisualTransformationTest {
|
||||
|
||||
// Fixed US-style symbols so grouping (',') / decimal ('.') separators are deterministic across machines.
|
||||
private fun usFormat(): DecimalFormat = DecimalFormat().apply {
|
||||
decimalFormatSymbols = DecimalFormatSymbols(Locale.US)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN symbol and no currency code WHEN filter THEN amount is followed by the symbol`() {
|
||||
// Arrange
|
||||
val sut = AmountVisualTransformation(decimals = 2, symbol = "ETH", decimalFormat = usFormat())
|
||||
|
||||
// Act
|
||||
val result = sut.filter(AnnotatedString("1234.5"))
|
||||
|
||||
// Assert — "1,234.5" + non-breaking space + "ETH"
|
||||
assertThat(result.text.text).isEqualTo("1,234.5${CURRENCY_SPACE}ETH")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN no symbol and no currency code WHEN filter THEN only the formatted amount is shown`() {
|
||||
// Arrange
|
||||
val sut = AmountVisualTransformation(decimals = 2, decimalFormat = usFormat())
|
||||
|
||||
// Act
|
||||
val result = sut.filter(AnnotatedString("1234.5"))
|
||||
|
||||
// Assert
|
||||
assertThat(result.text.text).isEqualTo("1,234.5")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN empty input WHEN filter THEN default formatted value is shown with symbol`() {
|
||||
// Arrange
|
||||
val format = usFormat()
|
||||
val sut = AmountVisualTransformation(decimals = 2, symbol = "ETH", decimalFormat = format)
|
||||
|
||||
// Act
|
||||
val result = sut.filter(AnnotatedString(""))
|
||||
|
||||
// Assert — empty input collapses to the default format, then the symbol branch appends the symbol
|
||||
assertThat(result.text.text).isEqualTo("${format.defaultFormat()}${CURRENCY_SPACE}ETH")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN grouping separators WHEN transformedToOriginal THEN separators are subtracted from offset`() {
|
||||
// Arrange
|
||||
val sut = AmountVisualTransformation(decimals = 2, symbol = "ETH", decimalFormat = usFormat())
|
||||
val result = sut.filter(AnnotatedString("1234"))
|
||||
// transformed text is "1,234 ETH" (one grouping separator before offset 5)
|
||||
|
||||
// Act — caret at the end of the digits in transformed space ("1,234" -> index 5)
|
||||
val original = result.offsetMapping.transformedToOriginal(5)
|
||||
|
||||
// Assert — minus the one grouping separator => 4 original digits
|
||||
assertThat(original).isEqualTo(4)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN grouping separators WHEN originalToTransformed THEN offset accounts for inserted separators`() {
|
||||
// Arrange
|
||||
val sut = AmountVisualTransformation(decimals = 2, symbol = "ETH", decimalFormat = usFormat())
|
||||
val result = sut.filter(AnnotatedString("1234"))
|
||||
|
||||
// Act — original caret after all 4 digits
|
||||
val transformed = result.offsetMapping.originalToTransformed(4)
|
||||
|
||||
// Assert — coerced to just before the currency symbol; 4 digits + 1 separator = 5
|
||||
assertThat(transformed).isEqualTo(5)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue