From 34bee1a11ca748e10fd689f9c2f270c5942aac59 Mon Sep 17 00:00:00 2001 From: crStiv Date: Thu, 30 Jan 2025 17:18:20 +0100 Subject: [PATCH 1/5] Update test-coin.ts --- packages/account/src/test-utils/test-coin.ts | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/account/src/test-utils/test-coin.ts b/packages/account/src/test-utils/test-coin.ts index e69de29bb2d..47846b1e456 100644 --- a/packages/account/src/test-utils/test-coin.ts +++ b/packages/account/src/test-utils/test-coin.ts @@ -0,0 +1,25 @@ +import { Coin } from '@fuel-ts/account'; +import { bn } from '@fuel-ts/math'; +import { getRandomB256 } from '@fuel-ts/crypto'; + +export class TestCoin { + /** + * Creates a single test coin with given parameters + */ + static create(params: Partial = {}): Coin { + return { + id: params.id || getRandomB256(), + owner: params.owner || getRandomB256(), + amount: params.amount || bn(1000000), + type: params.type || 0, + ...params + }; + } + + /** + * Generates an array of test coins with the same base parameters + */ + static many(params: Partial = {}, count = 1): Coin[] { + return Array.from({ length: count }, () => TestCoin.create(params)); + } +} From 6a2445581d477bfd63001d2236d71ef3a700ecd0 Mon Sep 17 00:00:00 2001 From: crStiv Date: Sat, 1 Feb 2025 12:35:05 +0100 Subject: [PATCH 2/5] Create test-coin.test.ts --- .../account/src/test-utils/test-coin.test.ts | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 packages/account/src/test-utils/test-coin.test.ts diff --git a/packages/account/src/test-utils/test-coin.test.ts b/packages/account/src/test-utils/test-coin.test.ts new file mode 100644 index 00000000000..3a88125c8c7 --- /dev/null +++ b/packages/account/src/test-utils/test-coin.test.ts @@ -0,0 +1,65 @@ +import { describe, expect, test } from 'vitest'; +import { Coin } from '@fuel-ts/account'; +import { bn } from '@fuel-ts/math'; +import { getRandomB256 } from '@fuel-ts/crypto'; + +import { TestCoin } from './TestCoin'; + +/** + * @group node + */ +describe('TestCoin', () => { + test('create() returns coin with default values', () => { + const coin = TestCoin.create(); + + expect(coin.id).toBeDefined(); + expect(coin.id).toMatch(/^0x[a-f0-9]{64}$/); + expect(coin.owner).toBeDefined(); + expect(coin.owner).toMatch(/^0x[a-f0-9]{64}$/); + expect(coin.amount).toBeDefined(); + expect(coin.amount.toString()).toBe('1000000'); + expect(coin.type).toBe(0); + }); + + test('create() accepts custom values', () => { + const customCoin: Partial = { + id: getRandomB256(), + owner: getRandomB256(), + amount: bn(500), + type: 1, + }; + + const coin = TestCoin.create(customCoin); + + expect(coin.id).toBe(customCoin.id); + expect(coin.owner).toBe(customCoin.owner); + expect(coin.amount).toBe(customCoin.amount); + expect(coin.type).toBe(customCoin.type); + }); + + test('many() creates specified number of coins', () => { + const count = 3; + const coins = TestCoin.many({}, count); + + expect(coins).toHaveLength(count); + expect(coins[0].id).not.toBe(coins[1].id); + expect(coins[1].id).not.toBe(coins[2].id); + }); + + test('many() applies same base parameters to all coins', () => { + const baseParams: Partial = { + owner: getRandomB256(), + amount: bn(1000), + type: 2, + }; + + const coins = TestCoin.many(baseParams, 2); + + expect(coins[0].owner).toBe(baseParams.owner); + expect(coins[0].amount).toBe(baseParams.amount); + expect(coins[0].type).toBe(baseParams.type); + expect(coins[1].owner).toBe(baseParams.owner); + expect(coins[1].amount).toBe(baseParams.amount); + expect(coins[1].type).toBe(baseParams.type); + }); +}); From 9e2914c8936dc4d9d258283abc7495fde2204025 Mon Sep 17 00:00:00 2001 From: crStiv Date: Mon, 3 Feb 2025 16:38:35 +0100 Subject: [PATCH 3/5] Update test-coin.ts --- packages/account/src/test-utils/test-coin.ts | 48 +++++++++++++++----- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/packages/account/src/test-utils/test-coin.ts b/packages/account/src/test-utils/test-coin.ts index 47846b1e456..6b16254cf14 100644 --- a/packages/account/src/test-utils/test-coin.ts +++ b/packages/account/src/test-utils/test-coin.ts @@ -1,25 +1,51 @@ import { Coin } from '@fuel-ts/account'; -import { bn } from '@fuel-ts/math'; +import { bn, type BN } from '@fuel-ts/math'; import { getRandomB256 } from '@fuel-ts/crypto'; +interface TestCoinSpecs { + id: string; + owner: string; + amount: BN; + type: number; +} + export class TestCoin { + public readonly id: string; + public readonly owner: string; + public readonly amount: BN; + public readonly type: number; + + /** + * A helper class to create coins for testing purposes. + */ + constructor({ + id = getRandomB256(), + owner = getRandomB256(), + amount = bn(1000000), + type = 0, + }: Partial = {}) { + this.id = id; + this.owner = owner; + this.amount = amount; + this.type = type; + } + /** - * Creates a single test coin with given parameters + * Creates a chain-compatible coin object */ - static create(params: Partial = {}): Coin { + toCoin(): Coin { return { - id: params.id || getRandomB256(), - owner: params.owner || getRandomB256(), - amount: params.amount || bn(1000000), - type: params.type || 0, - ...params + id: this.id, + owner: this.owner, + amount: this.amount, + type: this.type, }; } /** - * Generates an array of test coins with the same base parameters + * Creates multiple test coins with the same base parameters */ - static many(params: Partial = {}, count = 1): Coin[] { - return Array.from({ length: count }, () => TestCoin.create(params)); + static many(params: Partial = {}, count = 1): Coin[] { + return Array.from({ length: count }, () => new TestCoin(params).toCoin()); } } From 0f93c69573d3b1f8806bac106fbfcb8e023aa179 Mon Sep 17 00:00:00 2001 From: crStiv Date: Mon, 3 Feb 2025 16:40:33 +0100 Subject: [PATCH 4/5] Update test-coin.test.ts --- .../account/src/test-utils/test-coin.test.ts | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/account/src/test-utils/test-coin.test.ts b/packages/account/src/test-utils/test-coin.test.ts index 3a88125c8c7..4b0c705ade2 100644 --- a/packages/account/src/test-utils/test-coin.test.ts +++ b/packages/account/src/test-utils/test-coin.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from 'vitest'; -import { Coin } from '@fuel-ts/account'; -import { bn } from '@fuel-ts/math'; +import { type Coin } from '@fuel-ts/account'; +import { bn, type BN } from '@fuel-ts/math'; import { getRandomB256 } from '@fuel-ts/crypto'; import { TestCoin } from './TestCoin'; @@ -9,8 +9,9 @@ import { TestCoin } from './TestCoin'; * @group node */ describe('TestCoin', () => { - test('create() returns coin with default values', () => { - const coin = TestCoin.create(); + test('constructor creates coin with default values', () => { + const testCoin = new TestCoin(); + const coin = testCoin.toCoin(); expect(coin.id).toBeDefined(); expect(coin.id).toMatch(/^0x[a-f0-9]{64}$/); @@ -21,20 +22,21 @@ describe('TestCoin', () => { expect(coin.type).toBe(0); }); - test('create() accepts custom values', () => { - const customCoin: Partial = { + test('constructor accepts custom values', () => { + const customParams = { id: getRandomB256(), owner: getRandomB256(), amount: bn(500), type: 1, }; - const coin = TestCoin.create(customCoin); + const testCoin = new TestCoin(customParams); + const coin = testCoin.toCoin(); - expect(coin.id).toBe(customCoin.id); - expect(coin.owner).toBe(customCoin.owner); - expect(coin.amount).toBe(customCoin.amount); - expect(coin.type).toBe(customCoin.type); + expect(coin.id).toBe(customParams.id); + expect(coin.owner).toBe(customParams.owner); + expect(coin.amount).toBe(customParams.amount); + expect(coin.type).toBe(customParams.type); }); test('many() creates specified number of coins', () => { @@ -47,7 +49,7 @@ describe('TestCoin', () => { }); test('many() applies same base parameters to all coins', () => { - const baseParams: Partial = { + const baseParams = { owner: getRandomB256(), amount: bn(1000), type: 2, From 04a26727f88892549f73e1d95c732aaaf7d6befd Mon Sep 17 00:00:00 2001 From: crStiv Date: Tue, 4 Feb 2025 22:31:50 +0100 Subject: [PATCH 5/5] Update transaction.test.ts --- packages/fuel-gauge/src/transaction.test.ts | 45 ++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/fuel-gauge/src/transaction.test.ts b/packages/fuel-gauge/src/transaction.test.ts index 00cd03bc597..8c54b5f00fd 100644 --- a/packages/fuel-gauge/src/transaction.test.ts +++ b/packages/fuel-gauge/src/transaction.test.ts @@ -9,7 +9,8 @@ import { sleep, TransactionType, } from 'fuels'; -import { ASSET_A, expectToThrowFuelError, launchTestNode, TestMessage } from 'fuels/test-utils'; +import { ASSET_A, expectToThrowFuelError, launchTestNode, TestMessage, TestCoin } from 'fuels/test-utils'; +import { bn } from 'fuels'; import { CallTestContractFactory } from '../test/typegen'; @@ -317,4 +318,46 @@ describe('Transaction', () => { }) ); }); + + it('should handle transaction with TestCoin', async () => { + using launched = await launchTestNode(); + const { provider, wallets: [wallet] } = launched; + + const baseAssetId = await provider.getBaseAssetId(); + const initialBalance = await wallet.getBalance(baseAssetId); + + // Create test coins with specific parameters + const testCoin = new TestCoin({ + amount: bn(1000), + owner: wallet.address.toB256(), + assetId: baseAssetId, + }); + + const request = new ScriptTransactionRequest({ + gasLimit: 10000, + gasPrice: 1, + }); + + // Add test coin as input + request.addCoinInput(testCoin.toCoin()); + + // Add output to send coins back to wallet + request.addCoinOutput(wallet.address.toB256(), testCoin.amount, baseAssetId); + + // Fund and send transaction + await request.estimateAndFund(wallet); + const tx = await wallet.sendTransaction(request); + const result = await tx.waitForResult(); + + // Verify transaction success + expect(result.isStatusSuccess).toBeTruthy(); + + // Verify balance changes + const finalBalance = await wallet.getBalance(baseAssetId); + expect(finalBalance.gte(initialBalance)).toBeTruthy(); + + // Verify coin was spent + const spentCoins = await wallet.getCoinsToSpend(baseAssetId); + expect(spentCoins.find((c) => c.id === testCoin.id)).toBeUndefined(); + }); });