chore: replace jest with mocha

This commit is contained in:
Justin Starry
2021-02-06 10:59:00 +08:00
committed by Justin Starry
parent 612958ece0
commit c675c67c26
41 changed files with 4635 additions and 6665 deletions

View File

@ -0,0 +1,170 @@
// @flow
import bs58 from 'bs58';
import BN from 'bn.js';
import * as mockttp from 'mockttp';
import {mockRpcMessage} from './rpc-websockets';
import {Connection} from '../../src';
import type {Commitment} from '../../src/connection';
export const mockServer = process.env.TEST_LIVE || mockttp.getLocal();
let uniqueCounter = 0;
export const uniqueSignature = () => {
return bs58.encode(new BN(++uniqueCounter).toArray(null, 64));
};
export const uniqueBlockhash = () => {
return bs58.encode(new BN(++uniqueCounter).toArray(null, 32));
};
export const mockErrorMessage = 'Invalid';
export const mockErrorResponse = {
code: -32602,
message: mockErrorMessage,
};
export const mockRpcResponse = async ({
method,
params,
value,
error,
withContext,
}: {
method: string,
params: Array<any>,
value: any,
error: any,
withContext?: boolean,
}) => {
if (process.env.TEST_LIVE) return;
let result = withContext
? {
context: {
slot: 11,
},
value,
}
: value;
await mockServer
.post('/')
.withJsonBodyIncluding({
jsonrpc: '2.0',
method,
params,
})
.thenReply(
200,
JSON.stringify({
jsonrpc: '2.0',
id: '',
error,
result,
}),
);
};
const recentBlockhash = async ({
connection,
commitment,
}: {
connection: Connection,
commitment: ?Commitment,
}) => {
const blockhash = uniqueBlockhash();
const params = [];
if (commitment) {
params.push({commitment});
}
await mockRpcResponse({
method: 'getRecentBlockhash',
params,
value: {
blockhash,
feeCalculator: {
lamportsPerSignature: 42,
},
},
withContext: true,
});
return await connection.getRecentBlockhash(commitment);
};
const processTransaction = async ({
connection,
transaction,
signers,
commitment,
err,
}: {
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');
const signature = bs58.encode(transaction.signature);
await mockRpcResponse({
method: 'sendTransaction',
params: [encoded],
value: signature,
});
const sendOptions = err
? {
skipPreflight: true,
}
: {
preflightCommitment: commitment,
};
await connection.sendEncodedTransaction(encoded, sendOptions);
await mockRpcMessage({
method: 'signatureSubscribe',
params: [signature, {commitment}],
result: {err: err || null},
});
return await connection.confirmTransaction(signature, commitment);
};
const airdrop = async ({
connection,
address,
amount,
}: {
connection: Connection,
address: PublicKey,
amount: number,
}) => {
await mockRpcResponse({
method: 'requestAirdrop',
params: [address.toBase58(), amount],
value: uniqueSignature(),
});
const signature = await connection.requestAirdrop(address, amount);
await mockRpcMessage({
method: 'signatureSubscribe',
params: [signature, {commitment: 'singleGossip'}],
result: {err: null},
});
await connection.confirmTransaction(signature, 'singleGossip');
return signature;
};
export const helpers = {
airdrop,
processTransaction,
recentBlockhash,
};

View File

@ -0,0 +1,106 @@
// @flow
import {Client as LiveClient} from 'rpc-websockets';
import {expect} from 'chai';
import sinon from 'sinon';
import {Connection} from '../../src';
type RpcRequest = {
method: string,
params?: Array<any>,
};
type RpcResponse = {
context: {
slot: number,
},
value: any,
};
const mockRpcSocket: Array<[RpcRequest, RpcResponse]> = [];
const sandbox = sinon.createSandbox();
export const mockRpcMessage = ({
method,
params,
result,
}: {
method: string,
params: Array<any>,
result: any,
}) => {
mockRpcSocket.push([
{method, params},
{
context: {slot: 11},
value: result,
},
]);
};
export const stubRpcWebSocket = (connection: Connection) => {
const rpcWebSocket = connection._rpcWebSocket;
const mockClient = new MockClient(rpcWebSocket);
sandbox.stub(rpcWebSocket, 'connect').callsFake(() => {
mockClient.connect();
});
sandbox.stub(rpcWebSocket, 'close').callsFake(() => {
mockClient.close();
});
sandbox.stub(rpcWebSocket, 'call').callsFake((method, params) => {
return mockClient.call(method, params);
});
};
export const restoreRpcWebSocket = (connection: Connection) => {
connection._rpcWebSocket.close();
if (connection._rpcWebSocketIdleTimeout !== null) {
clearTimeout(connection._rpcWebSocketIdleTimeout);
connection._rpcWebSocketIdleTimeout = null;
}
sandbox.restore();
};
class MockClient {
mockOpen = false;
subscriptionCounter = 0;
constructor(rpcWebSocket: LiveClient) {
this.client = rpcWebSocket;
}
connect() {
if (!this.mockOpen) {
this.mockOpen = true;
this.client.emit('open');
}
}
close() {
if (this.mockOpen) {
this.mockOpen = false;
this.client.emit('close');
}
}
call(method: string, params: Array<any>): Promise<Object> {
expect(mockRpcSocket.length).to.be.at.least(1);
const [mockRequest, mockResponse] = mockRpcSocket.shift();
expect(method).to.eq(mockRequest.method);
expect(params).to.eql(mockRequest.params);
let id = ++this.subscriptionCounter;
const response = {
subscription: id,
result: mockResponse,
};
setImmediate(() => {
const eventName = method.replace('Subscribe', 'Notification');
this.client.emit(eventName, response);
});
return Promise.resolve(id);
}
}