-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(account): Add TestCoin helper class for testing purposes #3647
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { describe, expect, test } from 'vitest'; | ||
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'; | ||
|
||
/** | ||
* @group node | ||
*/ | ||
describe('TestCoin', () => { | ||
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}$/); | ||
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('constructor accepts custom values', () => { | ||
const customParams = { | ||
id: getRandomB256(), | ||
owner: getRandomB256(), | ||
amount: bn(500), | ||
type: 1, | ||
}; | ||
|
||
const testCoin = new TestCoin(customParams); | ||
const coin = testCoin.toCoin(); | ||
|
||
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', () => { | ||
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 = { | ||
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); | ||
}); | ||
}); |
danielbate marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,51 @@ | ||||||||||||||||||||||||||||||||||||||||||||
import { Coin } from '@fuel-ts/account'; | ||||||||||||||||||||||||||||||||||||||||||||
import { bn, type BN } from '@fuel-ts/math'; | ||||||||||||||||||||||||||||||||||||||||||||
import { getRandomB256 } from '@fuel-ts/crypto'; | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
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; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+12
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fuels-ts/packages/account/src/test-utils/test-message.ts Lines 18 to 24 in 01375ce
It is intended to be used when setting up a local node, just like the fuels-ts/apps/docs/src/guide/provider/snippets/functionality/get-messages-by-nonce.ts Lines 4 to 17 in 01375ce
Therefore, its properties should be the same ones as the Coin type for the stateConfig: |
||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||
* A helper class to create coins for testing purposes. | ||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||
constructor({ | ||||||||||||||||||||||||||||||||||||||||||||
id = getRandomB256(), | ||||||||||||||||||||||||||||||||||||||||||||
owner = getRandomB256(), | ||||||||||||||||||||||||||||||||||||||||||||
amount = bn(1000000), | ||||||||||||||||||||||||||||||||||||||||||||
type = 0, | ||||||||||||||||||||||||||||||||||||||||||||
}: Partial<TestCoinSpecs> = {}) { | ||||||||||||||||||||||||||||||||||||||||||||
this.id = id; | ||||||||||||||||||||||||||||||||||||||||||||
this.owner = owner; | ||||||||||||||||||||||||||||||||||||||||||||
this.amount = amount; | ||||||||||||||||||||||||||||||||||||||||||||
this.type = type; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||
* Creates a chain-compatible coin object | ||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||
toCoin(): Coin { | ||||||||||||||||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||||||||||||||||
id: this.id, | ||||||||||||||||||||||||||||||||||||||||||||
owner: this.owner, | ||||||||||||||||||||||||||||||||||||||||||||
amount: this.amount, | ||||||||||||||||||||||||||||||||||||||||||||
type: this.type, | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The property |
||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||||||||||
* Creates multiple test coins with the same base parameters | ||||||||||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||||||||||
static many(params: Partial<TestCoinSpecs> = {}, count = 1): Coin[] { | ||||||||||||||||||||||||||||||||||||||||||||
return Array.from({ length: count }, () => new TestCoin(params).toCoin()); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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, | ||
}); | ||
Comment on lines
+323
to
+334
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this test working? The transaction is being submitted with a coin not created on the local chain. |
||
|
||
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(); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.