summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/util/coinSelection.test.ts
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-06-15 13:07:31 -0300
committerSebastian <sebasjm@gmail.com>2023-06-15 13:07:31 -0300
commitd0d7685f169ecad5ba29210973a9e59834c979c7 (patch)
treef99393e6b6711343e4ee6fcbf1c0f815725b4787 /packages/taler-wallet-core/src/util/coinSelection.test.ts
parentf7058a86c9f9c6a727c58be80dbc0e2b3f7218f8 (diff)
downloadwallet-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.ts195
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");
});