chore: typecheck web3.js tests (#29422)
* fix: web3.js test typescript errors Fixes the typescript errors throughout the web3.js test suite * fix: node14 test AbortController is a default in node16 but needs to be imported for node14 * fix: additional typescript errors Adds the tests to the tsconfig to auto-include mocha and fixes remaining typescript errors * fix: graphql-tools to work with typescript version of graphql-tools initially installed has incompatible types preventing ./scripts/typegen.sh from passing when tests are added to the include path of tsconfig.json * Don't build typedefs for tests Co-authored-by: steveluscher <me+github@steveluscher.com>
This commit is contained in:
parent
84e0d12f91
commit
9679bc6d1f
File diff suppressed because it is too large
Load Diff
|
@ -42,16 +42,16 @@
|
|||
"clean": "rimraf ./coverage ./lib",
|
||||
"codecov": "set -ex; npm run test:cover; cat ./coverage/lcov.info | codecov",
|
||||
"dev": "cross-env NODE_ENV=development rollup -c",
|
||||
"doc": "set -ex; typedoc --treatWarningsAsErrors",
|
||||
"doc": "set -ex; typedoc --tsconfig ./tsconfig.library.json --treatWarningsAsErrors",
|
||||
"type:gen": "./scripts/typegen.sh",
|
||||
"lint": "set -ex; npm run pretty; eslint . --ext .js,.ts",
|
||||
"lint:fix": "npm run pretty:fix && eslint . --fix --ext .js,.ts",
|
||||
"type:check": "tsc -p tsconfig.json --noEmit",
|
||||
"type:check": "tsc -p tsconfig.library.json --noEmit && tsc -p tsconfig.tests.json --noEmit",
|
||||
"ok": "run-s lint test doc type:check",
|
||||
"pretty": "prettier --check '{,{src,test}/**/}*.{j,t}s'",
|
||||
"pretty:fix": "prettier --write '{,{src,test}/**/}*.{j,t}s'",
|
||||
"re": "semantic-release --repository-url git@github.com:solana-labs/solana-web3.js.git",
|
||||
"test": "cross-env NODE_ENV=test TS_NODE_COMPILER_OPTIONS='{ \"module\": \"commonjs\", \"target\": \"es2019\" }' ts-mocha --require esm './test/**/*.test.ts'",
|
||||
"test": "cross-env NODE_ENV=test TS_NODE_COMPILER_OPTIONS='{ \"module\": \"commonjs\", \"target\": \"es2019\" }' ts-mocha -p ./tsconfig.tests.json --require esm './test/**/*.test.ts'",
|
||||
"test:cover": "nyc --reporter=lcov npm run test",
|
||||
"test:live": "TEST_LIVE=1 npm run test",
|
||||
"test:live-with-test-validator": "start-server-and-test 'solana-test-validator --reset --quiet' http://localhost:8899/health test:live"
|
||||
|
@ -113,7 +113,7 @@
|
|||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"esm": "^3.2.25",
|
||||
"mocha": "^10.1.0",
|
||||
"mockttp": "^2.0.1",
|
||||
"mockttp": "^3.6.2",
|
||||
"mz": "^2.7.0",
|
||||
"node-abort-controller": "^3.0.1",
|
||||
"npm-run-all": "^4.1.5",
|
||||
|
|
|
@ -2,7 +2,6 @@ import alias from '@rollup/plugin-alias';
|
|||
import babel from '@rollup/plugin-babel';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import * as fs from 'fs';
|
||||
import json from '@rollup/plugin-json';
|
||||
import path from 'path';
|
||||
import nodeResolve from '@rollup/plugin-node-resolve';
|
||||
import replace from '@rollup/plugin-replace';
|
||||
|
|
|
@ -4,4 +4,5 @@ export default {
|
|||
input: './declarations/index.d.ts',
|
||||
output: [{file: 'lib/index.d.ts', format: 'es'}],
|
||||
plugins: [dts()],
|
||||
external: ['http', 'https'],
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import fs from 'mz/fs';
|
||||
import {expect, use} from 'chai';
|
||||
import chaiAsPromised from 'chai-as-promised';
|
||||
import {fail} from 'assert';
|
||||
|
||||
import {
|
||||
Connection,
|
||||
|
@ -160,10 +161,15 @@ if (process.env.TEST_LIVE) {
|
|||
])
|
||||
).value;
|
||||
const expectedReturnData = new Uint8Array([1, 2, 3]);
|
||||
var decodedData = Buffer.from(returnData.data[0], returnData.data[1]);
|
||||
expect(err).to.be.null;
|
||||
expect(returnData.programId).to.eql(program.publicKey.toString());
|
||||
expect(decodedData).to.eql(expectedReturnData);
|
||||
|
||||
if (returnData) {
|
||||
var decodedData = Buffer.from(returnData.data[0], returnData.data[1]);
|
||||
expect(err).to.be.null;
|
||||
expect(returnData.programId).to.eql(program.publicKey.toString());
|
||||
expect(decodedData).to.eql(expectedReturnData);
|
||||
} else {
|
||||
fail('return data must be defined!');
|
||||
}
|
||||
});
|
||||
|
||||
it('deprecated - simulate transaction without signature verification', async () => {
|
||||
|
|
|
@ -551,7 +551,7 @@ describe('Subscriptions', () => {
|
|||
});
|
||||
});
|
||||
describe('upon the socket connection reopening', () => {
|
||||
let fatalPriorUnubscribe;
|
||||
let fatalPriorUnubscribe: () => void;
|
||||
beforeEach(() => {
|
||||
fatalPriorUnubscribe = fatalUnsubscribe;
|
||||
stubbedSocket.call.resetHistory();
|
||||
|
@ -699,7 +699,7 @@ describe('Subscriptions', () => {
|
|||
});
|
||||
});
|
||||
describe('upon the socket connection reopening', () => {
|
||||
let fatalPriorSubscription;
|
||||
let fatalPriorSubscription: () => void;
|
||||
beforeEach(() => {
|
||||
fatalPriorSubscription = fatalSubscription;
|
||||
stubbedSocket.call.resetHistory();
|
||||
|
|
|
@ -5,9 +5,9 @@ import {expect, use} from 'chai';
|
|||
import chaiAsPromised from 'chai-as-promised';
|
||||
import {Agent as HttpAgent} from 'http';
|
||||
import {Agent as HttpsAgent} from 'https';
|
||||
import {AbortController} from 'node-abort-controller';
|
||||
import {match, mock, spy, useFakeTimers, SinonFakeTimers} from 'sinon';
|
||||
import sinonChai from 'sinon-chai';
|
||||
import {fail} from 'assert';
|
||||
|
||||
import {
|
||||
Authorized,
|
||||
|
@ -25,10 +25,11 @@ import {
|
|||
AddressLookupTableProgram,
|
||||
SYSTEM_INSTRUCTION_LAYOUTS,
|
||||
NONCE_ACCOUNT_LENGTH,
|
||||
MessageAddressTableLookup,
|
||||
} from '../src';
|
||||
import invariant from '../src/utils/assert';
|
||||
import {toBuffer} from '../src/utils/to-buffer';
|
||||
import {MOCK_PORT, url} from './url';
|
||||
import {MOCK_PORT, url, Node14Controller, nodeVersion} from './url';
|
||||
import {
|
||||
AccountInfo,
|
||||
BLOCKHASH_CACHE_TIMEOUT_MS,
|
||||
|
@ -171,10 +172,15 @@ describe('Connection', function () {
|
|||
it('should allow middleware to augment request', async () => {
|
||||
let connection = new Connection(url, {
|
||||
fetchMiddleware: (url, options, fetch) => {
|
||||
options.headers = Object.assign(options.headers, {
|
||||
Authorization: 'Bearer 123',
|
||||
});
|
||||
fetch(url, options);
|
||||
if (options) {
|
||||
options.headers = Object.assign(options.headers!, {
|
||||
Authorization: 'Bearer 123',
|
||||
});
|
||||
|
||||
fetch(url, options);
|
||||
} else {
|
||||
fail('options must be defined!');
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -192,7 +198,7 @@ describe('Connection', function () {
|
|||
}
|
||||
|
||||
describe('override HTTP agent', () => {
|
||||
let previousBrowserEnv;
|
||||
let previousBrowserEnv: string | undefined;
|
||||
beforeEach(() => {
|
||||
previousBrowserEnv = process.env.BROWSER;
|
||||
delete process.env.BROWSER;
|
||||
|
@ -254,7 +260,9 @@ describe('Connection', function () {
|
|||
it('should not attribute fetch errors to the middleware', async () => {
|
||||
let connection = new Connection(url, {
|
||||
fetchMiddleware: (url, _options, fetch) => {
|
||||
fetch(url, 'An `Object` was expected here; this is a `TypeError`.');
|
||||
fetch(url, {
|
||||
body: 'An `Object` was expected here; this is a `TypeError`.',
|
||||
});
|
||||
},
|
||||
});
|
||||
const error = await expect(connection.getVersion()).to.be.rejected;
|
||||
|
@ -1248,7 +1256,8 @@ describe('Connection', function () {
|
|||
it('rejects if called with an already-aborted `abortSignal`', () => {
|
||||
const mockSignature =
|
||||
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt';
|
||||
const abortController = new AbortController();
|
||||
const abortController: any =
|
||||
nodeVersion >= 16 ? new AbortController() : Node14Controller();
|
||||
abortController.abort();
|
||||
expect(
|
||||
connection.confirmTransaction({
|
||||
|
@ -1263,7 +1272,8 @@ describe('Connection', function () {
|
|||
it('rejects upon receiving an abort signal', async () => {
|
||||
const mockSignature =
|
||||
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt';
|
||||
const abortController = new AbortController();
|
||||
const abortController: any =
|
||||
nodeVersion >= 16 ? new AbortController() : Node14Controller();
|
||||
// Keep the subscription from ever returning data.
|
||||
await mockRpcMessage({
|
||||
method: 'signatureSubscribe',
|
||||
|
@ -1334,7 +1344,10 @@ describe('Connection', function () {
|
|||
const mockSignature =
|
||||
'LPJ18iiyfz3G1LpNNbcBnBtaS4dVBdPHKrnELqikjER2DcvB4iyTgz43nKQJH3JQAJHuZdM1xVh5Cnc5Hc7LrqC';
|
||||
|
||||
let resolveResultPromise: (result: SignatureResult) => void;
|
||||
let resolveResultPromise = function (result: SignatureResult): any {
|
||||
return result;
|
||||
};
|
||||
|
||||
await mockRpcMessage({
|
||||
method: 'signatureSubscribe',
|
||||
params: [mockSignature, {commitment: 'finalized'}],
|
||||
|
@ -1344,7 +1357,7 @@ describe('Connection', function () {
|
|||
});
|
||||
|
||||
// Simulate a failure to fetch the block height.
|
||||
let rejectBlockheightPromise: () => void;
|
||||
let rejectBlockheightPromise = function (): void {};
|
||||
await mockRpcResponse({
|
||||
method: 'getBlockHeight',
|
||||
params: [],
|
||||
|
@ -1375,7 +1388,9 @@ describe('Connection', function () {
|
|||
const mockSignature =
|
||||
'LPJ18iiyfz3G1LpNNbcBnBtaS4dVBdPHKrnELqikjER2DcvB4iyTgz43nKQJH3JQAJHuZdM1xVh5Cnc5Hc7LrqC';
|
||||
|
||||
let resolveResultPromise: (result: SignatureResult) => void;
|
||||
let resolveResultPromise = function (result: SignatureResult): any {
|
||||
return result;
|
||||
};
|
||||
await mockRpcMessage({
|
||||
method: 'signatureSubscribe',
|
||||
params: [mockSignature, {commitment: 'finalized'}],
|
||||
|
@ -1414,7 +1429,8 @@ describe('Connection', function () {
|
|||
it('rejects if called with an already-aborted `abortSignal`', () => {
|
||||
const mockSignature =
|
||||
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt';
|
||||
const abortController = new AbortController();
|
||||
const abortController: any =
|
||||
nodeVersion >= 16 ? new AbortController() : Node14Controller();
|
||||
abortController.abort();
|
||||
expect(
|
||||
connection.confirmTransaction({
|
||||
|
@ -1430,7 +1446,8 @@ describe('Connection', function () {
|
|||
it('rejects upon receiving an abort signal', async () => {
|
||||
const mockSignature =
|
||||
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt';
|
||||
const abortController = new AbortController();
|
||||
const abortController: any =
|
||||
nodeVersion >= 16 ? new AbortController() : Node14Controller();
|
||||
// Keep the subscription from ever returning data.
|
||||
await mockRpcMessage({
|
||||
method: 'signatureSubscribe',
|
||||
|
@ -1455,7 +1472,9 @@ describe('Connection', function () {
|
|||
const mockSignature =
|
||||
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG';
|
||||
|
||||
let resolveResultPromise: (result: SignatureResult) => void;
|
||||
let resolveResultPromise = function (result: SignatureResult): any {
|
||||
return result;
|
||||
};
|
||||
await mockRpcMessage({
|
||||
method: 'signatureSubscribe',
|
||||
params: [mockSignature, {commitment: 'finalized'}],
|
||||
|
@ -1666,7 +1685,9 @@ describe('Connection', function () {
|
|||
const mockSignature =
|
||||
'LPJ18iiyfz3G1LpNNbcBnBtaS4dVBdPHKrnELqikjER2DcvB4iyTgz43nKQJH3JQAJHuZdM1xVh5Cnc5Hc7LrqC';
|
||||
|
||||
let resolveResultPromise: (result: SignatureResult) => void;
|
||||
let resolveResultPromise = function (result: SignatureResult): any {
|
||||
return result;
|
||||
};
|
||||
await mockRpcMessage({
|
||||
method: 'signatureSubscribe',
|
||||
params: [mockSignature, {commitment: 'finalized'}],
|
||||
|
@ -1676,7 +1697,7 @@ describe('Connection', function () {
|
|||
});
|
||||
|
||||
// Simulate a failure to fetch the nonce account.
|
||||
let rejectNonceAccountFetchPromise: () => void;
|
||||
let rejectNonceAccountFetchPromise = function (): void {};
|
||||
await mockRpcResponse({
|
||||
method: 'getAccountInfo',
|
||||
params: [],
|
||||
|
@ -1762,7 +1783,9 @@ describe('Connection', function () {
|
|||
const mockSignature =
|
||||
'LPJ18iiyfz3G1LpNNbcBnBtaS4dVBdPHKrnELqikjER2DcvB4iyTgz43nKQJH3JQAJHuZdM1xVh5Cnc5Hc7LrqC';
|
||||
|
||||
let resolveResultPromise: (result: SignatureResult) => void;
|
||||
let resolveResultPromise = function (result: SignatureResult): any {
|
||||
return result;
|
||||
};
|
||||
await mockRpcMessage({
|
||||
method: 'signatureSubscribe',
|
||||
params: [mockSignature, {commitment: 'finalized'}],
|
||||
|
@ -5391,9 +5414,9 @@ describe('Connection', function () {
|
|||
);
|
||||
|
||||
await connection.confirmTransaction({
|
||||
blockhash: transaction.recentBlockhash,
|
||||
lastValidBlockHeight: transaction.lastValidBlockHeight,
|
||||
signature,
|
||||
blockhash: transaction.recentBlockhash!,
|
||||
lastValidBlockHeight: transaction.lastValidBlockHeight!,
|
||||
signature: signature,
|
||||
});
|
||||
|
||||
const response = (await connection.getSignatureStatus(signature)).value;
|
||||
|
@ -5733,8 +5756,8 @@ describe('Connection', function () {
|
|||
}
|
||||
});
|
||||
|
||||
let signature;
|
||||
let addressTableLookups;
|
||||
let signature: TransactionSignature;
|
||||
let addressTableLookups: MessageAddressTableLookup[];
|
||||
it('send and confirm', async () => {
|
||||
const {blockhash, lastValidBlockHeight} =
|
||||
await connection.getLatestBlockhash();
|
||||
|
@ -5802,7 +5825,7 @@ describe('Connection', function () {
|
|||
);
|
||||
});
|
||||
|
||||
let transactionSlot;
|
||||
let transactionSlot: number;
|
||||
it('getTransaction', async () => {
|
||||
// fetch v0 transaction
|
||||
const fetchedTransaction = await connection.getTransaction(signature, {
|
||||
|
|
|
@ -53,7 +53,7 @@ export const mockRpcBatchResponse = async ({
|
|||
});
|
||||
|
||||
await mockServer
|
||||
.post('/')
|
||||
.forPost('/')
|
||||
.withJsonBodyIncluding(request)
|
||||
.thenReply(200, JSON.stringify(response));
|
||||
};
|
||||
|
@ -86,7 +86,7 @@ export const mockRpcResponse = async ({
|
|||
if (!mockServer) return;
|
||||
|
||||
await mockServer
|
||||
.post('/')
|
||||
.forPost('/')
|
||||
.withJsonBodyIncluding({
|
||||
jsonrpc: '2.0',
|
||||
method,
|
||||
|
@ -128,7 +128,7 @@ const latestBlockhash = async ({
|
|||
commitment?: Commitment;
|
||||
}) => {
|
||||
const blockhash = uniqueBlockhash();
|
||||
const params = [];
|
||||
const params: Array<Object> = [];
|
||||
if (commitment) {
|
||||
params.push({commitment});
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ const recentBlockhash = async ({
|
|||
commitment?: Commitment;
|
||||
}) => {
|
||||
const blockhash = uniqueBlockhash();
|
||||
const params = [];
|
||||
const params: Array<Object> = [];
|
||||
if (commitment) {
|
||||
params.push({commitment});
|
||||
}
|
||||
|
|
|
@ -292,6 +292,7 @@ describe('Transaction', () => {
|
|||
foundIndex = ii;
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
});
|
||||
return foundIndex;
|
||||
})(),
|
||||
|
@ -342,6 +343,7 @@ describe('Transaction', () => {
|
|||
foundIndex = ii;
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
});
|
||||
return foundIndex;
|
||||
})(),
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
import {AbortController as AbortControllerPolyfill} from 'node-abort-controller';
|
||||
/**
|
||||
* The connection url to use when running unit tests against a live cluster
|
||||
*/
|
||||
|
||||
export const MOCK_PORT = 9999;
|
||||
|
||||
declare var process: {
|
||||
env: {
|
||||
TEST_LIVE: string;
|
||||
};
|
||||
version: string;
|
||||
};
|
||||
|
||||
export const url = process.env.TEST_LIVE
|
||||
? 'http://localhost:8899/'
|
||||
: 'http://localhost:9999/';
|
||||
|
@ -11,5 +19,11 @@ export const wsUrl = process.env.TEST_LIVE
|
|||
? 'ws://localhost:8900/'
|
||||
: 'ws://localhost:9999/';
|
||||
|
||||
export const nodeVersion = Number(process.version.split('.')[0]);
|
||||
|
||||
export const Node14Controller = function () {
|
||||
return new AbortControllerPolyfill();
|
||||
};
|
||||
|
||||
//export const url = 'https://api.devnet.solana.com/';
|
||||
//export const url = 'http://api.devnet.solana.com/';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"extends": "./tsconfig.library.json",
|
||||
"compilerOptions": {
|
||||
"emitDeclarationOnly": true,
|
||||
"stripInternal": true
|
||||
|
|
|
@ -1,22 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"allowJs": true,
|
||||
"declaration": true,
|
||||
"declarationDir": "declarations",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"baseUrl": "src",
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedParameters": true,
|
||||
"noUnusedLocals": true
|
||||
"composite": true
|
||||
},
|
||||
"include": ["src"]
|
||||
"references": [
|
||||
{"path": "./tsconfig.library.json"},
|
||||
{"path": "./tsconfig.tests.json"}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationDir": "declarations"
|
||||
},
|
||||
"extends": "./tsconfig.shared.json",
|
||||
"include": ["src"]
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"resolveJsonModule": true,
|
||||
"strict": true,
|
||||
"target": "esnext"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"declaration": false
|
||||
},
|
||||
"extends": "./tsconfig.shared.json",
|
||||
"include": ["test"]
|
||||
}
|
1377
web3.js/yarn.lock
1377
web3.js/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue