aboutsummaryrefslogtreecommitdiffstats
path: root/packages/sol-cov
diff options
context:
space:
mode:
Diffstat (limited to 'packages/sol-cov')
-rw-r--r--packages/sol-cov/CHANGELOG.json18
-rw-r--r--packages/sol-cov/CHANGELOG.md10
-rw-r--r--packages/sol-cov/compiler.json18
-rw-r--r--packages/sol-cov/package.json24
-rw-r--r--packages/sol-cov/src/collect_contract_data.ts27
-rw-r--r--packages/sol-cov/src/coverage_manager.ts63
-rw-r--r--packages/sol-cov/src/coverage_subprovider.ts10
-rw-r--r--packages/sol-cov/src/utils.ts4
-rw-r--r--packages/sol-cov/test/collect_contracts_data_test.ts3
9 files changed, 113 insertions, 64 deletions
diff --git a/packages/sol-cov/CHANGELOG.json b/packages/sol-cov/CHANGELOG.json
index 508b70631..468957fe3 100644
--- a/packages/sol-cov/CHANGELOG.json
+++ b/packages/sol-cov/CHANGELOG.json
@@ -1,5 +1,23 @@
[
{
+ "timestamp": 1525477860,
+ "version": "0.0.10",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
+ "timestamp": 1525428773,
+ "version": "0.0.9",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"timestamp": 1524044013,
"version": "0.0.8",
"changes": [
diff --git a/packages/sol-cov/CHANGELOG.md b/packages/sol-cov/CHANGELOG.md
index fa8039919..9e2995328 100644
--- a/packages/sol-cov/CHANGELOG.md
+++ b/packages/sol-cov/CHANGELOG.md
@@ -5,11 +5,19 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v0.0.10 - _May 5, 2018_
+
+ * Dependencies updated
+
+## v0.0.9 - _May 4, 2018_
+
+ * Dependencies updated
+
## v0.0.8 - _April 18, 2018_
* Dependencies updated
-## v0.0.7 - _April 12, 2018_
+## v0.0.7 - _April 11, 2018_
* Dependencies updated
diff --git a/packages/sol-cov/compiler.json b/packages/sol-cov/compiler.json
new file mode 100644
index 000000000..a6a0c6d3a
--- /dev/null
+++ b/packages/sol-cov/compiler.json
@@ -0,0 +1,18 @@
+{
+ "contracts": ["SimpleStorage"],
+ "contractsDir": "test/fixtures/contracts",
+ "artifactsDir": "test/fixtures/artifacts",
+ "compilerSettings": {
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode.object",
+ "evm.bytecode.sourceMap",
+ "evm.deployedBytecode.object",
+ "evm.deployedBytecode.sourceMap"
+ ]
+ }
+ }
+ }
+}
diff --git a/packages/sol-cov/package.json b/packages/sol-cov/package.json
index 886ca52c2..6268df4c7 100644
--- a/packages/sol-cov/package.json
+++ b/packages/sol-cov/package.json
@@ -1,20 +1,20 @@
{
"name": "@0xproject/sol-cov",
- "version": "0.0.8",
+ "version": "0.0.10",
"description": "Generate coverage reports for Solidity code",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"scripts": {
"build:watch": "tsc -w",
- "lint": "tslint --project . 'src/**/*.ts'",
+ "lint": "tslint --project .",
"test": "run-s clean build compile_test run_mocha",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
"test:circleci": "yarn test:coverage",
"run_mocha": "mocha lib/test/**/*_test.js --exit",
- "clean": "shx rm -rf lib scripts",
+ "clean": "shx rm -rf lib scripts test/fixtures/artifacts src/artifacts",
"build": "copyfiles 'test/fixtures/**/*' ./lib && tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
- "compile_test": "node ../deployer/lib/src/cli.js compile --contracts SimpleStorage --contracts-dir test/fixtures/contracts --artifacts-dir test/fixtures/artifacts",
+ "compile_test": "node ../sol-compiler/lib/src/cli.js compile",
"manual:postpublish": "yarn build; node ./scripts/postpublish.js",
"docs:stage": "yarn build && node ./scripts/stage_docs.js",
"docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --json $JSON_FILE_PATH $PROJECT_FILES",
@@ -43,21 +43,23 @@
},
"homepage": "https://github.com/0xProject/0x.js/packages/sol-cov/README.md",
"dependencies": {
- "@0xproject/subproviders": "^0.9.0",
- "@0xproject/types": "^0.6.1",
- "@0xproject/typescript-typings": "^0.2.0",
+ "@0xproject/subproviders": "^0.10.1",
+ "@0xproject/types": "^0.6.3",
+ "@0xproject/typescript-typings": "^0.3.1",
+ "@0xproject/utils": "^0.6.1",
"ethereumjs-util": "^5.1.1",
"glob": "^7.1.2",
"istanbul": "^0.4.5",
"lodash": "^4.17.4",
+ "mkdirp": "^0.5.1",
"semaphore-async-await": "^1.5.1",
"solidity-parser-antlr": "^0.2.8"
},
"devDependencies": {
- "@0xproject/deployer": "^0.3.5",
- "@0xproject/monorepo-scripts": "^0.1.18",
- "@0xproject/tslint-config": "^0.4.16",
- "@types/istanbul": "^0.4.29",
+ "@0xproject/monorepo-scripts": "^0.1.19",
+ "@0xproject/tslint-config": "^0.4.17",
+ "@types/istanbul": "^0.4.30",
+ "@types/mkdirp": "^0.5.1",
"@types/mocha": "^2.2.42",
"@types/node": "^8.0.53",
"chai": "^4.0.1",
diff --git a/packages/sol-cov/src/collect_contract_data.ts b/packages/sol-cov/src/collect_contract_data.ts
index 1d8bc7178..2c2a12835 100644
--- a/packages/sol-cov/src/collect_contract_data.ts
+++ b/packages/sol-cov/src/collect_contract_data.ts
@@ -5,28 +5,27 @@ import * as path from 'path';
import { ContractData } from './types';
-export const collectContractsData = (artifactsPath: string, sourcesPath: string, networkId: number) => {
+export const collectContractsData = (artifactsPath: string, sourcesPath: string) => {
const artifactsGlob = `${artifactsPath}/**/*.json`;
const artifactFileNames = glob.sync(artifactsGlob, { absolute: true });
- const contractsDataIfExists: Array<ContractData | {}> = _.map(artifactFileNames, artifactFileName => {
+ const contractsData: ContractData[] = [];
+ _.forEach(artifactFileNames, artifactFileName => {
const artifact = JSON.parse(fs.readFileSync(artifactFileName).toString());
- const sources = artifact.networks[networkId].sources;
- const contractName = artifact.contract_name;
+ const sources = _.keys(artifact.sources);
+ const contractName = artifact.contractName;
// We don't compute coverage for dependencies
- const sourceCodes = _.map(sources, (source: string) => fs.readFileSync(source).toString());
- if (_.isUndefined(artifact.networks[networkId])) {
- throw new Error(`No ${contractName} artifacts found for networkId ${networkId}`);
- }
+ const sourceCodes = _.map(sources, (source: string) =>
+ fs.readFileSync(path.join(sourcesPath, source)).toString(),
+ );
const contractData = {
sourceCodes,
sources,
- sourceMap: artifact.networks[networkId].source_map,
- sourceMapRuntime: artifact.networks[networkId].source_map_runtime,
- runtimeBytecode: artifact.networks[networkId].runtime_bytecode,
- bytecode: artifact.networks[networkId].bytecode,
+ bytecode: artifact.compilerOutput.evm.bytecode.object,
+ sourceMap: artifact.compilerOutput.evm.bytecode.sourceMap,
+ runtimeBytecode: artifact.compilerOutput.evm.deployedBytecode.object,
+ sourceMapRuntime: artifact.compilerOutput.evm.deployedBytecode.sourceMap,
};
- return contractData;
+ contractsData.push(contractData);
});
- const contractsData = _.filter(contractsDataIfExists, contractData => !_.isEmpty(contractData)) as ContractData[];
return contractsData;
};
diff --git a/packages/sol-cov/src/coverage_manager.ts b/packages/sol-cov/src/coverage_manager.ts
index 230ccc3c9..800ca96dd 100644
--- a/packages/sol-cov/src/coverage_manager.ts
+++ b/packages/sol-cov/src/coverage_manager.ts
@@ -1,6 +1,9 @@
+import { promisify } from '@0xproject/utils';
+import { addHexPrefix } from 'ethereumjs-util';
import * as fs from 'fs';
import { Collector } from 'istanbul';
import * as _ from 'lodash';
+import * as mkdirp from 'mkdirp';
import * as path from 'path';
import { collectContractsData } from './collect_contract_data';
@@ -28,11 +31,32 @@ import {
} from './types';
import { utils } from './utils';
+const mkdirpAsync = promisify<undefined>(mkdirp);
+
export class CoverageManager {
+ private _sourcesPath: string;
private _traceInfos: TraceInfo[] = [];
private _contractsData: ContractData[] = [];
private _getContractCodeAsync: (address: string) => Promise<string>;
- private static _getSingleFileCoverageForTrace(
+ constructor(
+ artifactsPath: string,
+ sourcesPath: string,
+ getContractCodeAsync: (address: string) => Promise<string>,
+ ) {
+ this._getContractCodeAsync = getContractCodeAsync;
+ this._sourcesPath = sourcesPath;
+ this._contractsData = collectContractsData(artifactsPath, this._sourcesPath);
+ }
+ public appendTraceInfo(traceInfo: TraceInfo): void {
+ this._traceInfos.push(traceInfo);
+ }
+ public async writeCoverageAsync(): Promise<void> {
+ const finalCoverage = await this._computeCoverageAsync();
+ const stringifiedCoverage = JSON.stringify(finalCoverage, null, '\t');
+ await mkdirpAsync('coverage');
+ fs.writeFileSync('coverage/coverage.json', stringifiedCoverage);
+ }
+ private _getSingleFileCoverageForTrace(
contractData: ContractData,
coveredPcs: number[],
pcToSourceRange: { [programCounter: number]: SourceRange },
@@ -94,11 +118,12 @@ export class CoverageManager {
);
statementCoverage[modifierStatementId] = isModifierCovered;
}
+ const absoluteFileName = path.join(this._sourcesPath, fileName);
const partialCoverage = {
- [contractData.sources[fileIndex]]: {
+ [absoluteFileName]: {
...coverageEntriesDescription,
l: {}, // It's able to derive it from statement coverage
- path: fileName,
+ path: absoluteFileName,
f: functionCoverage,
s: statementCoverage,
b: branchCoverage,
@@ -106,31 +131,13 @@ export class CoverageManager {
};
return partialCoverage;
}
- constructor(
- artifactsPath: string,
- sourcesPath: string,
- networkId: number,
- getContractCodeAsync: (address: string) => Promise<string>,
- ) {
- this._getContractCodeAsync = getContractCodeAsync;
- this._contractsData = collectContractsData(artifactsPath, sourcesPath, networkId);
- }
- public appendTraceInfo(traceInfo: TraceInfo): void {
- this._traceInfos.push(traceInfo);
- }
- public async writeCoverageAsync(): Promise<void> {
- const finalCoverage = await this._computeCoverageAsync();
- const jsonReplacer: null = null;
- const numberOfJsonSpaces = 4;
- const stringifiedCoverage = JSON.stringify(finalCoverage, jsonReplacer, numberOfJsonSpaces);
- fs.writeFileSync('coverage/coverage.json', stringifiedCoverage);
- }
private async _computeCoverageAsync(): Promise<Coverage> {
const collector = new Collector();
for (const traceInfo of this._traceInfos) {
if (traceInfo.address !== constants.NEW_CONTRACT) {
// Runtime transaction
- const runtimeBytecode = (traceInfo as TraceInfoExistingContract).runtimeBytecode;
+ let runtimeBytecode = (traceInfo as TraceInfoExistingContract).runtimeBytecode;
+ runtimeBytecode = addHexPrefix(runtimeBytecode);
const contractData = _.find(this._contractsData, { runtimeBytecode }) as ContractData;
if (_.isUndefined(contractData)) {
throw new Error(`Transaction to an unknown address: ${traceInfo.address}`);
@@ -144,7 +151,7 @@ export class CoverageManager {
contractData.sources,
);
for (let fileIndex = 0; fileIndex < contractData.sources.length; fileIndex++) {
- const singleFileCoverageForTrace = CoverageManager._getSingleFileCoverageForTrace(
+ const singleFileCoverageForTrace = this._getSingleFileCoverageForTrace(
contractData,
traceInfo.coveredPcs,
pcToSourceRange,
@@ -154,7 +161,8 @@ export class CoverageManager {
}
} else {
// Contract creation transaction
- const bytecode = (traceInfo as TraceInfoNewContract).bytecode;
+ let bytecode = (traceInfo as TraceInfoNewContract).bytecode;
+ bytecode = addHexPrefix(bytecode);
const contractData = _.find(this._contractsData, contractDataCandidate =>
bytecode.startsWith(contractDataCandidate.bytecode),
) as ContractData;
@@ -170,7 +178,7 @@ export class CoverageManager {
contractData.sources,
);
for (let fileIndex = 0; fileIndex < contractData.sources.length; fileIndex++) {
- const singleFileCoverageForTrace = CoverageManager._getSingleFileCoverageForTrace(
+ const singleFileCoverageForTrace = this._getSingleFileCoverageForTrace(
contractData,
traceInfo.coveredPcs,
pcToSourceRange,
@@ -180,7 +188,6 @@ export class CoverageManager {
}
}
}
- // TODO: Remove any cast as soon as https://github.com/DefinitelyTyped/DefinitelyTyped/pull/24233 gets merged
- return (collector as any).getFinalCoverage();
+ return collector.getFinalCoverage();
}
}
diff --git a/packages/sol-cov/src/coverage_subprovider.ts b/packages/sol-cov/src/coverage_subprovider.ts
index 6504d5a46..b08291afb 100644
--- a/packages/sol-cov/src/coverage_subprovider.ts
+++ b/packages/sol-cov/src/coverage_subprovider.ts
@@ -28,19 +28,13 @@ export class CoverageSubprovider extends Subprovider {
* Instantiates a CoverageSubprovider instance
* @param artifactsPath Path to the smart contract artifacts
* @param sourcesPath Path to the smart contract source files
- * @param networkId network id
* @param defaultFromAddress default from address to use when sending transactions
*/
- constructor(artifactsPath: string, sourcesPath: string, networkId: number, defaultFromAddress: string) {
+ constructor(artifactsPath: string, sourcesPath: string, defaultFromAddress: string) {
super();
this._lock = new Lock();
this._defaultFromAddress = defaultFromAddress;
- this._coverageManager = new CoverageManager(
- artifactsPath,
- sourcesPath,
- networkId,
- this._getContractCodeAsync.bind(this),
- );
+ this._coverageManager = new CoverageManager(artifactsPath, sourcesPath, this._getContractCodeAsync.bind(this));
}
/**
* Write the test coverage results to a file in Istanbul format.
diff --git a/packages/sol-cov/src/utils.ts b/packages/sol-cov/src/utils.ts
index f155043a1..d970c42ee 100644
--- a/packages/sol-cov/src/utils.ts
+++ b/packages/sol-cov/src/utils.ts
@@ -4,6 +4,10 @@ export const utils = {
compareLineColumn(lhs: LineColumn, rhs: LineColumn): number {
return lhs.line !== rhs.line ? lhs.line - rhs.line : lhs.column - rhs.column;
},
+ removeHexPrefix(hex: string): string {
+ const hexPrefix = '0x';
+ return hex.startsWith(hexPrefix) ? hex.slice(hexPrefix.length) : hex;
+ },
isRangeInside(childRange: SingleFileSourceRange, parentRange: SingleFileSourceRange): boolean {
return (
utils.compareLineColumn(parentRange.start, childRange.start) <= 0 &&
diff --git a/packages/sol-cov/test/collect_contracts_data_test.ts b/packages/sol-cov/test/collect_contracts_data_test.ts
index 943a4a878..c7c1dfe32 100644
--- a/packages/sol-cov/test/collect_contracts_data_test.ts
+++ b/packages/sol-cov/test/collect_contracts_data_test.ts
@@ -12,8 +12,7 @@ describe('Collect contracts data', () => {
it('correctly collects contracts data', () => {
const artifactsPath = path.resolve(__dirname, 'fixtures/artifacts');
const sourcesPath = path.resolve(__dirname, 'fixtures/contracts');
- const networkId = 50;
- const contractsData = collectContractsData(artifactsPath, sourcesPath, networkId);
+ const contractsData = collectContractsData(artifactsPath, sourcesPath);
_.forEach(contractsData, contractData => {
expect(contractData).to.have.keys([
'sourceCodes',