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
|
||||
* node.
|
||||
*/
|
||||
async function _getGanacheOrGethError(ganacheError: string, gethError: string): Promise<string> {
|
||||
async function _getGanacheOrGethErrorAsync(ganacheError: string, gethError: string): Promise<string> {
|
||||
if (_.isUndefined(nodeType)) {
|
||||
nodeType = await web3Wrapper.getNodeTypeAsync();
|
||||
}
|
||||
@ -38,15 +38,15 @@ async function _getGanacheOrGethError(ganacheError: string, gethError: 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> {
|
||||
return _getGanacheOrGethError('revert', 'always failing transaction');
|
||||
return _getGanacheOrGethErrorAsync('revert', 'always failing transaction');
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
// lodash. We should replace it by a library implementation, or move it to our
|
||||
// own.
|
||||
async function evaluatePromise<T>(promise: Promise<T>): Promise<PromiseResult<T>> {
|
||||
async function evaluatePromiseAsync<T>(promise: Promise<T>): Promise<PromiseResult<T>> {
|
||||
try {
|
||||
return new Value<T>(await promise);
|
||||
} catch (e) {
|
||||
@ -93,10 +93,10 @@ export async function testWithReferenceFuncAsync(
|
||||
values: any[],
|
||||
): Promise<void> {
|
||||
// Measure correct behaviour
|
||||
const expected = await evaluatePromise(referenceFuncAsync(...values));
|
||||
const expected = await evaluatePromiseAsync(referenceFuncAsync(...values));
|
||||
|
||||
// Measure actual behaviour
|
||||
const actual = await evaluatePromise(testFuncAsync(...values));
|
||||
const actual = await evaluatePromiseAsync(testFuncAsync(...values));
|
||||
|
||||
// Compare behaviour
|
||||
if (expected instanceof ErrorMessage) {
|
||||
|
@ -15,11 +15,11 @@ let connection: Connection;
|
||||
|
||||
(async () => {
|
||||
connection = await createConnection(ormConfig as ConnectionOptions);
|
||||
await getAndSaveTrades();
|
||||
await getAndSaveTradesAsync();
|
||||
process.exit(0);
|
||||
})().catch(handleError);
|
||||
|
||||
async function getAndSaveTrades(): Promise<void> {
|
||||
async function getAndSaveTradesAsync(): Promise<void> {
|
||||
const apiKey = process.env.BLOXY_API_KEY;
|
||||
if (apiKey === undefined) {
|
||||
throw new Error('Missing required env var: BLOXY_API_KEY');
|
||||
|
@ -25,7 +25,7 @@ let connection: Connection;
|
||||
const markets = await ddexSource.getActiveMarketsAsync();
|
||||
for (const marketsChunk of R.splitEvery(MARKET_ORDERBOOK_REQUEST_BATCH_SIZE, markets)) {
|
||||
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));
|
||||
}
|
||||
@ -38,7 +38,7 @@ let connection: Connection;
|
||||
* @param ddexSource Data source which can query Ddex API.
|
||||
* @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 observedTimestamp = Date.now();
|
||||
|
||||
|
@ -27,7 +27,7 @@ let connection: Connection;
|
||||
logUtils.log(`Got ${markets.length} markets.`);
|
||||
for (const marketsChunk of R.splitEvery(MARKET_ORDERBOOK_REQUEST_BATCH_SIZE, markets)) {
|
||||
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));
|
||||
}
|
||||
@ -40,7 +40,7 @@ let connection: Connection;
|
||||
* @param idexSource Data source which can query Idex API.
|
||||
* @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.`);
|
||||
const orderBook = await idexSource.getMarketOrderbookAsync(marketId);
|
||||
const observedTimestamp = Date.now();
|
||||
|
@ -27,7 +27,7 @@ let connection: Connection;
|
||||
rpcUrl: INFURA_ROOT_URL,
|
||||
});
|
||||
const web3Source = new Web3Source(provider);
|
||||
await getAllMissingBlocks(web3Source);
|
||||
await getAllMissingBlocksAsync(web3Source);
|
||||
process.exit(0);
|
||||
})().catch(handleError);
|
||||
|
||||
@ -35,23 +35,23 @@ interface MissingBlocksResponse {
|
||||
block_number: string;
|
||||
}
|
||||
|
||||
async function getAllMissingBlocks(web3Source: Web3Source): Promise<void> {
|
||||
async function getAllMissingBlocksAsync(web3Source: Web3Source): Promise<void> {
|
||||
const blocksRepository = connection.getRepository(Block);
|
||||
let fromBlock = EXCHANGE_START_BLOCK;
|
||||
while (true) {
|
||||
const blockNumbers = await getMissingBlockNumbers(fromBlock);
|
||||
const blockNumbers = await getMissingBlockNumbersAsync(fromBlock);
|
||||
if (blockNumbers.length === 0) {
|
||||
// There are no more missing blocks. We're done.
|
||||
break;
|
||||
}
|
||||
await getAndSaveBlocks(web3Source, blocksRepository, blockNumbers);
|
||||
await getAndSaveBlocksAsync(web3Source, blocksRepository, blockNumbers);
|
||||
fromBlock = Math.max(...blockNumbers) + 1;
|
||||
}
|
||||
const totalBlocks = await blocksRepository.count();
|
||||
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}...`);
|
||||
// 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
|
||||
@ -76,7 +76,7 @@ async function getMissingBlockNumbers(fromBlock: number): Promise<number[]> {
|
||||
return blockNumbers;
|
||||
}
|
||||
|
||||
async function getAndSaveBlocks(
|
||||
async function getAndSaveBlocksAsync(
|
||||
web3Source: Web3Source,
|
||||
blocksRepository: Repository<Block>,
|
||||
blockNumbers: number[],
|
||||
|
@ -27,7 +27,7 @@ let connection: Connection;
|
||||
logUtils.log(`Got ${markets.length} markets.`);
|
||||
for (const marketsChunk of R.splitEvery(MARKET_ORDERBOOK_REQUEST_BATCH_SIZE, markets)) {
|
||||
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));
|
||||
}
|
||||
@ -40,7 +40,7 @@ let connection: Connection;
|
||||
* @param oasisSource Data source which can query Oasis API.
|
||||
* @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.`);
|
||||
const orderBook = await oasisSource.getMarketOrderbookAsync(market.id);
|
||||
const observedTimestamp = Date.now();
|
||||
|
@ -29,7 +29,7 @@ let connection: Connection;
|
||||
const tokenInfoResponse = await paradexSource.getTokenInfoAsync();
|
||||
const extendedMarkets = addTokenAddresses(markets, tokenInfoResponse);
|
||||
await Promise.all(
|
||||
extendedMarkets.map(async (market: ParadexMarket) => getAndSaveMarketOrderbook(paradexSource, market)),
|
||||
extendedMarkets.map(async (market: ParadexMarket) => getAndSaveMarketOrderbookAsync(paradexSource, market)),
|
||||
);
|
||||
process.exit(0);
|
||||
})().catch(handleError);
|
||||
@ -70,7 +70,7 @@ function addTokenAddresses(
|
||||
* @param paradexSource Data source which can query the Paradex API.
|
||||
* @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 observedTimestamp = Date.now();
|
||||
|
||||
|
@ -16,12 +16,12 @@ let connection: Connection;
|
||||
|
||||
(async () => {
|
||||
connection = await createConnection(ormConfig as ConnectionOptions);
|
||||
await getMetamaskTrustedTokens();
|
||||
await getZeroExTrustedTokens();
|
||||
await getMetamaskTrustedTokensAsync();
|
||||
await getZeroExTrustedTokensAsync();
|
||||
process.exit(0);
|
||||
})().catch(handleError);
|
||||
|
||||
async function getMetamaskTrustedTokens(): Promise<void> {
|
||||
async function getMetamaskTrustedTokensAsync(): Promise<void> {
|
||||
// tslint:disable-next-line:no-console
|
||||
console.log('Getting latest metamask trusted tokens list ...');
|
||||
const trustedTokensRepository = connection.getRepository(TokenMetadata);
|
||||
@ -37,7 +37,7 @@ async function getMetamaskTrustedTokens(): Promise<void> {
|
||||
console.log('Done saving metamask trusted tokens.');
|
||||
}
|
||||
|
||||
async function getZeroExTrustedTokens(): Promise<void> {
|
||||
async function getZeroExTrustedTokensAsync(): Promise<void> {
|
||||
// tslint:disable-next-line:no-console
|
||||
console.log('Getting latest 0x trusted tokens list ...');
|
||||
const trustedTokensRepository = connection.getRepository(TokenMetadata);
|
||||
|
@ -17,11 +17,11 @@ let connection: Connection;
|
||||
|
||||
(async () => {
|
||||
connection = await createConnection(ormConfig as ConnectionOptions);
|
||||
await getRelayers();
|
||||
await getRelayersAsync();
|
||||
process.exit(0);
|
||||
})().catch(handleError);
|
||||
|
||||
async function getRelayers(): Promise<void> {
|
||||
async function getRelayersAsync(): Promise<void> {
|
||||
console.log('Getting latest relayer info...');
|
||||
const relayerRepository = connection.getRepository(Relayer);
|
||||
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",
|
||||
"changes": [
|
||||
|
@ -3,24 +3,33 @@ import * as Lint from 'tslint';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
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 {
|
||||
const methodNameNode = node.name;
|
||||
const methodName = methodNameNode.getText();
|
||||
if (!_.isUndefined(node.type)) {
|
||||
if (node.type.kind === ts.SyntaxKind.TypeReference) {
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const returnTypeName = (node.type as ts.TypeReferenceNode).typeName.getText();
|
||||
if (returnTypeName === 'Promise' && !methodName.endsWith('Async')) {
|
||||
const failure = this.createFailure(
|
||||
methodNameNode.getStart(),
|
||||
methodNameNode.getWidth(),
|
||||
AsyncSuffixWalker.FAILURE_STRING,
|
||||
);
|
||||
this.addFailure(failure);
|
||||
this._visitFunctionOrMethodDeclaration(node);
|
||||
super.visitMethodDeclaration(node);
|
||||
}
|
||||
private _visitFunctionOrMethodDeclaration(node: ts.MethodDeclaration | ts.FunctionDeclaration): void {
|
||||
const nameNode = node.name;
|
||||
if (!_.isUndefined(nameNode)) {
|
||||
const name = nameNode.getText();
|
||||
if (!_.isUndefined(node.type)) {
|
||||
if (node.type.kind === ts.SyntaxKind.TypeReference) {
|
||||
// tslint:disable-next-line:no-unnecessary-type-assertion
|
||||
const returnTypeName = (node.type as ts.TypeReferenceNode).typeName.getText();
|
||||
if (returnTypeName === 'Promise' && !name.endsWith('Async')) {
|
||||
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