chore: migrate tests to typescript
This commit is contained in:
parent
f912c63b22
commit
8ada44456d
|
@ -2,7 +2,6 @@
|
|||
/coverage
|
||||
/deploy
|
||||
/doc
|
||||
/flow-typed
|
||||
/lib
|
||||
/module.flow.js
|
||||
/.eslintrc.js
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
test/dist
|
||||
module.flow.js
|
||||
|
|
|
@ -8,8 +8,6 @@ test -r lib/index.iife.js
|
|||
test -r lib/index.cjs.js
|
||||
test -r lib/index.esm.js
|
||||
npm run doc
|
||||
npm run defs
|
||||
npm run flow
|
||||
npm run lint
|
||||
npm run codecov
|
||||
make -C examples/bpf-c-noop/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -56,12 +56,8 @@
|
|||
"codecov": "set -ex; npm run test:cover; cat ./coverage/lcov.info | codecov",
|
||||
"dev": "cross-env NODE_ENV=development rollup -c",
|
||||
"doc": "set -ex; typedoc",
|
||||
"defs": "set -ex; flow check-contents < module.flow.js; tsc module.d.ts",
|
||||
"doc:watch": "watch 'npm run doc' . --wait=1 --ignoreDirectoryPattern=/doc/",
|
||||
"examples": "set -ex; for example in examples/*.js; do node $example; done",
|
||||
"flow": "set -ex; flow stop; flow",
|
||||
"flow:stop": "flow stop",
|
||||
"flow:watch": "flow stop; watch 'flow' . --wait=1 --ignoreDirectoryPattern=/doc/",
|
||||
"lint": "set -ex; npm run pretty; eslint . --ext .js,.ts",
|
||||
"lint:fix": "npm run pretty:fix && eslint . --fix",
|
||||
"lint:watch": "watch 'npm run lint:fix' . --wait=1 --ignoreDirectoryPattern=/doc/",
|
||||
|
@ -69,13 +65,13 @@
|
|||
"localnet:logs": "bin/localnet.sh logs -f",
|
||||
"localnet:up": "bin/localnet.sh up",
|
||||
"localnet:update": "bin/localnet.sh update",
|
||||
"ok": "run-s lint flow test doc defs",
|
||||
"ok": "run-s lint test doc",
|
||||
"prepare": "run-s clean bpf-sdk:install bpf-sdk:remove-symlinks build",
|
||||
"pretty": "prettier --check '{,{examples,src,test}/**/}*.{j,t}s'",
|
||||
"pretty:fix": "prettier --write '{,{examples,src,test}/**/}*.{j,t}s'",
|
||||
"re": "semantic-release --repository-url git@github.com:solana-labs/solana-web3.js.git",
|
||||
"test": "npm run build:fixtures && mocha './test/**/*.test.js'",
|
||||
"test:cover": "nyc --reporter=lcov mocha './test/**/*.test.js'",
|
||||
"test": "npm run build:fixtures && mocha -r ts-node/register './test/**/*.test.ts'",
|
||||
"test:cover": "nyc --reporter=lcov mocha './test/**/*.test.ts'",
|
||||
"test:browser": "TEST_LIVE=1 npm run build:fixtures && npm run build:browser-test && mocha-headless-chrome -f http://localhost:8080/mocha.html --timeout 180000",
|
||||
"test:browser-with-server": "start-server-and-test 'http-server -p 8080' 8080 test:browser",
|
||||
"test:browser-with-test-validator": "start-server-and-test 'solana-test-validator --reset --quiet' http://localhost:8899/health test:browser-with-server",
|
||||
|
@ -116,9 +112,14 @@
|
|||
"@solana/spl-token": "^0.0.13",
|
||||
"@types/bn.js": "^5.1.0",
|
||||
"@types/bs58": "^4.0.1",
|
||||
"@types/chai": "^4.2.15",
|
||||
"@types/chai-as-promised": "^7.1.3",
|
||||
"@types/mocha": "^8.2.1",
|
||||
"@types/mz": "^2.7.3",
|
||||
"@types/node": "^14.14.26",
|
||||
"@types/node-fetch": "^2.5.8",
|
||||
"@types/secp256k1": "^4.0.1",
|
||||
"@types/sinon": "^9.0.11",
|
||||
"@typescript-eslint/eslint-plugin": "^4.14.2",
|
||||
"@typescript-eslint/parser": "^4.14.2",
|
||||
"chai": "^4.3.0",
|
||||
|
@ -127,14 +128,10 @@
|
|||
"cross-env": "7.0.3",
|
||||
"eslint": "^7.19.0",
|
||||
"eslint-config-prettier": "^8.0.0",
|
||||
"eslint-plugin-flowtype": "^5.2.0",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-mocha": "^8.0.0",
|
||||
"eslint-plugin-prettier": "^3.0.0",
|
||||
"esm": "^3.2.25",
|
||||
"flow-bin": "0.130.0",
|
||||
"flow-remove-types": "^2.143.1",
|
||||
"flow-typed": "3.3.1",
|
||||
"flowgen": "^1.13.0",
|
||||
"http-server": "^0.12.3",
|
||||
"mocha": "^8.2.1",
|
||||
|
@ -152,6 +149,7 @@
|
|||
"semantic-release": "^17.0.2",
|
||||
"sinon": "^9.2.4",
|
||||
"start-server-and-test": "^1.12.0",
|
||||
"ts-node": "^9.1.1",
|
||||
"tslib": "^2.1.0",
|
||||
"typedoc": "^0.20.31",
|
||||
"typescript": "^4.1.5",
|
||||
|
|
|
@ -27,8 +27,8 @@ function generateConfig(configType, format) {
|
|||
}),
|
||||
generateTypescript
|
||||
? typescript({
|
||||
browserslist: false,
|
||||
})
|
||||
browserslist: false,
|
||||
})
|
||||
: undefined,
|
||||
babel({
|
||||
exclude: '**/node_modules/**',
|
||||
|
|
|
@ -55,6 +55,12 @@ const BufferFromRawAccountData = coerce(
|
|||
value => Buffer.from(value[0], 'base64'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Attempt to use a recent blockhash for up to 30 seconds
|
||||
* @internal
|
||||
*/
|
||||
export const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
|
||||
|
||||
type RpcRequest = (methodName: string, args: Array<any>) => any;
|
||||
|
||||
export type TokenAccountsFilter =
|
||||
|
@ -2578,8 +2584,6 @@ export class Connection {
|
|||
while (this._pollingBlockhash) {
|
||||
await sleep(100);
|
||||
}
|
||||
// Attempt to use a recent blockhash for up to 30 seconds
|
||||
const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
|
||||
const timeSinceFetch = Date.now() - this._blockhashInfo.lastFetch;
|
||||
const expired = timeSinceFetch >= BLOCKHASH_CACHE_TIMEOUT_MS;
|
||||
if (this._blockhashInfo.recentBlockhash !== null && !expired) {
|
||||
|
|
|
@ -154,7 +154,7 @@ if (process.env.TEST_LIVE) {
|
|||
const {signatures, message} = parsedTx.transaction;
|
||||
expect(signatures[0]).to.eq(signature);
|
||||
const ix = message.instructions[0];
|
||||
if (ix.parsed) {
|
||||
if ('parsed' in ix) {
|
||||
expect('parsed' in ix).to.eq(false);
|
||||
} else {
|
||||
expect(ix.programId).to.eql(program.publicKey);
|
|
@ -5,8 +5,7 @@ import {clusterApiUrl} from '../src/util/cluster';
|
|||
describe('Cluster Util', () => {
|
||||
it('invalid', () => {
|
||||
expect(() => {
|
||||
// $FlowExpectedError
|
||||
clusterApiUrl('abc123');
|
||||
clusterApiUrl('abc123' as any);
|
||||
}).to.throw();
|
||||
});
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import bs58 from 'bs58';
|
||||
import invariant from 'assert';
|
||||
import {Buffer} from 'buffer';
|
||||
import {Token, u64} from '@solana/spl-token';
|
||||
import {expect, use} from 'chai';
|
||||
|
@ -18,7 +19,17 @@ import {
|
|||
} from '../src';
|
||||
import {DEFAULT_TICKS_PER_SLOT, NUM_TICKS_PER_SECOND} from '../src/timing';
|
||||
import {MOCK_PORT, url} from './url';
|
||||
import {BLOCKHASH_CACHE_TIMEOUT_MS} from '../src/connection';
|
||||
import {
|
||||
BLOCKHASH_CACHE_TIMEOUT_MS,
|
||||
Commitment,
|
||||
CompiledInnerInstruction,
|
||||
EpochInfo,
|
||||
EpochSchedule,
|
||||
InflationGovernor,
|
||||
ParsedInnerInstruction,
|
||||
ParsedInstruction,
|
||||
SlotInfo,
|
||||
} from '../src/connection';
|
||||
import {sleep} from '../src/util/sleep';
|
||||
import {
|
||||
helpers,
|
||||
|
@ -66,14 +77,15 @@ describe('Connection', () => {
|
|||
connection = new Connection(url);
|
||||
});
|
||||
|
||||
if (!process.env.TEST_LIVE) {
|
||||
if (mockServer) {
|
||||
const server = mockServer;
|
||||
beforeEach(() => {
|
||||
mockServer.start(MOCK_PORT);
|
||||
server.start(MOCK_PORT);
|
||||
stubRpcWebSocket(connection);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockServer.stop();
|
||||
server.stop();
|
||||
restoreRpcWebSocket(connection);
|
||||
});
|
||||
}
|
||||
|
@ -289,14 +301,15 @@ describe('Connection', () => {
|
|||
});
|
||||
|
||||
const inflation = await connection.getInflationGovernor();
|
||||
|
||||
for (const key of [
|
||||
const inflationKeys: (keyof InflationGovernor)[] = [
|
||||
'initial',
|
||||
'terminal',
|
||||
'taper',
|
||||
'foundation',
|
||||
'foundationTerm',
|
||||
]) {
|
||||
];
|
||||
|
||||
for (const key of inflationKeys) {
|
||||
expect(inflation).to.have.property(key);
|
||||
expect(inflation[key]).to.be.greaterThan(0);
|
||||
}
|
||||
|
@ -316,14 +329,15 @@ describe('Connection', () => {
|
|||
});
|
||||
|
||||
const epochInfo = await connection.getEpochInfo('confirmed');
|
||||
|
||||
for (const key of [
|
||||
const epochInfoKeys: (keyof EpochInfo)[] = [
|
||||
'epoch',
|
||||
'slotIndex',
|
||||
'slotsInEpoch',
|
||||
'absoluteSlot',
|
||||
'blockHeight',
|
||||
]) {
|
||||
];
|
||||
|
||||
for (const key of epochInfoKeys) {
|
||||
expect(epochInfo).to.have.property(key);
|
||||
expect(epochInfo[key]).to.be.at.least(0);
|
||||
}
|
||||
|
@ -343,13 +357,14 @@ describe('Connection', () => {
|
|||
});
|
||||
|
||||
const epochSchedule = await connection.getEpochSchedule();
|
||||
|
||||
for (const key of [
|
||||
const epochScheduleKeys: (keyof EpochSchedule)[] = [
|
||||
'firstNormalEpoch',
|
||||
'firstNormalSlot',
|
||||
'leaderScheduleSlotOffset',
|
||||
'slotsPerEpoch',
|
||||
]) {
|
||||
];
|
||||
|
||||
for (const key of epochScheduleKeys) {
|
||||
expect(epochSchedule).to.have.property('warmup');
|
||||
expect(epochSchedule).to.have.property(key);
|
||||
if (epochSchedule.warmup) {
|
||||
|
@ -385,7 +400,7 @@ describe('Connection', () => {
|
|||
});
|
||||
|
||||
const slot = await connection.getSlot();
|
||||
if (!process.env.TEST_LIVE) {
|
||||
if (mockServer) {
|
||||
expect(slot).to.eq(123);
|
||||
} else {
|
||||
// No idea what the correct slot value should be on a live cluster, so
|
||||
|
@ -402,7 +417,7 @@ describe('Connection', () => {
|
|||
});
|
||||
|
||||
const slotLeader = await connection.getSlotLeader();
|
||||
if (!process.env.TEST_LIVE) {
|
||||
if (mockServer) {
|
||||
expect(slotLeader).to.eq('11111111111111111111111111111111');
|
||||
} else {
|
||||
// No idea what the correct slotLeader value should be on a live cluster, so
|
||||
|
@ -427,7 +442,7 @@ describe('Connection', () => {
|
|||
});
|
||||
|
||||
const clusterNodes = await connection.getClusterNodes();
|
||||
if (!process.env.TEST_LIVE) {
|
||||
if (mockServer) {
|
||||
expect(clusterNodes).to.have.length(1);
|
||||
expect(clusterNodes[0].pubkey).to.eq('11111111111111111111111111111111');
|
||||
expect(typeof clusterNodes[0].gossip).to.eq('string');
|
||||
|
@ -564,8 +579,8 @@ describe('Connection', () => {
|
|||
|
||||
// Find a block that has a transaction, usually Block 1
|
||||
let slot = 0;
|
||||
let address: ?PublicKey;
|
||||
let expectedSignature: ?string;
|
||||
let address: PublicKey | undefined;
|
||||
let expectedSignature: string | undefined;
|
||||
while (!address || !expectedSignature) {
|
||||
slot++;
|
||||
const block = await connection.getConfirmedBlock(slot);
|
||||
|
@ -628,7 +643,7 @@ describe('Connection', () => {
|
|||
{limit: 1},
|
||||
);
|
||||
expect(confirmedSignatures2).to.have.length(1);
|
||||
if (!process.env.TEST_LIVE) {
|
||||
if (mockServer) {
|
||||
expect(confirmedSignatures2[0].signature).to.eq(expectedSignature);
|
||||
expect(confirmedSignatures2[0].slot).to.eq(slot);
|
||||
expect(confirmedSignatures2[0].err).to.be.null;
|
||||
|
@ -699,7 +714,7 @@ describe('Connection', () => {
|
|||
|
||||
// Find a block that has a transaction, usually Block 1
|
||||
let slot = 0;
|
||||
let confirmedTransaction: ?string;
|
||||
let confirmedTransaction: string | undefined;
|
||||
while (!confirmedTransaction) {
|
||||
slot++;
|
||||
const block = await connection.getConfirmedBlock(slot);
|
||||
|
@ -791,12 +806,12 @@ describe('Connection', () => {
|
|||
expect(nullResponse).to.be.null;
|
||||
});
|
||||
|
||||
if (!process.env.TEST_LIVE) {
|
||||
if (mockServer) {
|
||||
it('get parsed confirmed transaction coerces public keys of inner instructions', async () => {
|
||||
const confirmedTransaction: TransactionSignature =
|
||||
'4ADvAUQYxkh4qWKYE9QLW8gCLomGG94QchDLG4quvpBz1WqARYvzWQDDitKduAKspuy1DjcbnaDAnCAfnKpJYs48';
|
||||
|
||||
function getMockData(inner) {
|
||||
function getMockData(inner: any) {
|
||||
return {
|
||||
slot: 353050305,
|
||||
transaction: {
|
||||
|
@ -853,15 +868,10 @@ describe('Connection', () => {
|
|||
confirmedTransaction,
|
||||
);
|
||||
|
||||
if (
|
||||
result !== null &&
|
||||
result.meta &&
|
||||
result.meta.innerInstructions !== undefined &&
|
||||
result.meta.innerInstructions.length > 0
|
||||
) {
|
||||
expect(
|
||||
result.meta.innerInstructions[0].instructions[0].programId,
|
||||
).to.be.instanceOf(PublicKey);
|
||||
if (result && result.meta && result.meta.innerInstructions) {
|
||||
const innerInstructions = result.meta.innerInstructions;
|
||||
const firstIx = innerInstructions[0].instructions[0];
|
||||
expect(firstIx.programId).to.be.instanceOf(PublicKey);
|
||||
}
|
||||
|
||||
await mockRpcResponse({
|
||||
|
@ -877,15 +887,21 @@ describe('Connection', () => {
|
|||
}),
|
||||
});
|
||||
|
||||
//$FlowFixMe
|
||||
const result2 = await connection.getParsedConfirmedTransaction(
|
||||
confirmedTransaction,
|
||||
);
|
||||
|
||||
let instruction = result2.meta.innerInstructions[0].instructions[0];
|
||||
expect(instruction.programId).to.be.instanceOf(PublicKey);
|
||||
expect(instruction.accounts[0]).to.be.instanceOf(PublicKey);
|
||||
expect(instruction.accounts[1]).to.be.instanceOf(PublicKey);
|
||||
if (result2 && result2.meta && result2.meta.innerInstructions) {
|
||||
const innerInstructions = result2.meta.innerInstructions;
|
||||
const instruction = innerInstructions[0].instructions[0];
|
||||
expect(instruction.programId).to.be.instanceOf(PublicKey);
|
||||
if ('accounts' in instruction) {
|
||||
expect(instruction.accounts[0]).to.be.instanceOf(PublicKey);
|
||||
expect(instruction.accounts[1]).to.be.instanceOf(PublicKey);
|
||||
} else {
|
||||
expect('accounts' in instruction).to.be.true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -998,7 +1014,8 @@ describe('Connection', () => {
|
|||
});
|
||||
|
||||
it('get recent blockhash', async () => {
|
||||
for (const commitment of ['processed', 'confirmed', 'finalized']) {
|
||||
const commitments: Commitment[] = ['processed', 'confirmed', 'finalized'];
|
||||
for (const commitment of commitments) {
|
||||
const {blockhash, feeCalculator} = await helpers.recentBlockhash({
|
||||
connection,
|
||||
commitment,
|
||||
|
@ -1189,7 +1206,7 @@ describe('Connection', () => {
|
|||
|
||||
testOwner = accountOwner;
|
||||
testToken = token;
|
||||
testTokenAccount = tokenAccount;
|
||||
testTokenAccount = tokenAccount as PublicKey;
|
||||
});
|
||||
|
||||
it('get token supply', async () => {
|
||||
|
@ -1229,7 +1246,7 @@ describe('Connection', () => {
|
|||
const {signatures, message} = parsedTx.transaction;
|
||||
expect(signatures[0]).to.eq(testSignature);
|
||||
const ix = message.instructions[0];
|
||||
if (ix.parsed) {
|
||||
if ('parsed' in ix) {
|
||||
expect(ix.program).to.eq('spl-token');
|
||||
expect(ix.programId).to.eql(TOKEN_PROGRAM_ID);
|
||||
} else {
|
||||
|
@ -1456,11 +1473,11 @@ describe('Connection', () => {
|
|||
});
|
||||
}
|
||||
|
||||
if (!process.env.TEST_LIVE) {
|
||||
if (mockServer) {
|
||||
it('stake activation should only accept state with valid string literals', async () => {
|
||||
const publicKey = new Account().publicKey;
|
||||
|
||||
const addStakeActivationMock = async state => {
|
||||
const addStakeActivationMock = async (state: any) => {
|
||||
await mockRpcResponse({
|
||||
method: 'getStakeActivation',
|
||||
params: [publicKey.toBase58(), {}],
|
||||
|
@ -1567,7 +1584,7 @@ describe('Connection', () => {
|
|||
if (parsedAccountInfo === null) {
|
||||
expect(parsedAccountInfo).not.to.be.null;
|
||||
return;
|
||||
} else if (parsedAccountInfo.data.parsed) {
|
||||
} else if ('parsed' in parsedAccountInfo.data) {
|
||||
expect(parsedAccountInfo.data.parsed).not.to.be.ok;
|
||||
return;
|
||||
}
|
||||
|
@ -1616,6 +1633,7 @@ describe('Connection', () => {
|
|||
).value;
|
||||
expect(confirmResult.err).to.eql(expectedErr);
|
||||
|
||||
invariant(transaction.signature);
|
||||
const signature = bs58.encode(transaction.signature);
|
||||
await mockRpcResponse({
|
||||
method: 'getSignatureStatuses',
|
||||
|
@ -1814,7 +1832,7 @@ describe('Connection', () => {
|
|||
});
|
||||
|
||||
// it('account change notification', async () => {
|
||||
// if (!process.env.TEST_LIVE) {
|
||||
// if (mockServer) {
|
||||
// console.log('non-live test skipped');
|
||||
// return;
|
||||
// }
|
||||
|
@ -1939,7 +1957,7 @@ describe('Connection', () => {
|
|||
});
|
||||
|
||||
it('slot notification', async () => {
|
||||
let notifiedSlotInfo;
|
||||
let notifiedSlotInfo: SlotInfo | undefined;
|
||||
const subscriptionId = connection.onSlotChange(slotInfo => {
|
||||
notifiedSlotInfo = slotInfo;
|
||||
});
|
||||
|
@ -1963,7 +1981,7 @@ describe('Connection', () => {
|
|||
});
|
||||
|
||||
it('root notification', async () => {
|
||||
let roots = [];
|
||||
let roots: number[] = [];
|
||||
const subscriptionId = connection.onRootChange(root => {
|
||||
roots.push(root);
|
||||
});
|
|
@ -1,20 +1,21 @@
|
|||
import bs58 from 'bs58';
|
||||
import BN from 'bn.js';
|
||||
import invariant from 'assert';
|
||||
import * as mockttp from 'mockttp';
|
||||
|
||||
import {mockRpcMessage} from './rpc-websockets';
|
||||
import {Account, Connection, PublicKey, Transaction} from '../../src';
|
||||
import type {Commitment} from '../../src/connection';
|
||||
|
||||
export const mockServer: mockttp.Mockttp =
|
||||
process.env.TEST_LIVE || mockttp.getLocal();
|
||||
export const mockServer: mockttp.Mockttp | undefined =
|
||||
process.env.TEST_LIVE === undefined ? mockttp.getLocal() : undefined;
|
||||
|
||||
let uniqueCounter = 0;
|
||||
export const uniqueSignature = () => {
|
||||
return bs58.encode(new BN(++uniqueCounter).toArray(null, 64));
|
||||
return bs58.encode(new BN(++uniqueCounter).toArray(undefined, 64));
|
||||
};
|
||||
export const uniqueBlockhash = () => {
|
||||
return bs58.encode(new BN(++uniqueCounter).toArray(null, 32));
|
||||
return bs58.encode(new BN(++uniqueCounter).toArray(undefined, 32));
|
||||
};
|
||||
|
||||
export const mockErrorMessage = 'Invalid';
|
||||
|
@ -30,13 +31,13 @@ export const mockRpcResponse = async ({
|
|||
error,
|
||||
withContext,
|
||||
}: {
|
||||
method: string,
|
||||
params: Array<any>,
|
||||
value?: any,
|
||||
error?: any,
|
||||
withContext?: boolean,
|
||||
method: string;
|
||||
params: Array<any>;
|
||||
value?: any;
|
||||
error?: any;
|
||||
withContext?: boolean;
|
||||
}) => {
|
||||
if (process.env.TEST_LIVE) return;
|
||||
if (!mockServer) return;
|
||||
|
||||
let result = value;
|
||||
if (withContext) {
|
||||
|
@ -70,8 +71,8 @@ const recentBlockhash = async ({
|
|||
connection,
|
||||
commitment,
|
||||
}: {
|
||||
connection: Connection,
|
||||
commitment?: Commitment,
|
||||
connection: Connection;
|
||||
commitment?: Commitment;
|
||||
}) => {
|
||||
const blockhash = uniqueBlockhash();
|
||||
const params = [];
|
||||
|
@ -101,17 +102,18 @@ const processTransaction = async ({
|
|||
commitment,
|
||||
err,
|
||||
}: {
|
||||
connection: Connection,
|
||||
transaction: Transaction,
|
||||
signers: Array<Account>,
|
||||
commitment: Commitment,
|
||||
err?: any,
|
||||
connection: Connection;
|
||||
transaction: Transaction;
|
||||
signers: Array<Account>;
|
||||
commitment: Commitment;
|
||||
err?: any;
|
||||
}) => {
|
||||
const blockhash = (await recentBlockhash({connection})).blockhash;
|
||||
transaction.recentBlockhash = blockhash;
|
||||
transaction.sign(...signers);
|
||||
|
||||
const encoded = transaction.serialize().toString('base64');
|
||||
invariant(transaction.signature !== null);
|
||||
const signature = bs58.encode(transaction.signature);
|
||||
await mockRpcResponse({
|
||||
method: 'sendTransaction',
|
||||
|
@ -146,9 +148,9 @@ const airdrop = async ({
|
|||
address,
|
||||
amount,
|
||||
}: {
|
||||
connection: Connection,
|
||||
address: PublicKey,
|
||||
amount: number,
|
||||
connection: Connection;
|
||||
address: PublicKey;
|
||||
amount: number;
|
||||
}) => {
|
||||
await mockRpcResponse({
|
||||
method: 'requestAirdrop',
|
|
@ -5,15 +5,15 @@ import sinon from 'sinon';
|
|||
import {Connection} from '../../src';
|
||||
|
||||
type RpcRequest = {
|
||||
method: string,
|
||||
params?: Array<any>,
|
||||
method: string;
|
||||
params?: Array<any>;
|
||||
};
|
||||
|
||||
type RpcResponse = {
|
||||
context: {
|
||||
slot: number,
|
||||
},
|
||||
value: any,
|
||||
slot: number;
|
||||
};
|
||||
value: any;
|
||||
};
|
||||
|
||||
const mockRpcSocket: Array<[RpcRequest, RpcResponse]> = [];
|
||||
|
@ -24,9 +24,9 @@ export const mockRpcMessage = ({
|
|||
params,
|
||||
result,
|
||||
}: {
|
||||
method: string,
|
||||
params: Array<any>,
|
||||
result: any,
|
||||
method: string;
|
||||
params: Array<any>;
|
||||
result: any;
|
||||
}) => {
|
||||
mockRpcSocket.push([
|
||||
{method, params},
|
||||
|
@ -46,9 +46,11 @@ export const stubRpcWebSocket = (connection: Connection) => {
|
|||
sandbox.stub(rpcWebSocket, 'close').callsFake(() => {
|
||||
mockClient.close();
|
||||
});
|
||||
sandbox.stub(rpcWebSocket, 'call').callsFake((method, params) => {
|
||||
return mockClient.call(method, params);
|
||||
});
|
||||
sandbox
|
||||
.stub(rpcWebSocket, 'call')
|
||||
.callsFake((method: string, params: any) => {
|
||||
return mockClient.call(method, params);
|
||||
});
|
||||
};
|
||||
|
||||
export const restoreRpcWebSocket = (connection: Connection) => {
|
||||
|
@ -85,7 +87,10 @@ class MockClient {
|
|||
|
||||
call(method: string, params: Array<any>): Promise<Object> {
|
||||
expect(mockRpcSocket.length).to.be.at.least(1);
|
||||
const [mockRequest, mockResponse] = mockRpcSocket.shift();
|
||||
const [mockRequest, mockResponse] = mockRpcSocket.shift() as [
|
||||
RpcRequest,
|
||||
RpcResponse,
|
||||
];
|
||||
|
||||
expect(method).to.eq(mockRequest.method);
|
||||
expect(params).to.eql(mockRequest.params);
|
|
@ -31,14 +31,15 @@ describe('Nonce', () => {
|
|||
connection = new Connection(url);
|
||||
});
|
||||
|
||||
if (!process.env.TEST_LIVE) {
|
||||
if (mockServer) {
|
||||
const server = mockServer;
|
||||
beforeEach(() => {
|
||||
mockServer.start(MOCK_PORT);
|
||||
server.start(MOCK_PORT);
|
||||
stubRpcWebSocket(connection);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockServer.stop();
|
||||
server.stop();
|
||||
restoreRpcWebSocket(connection);
|
||||
});
|
||||
}
|
|
@ -1,17 +1,18 @@
|
|||
import alias from '@rollup/plugin-alias';
|
||||
import babel from '@rollup/plugin-babel';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import flowRemoveTypes from 'flow-remove-types';
|
||||
import json from '@rollup/plugin-json';
|
||||
import multi from '@rollup/plugin-multi-entry';
|
||||
import nodeResolve from '@rollup/plugin-node-resolve';
|
||||
import nodePolyfills from 'rollup-plugin-node-polyfills';
|
||||
import replace from '@rollup/plugin-replace';
|
||||
|
||||
const extensions = ['.js', '.ts'];
|
||||
|
||||
export default {
|
||||
input: {
|
||||
include: ['test/**/*.test.js'],
|
||||
exclude: ['test/agent-manager.test.js', 'test/bpf-loader.test.js'],
|
||||
include: ['test/**/*.test.ts'],
|
||||
exclude: ['test/agent-manager.test.ts', 'test/bpf-loader.test.ts'],
|
||||
},
|
||||
external: ['node-forge', 'http2', '_stream_wrap'],
|
||||
output: {
|
||||
|
@ -20,16 +21,17 @@ export default {
|
|||
sourcemap: true,
|
||||
},
|
||||
plugins: [
|
||||
flow(),
|
||||
multi(),
|
||||
commonjs(),
|
||||
nodeResolve({
|
||||
browser: true,
|
||||
preferBuiltins: false,
|
||||
extensions,
|
||||
dedupe: ['bn.js', 'buffer'],
|
||||
}),
|
||||
babel({
|
||||
exclude: '**/node_modules/**',
|
||||
extensions,
|
||||
babelHelpers: 'runtime',
|
||||
plugins: ['@babel/plugin-transform-runtime'],
|
||||
}),
|
||||
|
@ -54,18 +56,6 @@ export default {
|
|||
}
|
||||
},
|
||||
treeshake: {
|
||||
moduleSideEffects: path => path.endsWith('test.js'),
|
||||
moduleSideEffects: path => path.endsWith('test.ts'),
|
||||
},
|
||||
};
|
||||
|
||||
// Using this instead of rollup-plugin-flow due to
|
||||
// https://github.com/leebyron/rollup-plugin-flow/issues/5
|
||||
function flow() {
|
||||
return {
|
||||
name: 'flow-remove-types',
|
||||
transform: code => ({
|
||||
code: flowRemoveTypes(code).toString(),
|
||||
map: null,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ function checkEncodedArray(
|
|||
|
||||
describe('shortvec', () => {
|
||||
it('decodeLength', () => {
|
||||
let array = [];
|
||||
let array: number[] = [];
|
||||
checkDecodedArray(array, 0);
|
||||
|
||||
array = [5];
|
||||
|
@ -47,7 +47,7 @@ describe('shortvec', () => {
|
|||
});
|
||||
|
||||
it('encodeLength', () => {
|
||||
let array = [];
|
||||
let array: number[] = [];
|
||||
let prevLength = 1;
|
||||
checkEncodedArray(array, 0, prevLength, 1, [0]);
|
||||
|
||||
|
@ -63,7 +63,7 @@ describe('shortvec', () => {
|
|||
|
||||
checkEncodedArray(array, 0x7fff, (prevLength += 3), 3, [0xff, 0xff, 0x01]);
|
||||
|
||||
prevLength = checkEncodedArray(array, 0x200000, (prevLength += 4), 4, [
|
||||
checkEncodedArray(array, 0x200000, (prevLength += 4), 4, [
|
||||
0x80,
|
||||
0x80,
|
||||
0x80,
|
|
@ -1,4 +1,5 @@
|
|||
import base58 from 'bs58';
|
||||
import invariant from 'assert';
|
||||
import {expect} from 'chai';
|
||||
|
||||
import {
|
||||
|
@ -18,14 +19,15 @@ describe('Transaction Payer', () => {
|
|||
connection = new Connection(url);
|
||||
});
|
||||
|
||||
if (!process.env.TEST_LIVE) {
|
||||
if (mockServer) {
|
||||
const server = mockServer;
|
||||
beforeEach(() => {
|
||||
mockServer.start(MOCK_PORT);
|
||||
server.start(MOCK_PORT);
|
||||
stubRpcWebSocket(connection);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockServer.stop();
|
||||
server.stop();
|
||||
restoreRpcWebSocket(connection);
|
||||
});
|
||||
}
|
||||
|
@ -76,6 +78,7 @@ describe('Transaction Payer', () => {
|
|||
commitment: 'confirmed',
|
||||
});
|
||||
|
||||
invariant(transaction.signature);
|
||||
const signature = base58.encode(transaction.signature);
|
||||
|
||||
await mockRpcResponse({
|
|
@ -1,4 +1,5 @@
|
|||
import bs58 from 'bs58';
|
||||
import invariant from 'assert';
|
||||
import {Buffer} from 'buffer';
|
||||
import nacl from 'tweetnacl';
|
||||
import {expect} from 'chai';
|
||||
|
@ -9,6 +10,7 @@ import {Transaction} from '../src/transaction';
|
|||
import {StakeProgram} from '../src/stake-program';
|
||||
import {SystemProgram} from '../src/system-program';
|
||||
import {Message} from '../src/message';
|
||||
import {toBuffer} from '../src/util/to-buffer';
|
||||
|
||||
describe('Transaction', () => {
|
||||
describe('compileMessage', () => {
|
||||
|
@ -160,22 +162,17 @@ describe('Transaction', () => {
|
|||
|
||||
expect(partialTransaction).to.eql(transaction);
|
||||
|
||||
if (
|
||||
partialTransaction.signatures[0].signature != null /* <-- pacify flow */
|
||||
) {
|
||||
partialTransaction.signatures[0].signature[0] = 0;
|
||||
expect(() =>
|
||||
partialTransaction.serialize({requireAllSignatures: false}),
|
||||
).to.throw();
|
||||
expect(() =>
|
||||
partialTransaction.serialize({
|
||||
verifySignatures: false,
|
||||
requireAllSignatures: false,
|
||||
}),
|
||||
).not.to.throw();
|
||||
} else {
|
||||
throw new Error('unreachable');
|
||||
}
|
||||
invariant(partialTransaction.signatures[0].signature);
|
||||
partialTransaction.signatures[0].signature[0] = 0;
|
||||
expect(() =>
|
||||
partialTransaction.serialize({requireAllSignatures: false}),
|
||||
).to.throw();
|
||||
expect(() =>
|
||||
partialTransaction.serialize({
|
||||
verifySignatures: false,
|
||||
requireAllSignatures: false,
|
||||
}),
|
||||
).not.to.throw();
|
||||
});
|
||||
|
||||
describe('dedupe', () => {
|
||||
|
@ -261,7 +258,6 @@ describe('Transaction', () => {
|
|||
|
||||
const newTransaction = new Transaction({
|
||||
recentBlockhash: orgTransaction.recentBlockhash,
|
||||
feePayer: orgTransaction.feePayer,
|
||||
signatures: orgTransaction.signatures,
|
||||
}).add(transfer1, transfer2);
|
||||
|
||||
|
@ -451,7 +447,7 @@ describe('Transaction', () => {
|
|||
// Serializing the message is allowed when signature array has null signatures
|
||||
expectedTransaction.serializeMessage();
|
||||
|
||||
expectedTransaction.feePayer = null;
|
||||
expectedTransaction.feePayer = undefined;
|
||||
expectedTransaction.setSigners(sender.publicKey);
|
||||
expect(expectedTransaction.signatures).to.have.length(1);
|
||||
|
||||
|
@ -510,7 +506,7 @@ describe('Transaction', () => {
|
|||
tx.setSigners(from.publicKey);
|
||||
const tx_bytes = tx.serializeMessage();
|
||||
const signature = nacl.sign.detached(tx_bytes, from.secretKey);
|
||||
tx.addSignature(from.publicKey, signature);
|
||||
tx.addSignature(from.publicKey, toBuffer(signature));
|
||||
expect(tx.verifySignatures()).to.be.true;
|
||||
});
|
||||
|
||||
|
@ -532,7 +528,7 @@ describe('Transaction', () => {
|
|||
tx.feePayer = from.publicKey;
|
||||
const tx_bytes = tx.serializeMessage();
|
||||
const signature = nacl.sign.detached(tx_bytes, from.secretKey);
|
||||
tx.addSignature(from.publicKey, signature);
|
||||
tx.addSignature(from.publicKey, toBuffer(signature));
|
||||
expect(tx.verifySignatures()).to.be.true;
|
||||
});
|
||||
});
|
|
@ -16,7 +16,11 @@
|
|||
"isolatedModules": true,
|
||||
"baseUrl": "src",
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitReturns": true
|
||||
"noImplicitReturns": true,
|
||||
"paths": {
|
||||
// This is needed so that @solana/spl-token's @solana/web3.js doesn't conflict
|
||||
"@solana/web3.js": ["."]
|
||||
}
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue