@0x:contracts-integrations
Added collections of function assertions
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import { PromiseWithTransactionHash } from '@0x/base-contract';
|
||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||
import { BlockchainTestsEnvironment } from '@0x/contracts-test-utils';
|
||||
import { decodeThrownErrorAsRevertError } from '@0x/utils';
|
||||
import { BlockParam, CallData, TransactionReceiptWithDecodedLogs, TxData } from 'ethereum-types';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
export interface ContractGetterFunction {
|
||||
callAsync: (...args: any[]) => Promise<any>;
|
||||
@@ -9,18 +12,27 @@ export interface ContractWrapperFunction extends ContractGetterFunction {
|
||||
awaitTransactionSuccessAsync?: (...args: any[]) => PromiseWithTransactionHash<TransactionReceiptWithDecodedLogs>;
|
||||
}
|
||||
|
||||
export interface Condition {
|
||||
before: (...args: any[]) => Promise<any>;
|
||||
after: (beforeInfo: any, result: Result, ...args: any[]) => Promise<any>;
|
||||
}
|
||||
|
||||
export interface Result {
|
||||
data?: any;
|
||||
receipt?: TransactionReceiptWithDecodedLogs;
|
||||
success: boolean;
|
||||
receipt?: TransactionReceiptWithDecodedLogs;
|
||||
}
|
||||
|
||||
export class FunctionAssertion {
|
||||
export interface Condition {
|
||||
before?: (...args: any[]) => Promise<any>;
|
||||
after?: (beforeInfo: any, result: Result, ...args: any[]) => Promise<any>;
|
||||
}
|
||||
|
||||
export interface RunResult {
|
||||
beforeInfo: any;
|
||||
afterInfo: any;
|
||||
}
|
||||
|
||||
export interface Assertion {
|
||||
runAsync: (...args: any[]) => Promise<any>;
|
||||
}
|
||||
|
||||
export class FunctionAssertion implements Assertion {
|
||||
// A before and an after assertion that will be called around the wrapper function.
|
||||
public condition: Condition;
|
||||
|
||||
@@ -36,9 +48,9 @@ export class FunctionAssertion {
|
||||
* Runs the wrapped function and fails if the before or after assertions fail.
|
||||
* @param ...args The args to the contract wrapper function.
|
||||
*/
|
||||
public async runAsync(...args: any[]): Promise<{ beforeInfo: any; afterInfo: any }> {
|
||||
public async runAsync(...args: any[]): Promise<RunResult> {
|
||||
// Call the before condition.
|
||||
const beforeInfo = await this.condition.before(...args);
|
||||
const beforeInfo = this.condition.before !== undefined ? await this.condition.before(...args) : undefined;
|
||||
|
||||
// Initialize the callResult so that the default success value is true.
|
||||
let callResult: Result = { success: true };
|
||||
@@ -58,7 +70,10 @@ export class FunctionAssertion {
|
||||
}
|
||||
|
||||
// Call the after condition.
|
||||
const afterInfo = await this.condition.after(beforeInfo, callResult, ...args);
|
||||
const afterInfo =
|
||||
this.condition.after !== undefined
|
||||
? await this.condition.after(beforeInfo, callResult, ...args)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
beforeInfo,
|
||||
@@ -66,3 +81,64 @@ export class FunctionAssertion {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: This can be treated like a normal `FunctionAssertion`.
|
||||
*/
|
||||
export class FunctionAssertionSequence {
|
||||
public readonly assertions: Assertion[] = [];
|
||||
public readonly inputGenerators: Array<() => any[]> = [];
|
||||
|
||||
/**
|
||||
* Set up a set of function assertions equipped with generator functions.
|
||||
* A number can be specified for each assertion that will detail the frequency
|
||||
* that this assertion will be called relative to the other assertions in the
|
||||
* set.
|
||||
*/
|
||||
constructor(assertionGenerators: [Assertion, (() => any[])][]) {
|
||||
for (const assertionGenerator of assertionGenerators) {
|
||||
this.assertions.push(assertionGenerator[0]);
|
||||
this.inputGenerators.push(assertionGenerator[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the functions in this assertion set in order.
|
||||
*/
|
||||
public async runAsync(environment: BlockchainTestsEnvironment): Promise<void> {
|
||||
for (let i = 0; i < this.assertions.length; i++) {
|
||||
await this.assertions[i].runAsync(...this.inputGenerators[i]());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ContinuousFunctionAssertionSet {
|
||||
public readonly assertions: Assertion[] = [];
|
||||
public readonly inputGenerators: Array<() => any[]> = [];
|
||||
|
||||
/**
|
||||
* Set up a set of function assertions equipped with generator functions.
|
||||
* A number can be specified for each assertion that will detail the frequency
|
||||
* that this assertion will be called relative to the other assertions in the
|
||||
* set.
|
||||
*/
|
||||
constructor(assertionGenerators: [Assertion, (() => any[]), number?][]) {
|
||||
for (const assertionGenerator of assertionGenerators) {
|
||||
const frequency = assertionGenerator[2] || 1;
|
||||
for (let i = 0; i < frequency; i++) {
|
||||
this.assertions.push(assertionGenerator[0]);
|
||||
this.inputGenerators.push(assertionGenerator[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the functions in this assertion set continuously.
|
||||
*/
|
||||
public async runAsync(environment: BlockchainTestsEnvironment): Promise<void> {
|
||||
for (;;) {
|
||||
const randomIdx = Math.round(Math.random() * (this.assertions.length - 1));
|
||||
await this.assertions[randomIdx].runAsync(...this.inputGenerators[randomIdx]());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user