Updated on 2026-08-14
This commit is contained in:
parent
c1e1458f3f
commit
0de667c1d1
5 changed files with 94 additions and 10 deletions
|
|
@ -143,7 +143,8 @@ fun BigDecimalCryptoFormatStyled.defaultAmount(spanStyleReference: SpanStyleRefe
|
|||
val formattedAmount = formatter.format(value)
|
||||
|
||||
val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.decimalSeparator
|
||||
val separatorIndex = decimalSeparator?.let { formattedAmount.indexOf(it) } ?: formattedAmount.length
|
||||
val separatorIndex = decimalSeparator?.let { formattedAmount.indexOf(it).takeIf { i -> i >= 0 } }
|
||||
?: formattedAmount.length
|
||||
|
||||
combinedReference(
|
||||
stringReference(formattedAmount.take(separatorIndex)),
|
||||
|
|
@ -165,8 +166,9 @@ fun BigDecimalCryptoFormatStyled.defaultAmount(spanStyleReference: SpanStyleRefe
|
|||
cryptoCurrencySymbol = symbol,
|
||||
)
|
||||
|
||||
val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.decimalSeparator
|
||||
val separatorIndex = decimalSeparator?.let { formattedAmount.indexOf(it) } ?: formattedAmount.length
|
||||
val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.monetaryDecimalSeparator
|
||||
val separatorIndex = decimalSeparator?.let { formattedAmount.indexOf(it).takeIf { i -> i >= 0 } }
|
||||
?: formattedAmount.length
|
||||
|
||||
combinedReference(
|
||||
stringReference(formattedAmount.take(separatorIndex)),
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ fun BigDecimalFiatFormatStyled.defaultAmount(spanStyleReference: SpanStyleRefere
|
|||
value.zeroIfRoundsToZero(FIAT_MARKET_DEFAULT_DIGITS)
|
||||
}
|
||||
|
||||
val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.decimalSeparator
|
||||
val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.monetaryDecimalSeparator
|
||||
val currencySymbol = formatterCurrency.getSymbol(locale)
|
||||
val rawFormatted = formatter.format(formattingAmount)
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ private fun BigDecimalFiatFormatStyled.price(spanStyleReference: SpanStyleRefere
|
|||
roundingMode = RoundingMode.HALF_UP
|
||||
}
|
||||
|
||||
val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.decimalSeparator
|
||||
val decimalSeparator = (formatter as? DecimalFormat)?.decimalFormatSymbols?.monetaryDecimalSeparator
|
||||
val currencySymbol = formatterCurrency.getSymbol(locale)
|
||||
val rawFormatted = formatter.format(priceAmount)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
package com.tangem.core.ui.format.bigdecimal
|
||||
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.core.ui.extensions.SpanStyleReference
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.math.BigDecimal
|
||||
import java.text.DecimalFormat
|
||||
import java.text.NumberFormat
|
||||
import java.util.Locale
|
||||
|
||||
internal class BigDecimalCryptoFormatTest {
|
||||
|
|
@ -10,6 +15,7 @@ internal class BigDecimalCryptoFormatTest {
|
|||
private val testLocale = Locale.US
|
||||
private val testLocale2 = Locale.GERMANY
|
||||
private val symbol = "BTC"
|
||||
private val spanStyleStub = SpanStyleReference { SpanStyle() }
|
||||
|
||||
// === defaultAmount() ===
|
||||
|
||||
|
|
@ -125,6 +131,39 @@ internal class BigDecimalCryptoFormatTest {
|
|||
.isEqualTo("12,345,678.11".addSymbolWithSpaceLeft(symbol))
|
||||
}
|
||||
|
||||
// === defaultAmount() styled ===
|
||||
|
||||
@Test
|
||||
fun `GIVEN locale with distinct monetary separator WHEN styled defaultAmount THEN fraction split without crash`() {
|
||||
// Arrange
|
||||
// Regression: fr_CH plain separator is ',' but currency output uses '.' — indexOf(',') returned -1,
|
||||
// and formattedAmount.take(-1) threw IllegalArgumentException
|
||||
val swissLocale = Locale("fr", "CH")
|
||||
val symbols = (NumberFormat.getCurrencyInstance(swissLocale) as DecimalFormat).decimalFormatSymbols
|
||||
Truth.assertThat(symbols.monetaryDecimalSeparator).isNotEqualTo(symbols.decimalSeparator)
|
||||
|
||||
val testValue = BigDecimal("12.34")
|
||||
|
||||
// Act
|
||||
val formatted = testValue.formatStyled {
|
||||
cryptoStyled(
|
||||
symbol = symbol,
|
||||
decimals = 8,
|
||||
spanStyleReference = spanStyleStub,
|
||||
locale = swissLocale,
|
||||
)
|
||||
}
|
||||
|
||||
// Assert
|
||||
val refs = (formatted as TextReference.Combined).refs.data
|
||||
Truth.assertThat(refs).hasSize(2)
|
||||
Truth.assertThat((refs[0] as TextReference.Str).value).isEqualTo("12")
|
||||
|
||||
val fraction = refs[1] as TextReference.StyledStr
|
||||
Truth.assertThat(fraction.value).startsWith("${symbols.monetaryDecimalSeparator}34")
|
||||
Truth.assertThat(fraction.value).endsWith(symbol)
|
||||
}
|
||||
|
||||
// === shorted() ===
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
package com.tangem.core.ui.format.bigdecimal
|
||||
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.core.ui.extensions.SpanStyleReference
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.Arguments
|
||||
import org.junit.jupiter.params.provider.MethodSource
|
||||
import java.math.BigDecimal
|
||||
import java.text.DecimalFormat
|
||||
import java.text.NumberFormat
|
||||
import java.util.Locale
|
||||
|
||||
internal class BigDecimalFiatFormatTest {
|
||||
|
|
@ -16,6 +21,8 @@ internal class BigDecimalFiatFormatTest {
|
|||
val usdCurrencyCode = "USD"
|
||||
val usdSymbol = "$"
|
||||
|
||||
private val spanStyleStub = SpanStyleReference { SpanStyle() }
|
||||
|
||||
private fun String.addUsdSymbolLeft() = usdSymbol + this
|
||||
|
||||
// === defaultAmount() ===
|
||||
|
|
@ -132,6 +139,40 @@ internal class BigDecimalFiatFormatTest {
|
|||
.isEqualTo("-" + "0.01".addUsdSymbolLeft())
|
||||
}
|
||||
|
||||
// === defaultAmount() styled ===
|
||||
|
||||
@Test
|
||||
fun `GIVEN locale with distinct monetary separator WHEN styled defaultAmount THEN fraction split at monetary separator`() {
|
||||
// Arrange
|
||||
// fr_CH plain separator is ',' but currency output uses '.' — searching for the plain one
|
||||
// failed to split the amount into whole and styled fractional parts
|
||||
val swissLocale = Locale("fr", "CH")
|
||||
val symbols = (NumberFormat.getCurrencyInstance(swissLocale) as DecimalFormat).decimalFormatSymbols
|
||||
Truth.assertThat(symbols.monetaryDecimalSeparator).isNotEqualTo(symbols.decimalSeparator)
|
||||
|
||||
val testValue = BigDecimal("12.34")
|
||||
|
||||
// Act
|
||||
val formatted = testValue.formatStyled {
|
||||
fiat(
|
||||
fiatCurrencyCode = usdCurrencyCode,
|
||||
fiatCurrencySymbol = usdSymbol,
|
||||
spanStyleReference = spanStyleStub,
|
||||
locale = swissLocale,
|
||||
)
|
||||
}
|
||||
|
||||
// Assert
|
||||
val refs = (formatted as TextReference.Combined).refs.data
|
||||
Truth.assertThat(refs).hasSize(3)
|
||||
Truth.assertThat(refs[0]).isEqualTo(TextReference.EMPTY)
|
||||
Truth.assertThat((refs[1] as TextReference.Str).value).isEqualTo("12")
|
||||
|
||||
val fraction = refs[2] as TextReference.StyledStr
|
||||
Truth.assertThat(fraction.value).startsWith("${symbols.monetaryDecimalSeparator}34")
|
||||
Truth.assertThat(fraction.value).endsWith(usdSymbol)
|
||||
}
|
||||
|
||||
// === approximateAmount() ===
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -2,17 +2,19 @@
|
|||
|
||||
Generates Kotlin (Jetpack Compose) source files from design tokens and icons defined in the `ds-tokens` git submodule.
|
||||
|
||||
## Making sure submodule is at the pinned commit
|
||||
|
||||
***For the most cases*** (a fresh checkout, or making sure the submodule is at the pinned commit), use:
|
||||
```bash
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
## Updating tokens
|
||||
|
||||
> **Note:** You only need `git submodule update --remote` when you want to pull **new** design tokens
|
||||
> from the remote `ds-tokens` repository. If you're just regenerating Kotlin from the tokens already
|
||||
> checked out (e.g. changing the generation script), **skip step 1** — don't run it without the need,
|
||||
> as it moves the submodule pointer to the latest remote commit and pulls in unrelated token changes.
|
||||
>
|
||||
> For all other cases (a fresh checkout, or making sure the submodule is at the pinned commit), use:
|
||||
> ```bash
|
||||
> git submodule update --init --recursive
|
||||
> ```
|
||||
> This checks out the submodule at the commit already recorded in the repo, without pulling anything new.
|
||||
|
||||
1. *(Only if you need newer tokens)* Update the `ds-tokens` submodule to the latest commit:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue