Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit f9a93e5

Browse files
joncinquejordaaash
authored andcommitted
Port e2e tests to mocha
1 parent 70f2333 commit f9a93e5

15 files changed

+1173
-12
lines changed

token/js/.mocharc.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{
22
"extension": ["ts"],
3-
"node-option": ["experimental-specifier-resolution=node", "loader=ts-node/esm"],
4-
"spec": ["test/**/*.test.ts"]
3+
"node-option": ["experimental-specifier-resolution=node", "loader=ts-node/esm"]
54
}

token/js/.prettierignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
docs
22
lib
3-
3+
test-ledger

token/js/package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@
3131
"postbuild": "echo '{\"type\":\"commonjs\"}' > lib/cjs/package.json && echo '{\"type\":\"module\"}' > lib/esm/package.json",
3232
"deploy": "yarn docs && gh-pages --dist docs --dotfiles",
3333
"example": "node --experimental-specifier-resolution=node --loader ts-node/esm examples/create_mint_and_transfer_tokens.ts",
34-
"test": "mocha",
34+
"test": "yarn test:unit && yarn test:e2e-built && yarn test:e2e-native",
35+
"test:unit": "mocha test/unit",
36+
"test:e2e-built": "start-server-and-test 'solana-test-validator --bpf-program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA ../../target/deploy/spl_token.so --reset --quiet' http://localhost:8899/health 'mocha test/e2e'",
37+
"test:e2e-native": "start-server-and-test 'solana-test-validator --reset --quiet' http://localhost:8899/health 'mocha test/e2e'",
3538
"docs": "shx rm -rf docs && NODE_OPTIONS=--max_old_space_size=4096 typedoc && shx cp .nojekyll docs/",
3639
"fmt": "prettier --write '{*,**/*}.{js,ts,jsx,tsx,json}'",
3740
"lint": "eslint --ext .ts . && prettier --check '{*,**/*}.{js,ts,jsx,tsx,json}'",
@@ -41,7 +44,8 @@
4144
"dependencies": {
4245
"@solana/buffer-layout": "^4.0.0",
4346
"@solana/buffer-layout-utils": "^0.2.0",
44-
"@solana/web3.js": "^1.32.0"
47+
"@solana/web3.js": "^1.32.0",
48+
"start-server-and-test": "^1.14.0"
4549
},
4650
"devDependencies": {
4751
"@types/chai-as-promised": "^7.1.4",

token/js/test/e2e/burn.test.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import chai, { expect } from 'chai';
2+
import chaiAsPromised from 'chai-as-promised';
3+
chai.use(chaiAsPromised);
4+
5+
import { Connection, Keypair, PublicKey, Signer } from '@solana/web3.js';
6+
7+
import { TOKEN_PROGRAM_ID, createMint, createAccount, getAccount, mintTo, burn, burnChecked } from '../../src';
8+
9+
import { newAccountWithLamports, getConnection } from './common';
10+
11+
const TEST_TOKEN_DECIMALS = 2;
12+
describe('burn', () => {
13+
let connection: Connection;
14+
let payer: Signer;
15+
let mint: PublicKey;
16+
let mintAuthority: Keypair;
17+
let owner: Keypair;
18+
let account: PublicKey;
19+
let amount: bigint;
20+
before(async () => {
21+
connection = await getConnection();
22+
payer = await newAccountWithLamports(connection, 1000000000);
23+
mintAuthority = Keypair.generate();
24+
const mintKeypair = Keypair.generate();
25+
mint = await createMint(
26+
connection,
27+
payer,
28+
mintAuthority.publicKey,
29+
mintAuthority.publicKey,
30+
TEST_TOKEN_DECIMALS,
31+
mintKeypair,
32+
undefined,
33+
TOKEN_PROGRAM_ID
34+
);
35+
});
36+
beforeEach(async () => {
37+
owner = Keypair.generate();
38+
account = await createAccount(connection, payer, mint, owner.publicKey, undefined, undefined, TOKEN_PROGRAM_ID);
39+
amount = BigInt(1000);
40+
await mintTo(connection, payer, mint, account, mintAuthority, amount, [], undefined, TOKEN_PROGRAM_ID);
41+
});
42+
it('burn', async () => {
43+
const burnAmount = BigInt(1);
44+
await burn(connection, payer, account, mint, owner, burnAmount, [], undefined, TOKEN_PROGRAM_ID);
45+
const accountInfo = await getAccount(connection, account, undefined, TOKEN_PROGRAM_ID);
46+
expect(accountInfo.amount).to.eql(amount - burnAmount);
47+
});
48+
it('burnChecked', async () => {
49+
const burnAmount = BigInt(1);
50+
await burnChecked(
51+
connection,
52+
payer,
53+
account,
54+
mint,
55+
owner,
56+
burnAmount,
57+
TEST_TOKEN_DECIMALS,
58+
[],
59+
undefined,
60+
TOKEN_PROGRAM_ID
61+
);
62+
const accountInfo = await getAccount(connection, account, undefined, TOKEN_PROGRAM_ID);
63+
expect(accountInfo.amount).to.eql(amount - burnAmount);
64+
});
65+
});

token/js/test/e2e/close.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import chai, { expect } from 'chai';
2+
import chaiAsPromised from 'chai-as-promised';
3+
chai.use(chaiAsPromised);
4+
5+
import { Connection, Keypair, PublicKey, Signer } from '@solana/web3.js';
6+
7+
import { TOKEN_PROGRAM_ID, createMint, createAccount, closeAccount, mintTo } from '../../src';
8+
9+
import { newAccountWithLamports, getConnection } from './common';
10+
11+
const TEST_TOKEN_DECIMALS = 2;
12+
describe('freezeThaw', () => {
13+
let connection: Connection;
14+
let payer: Signer;
15+
let mint: PublicKey;
16+
let mintAuthority: Keypair;
17+
let freezeAuthority: Keypair;
18+
let owner: Keypair;
19+
let account: PublicKey;
20+
let destination: PublicKey;
21+
before(async () => {
22+
connection = await getConnection();
23+
payer = await newAccountWithLamports(connection, 1000000000);
24+
mintAuthority = Keypair.generate();
25+
freezeAuthority = Keypair.generate();
26+
const mintKeypair = Keypair.generate();
27+
mint = await createMint(
28+
connection,
29+
payer,
30+
mintAuthority.publicKey,
31+
freezeAuthority.publicKey,
32+
TEST_TOKEN_DECIMALS,
33+
mintKeypair,
34+
undefined,
35+
TOKEN_PROGRAM_ID
36+
);
37+
});
38+
beforeEach(async () => {
39+
owner = Keypair.generate();
40+
destination = Keypair.generate().publicKey;
41+
account = await createAccount(connection, payer, mint, owner.publicKey, undefined, undefined, TOKEN_PROGRAM_ID);
42+
});
43+
it('failsWithNonZeroAmount', async () => {
44+
const amount = BigInt(1000);
45+
await mintTo(connection, payer, mint, account, mintAuthority, amount, [], undefined, TOKEN_PROGRAM_ID);
46+
expect(closeAccount(connection, payer, account, destination, owner, [], undefined, TOKEN_PROGRAM_ID)).to.be
47+
.rejected;
48+
});
49+
it('works', async () => {
50+
const accountInfo = await connection.getAccountInfo(account);
51+
let tokenRentExemptAmount;
52+
expect(accountInfo).to.not.be.null;
53+
if (accountInfo !== null) {
54+
tokenRentExemptAmount = accountInfo.lamports;
55+
}
56+
57+
await closeAccount(connection, payer, account, destination, owner, [], undefined, TOKEN_PROGRAM_ID);
58+
59+
const closedInfo = await connection.getAccountInfo(account);
60+
expect(closedInfo).to.be.null;
61+
62+
const destinationInfo = await connection.getAccountInfo(destination);
63+
expect(destinationInfo).to.not.be.null;
64+
if (destinationInfo !== null) {
65+
expect(destinationInfo.lamports).to.eql(tokenRentExemptAmount);
66+
}
67+
});
68+
});

token/js/test/e2e/common.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Keypair, Connection, Signer } from '@solana/web3.js';
2+
3+
export async function newAccountWithLamports(connection: Connection, lamports = 1000000): Promise<Signer> {
4+
const account = Keypair.generate();
5+
const signature = await connection.requestAirdrop(account.publicKey, lamports);
6+
await connection.confirmTransaction(signature);
7+
return account;
8+
}
9+
10+
export async function getConnection(): Promise<Connection> {
11+
const url = 'http://localhost:8899';
12+
const connection = new Connection(url, 'confirmed');
13+
await connection.getVersion();
14+
return connection;
15+
}

