move calculations to model

This commit is contained in:
Manfred Karrer 2014-08-29 19:00:17 +02:00
parent b91fe8273b
commit d9e625a684
6 changed files with 197 additions and 254 deletions

View file

@ -28,6 +28,7 @@ import io.bitsquare.trade.TradeManager;
import io.bitsquare.user.User;
import com.google.bitcoin.core.Coin;
import com.google.bitcoin.utils.ExchangeRate;
import com.google.bitcoin.utils.Fiat;
import com.google.inject.Inject;
@ -50,6 +51,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkArgument;
import static io.bitsquare.gui.util.BSFormatter.reduceto4Dezimals;
/**
* Domain for that UI element.
@ -67,12 +69,6 @@ class CreateOfferModel {
private final String offerId;
private Direction direction = null;
final Coin totalFeesAsCoin;
Coin amountAsCoin;
Coin minAmountAsCoin;
Coin collateralAsCoin;
Fiat priceAsFiat;
Fiat volumeAsFiat;
AddressEntry addressEntry;
final StringProperty requestPlaceOfferErrorMessage = new SimpleStringProperty();
@ -86,7 +82,13 @@ class CreateOfferModel {
final BooleanProperty requestPlaceOfferSuccess = new SimpleBooleanProperty();
final BooleanProperty requestPlaceOfferFailed = new SimpleBooleanProperty();
final ObjectProperty<Coin> amountAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<Coin> minAmountAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<Fiat> priceAsFiat = new SimpleObjectProperty<>();
final ObjectProperty<Fiat> volumeAsFiat = new SimpleObjectProperty<>();
final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<Coin> collateralAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<Coin> totalFeesAsCoin = new SimpleObjectProperty<>();
ObservableList<Country> acceptedCountries = FXCollections.observableArrayList();
ObservableList<Locale> acceptedLanguages = FXCollections.observableArrayList();
@ -105,7 +107,7 @@ class CreateOfferModel {
// static data
offerId = UUID.randomUUID().toString();
totalFeesAsCoin = FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE);
totalFeesAsCoin.set(FeePolicy.CREATE_OFFER_FEE.add(FeePolicy.TX_FEE));
//TODO just for unit testing, use mockito?
@ -138,9 +140,9 @@ class CreateOfferModel {
void placeOffer() {
tradeManager.requestPlaceOffer(offerId,
direction,
priceAsFiat,
amountAsCoin,
minAmountAsCoin,
priceAsFiat.get(),
amountAsCoin.get(),
minAmountAsCoin.get(),
(transaction) -> {
requestPlaceOfferSuccess.set(true);
transactionId.set(transaction.getHashAsString());
@ -152,13 +154,45 @@ class CreateOfferModel {
);
}
void calculateVolume() {
if (priceAsFiat.get() != null && amountAsCoin.get() != null /*&& !amountAsCoin.get().isZero()*/)
volumeAsFiat.set(new ExchangeRate(priceAsFiat.get()).coinToFiat(amountAsCoin.get()));
}
void calculateAmount() {
if (volumeAsFiat.get() != null && priceAsFiat.get() != null/* && !volumeAsFiat.get().isZero() && !priceAsFiat
.get().isZero()*/) {
amountAsCoin.set(new ExchangeRate(priceAsFiat.get()).fiatToCoin(volumeAsFiat.get()));
// If we got a btc value with more then 4 decimals we convert it to max 4 decimals
amountAsCoin.set(reduceto4Dezimals(amountAsCoin.get()));
calculateTotalToPay();
calculateCollateral();
}
}
void calculateTotalToPay() {
calculateCollateral();
if (collateralAsCoin.get() != null) {
totalToPayAsCoin.set(collateralAsCoin.get().add(totalFeesAsCoin.get()));
}
}
void calculateCollateral() {
if (amountAsCoin.get() != null)
collateralAsCoin.set(amountAsCoin.get().multiply(collateralAsLong.get()).divide(1000));
}
///////////////////////////////////////////////////////////////////////////////////////////
// Validation
///////////////////////////////////////////////////////////////////////////////////////////
boolean isMinAmountLessOrEqualAmount() {
if (minAmountAsCoin != null && amountAsCoin != null)
return !minAmountAsCoin.isGreaterThan(amountAsCoin);
if (minAmountAsCoin.get() != null && amountAsCoin.get() != null)
return !minAmountAsCoin.get().isGreaterThan(amountAsCoin.get());
return true;
}

