mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-26 06:08:40 +01:00
intoduce-moneytext (#3447)
* feat: Introduce `MoneyText` and `CurrencySymbolText` Widgets * feat: add accessibility to `MoneyText`
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
import "package:cake_wallet/entities/balance_display_mode.dart";
|
||||
import "package:cake_wallet/entities/bitcoin_amount_display_mode.dart";
|
||||
import "package:cake_wallet/new-ui/widgets/money/currency_symbol_text.dart";
|
||||
import "package:cake_wallet/new-ui/widgets/money/money_settings_cubit.dart";
|
||||
import "package:cw_core/crypto_currency.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_bloc/flutter_bloc.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
|
||||
class FakeMoneySettingsCubit extends Cubit<MoneySettingsState> implements MoneySettingsCubit {
|
||||
FakeMoneySettingsCubit(super.initialState);
|
||||
|
||||
void setState(MoneySettingsState state) => emit(state);
|
||||
}
|
||||
|
||||
const _bitcoinMode = MoneySettingsState(
|
||||
bitcoinAmountDisplayMode: BitcoinAmountDisplayMode.bitcoin,
|
||||
displayMode: BalanceDisplayMode.fullBalance,
|
||||
);
|
||||
|
||||
const _satoshiMode = MoneySettingsState(
|
||||
bitcoinAmountDisplayMode: BitcoinAmountDisplayMode.satoshi,
|
||||
displayMode: BalanceDisplayMode.fullBalance,
|
||||
);
|
||||
|
||||
const _lnSatoshiMode = MoneySettingsState(
|
||||
bitcoinAmountDisplayMode: BitcoinAmountDisplayMode.satoshiForLightning,
|
||||
displayMode: BalanceDisplayMode.fullBalance,
|
||||
);
|
||||
|
||||
/// A non-BTC currency whose symbol exceeds the 8-char cap. `raw: -1` keeps it
|
||||
/// distinct from every real currency, so it never counts as BTC/BTCLN.
|
||||
const _longSymbol = CryptoCurrency(title: "SUPERLONGTOKEN", name: "superlongtoken", decimals: 8);
|
||||
|
||||
Future<FakeMoneySettingsCubit> _pump(
|
||||
WidgetTester tester,
|
||||
Widget child,
|
||||
MoneySettingsState state,
|
||||
) async {
|
||||
final cubit = FakeMoneySettingsCubit(state);
|
||||
addTearDown(cubit.close);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: BlocProvider<MoneySettingsCubit>.value(
|
||||
value: cubit,
|
||||
child: Scaffold(body: Center(child: child)),
|
||||
),
|
||||
),
|
||||
);
|
||||
return cubit;
|
||||
}
|
||||
|
||||
void main() {
|
||||
group("useBaseUnit == null (follows settings)", () {
|
||||
testWidgets("BTC in satoshi mode -> sats", (tester) async {
|
||||
await _pump(tester, const CurrencySymbolText(CryptoCurrency.btc), _satoshiMode);
|
||||
|
||||
expect(find.text("sats"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("BTC in bitcoin mode -> BTC", (tester) async {
|
||||
await _pump(tester, const CurrencySymbolText(CryptoCurrency.btc), _bitcoinMode);
|
||||
|
||||
expect(find.text("BTC"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("non-BTC currency ignores satoshi mode", (tester) async {
|
||||
await _pump(tester, const CurrencySymbolText(CryptoCurrency.xmr), _satoshiMode);
|
||||
|
||||
expect(find.text("XMR"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("BTCLN in LN-satoshi mode -> sats", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
const CurrencySymbolText(CryptoCurrency.btcln),
|
||||
_lnSatoshiMode,
|
||||
);
|
||||
|
||||
expect(find.text("sats"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("BTCLN in bitcoin mode -> BTC", (tester) async {
|
||||
await _pump(tester, const CurrencySymbolText(CryptoCurrency.btcln), _bitcoinMode);
|
||||
|
||||
// BTCLN's title/symbol is "BTC".
|
||||
expect(find.text("BTC"), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group("useBaseUnit == true (force base unit where supported)", () {
|
||||
testWidgets("BTC -> sats regardless of settings", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
const CurrencySymbolText(CryptoCurrency.btc, useBaseUnit: true),
|
||||
_bitcoinMode, // settings say bitcoin, but override wins
|
||||
);
|
||||
|
||||
expect(find.text("sats"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("BTCLN -> sats", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
const CurrencySymbolText(CryptoCurrency.btcln, useBaseUnit: true),
|
||||
_bitcoinMode,
|
||||
);
|
||||
|
||||
expect(find.text("sats"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("non-BTC currency keeps its symbol even when forced", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
const CurrencySymbolText(CryptoCurrency.xmr, useBaseUnit: true),
|
||||
_satoshiMode,
|
||||
);
|
||||
|
||||
expect(find.text("XMR"), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group("useBaseUnit == false (always the symbol)", () {
|
||||
testWidgets("BTC -> BTC even in satoshi mode", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
const CurrencySymbolText(CryptoCurrency.btc, useBaseUnit: false),
|
||||
_satoshiMode,
|
||||
);
|
||||
|
||||
expect(find.text("BTC"), findsOneWidget);
|
||||
expect(find.text("sats"), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets("BTCLN -> BTC even in LN-satoshi mode", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
const CurrencySymbolText(CryptoCurrency.btcln, useBaseUnit: false),
|
||||
_lnSatoshiMode,
|
||||
);
|
||||
|
||||
expect(find.text("BTC"), findsOneWidget);
|
||||
expect(find.text("sats"), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets("non-BTC currency -> symbol", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
const CurrencySymbolText(CryptoCurrency.xmr, useBaseUnit: false),
|
||||
_bitcoinMode,
|
||||
);
|
||||
|
||||
expect(find.text("XMR"), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group("symbol formatting", () {
|
||||
testWidgets("caps symbols longer than 8 characters", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
const CurrencySymbolText(_longSymbol, useBaseUnit: false),
|
||||
_bitcoinMode,
|
||||
);
|
||||
|
||||
// "SUPERLONGTOKEN" -> first 8 chars.
|
||||
expect(find.text("SUPERLON"), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group("rebuild on cubit state change", () {
|
||||
testWidgets("re-renders the symbol when settings change", (tester) async {
|
||||
final cubit = await _pump(
|
||||
tester,
|
||||
const CurrencySymbolText(CryptoCurrency.btc),
|
||||
_bitcoinMode,
|
||||
);
|
||||
expect(find.text("BTC"), findsOneWidget);
|
||||
|
||||
cubit.setState(_satoshiMode);
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text("BTC"), findsNothing);
|
||||
expect(find.text("sats"), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group("forwarding to the inner Text", () {
|
||||
testWidgets("passes through Text properties incl. semanticsIdentifier", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
const CurrencySymbolText(
|
||||
CryptoCurrency.btc,
|
||||
maxLines: 2,
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.fade,
|
||||
style: TextStyle(fontSize: 18),
|
||||
semanticsIdentifier: "currency-symbol",
|
||||
),
|
||||
_bitcoinMode,
|
||||
);
|
||||
|
||||
final text = tester.widget<Text>(
|
||||
find.descendant(of: find.byType(CurrencySymbolText), matching: find.byType(Text)),
|
||||
);
|
||||
|
||||
expect(text.maxLines, 2);
|
||||
expect(text.textAlign, TextAlign.center);
|
||||
expect(text.overflow, TextOverflow.fade);
|
||||
expect(text.style?.fontSize, 18);
|
||||
expect(text.semanticsIdentifier, "currency-symbol");
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
import "package:cake_wallet/entities/balance_display_mode.dart";
|
||||
import "package:cake_wallet/entities/bitcoin_amount_display_mode.dart";
|
||||
import "package:cake_wallet/new-ui/widgets/money/money_settings_cubit.dart";
|
||||
import "package:cake_wallet/new-ui/widgets/money/money_text.dart";
|
||||
import "package:cw_core/amount/money.dart";
|
||||
import "package:cw_core/crypto_currency.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_bloc/flutter_bloc.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
|
||||
class FakeMoneySettingsCubit extends Cubit<MoneySettingsState> implements MoneySettingsCubit {
|
||||
FakeMoneySettingsCubit(super.initialState);
|
||||
|
||||
void setState(MoneySettingsState state) => emit(state);
|
||||
}
|
||||
|
||||
/// Visible, BTC shown as bitcoin (not base unit).
|
||||
const _visibleBtc = MoneySettingsState(
|
||||
bitcoinAmountDisplayMode: BitcoinAmountDisplayMode.bitcoin,
|
||||
displayMode: BalanceDisplayMode.fullBalance,
|
||||
);
|
||||
|
||||
/// Hidden balance.
|
||||
const _hiddenBtc = MoneySettingsState(
|
||||
bitcoinAmountDisplayMode: BitcoinAmountDisplayMode.bitcoin,
|
||||
displayMode: BalanceDisplayMode.hiddenBalance,
|
||||
);
|
||||
|
||||
/// Visible, satoshi mode -> BTC/BTCLN use base unit.
|
||||
const _sats = MoneySettingsState(
|
||||
bitcoinAmountDisplayMode: BitcoinAmountDisplayMode.satoshi,
|
||||
displayMode: BalanceDisplayMode.fullBalance,
|
||||
);
|
||||
|
||||
/// Visible, LN-only satoshi mode -> only BTCLN uses base unit.
|
||||
const _lnSats = MoneySettingsState(
|
||||
bitcoinAmountDisplayMode: BitcoinAmountDisplayMode.satoshiForLightning,
|
||||
displayMode: BalanceDisplayMode.fullBalance,
|
||||
);
|
||||
|
||||
// --- Money fixtures --------------------------------------------------------
|
||||
final _btc012 = Money.fromInt(12345678, CryptoCurrency.btc); // 0.12345678 BTC
|
||||
final _btcTrailing = Money.fromInt(12000000, CryptoCurrency.btc); // 0.12 BTC
|
||||
final _btcGrouping = Money.fromInt(123450000000, CryptoCurrency.btc); // 1234.5 BTC
|
||||
final _xmrHalf = Money.fromInt(500000000000, CryptoCurrency.xmr); // 0.5 XMR
|
||||
final _btclnAmount = Money.fromInt(12345678, CryptoCurrency.btcln); // 0.12345678 BTC (LN)
|
||||
|
||||
const _hidden = "●●●●●●";
|
||||
|
||||
Future<FakeMoneySettingsCubit> _pump(
|
||||
WidgetTester tester,
|
||||
Widget child,
|
||||
MoneySettingsState state,
|
||||
) async {
|
||||
final cubit = FakeMoneySettingsCubit(state);
|
||||
addTearDown(cubit.close);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: BlocProvider<MoneySettingsCubit>.value(
|
||||
value: cubit,
|
||||
child: Scaffold(body: Center(child: child)),
|
||||
),
|
||||
),
|
||||
);
|
||||
return cubit;
|
||||
}
|
||||
|
||||
void main() {
|
||||
group("hidden amount", () {
|
||||
testWidgets("isHiddenAmount:true hides even when state is visible", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012, isHiddenAmount: true), _visibleBtc);
|
||||
|
||||
expect(find.text(_hidden), findsOneWidget);
|
||||
expect(find.text("0.12345678 BTC"), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets("isHiddenAmount:false overrides a hidden state", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012, isHiddenAmount: false), _hiddenBtc);
|
||||
|
||||
expect(find.text("0.12345678 BTC"), findsOneWidget);
|
||||
expect(find.text(_hidden), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets("isHiddenAmount:null falls back to state.isHidden (hidden)", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012), _hiddenBtc);
|
||||
|
||||
expect(find.text(_hidden), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("isHiddenAmount:null falls back to state.isHidden (visible)", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012), _visibleBtc);
|
||||
|
||||
expect(find.text("0.12345678 BTC"), findsOneWidget);
|
||||
expect(find.text(_hidden), findsNothing);
|
||||
});
|
||||
});
|
||||
|
||||
group("symbol vs precision", () {
|
||||
testWidgets("showSymbol:true appends the currency symbol", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012), _visibleBtc);
|
||||
|
||||
expect(find.text("0.12345678 BTC"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("showSymbol:false omits the currency symbol", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012, showSymbol: false), _visibleBtc);
|
||||
|
||||
expect(find.text("0.12345678"), findsOneWidget);
|
||||
expect(find.text("0.12345678 BTC"), findsNothing);
|
||||
});
|
||||
});
|
||||
|
||||
group("withSymbolPrefix", () {
|
||||
test("defaults to false on the constructor", () {
|
||||
expect(MoneyText(_btc012).withSymbolPrefix, false);
|
||||
});
|
||||
|
||||
test("defaults to false via optional", () {
|
||||
expect((MoneyText.optional(_btc012) as MoneyText).withSymbolPrefix, false);
|
||||
});
|
||||
|
||||
testWidgets("ignored when showSymbol is false", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
MoneyText(_btc012, showSymbol: false, withSymbolPrefix: true),
|
||||
_visibleBtc,
|
||||
);
|
||||
|
||||
expect(find.text("0.12345678"), findsOneWidget);
|
||||
expect(find.text("BTC 0.12345678"), findsNothing);
|
||||
expect(find.text("0.12345678 BTC"), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets("prefixes the symbol before the amount", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012, withSymbolPrefix: true), _visibleBtc);
|
||||
|
||||
expect(find.text("BTC 0.12345678"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("prefixed amount is still localized (en_US grouping)", (tester) async {
|
||||
await _pump(tester, MoneyText(_btcGrouping, withSymbolPrefix: true), _visibleBtc);
|
||||
|
||||
expect(find.text("BTC 1,234.5"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("prefixed amount respects an explicit de_DE locale", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
MoneyText(_btcGrouping, withSymbolPrefix: true, locale: const Locale("de", "DE")),
|
||||
_visibleBtc,
|
||||
);
|
||||
|
||||
expect(find.text("BTC 1.234,5"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("prefixes the base-unit ticker (sats)", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
MoneyText(_btc012, withSymbolPrefix: true, useBaseUnit: true),
|
||||
_visibleBtc,
|
||||
);
|
||||
|
||||
expect(find.text("sats 12,345,678"), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group("base unit (useBaseUnit)", () {
|
||||
testWidgets("explicit useBaseUnit:true renders sats", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012, useBaseUnit: true), _visibleBtc);
|
||||
|
||||
// 12345678 sats, localized grouping applied by withLocalSeperator.
|
||||
expect(find.text("12,345,678 sats"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("explicit useBaseUnit:false overrides a satoshi state", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012, useBaseUnit: false), _sats);
|
||||
|
||||
expect(find.text("0.12345678 BTC"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("useBaseUnit:null -> state decides (BTC in satoshi mode -> sats)", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012), _sats);
|
||||
|
||||
expect(find.text("12,345,678 sats"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("useBaseUnit:null -> state decides (BTC in bitcoin mode -> BTC)", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012), _visibleBtc);
|
||||
|
||||
expect(find.text("0.12345678 BTC"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("non-BTC currency ignores satoshi mode", (tester) async {
|
||||
await _pump(tester, MoneyText(_xmrHalf), _sats);
|
||||
|
||||
expect(find.text("0.5 XMR"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("LN-satoshi mode makes BTCLN use base unit", (tester) async {
|
||||
await _pump(tester, MoneyText(_btclnAmount), _lnSats);
|
||||
|
||||
expect(find.text("12,345,678 sats"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("LN-satoshi mode leaves plain BTC untouched", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012), _lnSats);
|
||||
|
||||
expect(find.text("0.12345678 BTC"), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group("fractionalDigits & trimZeros", () {
|
||||
testWidgets("fractionalDigits truncates (does not round)", (tester) async {
|
||||
await _pump(tester, MoneyText(_btc012, fractionalDigits: 2), _visibleBtc);
|
||||
|
||||
// 0.12345678 truncated to 2 digits -> 0.12 (NOT 0.13).
|
||||
expect(find.text("0.12 BTC"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("trimZeros:true (default) removes trailing zeros", (tester) async {
|
||||
await _pump(tester, MoneyText(_btcTrailing), _visibleBtc);
|
||||
|
||||
expect(find.text("0.12 BTC"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("trimZeros:false keeps trailing zeros", (tester) async {
|
||||
await _pump(tester, MoneyText(_btcTrailing, trimZeros: false), _visibleBtc);
|
||||
|
||||
expect(find.text("0.12000000 BTC"), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group("locale & separators", () {
|
||||
testWidgets('default locale (en_US) uses "," grouping and "." decimal', (tester) async {
|
||||
await _pump(tester, MoneyText(_btcGrouping), _visibleBtc);
|
||||
|
||||
expect(find.text("1,234.5 BTC"), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("explicit de_DE locale swaps grouping/decimal separators", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
MoneyText(_btcGrouping, locale: const Locale("de", "DE")),
|
||||
_visibleBtc,
|
||||
);
|
||||
|
||||
expect(find.text("1.234,5 BTC"), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group("rebuild on cubit state change", () {
|
||||
testWidgets("re-renders when the settings state changes", (tester) async {
|
||||
final cubit = await _pump(tester, MoneyText(_btc012), _visibleBtc);
|
||||
expect(find.text("0.12345678 BTC"), findsOneWidget);
|
||||
|
||||
cubit.setState(_hiddenBtc);
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text("0.12345678 BTC"), findsNothing);
|
||||
expect(find.text(_hidden), findsOneWidget);
|
||||
});
|
||||
});
|
||||
|
||||
group("forwarding to the inner Text", () {
|
||||
testWidgets("passes through Text properties incl. semanticsIdentifier", (tester) async {
|
||||
await _pump(
|
||||
tester,
|
||||
MoneyText(
|
||||
_btc012,
|
||||
maxLines: 3,
|
||||
textAlign: TextAlign.right,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontSize: 42),
|
||||
semanticsIdentifier: "via-ctor",
|
||||
),
|
||||
_visibleBtc,
|
||||
);
|
||||
|
||||
final text = tester.widget<Text>(
|
||||
find.descendant(of: find.byType(MoneyText), matching: find.byType(Text)),
|
||||
);
|
||||
|
||||
expect(text.maxLines, 3);
|
||||
expect(text.textAlign, TextAlign.right);
|
||||
expect(text.overflow, TextOverflow.ellipsis);
|
||||
expect(text.style?.fontSize, 42);
|
||||
expect(text.semanticsIdentifier, "via-ctor");
|
||||
});
|
||||
});
|
||||
|
||||
group("MoneyText.optional", () {
|
||||
test("returns SizedBox.shrink for a null amount", () {
|
||||
final widget = MoneyText.optional(null);
|
||||
|
||||
expect(widget, isA<SizedBox>());
|
||||
final box = widget as SizedBox;
|
||||
expect(box.width, 0.0);
|
||||
expect(box.height, 0.0);
|
||||
});
|
||||
|
||||
test("returns a MoneyText for a non-null amount", () {
|
||||
expect(MoneyText.optional(_btc012), isA<MoneyText>());
|
||||
});
|
||||
|
||||
test("forwards money-specific parameters to MoneyText", () {
|
||||
final widget = MoneyText.optional(
|
||||
_btc012,
|
||||
showSymbol: false,
|
||||
fractionalDigits: 3,
|
||||
trimZeros: false,
|
||||
isHiddenAmount: true,
|
||||
useBaseUnit: true,
|
||||
withSymbolPrefix: true,
|
||||
) as MoneyText;
|
||||
|
||||
expect(widget.showSymbol, false);
|
||||
expect(widget.fractionalDigits, 3);
|
||||
expect(widget.trimZeros, false);
|
||||
expect(widget.isHiddenAmount, true);
|
||||
expect(widget.useBaseUnit, true);
|
||||
expect(widget.withSymbolPrefix, true);
|
||||
});
|
||||
|
||||
testWidgets("renders identically to a direct MoneyText", (tester) async {
|
||||
await _pump(tester, MoneyText.optional(_btc012), _visibleBtc);
|
||||
|
||||
expect(find.byType(MoneyText), findsOneWidget);
|
||||
expect(find.text("0.12345678 BTC"), findsOneWidget);
|
||||
});
|
||||
|
||||
test(
|
||||
"forwards semanticsIdentifier to MoneyText",
|
||||
() {
|
||||
final widget = MoneyText.optional(_btc012, semanticsIdentifier: "sid") as MoneyText;
|
||||
|
||||
expect(widget.semanticsIdentifier, "sid");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user