From 13299158d1e22d1af1cd36434fc403a74743ecb1 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Sun, 4 Mar 2018 19:05:26 -0800 Subject: Add sol-cover implementation --- packages/dev-utils/CHANGELOG.md | 6 +++ packages/dev-utils/package.json | 1 + packages/dev-utils/src/blockchain_lifecycle.ts | 15 +++--- packages/dev-utils/src/constants.ts | 2 +- packages/dev-utils/src/coverage.ts | 14 +++++ packages/dev-utils/src/index.ts | 2 +- packages/dev-utils/src/rpc.ts | 62 ---------------------- packages/dev-utils/src/web3_factory.ts | 49 +++++++++++++---- .../dev-utils/test/blockchain_lifecycle_test.ts | 11 ++-- packages/dev-utils/test/rpc_test.ts | 19 ++++--- packages/dev-utils/tslint.json | 5 +- 11 files changed, 90 insertions(+), 96 deletions(-) create mode 100644 packages/dev-utils/src/coverage.ts delete mode 100644 packages/dev-utils/src/rpc.ts (limited to 'packages/dev-utils') diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index ecc5546ae..3e5708402 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGELOG +## v0.3.0 - _TBD, 2018_ + + * Add coverage subprovider if enabled (#426) + * Refactor `BlockchainLifecycle` to work with in-process ganache (#426) + * Remove `RPC` class and move it's logic to `Web3Wrapper` (#426) + ## v0.2.0 - _February 16, 2018_ * Remove subproviders (#392) diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index fbbcb182f..dc594daaf 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -38,6 +38,7 @@ "typescript": "2.7.1" }, "dependencies": { + "@0xproject/sol-cov": "^0.0.1", "@0xproject/subproviders": "^0.7.0", "@0xproject/types": "^0.3.1", "@0xproject/utils": "^0.4.1", diff --git a/packages/dev-utils/src/blockchain_lifecycle.ts b/packages/dev-utils/src/blockchain_lifecycle.ts index c46902f76..48746f8c1 100644 --- a/packages/dev-utils/src/blockchain_lifecycle.ts +++ b/packages/dev-utils/src/blockchain_lifecycle.ts @@ -1,21 +1,24 @@ -import { RPC } from './rpc'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as Web3 from 'web3'; export class BlockchainLifecycle { - private _rpc: RPC; + private _web3Wrapper: Web3Wrapper; private _snapshotIdsStack: number[]; - constructor() { - this._rpc = new RPC(); + constructor(web3Orweb3Wrapper: Web3Wrapper | Web3) { + this._web3Wrapper = (web3Orweb3Wrapper as Web3Wrapper).isZeroExWeb3Wrapper + ? (web3Orweb3Wrapper as Web3Wrapper) + : new Web3Wrapper((web3Orweb3Wrapper as Web3).currentProvider); this._snapshotIdsStack = []; } // TODO: In order to run these tests on an actual node, we should check if we are running against // TestRPC, if so, use snapshots, otherwise re-deploy contracts before every test public async startAsync(): Promise { - const snapshotId = await this._rpc.takeSnapshotAsync(); + const snapshotId = await this._web3Wrapper.takeSnapshotAsync(); this._snapshotIdsStack.push(snapshotId); } public async revertAsync(): Promise { const snapshotId = this._snapshotIdsStack.pop() as number; - const didRevert = await this._rpc.revertSnapshotAsync(snapshotId); + const didRevert = await this._web3Wrapper.revertSnapshotAsync(snapshotId); if (!didRevert) { throw new Error(`Snapshot with id #${snapshotId} failed to revert`); } diff --git a/packages/dev-utils/src/constants.ts b/packages/dev-utils/src/constants.ts index 4f7b4202a..b018ba791 100644 --- a/packages/dev-utils/src/constants.ts +++ b/packages/dev-utils/src/constants.ts @@ -1,5 +1,5 @@ export const constants = { RPC_URL: 'http://localhost:8545', RPC_PORT: 8545, - GAS_ESTIMATE: 1000000, + GAS_ESTIMATE: 5000000, }; diff --git a/packages/dev-utils/src/coverage.ts b/packages/dev-utils/src/coverage.ts new file mode 100644 index 000000000..1750d19ce --- /dev/null +++ b/packages/dev-utils/src/coverage.ts @@ -0,0 +1,14 @@ +import { CoverageSubprovider } from '@0xproject/sol-cov'; +import * as _ from 'lodash'; + +let coverageSubprovider: CoverageSubprovider; + +export function getCoverageSubprovider(): CoverageSubprovider { + if (_.isUndefined(coverageSubprovider)) { + const artifactsPath = './src/artifacts'; + const contractsPath = './src/contracts'; + const networkId = 50; + coverageSubprovider = new CoverageSubprovider(artifactsPath, contractsPath, networkId); + } + return coverageSubprovider; +} diff --git a/packages/dev-utils/src/index.ts b/packages/dev-utils/src/index.ts index e899ac206..c8009158f 100644 --- a/packages/dev-utils/src/index.ts +++ b/packages/dev-utils/src/index.ts @@ -1,4 +1,4 @@ -export { RPC } from './rpc'; export { BlockchainLifecycle } from './blockchain_lifecycle'; export { web3Factory } from './web3_factory'; export { constants as devConstants } from './constants'; +export { getCoverageSubprovider } from './coverage'; diff --git a/packages/dev-utils/src/rpc.ts b/packages/dev-utils/src/rpc.ts deleted file mode 100644 index 47a359263..000000000 --- a/packages/dev-utils/src/rpc.ts +++ /dev/null @@ -1,62 +0,0 @@ -import * as ethUtil from 'ethereumjs-util'; -import * as request from 'request-promise-native'; - -import { constants } from './constants'; - -export class RPC { - private _url: string; - private _id: number; - constructor() { - this._url = constants.RPC_URL; - this._id = 0; - } - public async takeSnapshotAsync(): Promise { - const method = 'evm_snapshot'; - const params: any[] = []; - const payload = this._toPayload(method, params); - const snapshotIdHex = await this._sendAsync(payload); - const snapshotId = ethUtil.bufferToInt(ethUtil.toBuffer(snapshotIdHex)); - return snapshotId; - } - public async revertSnapshotAsync(snapshotId: number): Promise { - const method = 'evm_revert'; - const params = [snapshotId]; - const payload = this._toPayload(method, params); - const didRevert = await this._sendAsync(payload); - return didRevert; - } - public async increaseTimeAsync(time: number) { - const method = 'evm_increaseTime'; - const params = [time]; - const payload = this._toPayload(method, params); - return this._sendAsync(payload); - } - public async mineBlockAsync(): Promise { - const method = 'evm_mine'; - const params: any[] = []; - const payload = this._toPayload(method, params); - await this._sendAsync(payload); - } - private _toPayload(method: string, params: any[] = []): string { - const payload = JSON.stringify({ - id: this._id, - method, - params, - }); - this._id += 1; - return payload; - } - private async _sendAsync(payload: string): Promise { - const opts = { - method: 'POST', - uri: this._url, - body: payload, - headers: { - 'content-type': 'application/json', - }, - }; - const bodyString = await request(opts); - const body = JSON.parse(bodyString); - return body.result; - } -} diff --git a/packages/dev-utils/src/web3_factory.ts b/packages/dev-utils/src/web3_factory.ts index b0e0e4d3f..74359d4f6 100644 --- a/packages/dev-utils/src/web3_factory.ts +++ b/packages/dev-utils/src/web3_factory.ts @@ -6,9 +6,13 @@ import ProviderEngine = require('web3-provider-engine'); import RpcSubprovider = require('web3-provider-engine/subproviders/rpc'); -import { EmptyWalletSubprovider, FakeGasEstimateSubprovider } from '@0xproject/subproviders'; +import { EmptyWalletSubprovider, FakeGasEstimateSubprovider, GanacheSubprovider } from '@0xproject/subproviders'; +import * as fs from 'fs'; +import * as _ from 'lodash'; +import * as process from 'process'; import { constants } from './constants'; +import { getCoverageSubprovider } from './coverage'; // HACK: web3 leaks XMLHttpRequest into the global scope and causes requests to hang // because they are using the wrong XHR package. @@ -17,24 +21,51 @@ import { constants } from './constants'; // tslint:disable-next-line:ordered-imports import * as Web3 from 'web3'; +export interface Web3Config { + hasAddresses?: boolean; // default: true + useInProcessGanache?: boolean; // default: false +} + export const web3Factory = { - create(hasAddresses: boolean = true): Web3 { - const provider = this.getRpcProvider(hasAddresses); + create(config: Web3Config = {}): Web3 { + const provider = this.getRpcProvider(config); const web3 = new Web3(); web3.setProvider(provider); return web3; }, - getRpcProvider(hasAddresses: boolean = true): Web3.Provider { + getRpcProvider(config: Web3Config = {}): Web3.Provider { const provider = new ProviderEngine(); + if (process.env.COVERAGE) { + provider.addProvider(getCoverageSubprovider()); + } + const hasAddresses = _.isUndefined(config.hasAddresses) || config.hasAddresses; if (!hasAddresses) { provider.addProvider(new EmptyWalletSubprovider()); } provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE)); - provider.addProvider( - new RpcSubprovider({ - rpcUrl: constants.RPC_URL, - }), - ); + const logger = { + log: (arg: any) => { + fs.appendFileSync('ganache.log', `${arg}\n`); + }, + }; + const useInProcessGanache = config.useInProcessGanache; + if (useInProcessGanache) { + provider.addProvider( + new GanacheSubprovider({ + logger, + verbose: process.env.VERBOSE_GANACHE, + port: 8545, + networkId: 50, + mnemonic: 'concert load couple harbor equip island argue ramp clarify fence smart topic', + }), + ); + } else { + provider.addProvider( + new RpcSubprovider({ + rpcUrl: constants.RPC_URL, + }), + ); + } provider.start(); return provider; }, diff --git a/packages/dev-utils/test/blockchain_lifecycle_test.ts b/packages/dev-utils/test/blockchain_lifecycle_test.ts index 4fdc53c87..5ed67e012 100644 --- a/packages/dev-utils/test/blockchain_lifecycle_test.ts +++ b/packages/dev-utils/test/blockchain_lifecycle_test.ts @@ -3,20 +3,19 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import 'mocha'; -import { BlockchainLifecycle, RPC, web3Factory } from '../src'; +import { BlockchainLifecycle, web3Factory } from '../src'; const expect = chai.expect; describe('BlockchainLifecycle tests', () => { - const web3 = web3Factory.create(); - const web3Wrapper = new Web3Wrapper(web3.currentProvider); - const rpc = new RPC(); - const blockchainLifecycle = new BlockchainLifecycle(); + const web3Provider = web3Factory.getRpcProvider(); + const web3Wrapper = new Web3Wrapper(web3Provider); + const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); describe('#startAsync/revertAsync', () => { it('reverts changes in between', async () => { const blockNumberBefore = await web3Wrapper.getBlockNumberAsync(); await blockchainLifecycle.startAsync(); - await rpc.mineBlockAsync(); + await web3Wrapper.mineBlockAsync(); const blockNumberAfter = await web3Wrapper.getBlockNumberAsync(); expect(blockNumberAfter).to.be.equal(blockNumberBefore + 1); await blockchainLifecycle.revertAsync(); diff --git a/packages/dev-utils/test/rpc_test.ts b/packages/dev-utils/test/rpc_test.ts index 2f0e5ff7f..1bdea3613 100644 --- a/packages/dev-utils/test/rpc_test.ts +++ b/packages/dev-utils/test/rpc_test.ts @@ -3,18 +3,17 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import 'mocha'; -import { RPC, web3Factory } from '../src'; +import { web3Factory } from '../src'; const expect = chai.expect; describe('RPC tests', () => { - const web3 = web3Factory.create(); - const web3Wrapper = new Web3Wrapper(web3.currentProvider); - const rpc = new RPC(); + const web3Provider = web3Factory.getRpcProvider(); + const web3Wrapper = new Web3Wrapper(web3Provider); describe('#mineBlockAsync', () => { it('increases block number when called', async () => { const blockNumberBefore = await web3Wrapper.getBlockNumberAsync(); - await rpc.mineBlockAsync(); + await web3Wrapper.mineBlockAsync(); const blockNumberAfter = await web3Wrapper.getBlockNumberAsync(); expect(blockNumberAfter).to.be.equal(blockNumberBefore + 1); }); @@ -23,8 +22,8 @@ describe('RPC tests', () => { it('increases time when called', async () => { const TIME_DELTA = 1000; const blockTimestampBefore = await web3Wrapper.getBlockTimestampAsync(BlockParamLiteral.Latest); - await rpc.increaseTimeAsync(TIME_DELTA); - await rpc.mineBlockAsync(); + await web3Wrapper.increaseTimeAsync(TIME_DELTA); + await web3Wrapper.mineBlockAsync(); const blockTimestampAfter = await web3Wrapper.getBlockTimestampAsync(BlockParamLiteral.Latest); expect(blockTimestampAfter).to.be.at.least(blockTimestampBefore + TIME_DELTA); }); @@ -32,9 +31,9 @@ describe('RPC tests', () => { describe('#takeSnapshotAsync/revertSnapshotAsync', () => { it('reverts changes in between', async () => { const blockNumberBefore = await web3Wrapper.getBlockNumberAsync(); - const snapshotId = await rpc.takeSnapshotAsync(); - await rpc.mineBlockAsync(); - await rpc.revertSnapshotAsync(snapshotId); + const snapshotId = await web3Wrapper.takeSnapshotAsync(); + await web3Wrapper.mineBlockAsync(); + await web3Wrapper.revertSnapshotAsync(snapshotId); const blockNumberAfter = await web3Wrapper.getBlockNumberAsync(); expect(blockNumberAfter).to.be.equal(blockNumberBefore); }); diff --git a/packages/dev-utils/tslint.json b/packages/dev-utils/tslint.json index ffaefe83a..015dce851 100644 --- a/packages/dev-utils/tslint.json +++ b/packages/dev-utils/tslint.json @@ -1,3 +1,6 @@ { - "extends": ["@0xproject/tslint-config"] + "extends": ["@0xproject/tslint-config"], + "rules": { + "completed-docs": false + } } -- cgit v1.2.3