@0x/contracts-test-utils: Export a custom describe() instead of

extending Mocha's ambient declarations.
`@0x/contracts-exchange`: Use `describe.optional` instead of
`blockchainTests.optional` in `test/fill_order.ts`.
This commit is contained in:
Lawrence Forman 2019-07-28 13:23:47 -04:00
parent 930b742663
commit 3cf48a831b
4 changed files with 140 additions and 115 deletions

View File

@ -1,4 +1,4 @@
import { blockchainTests } from '@0x/contracts-test-utils'; import { blockchainTests, describe } from '@0x/contracts-test-utils';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { import {
@ -664,7 +664,7 @@ blockchainTests.resets('FillOrder Tests', ({ web3Wrapper, txDefaults }) => {
} }
}); });
blockchainTests.optional('Combinatorially generated fills orders', () => { describe.optional('Combinatorially generated fills orders', () => {
const allFillScenarios = FillOrderCombinatorialUtils.generateFillOrderCombinations(); const allFillScenarios = FillOrderCombinatorialUtils.generateFillOrderCombinations();
for (const fillScenario of allFillScenarios) { for (const fillScenario of allFillScenarios) {
const description = `Combinatorial OrderFill: ${JSON.stringify(fillScenario)}`; const description = `Combinatorial OrderFill: ${JSON.stringify(fillScenario)}`;

View File

@ -45,5 +45,5 @@ export {
Token, Token,
TransactionDataParams, TransactionDataParams,
} from './types'; } from './types';
export { blockchainTests, BlockchainTestsEnvironment } from './mocha_blockchain'; export { blockchainTests, BlockchainTestsEnvironment, describe } from './mocha_blockchain';
export { chaiSetup, expect } from './chai_setup'; export { chaiSetup, expect } from './chai_setup';

View File

@ -11,15 +11,20 @@ import { provider, txDefaults, web3Wrapper } from './web3_wrapper';
// tslint:disable: no-namespace only-arrow-functions no-unbound-method // tslint:disable: no-namespace only-arrow-functions no-unbound-method
// Extend Mocha ambient definitions. export type ISuite = Mocha.ISuite;
declare global { export type ISuiteCallbackContext = Mocha.ISuiteCallbackContext;
export namespace Mocha { export type SuiteCallback = (this: ISuiteCallbackContext) => void;
type BlockchainSuiteCallback = (this: ISuiteCallbackContext, env: BlockchainTestsEnvironment) => void; export type ContextDefinitionCallback<T> = (description: string, callback: SuiteCallback) => T;
type SuiteCallback = (this: ISuiteCallbackContext) => void; export type BlockchainSuiteCallback = (this: ISuiteCallbackContext, env: BlockchainTestsEnvironment) => void;
type BlockchainContextDefinitionCallback<T> = (description: string, callback: BlockchainSuiteCallback) => T; export type BlockchainContextDefinitionCallback<T> = (description: string, callback: BlockchainSuiteCallback) => T;
type ContextDefinitionCallback<T> = (description: string, callback: SuiteCallback) => T; export interface ContextDefinition extends Mocha.IContextDefinition {
optional: ContextDefinitionCallback<ISuite | void>;
}
interface BlockchainContextDefinition { /**
* Interface for `blockchainTests()`.
*/
export interface BlockchainContextDefinition {
resets: { resets: {
only: BlockchainContextDefinitionCallback<ISuite>; only: BlockchainContextDefinitionCallback<ISuite>;
skip: BlockchainContextDefinitionCallback<void>; skip: BlockchainContextDefinitionCallback<void>;
@ -31,14 +36,24 @@ declare global {
optional: BlockchainContextDefinitionCallback<ISuite | void>; optional: BlockchainContextDefinitionCallback<ISuite | void>;
(description: string, callback: BlockchainSuiteCallback): ISuite; (description: string, callback: BlockchainSuiteCallback): ISuite;
} }
}
/**
* Describes the environment object passed into the `blockchainTests()` callback.
*/
export interface BlockchainTestsEnvironment {
blockchainLifecycle: BlockchainLifecycle;
provider: Web3ProviderEngine;
txDefaults: Partial<TxData>;
web3Wrapper: Web3Wrapper;
getChainIdAsync(): Promise<number>;
getAccountAddressesAsync(): Promise<string[]>;
} }
/** /**
* Describes the test environment prepared by `blockchainTests()`. * Concret implementation of `BlockchainTestsEnvironment`.
*/ */
export class BlockchainTestsEnvironment { export class BlockchainTestsEnvironmentSingleton {
private static _instance: BlockchainTestsEnvironment | undefined; private static _instance: BlockchainTestsEnvironmentSingleton | undefined;
public blockchainLifecycle: BlockchainLifecycle; public blockchainLifecycle: BlockchainLifecycle;
public provider: Web3ProviderEngine; public provider: Web3ProviderEngine;
@ -46,16 +61,16 @@ export class BlockchainTestsEnvironment {
public web3Wrapper: Web3Wrapper; public web3Wrapper: Web3Wrapper;
// Create or retrieve the singleton instance of this class. // Create or retrieve the singleton instance of this class.
public static create(): BlockchainTestsEnvironment { public static create(): BlockchainTestsEnvironmentSingleton {
if (BlockchainTestsEnvironment._instance === undefined) { if (BlockchainTestsEnvironmentSingleton._instance === undefined) {
BlockchainTestsEnvironment._instance = new BlockchainTestsEnvironment(); BlockchainTestsEnvironmentSingleton._instance = new BlockchainTestsEnvironmentSingleton();
} }
return BlockchainTestsEnvironment._instance; return BlockchainTestsEnvironmentSingleton._instance;
} }
// Get the singleton instance of this class. // Get the singleton instance of this class.
public static getInstance(): BlockchainTestsEnvironment | undefined { public static getInstance(): BlockchainTestsEnvironmentSingleton | undefined {
return BlockchainTestsEnvironment._instance; return BlockchainTestsEnvironmentSingleton._instance;
} }
public async getChainIdAsync(): Promise<number> { public async getChainIdAsync(): Promise<number> {
@ -74,99 +89,99 @@ export class BlockchainTestsEnvironment {
} }
} }
// The original `describe()` global provided by mocha.
const mochaDescribe = (global as any).describe as Mocha.IContextDefinition;
/**
* An augmented version of Mocha's `describe()`.
*/
export const describe = _.assign(mochaDescribe, {
optional(description: string, callback: SuiteCallback): ISuite | void {
const describeCall = process.env.TEST_ALL ? mochaDescribe : mochaDescribe.skip;
return describeCall(description, callback);
},
}) as ContextDefinition;
/**
* Like mocha's `describe()`, but sets up a blockchain environment on first call.
*/
export const blockchainTests: BlockchainContextDefinition = _.assign(
function(description: string, callback: BlockchainSuiteCallback): ISuite {
return defineBlockchainSuite(description, callback, describe);
},
{
only(description: string, callback: BlockchainSuiteCallback): ISuite {
return defineBlockchainSuite(description, callback, describe.only);
},
skip(description: string, callback: BlockchainSuiteCallback): void {
return defineBlockchainSuite(description, callback, describe.skip);
},
optional(description: string, callback: BlockchainSuiteCallback): ISuite | void {
return defineBlockchainSuite(description, callback, process.env.TEST_ALL ? describe : describe.skip);
},
resets: _.assign(
function(description: string, callback: BlockchainSuiteCallback): ISuite {
return defineBlockchainSuite(description, callback, function(
_description: string,
_callback: SuiteCallback,
): ISuite {
return defineResetsSuite(_description, _callback, describe);
});
},
{
only(description: string, callback: BlockchainSuiteCallback): ISuite {
return defineBlockchainSuite(description, callback, function(
_description: string,
_callback: SuiteCallback,
): ISuite {
return defineResetsSuite(_description, _callback, describe.only);
});
},
skip(description: string, callback: BlockchainSuiteCallback): void {
return defineBlockchainSuite(description, callback, function(
_description: string,
_callback: SuiteCallback,
): void {
return defineResetsSuite(_description, _callback, describe.skip);
});
},
optional(description: string, callback: BlockchainSuiteCallback): ISuite | void {
return defineBlockchainSuite(description, callback, function(
_description: string,
_callback: SuiteCallback,
): ISuite | void {
return defineResetsSuite(_description, _callback, describe.optional);
});
},
},
),
},
) as BlockchainContextDefinition;
function defineBlockchainSuite<T>( function defineBlockchainSuite<T>(
description: string, description: string,
callback: Mocha.BlockchainSuiteCallback, callback: BlockchainSuiteCallback,
describeCall: Mocha.ContextDefinitionCallback<T>, describeCall: ContextDefinitionCallback<T>,
): T { ): T {
const env = BlockchainTestsEnvironment.create(); const env = BlockchainTestsEnvironmentSingleton.create();
return describeCall(description, function(this: Mocha.ISuiteCallbackContext): void { return describeCall(description, function(this: ISuiteCallbackContext): void {
before( before(async () => env.blockchainLifecycle.startAsync());
async (): Promise<void> => { before(async () => env.blockchainLifecycle.revertAsync());
return env.blockchainLifecycle.startAsync();
},
);
before(
async (): Promise<void> => {
return env.blockchainLifecycle.revertAsync();
},
);
callback.call(this, env); callback.call(this, env);
}); });
} }
function defineResetsSuite<T>( function defineResetsSuite<T>(
description: string, description: string,
callback: Mocha.SuiteCallback, callback: SuiteCallback,
describeCall: Mocha.ContextDefinitionCallback<T>, describeCall: ContextDefinitionCallback<T>,
): T { ): T {
return describeCall(description, function(this: Mocha.ISuiteCallbackContext): void { return describeCall(description, function(this: ISuiteCallbackContext): void {
const env = BlockchainTestsEnvironment.getInstance(); const env = BlockchainTestsEnvironmentSingleton.getInstance();
if (env !== undefined) { if (env !== undefined) {
beforeEach(async () => { beforeEach(async () => env.blockchainLifecycle.startAsync());
return env.blockchainLifecycle.startAsync(); afterEach(async () => env.blockchainLifecycle.revertAsync());
});
afterEach(async () => {
return env.blockchainLifecycle.revertAsync();
});
} }
callback.call(this); callback.call(this);
}); });
} }
/**
* Like mocha's `describe()`, but sets up a BlockchainLifecycle and Web3Wrapper.
*/
export const blockchainTests: Mocha.BlockchainContextDefinition = _.assign(
function(description: string, callback: Mocha.BlockchainSuiteCallback): Mocha.ISuite {
return defineBlockchainSuite(description, callback, describe);
},
{
only(description: string, callback: Mocha.BlockchainSuiteCallback): Mocha.ISuite {
return defineBlockchainSuite(description, callback, describe.only);
},
skip(description: string, callback: Mocha.BlockchainSuiteCallback): void {
return defineBlockchainSuite(description, callback, describe.skip);
},
optional(description: string, callback: Mocha.BlockchainSuiteCallback): Mocha.ISuite | void {
return defineBlockchainSuite(description, callback, process.env.TEST_ALL ? describe : describe.skip);
},
resets: _.assign(
function(description: string, callback: Mocha.BlockchainSuiteCallback): Mocha.ISuite {
return defineBlockchainSuite(description, callback, function(
_description: string,
_callback: Mocha.SuiteCallback,
): Mocha.ISuite {
return defineResetsSuite(_description, _callback, describe);
});
},
{
only(description: string, callback: Mocha.BlockchainSuiteCallback): Mocha.ISuite {
return defineBlockchainSuite(description, callback, function(
_description: string,
_callback: Mocha.SuiteCallback,
): Mocha.ISuite {
return defineResetsSuite(_description, _callback, describe.only);
});
},
skip(description: string, callback: Mocha.BlockchainSuiteCallback): void {
return defineBlockchainSuite(description, callback, function(
_description: string,
_callback: Mocha.SuiteCallback,
): void {
return defineResetsSuite(_description, _callback, describe.skip);
});
},
optional(description: string, callback: Mocha.BlockchainSuiteCallback): Mocha.ISuite | void {
const describeCall = process.env.TEST_ALL ? describe : describe.skip;
return defineBlockchainSuite(description, callback, function(
_description: string,
_callback: Mocha.SuiteCallback,
): Mocha.ISuite | void {
return defineResetsSuite(_description, _callback, describeCall);
});
},
},
),
},
) as Mocha.BlockchainContextDefinition;

View File

@ -1,7 +1,7 @@
import * as _ from 'lodash'; import * as _ from 'lodash';
import * as process from 'process'; import * as process from 'process';
import { blockchainTests, constants, expect } from '../src'; import { blockchainTests, constants, describe, expect } from '../src';
blockchainTests('mocha blockchain extensions', env => { blockchainTests('mocha blockchain extensions', env => {
describe('blockchainTests()', () => { describe('blockchainTests()', () => {
@ -79,6 +79,16 @@ blockchainTests('mocha blockchain extensions', env => {
require('./subtests/mocha_blockchain_1').append(env); require('./subtests/mocha_blockchain_1').append(env);
}); });
}); });
describe('describe extensions', () => {
describe('modifiers', () => {
describe.optional('optional', () => {
it('only runs this with `TEST_ALL` environment flag set', () => {
expect(process.env.TEST_ALL).to.be.ok('');
});
});
});
});
}); });
function createHookedObject(obj: any, handler: (name: string) => void, methods: string[]): any { function createHookedObject(obj: any, handler: (name: string) => void, methods: string[]): any {