Skip to content

Commit 81f5ee2

Browse files
authored
Migrate JS tests from AVA to Vitest (#156)
Replaces the AVA test runner with Vitest in the token JS client.
1 parent 3d00ad7 commit 81f5ee2

16 files changed

Lines changed: 1852 additions & 2154 deletions

clients/js/package.json

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"scripts": {
2323
"build": "rimraf dist && tsup && tsc -p ./tsconfig.declarations.json",
2424
"build:docs": "typedoc",
25-
"test": "ava",
25+
"dev": "vitest",
26+
"test": "vitest run",
2627
"lint": "eslint --ext js,ts,tsx src",
2728
"lint:fix": "eslint --fix --ext js,ts,tsx src",
2829
"format": "prettier --check src test",
@@ -49,30 +50,18 @@
4950
"@solana-program/system": "^0.12.0"
5051
},
5152
"devDependencies": {
52-
"@ava/typescript": "^4.1.0",
5353
"@solana/eslint-config-solana": "^3.0.3",
5454
"@solana/kit": "^6.5.0",
5555
"@solana/kit-client-rpc": "^0.9.0",
5656
"@types/node": "^24",
5757
"@typescript-eslint/eslint-plugin": "^7.16.1",
5858
"@typescript-eslint/parser": "^7.16.1",
59-
"ava": "^6.1.3",
6059
"eslint": "^8.57.0",
6160
"prettier": "^3.8.1",
6261
"rimraf": "^5.0.5",
6362
"tsup": "^8.1.2",
6463
"typedoc": "^0.25.12",
65-
"typescript": "^5.9.3"
66-
},
67-
"ava": {
68-
"nodeArguments": [
69-
"--no-warnings"
70-
],
71-
"typescript": {
72-
"compile": false,
73-
"rewritePaths": {
74-
"test/": "dist/test/"
75-
}
76-
}
64+
"typescript": "^5.9.3",
65+
"vitest": "^4.0.15"
7766
}
7867
}

clients/js/pnpm-lock.yaml

Lines changed: 1753 additions & 2040 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

