diff options
author | Sebastian <sebasjm@gmail.com> | 2023-06-15 13:07:31 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-06-15 13:07:31 -0300 |
commit | d0d7685f169ecad5ba29210973a9e59834c979c7 (patch) | |
tree | f99393e6b6711343e4ee6fcbf1c0f815725b4787 /packages/taler-wallet-core/src/util/coinSelection.test.ts | |
parent | f7058a86c9f9c6a727c58be80dbc0e2b3f7218f8 (diff) | |
download | wallet-core-d0d7685f169ecad5ba29210973a9e59834c979c7.tar.gz wallet-core-d0d7685f169ecad5ba29210973a9e59834c979c7.tar.bz2 wallet-core-d0d7685f169ecad5ba29210973a9e59834c979c7.zip |
add test to coin selection algorithm
Diffstat (limited to 'packages/taler-wallet-core/src/util/coinSelection.test.ts')
-rw-r--r-- | packages/taler-wallet-core/src/util/coinSelection.test.ts | 195 |
1 files changed, 193 insertions, 2 deletions
diff --git a/packages/taler-wallet-core/src/util/coinSelection.test.ts b/packages/taler-wallet-core/src/util/coinSelection.test.ts index c0edc4cc1..7f4164aa9 100644 --- a/packages/taler-wallet-core/src/util/coinSelection.test.ts +++ b/packages/taler-wallet-core/src/util/coinSelection.test.ts @@ -14,6 +14,18 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ import test, { ExecutionContext } from "ava"; +import { + calculatePlanFormAvailableCoins, + selectCoinForOperation, +} from "./coinSelection.js"; +import { + AbsoluteTime, + AgeRestriction, + AmountJson, + Amounts, + Duration, + TransactionType, +} from "@gnu-taler/taler-util"; function expect(t: ExecutionContext, thing: any): any { return { @@ -24,6 +36,185 @@ function expect(t: ExecutionContext, thing: any): any { }; } -test("should have a test", (t) => { - expect(t, true).deep.equal(true); +function kudos(v: number): AmountJson { + return Amounts.fromFloat(v, "KUDOS"); +} + +function defaultFeeConfig(value: AmountJson, totalAvailable: number) { + return { + id: Amounts.stringify(value), + denomDeposit: kudos(0.01), + denomRefresh: kudos(0.01), + denomWithdraw: kudos(0.01), + duration: Duration.getForever(), + exchangePurse: undefined, + exchangeWire: undefined, + maxAge: AgeRestriction.AGE_UNRESTRICTED, + totalAvailable, + value, + }; +} +type Coin = [AmountJson, number]; + +/** + * selectCoinForOperation test + * + * Test here should check that the correct coins are selected + */ + +test("get effective 2", (t) => { + const coinList: Coin[] = [ + [kudos(2), 5], + [kudos(5), 5], + ]; + const result = selectCoinForOperation("credit", kudos(2), "net", { + list: coinList.map(([v, t]) => defaultFeeConfig(v, t)), + exchanges: {}, + }); + expect(t, result.coins).deep.equal(["KUDOS:2"]); + t.assert(result.refresh === undefined); +}); + +test("get raw 4", (t) => { + const coinList: Coin[] = [ + [kudos(2), 5], + [kudos(5), 5], + ]; + const result = selectCoinForOperation("credit", kudos(4), "gross", { + list: coinList.map(([v, t]) => defaultFeeConfig(v, t)), + exchanges: {}, + }); + + expect(t, result.coins).deep.equal(["KUDOS:2", "KUDOS:2"]); + t.assert(result.refresh === undefined); +}); + +test("send effective 6", (t) => { + const coinList: Coin[] = [ + [kudos(2), 5], + [kudos(5), 5], + ]; + const result = selectCoinForOperation("debit", kudos(6), "gross", { + list: coinList.map(([v, t]) => defaultFeeConfig(v, t)), + exchanges: {}, + }); + + expect(t, result.coins).deep.equal(["KUDOS:5"]); + t.assert(result.refresh?.selected === "KUDOS:2"); +}); + +test("send raw 6", (t) => { + const coinList: Coin[] = [ + [kudos(2), 5], + [kudos(5), 5], + ]; + const result = selectCoinForOperation("debit", kudos(6), "gross", { + list: coinList.map(([v, t]) => defaultFeeConfig(v, t)), + exchanges: {}, + }); + + expect(t, result.coins).deep.equal(["KUDOS:5"]); + t.assert(result.refresh?.selected === "KUDOS:2"); +}); + +test("send raw 20 (not enough)", (t) => { + const coinList: Coin[] = [ + [kudos(2), 1], + [kudos(5), 2], + ]; + const result = selectCoinForOperation("debit", kudos(20), "gross", { + list: coinList.map(([v, t]) => defaultFeeConfig(v, t)), + exchanges: {}, + }); + + expect(t, result.coins).deep.equal(["KUDOS:5", "KUDOS:5", "KUDOS:2"]); + t.assert(result.refresh === undefined); +}); + +/** + * calculatePlanFormAvailableCoins test + * + * Test here should check that the plan summary for a transaction is correct + * * effective amount + * * raw amount + */ + +test("deposit effective 2 ", (t) => { + const coinList: Coin[] = [ + [kudos(2), 1], + [kudos(5), 2], + ]; + const result = calculatePlanFormAvailableCoins( + TransactionType.Deposit, + kudos(2), + "effective", + { + list: coinList.map(([v, t]) => defaultFeeConfig(v, t)), + exchanges: { + "2": { + creditDeadline: AbsoluteTime.never(), + debitDeadline: AbsoluteTime.never(), + wireFee: kudos(0.01), + purseFee: kudos(0.01), + }, + }, + }, + ); + + t.deepEqual(result.rawAmount, "KUDOS:1.98"); + t.deepEqual(result.effectiveAmount, "KUDOS:2"); +}); + +test("deposit raw 2 ", (t) => { + const coinList: Coin[] = [ + [kudos(2), 1], + [kudos(5), 2], + ]; + const result = calculatePlanFormAvailableCoins( + TransactionType.Deposit, + kudos(2), + "raw", + { + list: coinList.map(([v, t]) => defaultFeeConfig(v, t)), + exchanges: { + "2": { + creditDeadline: AbsoluteTime.never(), + debitDeadline: AbsoluteTime.never(), + wireFee: kudos(0.01), + purseFee: kudos(0.01), + }, + }, + }, + ); + + t.deepEqual(result.rawAmount, "KUDOS:2"); + t.deepEqual(result.effectiveAmount, "KUDOS:2.04"); +}); + +test("withdraw raw 21 ", (t) => { + const coinList: Coin[] = [ + [kudos(2), 1], + [kudos(5), 2], + ]; + const result = calculatePlanFormAvailableCoins( + TransactionType.Withdrawal, + kudos(21), + "raw", + { + list: coinList.map(([v, t]) => defaultFeeConfig(v, t)), + exchanges: { + "2": { + creditDeadline: AbsoluteTime.never(), + debitDeadline: AbsoluteTime.never(), + wireFee: kudos(0.01), + purseFee: kudos(0.01), + }, + }, + }, + ); + + // denominations configuration is not suitable + // for greedy algorithm + t.deepEqual(result.rawAmount, "KUDOS:20"); + t.deepEqual(result.effectiveAmount, "KUDOS:19.96"); }); |