Merge pull request #1425 from 0xProject/feature/async-suffix
Check for an Async suffix in functions, not just methods.
This commit is contained in:
commit
f9d436cd21
@ -23,7 +23,7 @@ export type sendTransactionResult = Promise<TransactionReceipt | TransactionRece
|
|||||||
* @returns either the given ganacheError or gethError depending on the backing
|
* @returns either the given ganacheError or gethError depending on the backing
|
||||||
* node.
|
* node.
|
||||||
*/
|
*/
|
||||||
async function _getGanacheOrGethError(ganacheError: string, gethError: string): Promise<string> {
|
async function _getGanacheOrGethErrorAsync(ganacheError: string, gethError: string): Promise<string> {
|
||||||
if (_.isUndefined(nodeType)) {
|
if (_.isUndefined(nodeType)) {
|
||||||
nodeType = await web3Wrapper.getNodeTypeAsync();
|
nodeType = await web3Wrapper.getNodeTypeAsync();
|
||||||
}
|
}
|
||||||
@ -38,15 +38,15 @@ async function _getGanacheOrGethError(ganacheError: string, gethError: string):
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function _getInsufficientFundsErrorMessageAsync(): Promise<string> {
|
async function _getInsufficientFundsErrorMessageAsync(): Promise<string> {
|
||||||
return _getGanacheOrGethError("sender doesn't have enough funds", 'insufficient funds');
|
return _getGanacheOrGethErrorAsync("sender doesn't have enough funds", 'insufficient funds');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _getTransactionFailedErrorMessageAsync(): Promise<string> {
|
async function _getTransactionFailedErrorMessageAsync(): Promise<string> {
|
||||||
return _getGanacheOrGethError('revert', 'always failing transaction');
|
return _getGanacheOrGethErrorAsync('revert', 'always failing transaction');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _getContractCallFailedErrorMessageAsync(): Promise<string> {
|
async function _getContractCallFailedErrorMessageAsync(): Promise<string> {
|
||||||
return _getGanacheOrGethError('revert', 'Contract call failed');
|
return _getGanacheOrGethErrorAsync('revert', 'Contract call failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,7 +54,7 @@ async function _getContractCallFailedErrorMessageAsync(): Promise<string> {
|
|||||||
* contract call. The exact error message depends on the backing Ethereum node.
|
* contract call. The exact error message depends on the backing Ethereum node.
|
||||||
*/
|
*/
|
||||||
export async function getInvalidOpcodeErrorMessageForCallAsync(): Promise<string> {
|
export async function getInvalidOpcodeErrorMessageForCallAsync(): Promise<string> {
|
||||||
return _getGanacheOrGethError('invalid opcode', 'Contract call failed');
|
return _getGanacheOrGethErrorAsync('invalid opcode', 'Contract call failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,7 +65,7 @@ export async function getInvalidOpcodeErrorMessageForCallAsync(): Promise<string
|
|||||||
* @returns the expected error message.
|
* @returns the expected error message.
|
||||||
*/
|
*/
|
||||||
export async function getRevertReasonOrErrorMessageForSendTransactionAsync(reason: RevertReason): Promise<string> {
|
export async function getRevertReasonOrErrorMessageForSendTransactionAsync(reason: RevertReason): Promise<string> {
|
||||||
return _getGanacheOrGethError(reason, 'always failing transaction');
|
return _getGanacheOrGethErrorAsync(reason, 'always failing transaction');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +26,7 @@ type PromiseResult<T> = Value<T> | ErrorMessage;
|
|||||||
// TODO(albrow): This seems like a generic utility function that could exist in
|
// TODO(albrow): This seems like a generic utility function that could exist in
|
||||||
// lodash. We should replace it by a library implementation, or move it to our
|
// lodash. We should replace it by a library implementation, or move it to our
|
||||||
// own.
|
// own.
|
||||||
async function evaluatePromise<T>(promise: Promise<T>): Promise<PromiseResult<T>> {
|
async function evaluatePromiseAsync<T>(promise: Promise<T>): Promise<PromiseResult<T>> {
|
||||||
try {
|
try {
|
||||||
return new Value<T>(await promise);
|
return new Value<T>(await promise);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -93,10 +93,10 @@ export async function testWithReferenceFuncAsync(
|
|||||||
values: any[],
|
values: any[],
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Measure correct behaviour
|
// Measure correct behaviour
|
||||||
const expected = await evaluatePromise(referenceFuncAsync(...values));
|
const expected = await evaluatePromiseAsync(referenceFuncAsync(...values));
|
||||||
|
|
||||||
// Measure actual behaviour
|
// Measure actual behaviour
|
||||||
const actual = await evaluatePromise(testFuncAsync(...values));
|
const actual = await evaluatePromiseAsync(testFuncAsync(...values));
|
||||||
|
|
||||||
// Compare behaviour
|
// Compare behaviour
|
||||||
if (expected instanceof ErrorMessage) {
|
if (expected instanceof ErrorMessage) {
|
||||||
|
@ -15,11 +15,11 @@ let connection: Connection;
|
|||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
connection = await createConnection(ormConfig as ConnectionOptions);
|
connection = await createConnection(ormConfig as ConnectionOptions);
|
||||||
await getAndSaveTrades();
|
await getAndSaveTradesAsync();
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
})().catch(handleError);
|
})().catch(handleError);
|
||||||
|
|
||||||
async function getAndSaveTrades(): Promise<void> {
|
async function getAndSaveTradesAsync(): Promise<void> {
|
||||||
const apiKey = process.env.BLOXY_API_KEY;
|
const apiKey = process.env.BLOXY_API_KEY;
|
||||||
if (apiKey === undefined) {
|
if (apiKey === undefined) {
|
||||||
throw new Error('Missing required env var: BLOXY_API_KEY');
|
throw new Error('Missing required env var: BLOXY_API_KEY');
|
||||||
|
@ -25,7 +25,7 @@ let connection: Connection;
|
|||||||
const markets = await ddexSource.getActiveMarketsAsync();
|
const markets = await ddexSource.getActiveMarketsAsync();
|
||||||
for (const marketsChunk of R.splitEvery(MARKET_ORDERBOOK_REQUEST_BATCH_SIZE, markets)) {
|
for (const marketsChunk of R.splitEvery(MARKET_ORDERBOOK_REQUEST_BATCH_SIZE, markets)) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
marketsChunk.map(async (market: DdexMarket) => getAndSaveMarketOrderbook(ddexSource, market)),
|
marketsChunk.map(async (market: DdexMarket) => getAndSaveMarketOrderbookAsync(ddexSource, market)),
|
||||||
);
|
);
|
||||||
await new Promise<void>(resolve => setTimeout(resolve, MILLISEC_MARKET_ORDERBOOK_REQUEST_DELAY));
|
await new Promise<void>(resolve => setTimeout(resolve, MILLISEC_MARKET_ORDERBOOK_REQUEST_DELAY));
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ let connection: Connection;
|
|||||||
* @param ddexSource Data source which can query Ddex API.
|
* @param ddexSource Data source which can query Ddex API.
|
||||||
* @param market Object from Ddex API containing market data.
|
* @param market Object from Ddex API containing market data.
|
||||||
*/
|
*/
|
||||||
async function getAndSaveMarketOrderbook(ddexSource: DdexSource, market: DdexMarket): Promise<void> {
|
async function getAndSaveMarketOrderbookAsync(ddexSource: DdexSource, market: DdexMarket): Promise<void> {
|
||||||
const orderBook = await ddexSource.getMarketOrderbookAsync(market.id);
|
const orderBook = await ddexSource.getMarketOrderbookAsync(market.id);
|
||||||
const observedTimestamp = Date.now();
|
const observedTimestamp = Date.now();
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ let connection: Connection;
|
|||||||
logUtils.log(`Got ${markets.length} markets.`);
|
logUtils.log(`Got ${markets.length} markets.`);
|
||||||
for (const marketsChunk of R.splitEvery(MARKET_ORDERBOOK_REQUEST_BATCH_SIZE, markets)) {
|
for (const marketsChunk of R.splitEvery(MARKET_ORDERBOOK_REQUEST_BATCH_SIZE, markets)) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
marketsChunk.map(async (marketId: string) => getAndSaveMarketOrderbook(idexSource, marketId)),
|
marketsChunk.map(async (marketId: string) => getAndSaveMarketOrderbookAsync(idexSource, marketId)),
|
||||||
);
|
);
|
||||||
await new Promise<void>(resolve => setTimeout(resolve, MILLISEC_MARKET_ORDERBOOK_REQUEST_DELAY));
|
await new Promise<void>(resolve => setTimeout(resolve, MILLISEC_MARKET_ORDERBOOK_REQUEST_DELAY));
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ let connection: Connection;
|
|||||||
* @param idexSource Data source which can query Idex API.
|
* @param idexSource Data source which can query Idex API.
|
||||||
* @param marketId String representing market of interest, eg. 'ETH_TIC'.
|
* @param marketId String representing market of interest, eg. 'ETH_TIC'.
|
||||||
*/
|
*/
|
||||||
async function getAndSaveMarketOrderbook(idexSource: IdexSource, marketId: string): Promise<void> {
|
async function getAndSaveMarketOrderbookAsync(idexSource: IdexSource, marketId: string): Promise<void> {
|
||||||
logUtils.log(`${marketId}: Retrieving orderbook.`);
|
logUtils.log(`${marketId}: Retrieving orderbook.`);
|
||||||
const orderBook = await idexSource.getMarketOrderbookAsync(marketId);
|
const orderBook = await idexSource.getMarketOrderbookAsync(marketId);
|
||||||
const observedTimestamp = Date.now();
|
const observedTimestamp = Date.now();
|
||||||
|
@ -27,7 +27,7 @@ let connection: Connection;
|
|||||||
rpcUrl: INFURA_ROOT_URL,
|
rpcUrl: INFURA_ROOT_URL,
|
||||||
});
|
});
|
||||||
const web3Source = new Web3Source(provider);
|
const web3Source = new Web3Source(provider);
|
||||||
await getAllMissingBlocks(web3Source);
|
await getAllMissingBlocksAsync(web3Source);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
})().catch(handleError);
|
})().catch(handleError);
|
||||||
|
|
||||||
@ -35,23 +35,23 @@ interface MissingBlocksResponse {
|
|||||||
block_number: string;
|
block_number: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAllMissingBlocks(web3Source: Web3Source): Promise<void> {
|
async function getAllMissingBlocksAsync(web3Source: Web3Source): Promise<void> {
|
||||||
const blocksRepository = connection.getRepository(Block);
|
const blocksRepository = connection.getRepository(Block);
|
||||||
let fromBlock = EXCHANGE_START_BLOCK;
|
let fromBlock = EXCHANGE_START_BLOCK;
|
||||||
while (true) {
|
while (true) {
|
||||||
const blockNumbers = await getMissingBlockNumbers(fromBlock);
|
const blockNumbers = await getMissingBlockNumbersAsync(fromBlock);
|
||||||
if (blockNumbers.length === 0) {
|
if (blockNumbers.length === 0) {
|
||||||
// There are no more missing blocks. We're done.
|
// There are no more missing blocks. We're done.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
await getAndSaveBlocks(web3Source, blocksRepository, blockNumbers);
|
await getAndSaveBlocksAsync(web3Source, blocksRepository, blockNumbers);
|
||||||
fromBlock = Math.max(...blockNumbers) + 1;
|
fromBlock = Math.max(...blockNumbers) + 1;
|
||||||
}
|
}
|
||||||
const totalBlocks = await blocksRepository.count();
|
const totalBlocks = await blocksRepository.count();
|
||||||
console.log(`Done saving blocks. There are now ${totalBlocks} total blocks.`);
|
console.log(`Done saving blocks. There are now ${totalBlocks} total blocks.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getMissingBlockNumbers(fromBlock: number): Promise<number[]> {
|
async function getMissingBlockNumbersAsync(fromBlock: number): Promise<number[]> {
|
||||||
console.log(`Checking for missing blocks starting at ${fromBlock}...`);
|
console.log(`Checking for missing blocks starting at ${fromBlock}...`);
|
||||||
// Note(albrow): The easiest way to get all the blocks we need is to
|
// Note(albrow): The easiest way to get all the blocks we need is to
|
||||||
// consider all the events tables together in a single query. If this query
|
// consider all the events tables together in a single query. If this query
|
||||||
@ -76,7 +76,7 @@ async function getMissingBlockNumbers(fromBlock: number): Promise<number[]> {
|
|||||||
return blockNumbers;
|
return blockNumbers;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getAndSaveBlocks(
|
async function getAndSaveBlocksAsync(
|
||||||
web3Source: Web3Source,
|
web3Source: Web3Source,
|
||||||
blocksRepository: Repository<Block>,
|
blocksRepository: Repository<Block>,
|
||||||
blockNumbers: number[],
|
blockNumbers: number[],
|
||||||
|
@ -27,7 +27,7 @@ let connection: Connection;
|
|||||||
logUtils.log(`Got ${markets.length} markets.`);
|
logUtils.log(`Got ${markets.length} markets.`);
|
||||||
for (const marketsChunk of R.splitEvery(MARKET_ORDERBOOK_REQUEST_BATCH_SIZE, markets)) {
|
for (const marketsChunk of R.splitEvery(MARKET_ORDERBOOK_REQUEST_BATCH_SIZE, markets)) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
marketsChunk.map(async (market: OasisMarket) => getAndSaveMarketOrderbook(oasisSource, market)),
|
marketsChunk.map(async (market: OasisMarket) => getAndSaveMarketOrderbookAsync(oasisSource, market)),
|
||||||
);
|
);
|
||||||
await new Promise<void>(resolve => setTimeout(resolve, MILLISEC_MARKET_ORDERBOOK_REQUEST_DELAY));
|
await new Promise<void>(resolve => setTimeout(resolve, MILLISEC_MARKET_ORDERBOOK_REQUEST_DELAY));
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ let connection: Connection;
|
|||||||
* @param oasisSource Data source which can query Oasis API.
|
* @param oasisSource Data source which can query Oasis API.
|
||||||
* @param marketId String identifying market we want data for. eg. 'REPAUG'.
|
* @param marketId String identifying market we want data for. eg. 'REPAUG'.
|
||||||
*/
|
*/
|
||||||
async function getAndSaveMarketOrderbook(oasisSource: OasisSource, market: OasisMarket): Promise<void> {
|
async function getAndSaveMarketOrderbookAsync(oasisSource: OasisSource, market: OasisMarket): Promise<void> {
|
||||||
logUtils.log(`${market.id}: Retrieving orderbook.`);
|
logUtils.log(`${market.id}: Retrieving orderbook.`);
|
||||||
const orderBook = await oasisSource.getMarketOrderbookAsync(market.id);
|
const orderBook = await oasisSource.getMarketOrderbookAsync(market.id);
|
||||||
const observedTimestamp = Date.now();
|
const observedTimestamp = Date.now();
|
||||||
|
@ -29,7 +29,7 @@ let connection: Connection;
|
|||||||
const tokenInfoResponse = await paradexSource.getTokenInfoAsync();
|
const tokenInfoResponse = await paradexSource.getTokenInfoAsync();
|
||||||
const extendedMarkets = addTokenAddresses(markets, tokenInfoResponse);
|
const extendedMarkets = addTokenAddresses(markets, tokenInfoResponse);
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
extendedMarkets.map(async (market: ParadexMarket) => getAndSaveMarketOrderbook(paradexSource, market)),
|
extendedMarkets.map(async (market: ParadexMarket) => getAndSaveMarketOrderbookAsync(paradexSource, market)),
|
||||||
);
|
);
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
})().catch(handleError);
|
})().catch(handleError);
|
||||||
@ -70,7 +70,7 @@ function addTokenAddresses(
|
|||||||
* @param paradexSource Data source which can query the Paradex API.
|
* @param paradexSource Data source which can query the Paradex API.
|
||||||
* @param market Object from the Paradex API with information about the market in question.
|
* @param market Object from the Paradex API with information about the market in question.
|
||||||
*/
|
*/
|
||||||
async function getAndSaveMarketOrderbook(paradexSource: ParadexSource, market: ParadexMarket): Promise<void> {
|
async function getAndSaveMarketOrderbookAsync(paradexSource: ParadexSource, market: ParadexMarket): Promise<void> {
|
||||||
const paradexOrderbookResponse = await paradexSource.getMarketOrderbookAsync(market.symbol);
|
const paradexOrderbookResponse = await paradexSource.getMarketOrderbookAsync(market.symbol);
|
||||||
const observedTimestamp = Date.now();
|
const observedTimestamp = Date.now();
|
||||||
|
|
||||||
|
@ -16,12 +16,12 @@ let connection: Connection;
|
|||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
connection = await createConnection(ormConfig as ConnectionOptions);
|
connection = await createConnection(ormConfig as ConnectionOptions);
|
||||||
await getMetamaskTrustedTokens();
|
await getMetamaskTrustedTokensAsync();
|
||||||
await getZeroExTrustedTokens();
|
await getZeroExTrustedTokensAsync();
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
})().catch(handleError);
|
})().catch(handleError);
|
||||||
|
|
||||||
async function getMetamaskTrustedTokens(): Promise<void> {
|
async function getMetamaskTrustedTokensAsync(): Promise<void> {
|
||||||
// tslint:disable-next-line:no-console
|
// tslint:disable-next-line:no-console
|
||||||
console.log('Getting latest metamask trusted tokens list ...');
|
console.log('Getting latest metamask trusted tokens list ...');
|
||||||
const trustedTokensRepository = connection.getRepository(TokenMetadata);
|
const trustedTokensRepository = connection.getRepository(TokenMetadata);
|
||||||
@ -37,7 +37,7 @@ async function getMetamaskTrustedTokens(): Promise<void> {
|
|||||||
console.log('Done saving metamask trusted tokens.');
|
console.log('Done saving metamask trusted tokens.');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getZeroExTrustedTokens(): Promise<void> {
|
async function getZeroExTrustedTokensAsync(): Promise<void> {
|
||||||
// tslint:disable-next-line:no-console
|
// tslint:disable-next-line:no-console
|
||||||
console.log('Getting latest 0x trusted tokens list ...');
|
console.log('Getting latest 0x trusted tokens list ...');
|
||||||
const trustedTokensRepository = connection.getRepository(TokenMetadata);
|
const trustedTokensRepository = connection.getRepository(TokenMetadata);
|
||||||
|
@ -17,11 +17,11 @@ let connection: Connection;
|
|||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
connection = await createConnection(ormConfig as ConnectionOptions);
|
connection = await createConnection(ormConfig as ConnectionOptions);
|
||||||
await getRelayers();
|
await getRelayersAsync();
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
})().catch(handleError);
|
})().catch(handleError);
|
||||||
|
|
||||||
async function getRelayers(): Promise<void> {
|
async function getRelayersAsync(): Promise<void> {
|
||||||
console.log('Getting latest relayer info...');
|
console.log('Getting latest relayer info...');
|
||||||
const relayerRepository = connection.getRepository(Relayer);
|
const relayerRepository = connection.getRepository(Relayer);
|
||||||
const relayerSource = new RelayerRegistrySource(RELAYER_REGISTRY_URL);
|
const relayerSource = new RelayerRegistrySource(RELAYER_REGISTRY_URL);
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
[
|
[
|
||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"note": "Improve async-suffix rule to check functions too, not just methods",
|
||||||
|
"pr": 1425
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"changes": [
|
"changes": [
|
||||||
|
@ -3,24 +3,33 @@ import * as Lint from 'tslint';
|
|||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
export class AsyncSuffixWalker extends Lint.RuleWalker {
|
export class AsyncSuffixWalker extends Lint.RuleWalker {
|
||||||
public static FAILURE_STRING = 'async functions must have an Async suffix';
|
public static FAILURE_STRING = 'async functions/methods must have an Async suffix';
|
||||||
|
public visitFunctionDeclaration(node: ts.FunctionDeclaration): void {
|
||||||
|
this._visitFunctionOrMethodDeclaration(node);
|
||||||
|
super.visitFunctionDeclaration(node);
|
||||||
|
}
|
||||||
public visitMethodDeclaration(node: ts.MethodDeclaration): void {
|
public visitMethodDeclaration(node: ts.MethodDeclaration): void {
|
||||||
const methodNameNode = node.name;
|
this._visitFunctionOrMethodDeclaration(node);
|
||||||
const methodName = methodNameNode.getText();
|
super.visitMethodDeclaration(node);
|
||||||
if (!_.isUndefined(node.type)) {
|
}
|
||||||
if (node.type.kind === ts.SyntaxKind.TypeReference) {
|
private _visitFunctionOrMethodDeclaration(node: ts.MethodDeclaration | ts.FunctionDeclaration): void {
|
||||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
const nameNode = node.name;
|
||||||
const returnTypeName = (node.type as ts.TypeReferenceNode).typeName.getText();
|
if (!_.isUndefined(nameNode)) {
|
||||||
if (returnTypeName === 'Promise' && !methodName.endsWith('Async')) {
|
const name = nameNode.getText();
|
||||||
const failure = this.createFailure(
|
if (!_.isUndefined(node.type)) {
|
||||||
methodNameNode.getStart(),
|
if (node.type.kind === ts.SyntaxKind.TypeReference) {
|
||||||
methodNameNode.getWidth(),
|
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||||
AsyncSuffixWalker.FAILURE_STRING,
|
const returnTypeName = (node.type as ts.TypeReferenceNode).typeName.getText();
|
||||||
);
|
if (returnTypeName === 'Promise' && !name.endsWith('Async')) {
|
||||||
this.addFailure(failure);
|
const failure = this.createFailure(
|
||||||
|
nameNode.getStart(),
|
||||||
|
nameNode.getWidth(),
|
||||||
|
AsyncSuffixWalker.FAILURE_STRING,
|
||||||
|
);
|
||||||
|
this.addFailure(failure);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.visitMethodDeclaration(node);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user