clients/js/test/batch.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
some,
1414
} from '@solana/kit';
1515
import { createLocalClient } from '@solana/kit-client-rpc';
16-
import test from 'ava';
16+
import { expect, it } from 'vitest';
1717
import {
1818
AccountState,
1919
getBatchInstruction,
@@ -28,7 +28,7 @@ import {
2828
tokenProgram,
2929
} from '../src';
3030

31-
test('it batches multiple token instructions together', async t => {
31+
it('batches multiple token instructions together', async () => {
3232
// Given a local validator client with some generated keypairs.
3333
const client = await createLocalClient().use(systemProgram()).use(tokenProgram());
3434
const [mint, token, mintAuthority, tokenOwner] = await Promise.all([
@@ -76,7 +76,7 @@ test('it batches multiple token instructions together', async t => {
7676

7777
// Then we expect the mint account to have the correct data.
7878
const mintAccount = await client.token.accounts.mint.fetch(mint.address);
79-
t.like(mintAccount.data, {
79+
expect(mintAccount.data).toMatchObject({
8080
mintAuthority: some(mintAuthority.address),
8181
supply: 123_45n,
8282
decimals: 2,
@@ -86,15 +86,15 @@ test('it batches multiple token instructions together', async t => {
8686

8787
// And we expect the token account to have the correct data.
8888
const tokenAccount = await client.token.accounts.token.fetch(token.address);
89-
t.like(tokenAccount.data, {
89+
expect(tokenAccount.data).toMatchObject({
9090
mint: mint.address,
9191
owner: tokenOwner.address,
9292
amount: 123_45n,
9393
state: AccountState.Initialized,
9494
});
9595
});
9696

97-
test('it fails to batch nested batch instructions', async t => {
97+
it('fails to batch nested batch instructions', async () => {
9898
// Given a local validator client with some generated keypairs.
9999
const client = await createLocalClient().use(systemProgram()).use(tokenProgram());
100100
const [mint, token, mintAuthority, tokenOwner] = await Promise.all([
@@ -129,10 +129,10 @@ test('it fails to batch nested batch instructions', async t => {
129129
]);
130130

131131
// Then we expect an error to be thrown.
132-
t.throws(createNestedBatch, { message: 'Batch instructions cannot be nested within other batch instructions.' });
132+
expect(createNestedBatch).toThrow('Batch instructions cannot be nested within other batch instructions.');
133133
});
134134

135-
test('it parses batch instructions including its inner instructions', async t => {
135+
it('parses batch instructions including its inner instructions', async () => {
136136
// Given a batch instruction with multiple token inner instructions.
137137
const [mint, token, mintAuthority, tokenOwner] = await Promise.all([
138138
generateKeyPairSigner(),
@@ -163,7 +163,7 @@ test('it parses batch instructions including its inner instructions', async t =>
163163
const parsedInstruction = parseBatchInstruction(batchInstruction);
164164

165165
// Then we expect the parsed instruction to have the following inner instructions.
166-
t.deepEqual(parsedInstruction.instructions, [
166+
expect(parsedInstruction.instructions).toEqual([
167167
{
168168
instructionType: TokenInstruction.InitializeMint2,
169169
programAddress: TOKEN_PROGRAM_ADDRESS,
@@ -209,7 +209,7 @@ test('it parses batch instructions including its inner instructions', async t =>
209209
]);
210210
});
211211

212-
test('it parses batch instructions from a fetched transaction', async t => {
212+
it('parses batch instructions from a fetched transaction', async () => {
213213
// Given a client with some generated keypairs.
214214
const client = await createLocalClient().use(systemProgram()).use(tokenProgram());
215215
const [mint, token, mintAuthority, tokenOwner] = await Promise.all([
@@ -259,7 +259,7 @@ test('it parses batch instructions from a fetched transaction', async t => {
259259
const transactionResult = await client.rpc
260260
.getTransaction(result.context.signature, { encoding: 'base64', maxSupportedTransactionVersion: 0 })
261261
.send();
262-
t.assert(transactionResult);
262+
expect(transactionResult).toBeTruthy();
263263
const transactionBytes = getBase64Encoder().encode(transactionResult!.transaction[0]);
264264
const transaction = getTransactionDecoder().decode(transactionBytes);
265265
const compiledMessage = getCompiledTransactionMessageDecoder().decode(transaction.messageBytes);
@@ -272,7 +272,7 @@ test('it parses batch instructions from a fetched transaction', async t => {
272272
const parsedInstruction = parseBatchInstruction(batchInstruction);
273273

274274
// Then we expect the parsed instruction to have the following inner instructions.
275-
t.deepEqual(parsedInstruction.instructions, [
275+
expect(parsedInstruction.instructions).toEqual([
276276
{
277277
instructionType: TokenInstruction.InitializeMint2,
278278
programAddress: TOKEN_PROGRAM_ADDRESS,

clients/js/test/burnChecked.test.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { appendTransactionMessageInstruction, generateKeyPairSigner, pipe } from '@solana/kit';
2-
import test from 'ava';
2+
import { expect, it } from 'vitest';
33
import { fetchMint, fetchToken, getApproveInstruction, getBurnCheckedInstruction } from '../src';
44
import {
55
createDefaultSolanaClient,
@@ -10,7 +10,7 @@ import {
1010
signAndSendTransaction,
1111
} from './_setup';
1212

13-
test('it burns tokens with correct decimals', async t => {
13+
it('burns tokens with correct decimals', async () => {
1414
// Given a mint with 9 decimals and a token account with 200 tokens.
1515
const client = createDefaultSolanaClient();
1616
const [payer, mintAuthority, owner] = await Promise.all([
@@ -36,14 +36,14 @@ test('it burns tokens with correct decimals', async t => {
3636
);
3737

3838
const { data: mintData } = await fetchMint(client.rpc, mint);
39-
t.is(mintData.supply, 175n);
39+
expect(mintData.supply).toBe(175n);
4040

4141
// Then we expect the token account to have 175 tokens remaining.
4242
const { data: tokenData } = await fetchToken(client.rpc, token);
43-
t.is(tokenData.amount, 175n);
43+
expect(tokenData.amount).toBe(175n);
4444
});
4545

46-
test('it burns tokens using a delegate', async t => {
46+
it('burns tokens using a delegate', async () => {
4747
// Given a token account with 100 tokens and a delegate approved for 60 tokens.
4848
const client = createDefaultSolanaClient();
4949
const [payer, mintAuthority, owner, delegate] = await Promise.all([
@@ -84,11 +84,11 @@ test('it burns tokens using a delegate', async t => {
8484

8585
// Then the token account should have 70 tokens remaining.
8686
const { data: tokenData } = await fetchToken(client.rpc, token);
87-
t.is(tokenData.amount, 70n);
88-
t.is(tokenData.delegatedAmount, 30n); // Remaining delegated amount
87+
expect(tokenData.amount).toBe(70n);
88+
expect(tokenData.delegatedAmount).toBe(30n); // Remaining delegated amount
8989
});
9090

91-
test('it fails when decimals mismatch', async t => {
91+
it('fails when decimals mismatch', async () => {
9292
// Given a mint with 9 decimals and a token account with tokens.
9393
const client = createDefaultSolanaClient();
9494
const [payer, mintAuthority, owner] = await Promise.all([
@@ -112,10 +112,10 @@ test('it fails when decimals mismatch', async t => {
112112
);
113113

114114
// Then it should fail with MintDecimalsMismatch error.
115-
await t.throwsAsync(signAndSendTransaction(client, transactionMessage));
115+
await expect(signAndSendTransaction(client, transactionMessage)).rejects.toThrow();
116116
});
117117

118-
test('it fails when burning more than account balance', async t => {
118+
it('fails when burning more than account balance', async () => {
119119
// Given a token account with only 50 tokens.
120120
const client = createDefaultSolanaClient();
121121
const [payer, mintAuthority, owner] = await Promise.all([
@@ -139,10 +139,10 @@ test('it fails when burning more than account balance', async t => {
139139
);
140140

141141
// Then it should fail with InsufficientFunds error.
142-
await t.throwsAsync(signAndSendTransaction(client, transactionMessage));
142+
await expect(signAndSendTransaction(client, transactionMessage)).rejects.toThrow();
143143
});
144144

145-
test('it fails when authority is not a signer', async t => {
145+
it('fails when authority is not a signer', async () => {
146146
// Given a token account with tokens.
147147
const client = createDefaultSolanaClient();
148148
const [payer, mintAuthority, owner, wrongAuthority] = await Promise.all([
@@ -167,10 +167,10 @@ test('it fails when authority is not a signer', async t => {
167167
);
168168

169169
// Then it should fail (owner mismatch or missing signature).
170-
await t.throwsAsync(signAndSendTransaction(client, transactionMessage));
170+
await expect(signAndSendTransaction(client, transactionMessage)).rejects.toThrow();
171171
});
172172

173-
test('it fails when delegate has insufficient delegated amount', async t => {
173+
it('fails when delegate has insufficient delegated amount', async () => {
174174
// Given a token account with 100 tokens and a delegate approved for only 20 tokens.
175175
const client = createDefaultSolanaClient();
176176
const [payer, mintAuthority, owner, delegate] = await Promise.all([
@@ -208,10 +208,10 @@ test('it fails when delegate has insufficient delegated amount', async t => {
208208
);
209209

210210
// Then it should fail with InsufficientFunds error.
211-
await t.throwsAsync(signAndSendTransaction(client, transactionMessage));
211+
await expect(signAndSendTransaction(client, transactionMessage)).rejects.toThrow();
212212
});
213213

214-
test('it burns zero tokens successfully', async t => {
214+
it('burns zero tokens successfully', async () => {
215215
// Given a token account with tokens.
216216
const client = createDefaultSolanaClient();
217217
const [payer, mintAuthority, owner] = await Promise.all([
@@ -238,5 +238,5 @@ test('it burns zero tokens successfully', async t => {
238238

239239
// Then the balance should remain unchanged.
240240
const { data: tokenData } = await fetchToken(client.rpc, token);
241-
t.is(tokenData.amount, 100n);
241+
expect(tokenData.amount).toBe(100n);
242242
});

clients/js/test/createAssociatedToken.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Account, appendTransactionMessageInstruction, generateKeyPairSigner, none, pipe } from '@solana/kit';
2-
import test from 'ava';
2+
import { expect, it } from 'vitest';
33
import {
44
AccountState,
55
TOKEN_PROGRAM_ADDRESS,
@@ -16,7 +16,7 @@ import {
1616
signAndSendTransaction,
1717
} from './_setup';
1818

19-
test('it creates a new associated token account', async t => {
19+
it('creates a new associated token account', async () => {
2020
// Given a mint account, its mint authority and a token owner.
2121
const client = createDefaultSolanaClient();
2222
const [payer, mintAuthority, owner] = await Promise.all([
@@ -45,7 +45,7 @@ test('it creates a new associated token account', async t => {
4545
owner: owner.address,
4646
tokenProgram: TOKEN_PROGRAM_ADDRESS,
4747
});
48-
t.like(await fetchToken(client.rpc, ata), <Account<Token>>{
48+
expect(await fetchToken(client.rpc, ata)).toMatchObject(<Account<Token>>{
4949
address: ata,
5050
data: {
5151
mint,

clients/js/test/createAssociatedTokenIdempotent.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Account, appendTransactionMessageInstruction, generateKeyPairSigner, none, pipe } from '@solana/kit';
2-
import test from 'ava';
2+
import { expect, it } from 'vitest';
33
import {
44
AccountState,
55
TOKEN_PROGRAM_ADDRESS,
@@ -16,7 +16,7 @@ import {
1616
signAndSendTransaction,
1717
} from './_setup';
1818

19-
test('it creates a new associated token account', async t => {
19+
it('creates a new associated token account', async () => {
2020
// Given a mint account, its mint authority and a token owner.
2121
const client = createDefaultSolanaClient();
2222
const [payer, mintAuthority, owner] = await Promise.all([
@@ -45,7 +45,7 @@ test('it creates a new associated token account', async t => {
4545
owner: owner.address,
4646
tokenProgram: TOKEN_PROGRAM_ADDRESS,
4747
});
48-
t.like(await fetchToken(client.rpc, ata), <Account<Token>>{
48+
expect(await fetchToken(client.rpc, ata)).toMatchObject(<Account<Token>>{
4949
address: ata,
5050
data: {
5151
mint,

clients/js/test/createMint.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { Account, generateKeyPairSigner, none, some } from '@solana/kit';
22
import { createLocalClient } from '@solana/kit-client-rpc';
3-
import test from 'ava';
3+
import { expect, it } from 'vitest';
44
import { fetchMint, getCreateMintInstructionPlan, Mint, tokenProgram } from '../src';
55
import { createDefaultSolanaClient, createDefaultTransactionPlanner, generateKeyPairSignerWithSol } from './_setup';
66

7-
test('it creates and initializes a new mint account', async t => {
7+
it('creates and initializes a new mint account', async () => {
88
// Given an authority and a mint account.
99
const client = createDefaultSolanaClient();
1010
const authority = await generateKeyPairSignerWithSol(client);
@@ -24,7 +24,7 @@ test('it creates and initializes a new mint account', async t => {
2424

2525
// Then we expect the mint account to exist and have the following data.
2626
const mintAccount = await fetchMint(client.rpc, mint.address);
27-
t.like(mintAccount, <Account<Mint>>{
27+
expect(mintAccount).toMatchObject(<Account<Mint>>{
2828
address: mint.address,
2929
data: {
3030
mintAuthority: some(authority.address),
@@ -36,7 +36,7 @@ test('it creates and initializes a new mint account', async t => {
3636
});
3737
});
3838

39-
test('it creates a new mint account with a freeze authority', async t => {
39+
it('creates a new mint account with a freeze authority', async () => {
4040
// Given an authority and a mint account.
4141
const client = createDefaultSolanaClient();
4242
const [payer, mintAuthority, freezeAuthority, mint] = await Promise.all([
@@ -61,7 +61,7 @@ test('it creates a new mint account with a freeze authority', async t => {
6161

6262
// Then we expect the mint account to exist and have the following data.
6363
const mintAccount = await fetchMint(client.rpc, mint.address);
64-
t.like(mintAccount, <Account<Mint>>{
64+
expect(mintAccount).toMatchObject(<Account<Mint>>{
6565
address: mint.address,
6666
data: {
6767
mintAuthority: some(mintAuthority.address),
@@ -70,7 +70,7 @@ test('it creates a new mint account with a freeze authority', async t => {
7070
});
7171
});
7272

73-
test('it creates and initializes a new mint account using the token program plugin', async t => {
73+
it('creates and initializes a new mint account using the token program plugin', async () => {
7474
// Given a client with the token program plugin, and a mint account.
7575
const client = await createLocalClient().use(tokenProgram());
7676
const mint = await generateKeyPairSigner();
@@ -82,7 +82,7 @@ test('it creates and initializes a new mint account using the token program plug
8282

8383
// Then we expect the mint account to exist and have the following data.
8484
const mintAccount = await client.token.accounts.mint.fetch(mint.address);
85-
t.like(mintAccount, {
85+
expect(mintAccount).toMatchObject({
8686
address: mint.address,
8787
data: {
8888
mintAuthority: some(client.payer.address),

clients/js/test/initializeAccount.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getCreateAccountInstruction } from '@solana-program/system';
22
import { Account, appendTransactionMessageInstructions, generateKeyPairSigner, none, pipe } from '@solana/kit';
3-
import test from 'ava';
3+
import { expect, it } from 'vitest';
44
import {
55
AccountState,
66
TOKEN_PROGRAM_ADDRESS,
@@ -17,7 +17,7 @@ import {
1717
signAndSendTransaction,
1818
} from './_setup';
1919

20-
test('it creates and initializes a new token account', async t => {
20+
it('creates and initializes a new token account', async () => {
2121
// Given a mint account, its mint authority and two generated keypairs
2222
// for the token to be created and its owner.
2323
const client = createDefaultSolanaClient();
@@ -54,7 +54,7 @@ test('it creates and initializes a new token account', async t => {
5454

5555
// Then we expect the token account to exist and have the following data.
5656
const tokenAccount = await fetchToken(client.rpc, token.address);
57-
t.like(tokenAccount, <Account<Token>>{
57+
expect(tokenAccount).toMatchObject(<Account<Token>>{
5858
address: token.address,
5959
data: {
6060
mint,

0 commit comments

Comments
 (0)