View file

@ -28,7 +28,6 @@ import io.bitsquare.trade.orderbook.OrderBookFilter;
import com.google.bitcoin.core.Address;
import com.google.bitcoin.core.Coin;
import com.google.bitcoin.utils.ExchangeRate;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
@ -85,7 +84,9 @@ class CreateOfferPM {
final ObjectProperty<InputValidator.ValidationResult> priceValidationResult = new SimpleObjectProperty<>();
final ObjectProperty<InputValidator.ValidationResult> volumeValidationResult = new SimpleObjectProperty<>();
// That is needed for the addressTextField
final ObjectProperty<Coin> totalToPayAsCoin = new SimpleObjectProperty<>();
final ObjectProperty<Address> address = new SimpleObjectProperty<>();
@ -103,7 +104,9 @@ class CreateOfferPM {
///////////////////////////////////////////////////////////////////////////////////////////
void onViewInitialized() {
totalFees.set(BSFormatter.formatCoin(model.totalFeesAsCoin));
// todo move to contr.
// static
paymentLabel.set("Bitsquare trade (" + model.getOfferId() + ")");
if (model.addressEntry != null) {
@ -111,33 +114,8 @@ class CreateOfferPM {
address.set(model.addressEntry.getAddress());
}
setupInputListeners();
collateralLabel.bind(Bindings.createStringBinding(() -> "Collateral (" + BSFormatter.formatCollateralPercent
(model.collateralAsLong.get()) + "):", model.collateralAsLong));
bankAccountType.bind(Bindings.createStringBinding(() -> Localisation.get(model.bankAccountType.get()),
model.bankAccountType));
bankAccountCurrency.bind(model.bankAccountCurrency);
bankAccountCounty.bind(model.bankAccountCounty);
totalToPayAsCoin.bind(model.totalToPayAsCoin);
model.acceptedCountries.addListener((Observable o) -> acceptedCountries.set(BSFormatter
.countryLocalesToString(model.acceptedCountries)));
model.acceptedLanguages.addListener((Observable o) -> acceptedLanguages.set(BSFormatter
.languageLocalesToString(model.acceptedLanguages)));
isCloseButtonVisible.bind(model.requestPlaceOfferSuccess);
requestPlaceOfferErrorMessage.bind(model.requestPlaceOfferErrorMessage);
requestPlaceOfferFailed.bind(model.requestPlaceOfferFailed);
showTransactionPublishedScreen.bind(model.requestPlaceOfferSuccess);
model.requestPlaceOfferFailed.addListener((o, oldValue, newValue) -> {
if (newValue) isPlaceOfferButtonDisabled.set(false);
});
model.requestPlaceOfferSuccess.addListener((o, oldValue, newValue) -> {
if (newValue) isPlaceOfferButtonVisible.set(false);
});
setupModelBindings();
setupUIInputListeners();
// TODO transactionId,
}
@ -162,20 +140,15 @@ class CreateOfferPM {
model.setDirection(orderBookFilter.getDirection());
directionLabel.set(model.getDirection() == Direction.BUY ? "Buy:" : "Sell:");
if (orderBookFilter.getAmount() != null) {
model.amountAsCoin = orderBookFilter.getAmount();
amount.set(formatCoin(model.amountAsCoin));
model.minAmountAsCoin = orderBookFilter.getAmount();
minAmount.set(formatCoin(model.minAmountAsCoin));
if (orderBookFilter.getAmount() != null && isBtcInputValid(orderBookFilter.getAmount().toPlainString())
.isValid) {
model.amountAsCoin.set(orderBookFilter.getAmount());
model.minAmountAsCoin.set(orderBookFilter.getAmount());
}
// TODO use Fiat in orderBookFilter
if (orderBookFilter.getPrice() != 0) {
model.priceAsFiat = parseToFiatWith2Decimals(String.valueOf(orderBookFilter.getPrice()));
price.set(formatFiat(model.priceAsFiat));
}
if (orderBookFilter.getPrice() != 0 && isBtcInputValid(String.valueOf(orderBookFilter.getPrice())).isValid)
model.priceAsFiat.set(parseToFiatWith2Decimals(String.valueOf(orderBookFilter.getPrice())));
}
@ -184,23 +157,14 @@ class CreateOfferPM {
///////////////////////////////////////////////////////////////////////////////////////////
void placeOffer() {
if (allInputsValid()) {
model.amountAsCoin = parseToCoinWith4Decimals(amount.get());
model.minAmountAsCoin = parseToCoinWith4Decimals(minAmount.get());
model.priceAsFiat = parseToFiatWith2Decimals(price.get());
model.minAmountAsCoin = parseToCoinWith4Decimals(minAmount.get());
model.placeOffer();
isPlaceOfferButtonDisabled.set(true);
isPlaceOfferButtonVisible.set(true);
}
model.placeOffer();
isPlaceOfferButtonDisabled.set(true);
isPlaceOfferButtonVisible.set(true);
}
void close() {
}
///////////////////////////////////////////////////////////////////////////////////////////
// UI events (called by CB)
///////////////////////////////////////////////////////////////////////////////////////////
@ -215,9 +179,8 @@ class CreateOfferPM {
if (isValid) {
showWarningInvalidBtcDecimalPlaces.set(!hasBtcValidDecimals(amount.get()));
// only allow max 4 decimal places for btc values
model.amountAsCoin = parseToCoinWith4Decimals(amount.get());
setAmountToModel();
// reformat input to general btc format
amount.set(formatCoin(model.amountAsCoin));
calculateVolume();
if (!model.isMinAmountLessOrEqualAmount()) {
@ -241,8 +204,7 @@ class CreateOfferPM {
minAmountValidationResult.set(result);
if (isValid) {
showWarningInvalidBtcDecimalPlaces.set(!hasBtcValidDecimals(minAmount.get()));
model.minAmountAsCoin = parseToCoinWith4Decimals(minAmount.get());
minAmount.set(formatCoin(model.minAmountAsCoin));
setMinAmountToModel();
if (!model.isMinAmountLessOrEqualAmount()) {
minAmountValidationResult.set(new InputValidator.ValidationResult(false,
@ -264,8 +226,8 @@ class CreateOfferPM {
priceValidationResult.set(result);
if (isValid) {
showWarningInvalidFiatDecimalPlaces.set(!hasFiatValidDecimals(price.get()));
model.priceAsFiat = parseToFiatWith2Decimals(price.get());
price.set(formatFiat(model.priceAsFiat));
setPriceToModel();
calculateVolume();
}
}
@ -279,9 +241,8 @@ class CreateOfferPM {
if (isValid) {
String origVolume = volume.get();
showWarningInvalidFiatDecimalPlaces.set(!hasFiatValidDecimals(volume.get()));
model.volumeAsFiat = parseToFiatWith2Decimals(volume.get());
setVolumeToModel();
volume.set(formatFiat(model.volumeAsFiat));
calculateAmount();
// must be after calculateAmount (btc value has been adjusted in case the calculation leads to
@ -305,69 +266,102 @@ class CreateOfferPM {
// Private
///////////////////////////////////////////////////////////////////////////////////////////
private void setupInputListeners() {
private void setupUIInputListeners() {
// bindBidirectional for amount, price, volume and minAmount
// We do volume/amount calculation during input
amount.addListener((ov, oldValue, newValue) -> {
if (isBtcInputValid(newValue).isValid) {
model.amountAsCoin = parseToCoinWith4Decimals(newValue);
model.amountAsCoin.set(parseToCoinWith4Decimals(newValue));
calculateVolume();
calculateTotalToPay();
calculateCollateral();
model.calculateTotalToPay();
model.calculateCollateral();
}
});
price.addListener((ov, oldValue, newValue) -> {
if (isFiatInputValid(newValue).isValid) {
model.priceAsFiat = parseToFiatWith2Decimals(newValue);
model.priceAsFiat.set(parseToFiatWith2Decimals(newValue));
calculateVolume();
calculateTotalToPay();
calculateCollateral();
model.calculateTotalToPay();
model.calculateCollateral();
}
});
volume.addListener((ov, oldValue, newValue) -> {
if (isFiatInputValid(newValue).isValid) {
model.volumeAsFiat = parseToFiatWith2Decimals(newValue);
calculateAmount();
calculateTotalToPay();
calculateCollateral();
model.volumeAsFiat.set(parseToFiatWith2Decimals(newValue));
setVolumeToModel();
setPriceToModel();
model.calculateAmount();
model.calculateTotalToPay();
model.calculateCollateral();
}
});
}
private void setupModelBindings() {
private boolean allInputsValid() {
return isBtcInputValid(amount.get()).isValid && isFiatInputValid(price.get()).isValid && isFiatInputValid
(volume.get()).isValid;
amount.bind(Bindings.createObjectBinding(() -> formatCoin(model.amountAsCoin.get()), model.amountAsCoin));
minAmount.bind(Bindings.createObjectBinding(() -> formatCoin(model.minAmountAsCoin.get()),
model.minAmountAsCoin));
price.bind(Bindings.createObjectBinding(() -> formatFiat(model.priceAsFiat.get()), model.priceAsFiat));
volume.bind(Bindings.createObjectBinding(() -> formatFiat(model.volumeAsFiat.get()), model.volumeAsFiat));
totalToPay.bind(createStringBinding(() -> formatCoinWithCode(model.totalToPayAsCoin.get()),
model.totalToPayAsCoin));
collateral.bind(createStringBinding(() -> formatCoinWithCode(model.collateralAsCoin.get()),
model.collateralAsCoin));
collateralLabel.bind(Bindings.createStringBinding(() -> "Collateral (" + BSFormatter.formatCollateralPercent
(model.collateralAsLong.get()) + "):", model.collateralAsLong));
totalToPayAsCoin.bind(model.totalToPayAsCoin);
bankAccountType.bind(Bindings.createStringBinding(() -> Localisation.get(model.bankAccountType.get()),
model.bankAccountType));
bankAccountCurrency.bind(model.bankAccountCurrency);
bankAccountCounty.bind(model.bankAccountCounty);
// ObservableLists
model.acceptedCountries.addListener((Observable o) -> acceptedCountries.set(BSFormatter
.countryLocalesToString(model.acceptedCountries)));
model.acceptedLanguages.addListener((Observable o) -> acceptedLanguages.set(BSFormatter
.languageLocalesToString(model.acceptedLanguages)));
isCloseButtonVisible.bind(model.requestPlaceOfferSuccess);
requestPlaceOfferErrorMessage.bind(model.requestPlaceOfferErrorMessage);
requestPlaceOfferFailed.bind(model.requestPlaceOfferFailed);
showTransactionPublishedScreen.bind(model.requestPlaceOfferSuccess);
amount.bind(Bindings.createObjectBinding(() -> formatCoin(model.amountAsCoin.get()), model.amountAsCoin));
isPlaceOfferButtonDisabled.bind(Bindings.createBooleanBinding(() -> !model.requestPlaceOfferFailed.get(),
model.requestPlaceOfferFailed));
isPlaceOfferButtonVisible.bind(Bindings.createBooleanBinding(() -> !model.requestPlaceOfferSuccess.get(),
model.requestPlaceOfferSuccess));
/* model.requestPlaceOfferFailed.addListener((o, oldValue, newValue) -> {
if (newValue) isPlaceOfferButtonDisabled.set(false);
});
model.requestPlaceOfferSuccess.addListener((o, oldValue, newValue) -> {
if (newValue) isPlaceOfferButtonVisible.set(false);
});*/
}
//TODO move to model
private void calculateVolume() {
model.amountAsCoin = parseToCoinWith4Decimals(amount.get());
model.priceAsFiat = parseToFiatWith2Decimals(price.get());
if (model.priceAsFiat != null && model.amountAsCoin != null && !model.amountAsCoin.isZero()) {
model.volumeAsFiat = new ExchangeRate(model.priceAsFiat).coinToFiat(model.amountAsCoin);
volume.set(formatFiat(model.volumeAsFiat));
}
setAmountToModel();
setPriceToModel();
model.calculateVolume();
}
//TODO move to model
private void calculateAmount() {
model.volumeAsFiat = parseToFiatWith2Decimals(volume.get());
model.priceAsFiat = parseToFiatWith2Decimals(price.get());
if (model.volumeAsFiat != null && model.priceAsFiat != null && !model.priceAsFiat.isZero()) {
model.amountAsCoin = new ExchangeRate(model.priceAsFiat).fiatToCoin(model.volumeAsFiat);
// If we got a btc value with more then 4 decimals we convert it to max 4 decimals
model.amountAsCoin = reduceto4Dezimals(model.amountAsCoin);
amount.set(formatCoin(model.amountAsCoin));
calculateTotalToPay();
calculateCollateral();
}
setVolumeToModel();
setPriceToModel();
model.calculateAmount();
if (!model.isMinAmountLessOrEqualAmount()) {
amountValidationResult.set(new InputValidator.ValidationResult(false,
@ -381,23 +375,20 @@ class CreateOfferPM {
}
}
//TODO move to model
private void calculateTotalToPay() {
calculateCollateral();
if (model.collateralAsCoin != null) {
model.totalToPayAsCoin.set(model.collateralAsCoin.add(model.totalFeesAsCoin));
totalToPay.bind(createStringBinding(() -> formatCoinWithCode(model.totalToPayAsCoin.get()),
model.totalToPayAsCoin));
}
private void setAmountToModel() {
model.amountAsCoin.set(parseToCoinWith4Decimals(amount.get()));
}
//TODO move to model
private void calculateCollateral() {
if (model.amountAsCoin != null) {
model.collateralAsCoin = model.amountAsCoin.multiply(model.collateralAsLong.get()).divide(1000);
collateral.set(BSFormatter.formatCoinWithCode(model.collateralAsCoin));
}
private void setMinAmountToModel() {
model.minAmountAsCoin.set(parseToCoinWith4Decimals(minAmount.get()));
}
private void setPriceToModel() {
model.priceAsFiat.set(parseToFiatWith2Decimals(price.get()));
}
private void setVolumeToModel() {
model.volumeAsFiat.set(parseToFiatWith2Decimals(volume.get()));
}
///////////////////////////////////////////////////////////////////////////////////////////

View file

@ -59,6 +59,8 @@ public abstract class InputValidator {
///////////////////////////////////////////////////////////////////////////////////////////
public static class ValidationResult {
public final boolean isValid;
public final String errorMessage;

View file

@ -22,7 +22,6 @@ import io.bitsquare.gui.util.BSFormatter;
import io.bitsquare.locale.Country;
import com.google.bitcoin.core.Coin;
import com.google.bitcoin.core.NetworkParameters;
import com.google.bitcoin.utils.Fiat;
import java.util.Locale;
@ -52,53 +51,6 @@ public class CreateOfferPMTest {
presenter.onViewInitialized();
}
@Test
public void testIsBtcInputValid() {
assertTrue(presenter.isBtcInputValid("1").isValid);
assertTrue(presenter.isBtcInputValid("1,1").isValid);
assertTrue(presenter.isBtcInputValid("1.1").isValid);
assertTrue(presenter.isBtcInputValid(",1").isValid);
assertTrue(presenter.isBtcInputValid(".1").isValid);
assertTrue(presenter.isBtcInputValid("0.12345678").isValid);
assertTrue(presenter.isBtcInputValid(Coin.SATOSHI.toPlainString()).isValid);
assertTrue(presenter.isBtcInputValid(NetworkParameters.MAX_MONEY.toPlainString()).isValid);
assertFalse(presenter.isBtcInputValid(null).isValid);
assertFalse(presenter.isBtcInputValid("").isValid);
assertFalse(presenter.isBtcInputValid("0").isValid);
assertFalse(presenter.isBtcInputValid("0.0").isValid);
assertFalse(presenter.isBtcInputValid("0,1,1").isValid);
assertFalse(presenter.isBtcInputValid("0.1.1").isValid);
assertFalse(presenter.isBtcInputValid("1,000.1").isValid);
assertFalse(presenter.isBtcInputValid("1.000,1").isValid);
assertFalse(presenter.isBtcInputValid("0.123456789").isValid);
assertFalse(presenter.isBtcInputValid("-1").isValid);
assertFalse(presenter.isBtcInputValid(String.valueOf(NetworkParameters.MAX_MONEY.longValue() + Coin.SATOSHI
.longValue())).isValid);
}
@Test
public void testIsFiatInputValid() {
assertTrue(presenter.isFiatInputValid("1").isValid);
assertTrue(presenter.isFiatInputValid("1,1").isValid);
assertTrue(presenter.isFiatInputValid("1.1").isValid);
assertTrue(presenter.isFiatInputValid(",1").isValid);
assertTrue(presenter.isFiatInputValid(".1").isValid);
assertTrue(presenter.isFiatInputValid("0.01").isValid);
assertTrue(presenter.isFiatInputValid("1000000.00").isValid);
assertFalse(presenter.isFiatInputValid(null).isValid);
assertFalse(presenter.isFiatInputValid("").isValid);
assertFalse(presenter.isFiatInputValid("0").isValid);
assertFalse(presenter.isFiatInputValid("-1").isValid);
assertFalse(presenter.isFiatInputValid("0.0").isValid);
assertFalse(presenter.isFiatInputValid("0,1,1").isValid);
assertFalse(presenter.isFiatInputValid("0.1.1").isValid);
assertFalse(presenter.isFiatInputValid("1,000.1").isValid);
assertFalse(presenter.isFiatInputValid("1.000,1").isValid);
assertFalse(presenter.isFiatInputValid("0.009").isValid);
assertFalse(presenter.isFiatInputValid("1000000.01").isValid);
}
@Test
public void testBindings() {

View file

@ -18,7 +18,6 @@
package io.bitsquare.gui.util;
import io.bitsquare.gui.util.validation.BtcValidator;
import io.bitsquare.gui.util.validation.NumberValidator;
import com.google.bitcoin.core.Coin;
import com.google.bitcoin.core.NetworkParameters;
@ -29,25 +28,30 @@ import static org.junit.Assert.*;
public class BtcValidatorTest {
@Test
public void testValidate() {
public void testIsValid() {
BtcValidator validator = new BtcValidator();
NumberValidator.ValidationResult validationResult;
// invalid cases
validationResult = validator.validate("0.000000011");// minBtc is "0.00000001"
assertFalse(validationResult.isValid);
assertTrue(validator.validate("1").isValid);
assertTrue(validator.validate("1,1").isValid);
assertTrue(validator.validate("1.1").isValid);
assertTrue(validator.validate(",1").isValid);
assertTrue(validator.validate(".1").isValid);
assertTrue(validator.validate("0.12345678").isValid);
assertTrue(validator.validate(Coin.SATOSHI.toPlainString()).isValid);
assertTrue(validator.validate(NetworkParameters.MAX_MONEY.toPlainString()).isValid);
validationResult = validator.validate("21000001"); //maxBtc is "21000000"
assertFalse(validationResult.isValid);
// valid cases
String minBtc = Coin.SATOSHI.toPlainString(); // "0.00000001"
validationResult = validator.validate(minBtc);
assertTrue(validationResult.isValid);
String maxBtc = Coin.valueOf(NetworkParameters.MAX_MONEY.longValue()).toPlainString(); //"21000000"
validationResult = validator.validate(maxBtc);
assertTrue(validationResult.isValid);
assertFalse(validator.validate(null).isValid);
assertFalse(validator.validate("").isValid);
assertFalse(validator.validate("0").isValid);
assertFalse(validator.validate("0.0").isValid);
assertFalse(validator.validate("0,1,1").isValid);
assertFalse(validator.validate("0.1.1").isValid);
assertFalse(validator.validate("1,000.1").isValid);
assertFalse(validator.validate("1.000,1").isValid);
assertFalse(validator.validate("0.123456789").isValid);
assertFalse(validator.validate("-1").isValid);
assertFalse(validator.validate(String.valueOf(NetworkParameters.MAX_MONEY.longValue() + Coin.SATOSHI
.longValue())).isValid);
}
}

View file

@ -31,75 +31,35 @@ public class FiatValidatorTest {
NumberValidator.ValidationResult validationResult;
// invalid cases
validationResult = validator.validate(null);
assertFalse(validationResult.isValid);
assertTrue(validator.validate("1").isValid);
assertTrue(validator.validate("1,1").isValid);
assertTrue(validator.validate("1.1").isValid);
assertTrue(validator.validate(",1").isValid);
assertTrue(validator.validate(".1").isValid);
assertTrue(validator.validate("0.01").isValid);
assertTrue(validator.validate("1000000.00").isValid);
assertTrue(validator.validate(String.valueOf(FiatValidator.MIN_FIAT_VALUE)).isValid);
assertTrue(validator.validate(String.valueOf(FiatValidator.MAX_FIAT_VALUE)).isValid);
validationResult = validator.validate("");
assertFalse(validationResult.isValid);
assertFalse(validator.validate(null).isValid);
assertFalse(validator.validate("").isValid);
assertFalse(validator.validate("a").isValid);
assertFalse(validator.validate("2a").isValid);
assertFalse(validator.validate("a2").isValid);
assertFalse(validator.validate("0").isValid);
assertFalse(validator.validate("-1").isValid);
assertFalse(validator.validate("0.0").isValid);
assertFalse(validator.validate("0,1,1").isValid);
assertFalse(validator.validate("0.1.1").isValid);
assertFalse(validator.validate("1,000.1").isValid);
assertFalse(validator.validate("1.000,1").isValid);
assertFalse(validator.validate("0.009").isValid);
assertFalse(validator.validate("1000000.01").isValid);
validationResult = validator.validate("0");
assertFalse(validationResult.isValid);
assertFalse(validator.validate(String.valueOf(FiatValidator.MIN_FIAT_VALUE - 0.0000001)).isValid);
assertFalse(validator.validate(String.valueOf(FiatValidator.MAX_FIAT_VALUE + 0.0000001)).isValid);
assertFalse(validator.validate(String.valueOf(Double.MIN_VALUE)).isValid);
assertFalse(validator.validate(String.valueOf(Double.MAX_VALUE)).isValid);
validationResult = validator.validate("-1");
assertFalse(validationResult.isValid);
validationResult = validator.validate("a");
assertFalse(validationResult.isValid);
validationResult = validator.validate("2a");
assertFalse(validationResult.isValid);
validationResult = validator.validate("a2");
assertFalse(validationResult.isValid);
// at the moment we dont support thousand separators, can be added later
validationResult = validator.validate("1,100.1");
assertFalse(validationResult.isValid);
// at the moment we dont support thousand separators, can be added later
validationResult = validator.validate("1.100,1");
assertFalse(validationResult.isValid);
validationResult = validator.validate("1.100.1");
assertFalse(validationResult.isValid);
validationResult = validator.validate("1,100,1");
assertFalse(validationResult.isValid);
validationResult = validator.validate(String.valueOf(FiatValidator.MIN_FIAT_VALUE - 0.0000001));
assertFalse(validationResult.isValid);
validationResult = validator.validate(String.valueOf(FiatValidator.MAX_FIAT_VALUE + 0.0000001));
assertFalse(validationResult.isValid);
validationResult = validator.validate(String.valueOf(Double.MIN_VALUE));
assertFalse(validationResult.isValid);
validationResult = validator.validate(String.valueOf(Double.MAX_VALUE));
assertFalse(validationResult.isValid);
// valid cases
validationResult = validator.validate("1");
assertTrue(validationResult.isValid);
validationResult = validator.validate("0,1");
assertTrue(validationResult.isValid);
validationResult = validator.validate("0.1");
assertTrue(validationResult.isValid);
validationResult = validator.validate(",1");
assertTrue(validationResult.isValid);
validationResult = validator.validate(".1");
assertTrue(validationResult.isValid);
validationResult = validator.validate(String.valueOf(FiatValidator.MIN_FIAT_VALUE));
assertTrue(validationResult.isValid);
validationResult = validator.validate(String.valueOf(FiatValidator.MAX_FIAT_VALUE));
assertTrue(validationResult.isValid);
}
}