Merge pull request #52 from sc-forks/allow-exclusions

Allow files to be skipped during coverage
pull/53/head
c-g-e-w-e-k-e- 8 years ago committed by GitHub
commit aa41e80f1f
  1. 1
      README.md
  2. 12
      bin/exec.js
  3. 22
      test/cli.js

@ -76,6 +76,7 @@ can be useful if you are using a different vm like the [sc-forks version of pyet
directory. `dir` allows you to define a relative path from the root directory to those assets. directory. `dir` allows you to define a relative path from the root directory to those assets.
`dir: "./<dirname>"` would tell solidity-coverage to look for `./<dirname>/contracts/` and `./<dirname>/test/` `dir: "./<dirname>"` would tell solidity-coverage to look for `./<dirname>/contracts/` and `./<dirname>/test/`
+ **copyNodeModules**: *{ Boolean }* : When true, will copy `node_modules` into the coverage environment. False by default, and may significantly increase the time for coverage to complete if enabled. Only enable if required. + **copyNodeModules**: *{ Boolean }* : When true, will copy `node_modules` into the coverage environment. False by default, and may significantly increase the time for coverage to complete if enabled. Only enable if required.
+ **skipFiles**: *{ Array }* : An array of contracts (with paths expressed relative to the `contracts` directory) that should be skipped when doing instrumentation. `Migrations.sol` is skipped by default, and does not need to be added to this configuration option if it is used.
**Example .solcover.js config file** **Example .solcover.js config file**
```javascript ```javascript

@ -62,6 +62,7 @@ const workingDir = config.dir || '.'; // Relative path to contracts folder
let port = config.port || 8555; // Port testrpc listens on let port = config.port || 8555; // Port testrpc listens on
const accounts = config.accounts || 35; // Number of accounts to testrpc launches with const accounts = config.accounts || 35; // Number of accounts to testrpc launches with
const copyNodeModules = config.copyNodeModules || false; // Whether we copy node_modules when making coverage environment const copyNodeModules = config.copyNodeModules || false; // Whether we copy node_modules when making coverage environment
let skipFiles = config.skipFiles || []; // Which files should be skipped during instrumentation
// Silence shell and script logging (for solcover's unit tests / CI) // Silence shell and script logging (for solcover's unit tests / CI)
if (config.silent) { if (config.silent) {
@ -114,18 +115,19 @@ try {
cleanUp(msg + err); cleanUp(msg + err);
} }
// For each contract except migrations.sol: // For each contract except migrations.sol (or those in skipFiles):
// 1. Generate file path reference for coverage report // 1. Generate file path reference for coverage report
// 2. Load contract as string // 2. Load contract as string
// 3. Instrument contract // 3. Instrument contract
// 4. Save instrumented contract in the coverage environment folder where covered tests will run // 4. Save instrumented contract in the coverage environment folder where covered tests will run
// 5. Add instrumentation info to the coverage map // 5. Add instrumentation info to the coverage map
skipFiles = skipFiles.map(contract => `${coverageDir}/contracts/` + contract);
skipFiles.push(`${coverageDir}/contracts/Migrations.sol`);
let currentFile; let currentFile;
try { try {
shell.ls(`${coverageDir}/contracts/**/*.sol`).forEach(file => { shell.ls(`${coverageDir}/contracts/**/*.sol`).forEach(file => {
const migrations = `${coverageDir}/contracts/Migrations.sol`; if (!skipFiles.includes(file)) {
if (file !== migrations) {
log('Instrumenting ', file); log('Instrumenting ', file);
currentFile = file; currentFile = file;
@ -135,6 +137,8 @@ try {
const instrumentedContractInfo = getInstrumentedVersion(contract, canonicalPath); const instrumentedContractInfo = getInstrumentedVersion(contract, canonicalPath);
fs.writeFileSync(contractPath, instrumentedContractInfo.contract); fs.writeFileSync(contractPath, instrumentedContractInfo.contract);
coverage.addContract(instrumentedContractInfo, canonicalPath); coverage.addContract(instrumentedContractInfo, canonicalPath);
} else {
log('Skipping instrumentation of ', file);
} }
}); });
} catch (err) { } catch (err) {

@ -242,6 +242,28 @@ describe('cli', () => {
collectGarbage(); collectGarbage();
}); });
it('contracts are skipped: should generate coverage, cleanup & exit(0)', () => {
// Skip instrumentation of some contracts
assert(pathExists('./coverage') === false, 'should start without: coverage');
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json');
const testConfig = Object.assign({}, config);
testConfig.skipFiles = ['Owned.sol'];
mock.installInheritanceTest(testConfig);
shell.exec(script);
assert(shell.error() === null, 'script should not error');
assert(pathExists('./coverage') === true, 'script should gen coverage folder');
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json');
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8'));
const firstKey = Object.keys(produced)[0];
assert(Object.keys(produced).length === 1, 'coverage.json should only contain instrumentation for one contract');
assert(firstKey.substr(firstKey.length - 9) === 'Proxy.sol', 'coverage.json should only contain instrumentation for Proxy.sol');
collectGarbage();
});
it('truffle tests failing: should generate coverage, cleanup & exit(1)', () => { it('truffle tests failing: should generate coverage, cleanup & exit(1)', () => {
assert(pathExists('./coverage') === false, 'should start without: coverage'); assert(pathExists('./coverage') === false, 'should start without: coverage');
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); assert(pathExists('./coverage.json') === false, 'should start without: coverage.json');

Loading…
Cancel
Save