token/js/test/e2e/create.test.ts

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import { Connection, Keypair, PublicKey, Signer } from '@solana/web3.js';
2+
3+
import chai, { expect } from 'chai';
4+
import chaiAsPromised from 'chai-as-promised';
5+
chai.use(chaiAsPromised);
6+
7+
import {
8+
TOKEN_PROGRAM_ID,
9+
ASSOCIATED_TOKEN_PROGRAM_ID,
10+
createMint,
11+
getMint,
12+
createAccount,
13+
getAccount,
14+
getAssociatedTokenAddress,
15+
} from '../../src';
16+
17+
import { newAccountWithLamports, getConnection } from './common';
18+
19+
const TEST_TOKEN_DECIMALS = 2;
20+
describe('createMint', () => {
21+
it('works', async () => {
22+
const connection = await getConnection();
23+
const payer = await newAccountWithLamports(connection, 1000000000);
24+
const testMintAuthority = Keypair.generate();
25+
const mintKeypair = Keypair.generate();
26+
const mint = await createMint(
27+
connection,
28+
payer,
29+
testMintAuthority.publicKey,
30+
testMintAuthority.publicKey,
31+
TEST_TOKEN_DECIMALS,
32+
mintKeypair,
33+
undefined,
34+
TOKEN_PROGRAM_ID
35+
);
36+
37+
const mintInfo = await getMint(connection, mint, undefined, TOKEN_PROGRAM_ID);
38+
39+
expect(mintInfo.mintAuthority).to.eql(testMintAuthority.publicKey);
40+
expect(mintInfo.supply).to.eql(BigInt(0));
41+
expect(mintInfo.decimals).to.eql(TEST_TOKEN_DECIMALS);
42+
expect(mintInfo.isInitialized).to.be.true;
43+
expect(mintInfo.freezeAuthority).to.eql(testMintAuthority.publicKey);
44+
});
45+
});
46+
47+
describe('createAccount', () => {
48+
let connection: Connection;
49+
let payer: Signer;
50+
let mint: PublicKey;
51+
before(async () => {
52+
connection = await getConnection();
53+
payer = await newAccountWithLamports(connection, 1000000000);
54+
const mintAuthority = Keypair.generate();
55+
const mintKeypair = Keypair.generate();
56+
mint = await createMint(
57+
connection,
58+
payer,
59+
mintAuthority.publicKey,
60+
mintAuthority.publicKey,
61+
TEST_TOKEN_DECIMALS,
62+
mintKeypair,
63+
undefined,
64+
TOKEN_PROGRAM_ID
65+
);
66+
}),
67+
it('auxiliary token account', async () => {
68+
const owner = Keypair.generate();
69+
const account = await createAccount(
70+
connection,
71+
payer,
72+
mint,
73+
owner.publicKey,
74+
Keypair.generate(),
75+
undefined,
76+
TOKEN_PROGRAM_ID
77+
);
78+
const accountInfo = await getAccount(connection, account, undefined, TOKEN_PROGRAM_ID);
79+
expect(accountInfo.mint).to.eql(mint);
80+
expect(accountInfo.owner).to.eql(owner.publicKey);
81+
expect(accountInfo.amount).to.eql(BigInt(0));
82+
expect(accountInfo.delegate).to.be.null;
83+
expect(accountInfo.delegatedAmount).to.eql(BigInt(0));
84+
expect(accountInfo.isInitialized).to.be.true;
85+
expect(accountInfo.isFrozen).to.be.false;
86+
expect(accountInfo.isNative).to.be.false;
87+
expect(accountInfo.rentExemptReserve).to.be.null;
88+
expect(accountInfo.closeAuthority).to.be.null;
89+
90+
// you can create as many accounts as with same owner
91+
const account2 = await createAccount(
92+
connection,
93+
payer,
94+
mint,
95+
owner.publicKey,
96+
Keypair.generate(),
97+
undefined,
98+
TOKEN_PROGRAM_ID
99+
);
100+
expect(account2).to.not.eql(account);
101+
}),
102+
it('associated token account', async () => {
103+
const owner = Keypair.generate();
104+
const associatedAddress = await getAssociatedTokenAddress(
105+
mint,
106+
owner.publicKey,
107+
false,
108+
TOKEN_PROGRAM_ID,
109+
ASSOCIATED_TOKEN_PROGRAM_ID
110+
);
111+
112+
// associated account shouldn't exist
113+
const info = await connection.getAccountInfo(associatedAddress);
114+
expect(info).to.be.null;
115+
116+
const createdAddress = await createAccount(
117+
connection,
118+
payer,
119+
mint,
120+
owner.publicKey,
121+
undefined, // uses ATA by default
122+
undefined,
123+
TOKEN_PROGRAM_ID
124+
);
125+
expect(createdAddress).to.eql(associatedAddress);
126+
127+
const accountInfo = await getAccount(connection, associatedAddress, undefined, TOKEN_PROGRAM_ID);
128+
expect(accountInfo).to.not.be.null;
129+
expect(accountInfo.mint).to.eql(mint);
130+
expect(accountInfo.owner).to.eql(owner.publicKey);
131+
expect(accountInfo.amount).to.eql(BigInt(0));
132+
133+
// creating again should cause TX error for the associated token account
134+
expect(
135+
createAccount(
136+
connection,
137+
payer,
138+
mint,
139+
owner.publicKey,
140+
undefined, // uses ATA by default
141+
undefined,
142+
TOKEN_PROGRAM_ID
143+
)
144+
).to.be.rejected;
145+
});
146+
});

0 commit comments

Comments
 (0)