Merge pull request #103 from A248/master

Solve #100
This commit is contained in:
AppleDash 2020-06-06 13:11:42 -04:00 committed by GitHub
commit ed3ccceb1d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 2 deletions

View File

@ -29,6 +29,8 @@ public class EconomyManager {
private final Currency currency;
private final EconomyStorageBackend backend;
private final String serverAccountName;
private static final BigDecimal REQUIRED_BALANCE_ACCURACY = new BigDecimal("0.0001");
public EconomyManager(ISaneEconomy saneEconomy, Currency currency, EconomyStorageBackend backend, String serverAccountName) {
this.saneEconomy = saneEconomy;
@ -84,8 +86,25 @@ public class EconomyManager {
* @return True if they have requiredBalance or more, false otherwise
*/
public boolean hasBalance(Economable targetPlayer, BigDecimal requiredBalance) {
return (EconomableConsole.isConsole(targetPlayer)) || (this.getBalance(targetPlayer).compareTo(requiredBalance) >= 0);
return (EconomableConsole.isConsole(targetPlayer)) || (hasBalance(this.getBalance(targetPlayer), requiredBalance));
}
/**
* Compare account balance and required balance to a reasonable degree of accuracy. <br>
* <b>Visible for testing</b>
*
* @param accountBalance account balance
* @param requiredBalance required balance
* @return true if the account has the required balance to some degree of accuracy, false otherwise
*/
public boolean hasBalance(BigDecimal accountBalance, BigDecimal requiredBalance) {
if (accountBalance.compareTo(requiredBalance) >= 0) {
return true;
}
// Must compare to degree of accuracy
// See https://github.com/AppleDash/SaneEconomy/issues/100
BigDecimal difference = requiredBalance.subtract(accountBalance);
return difference.compareTo(REQUIRED_BALANCE_ACCURACY) < 0; // difference < PRECISION
}
/**

View File

@ -18,6 +18,7 @@ import org.junit.Test;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
/**
@ -117,4 +118,25 @@ public class EconomyManagerTest {
return true;
}
@Test
public void testHasRequiredBalance() {
for (int n = 0; n < 20; n++) { // in the absence of Junit 5's @RepeatedTest
BigDecimal bigDecimal = randomBigDecimal();
// We MUST modify the BigDecimal in some way otherwise the test will always succeed
// See https://github.com/AppleDash/SaneEconomy/issues/100
for (int m = 0; m < 20; m++) {
bigDecimal = bigDecimal.add(randomBigDecimal()).subtract(randomBigDecimal());
}
//
Assert.assertTrue("Account must have required balance despite loss of precision (repeat " + n + ")",
economyManager.hasBalance(bigDecimal, new BigDecimal(bigDecimal.doubleValue())));
}
}
private static BigDecimal randomBigDecimal() {
return new BigDecimal(ThreadLocalRandom.current().nextDouble());
}
}