Skip to content

Commit aa41e80

Browse files
authored
Merge pull request #52 from sc-forks/allow-exclusions
Allow files to be skipped during coverage
2 parents c0d5f2e + c500b9d commit aa41e80

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ can be useful if you are using a different vm like the [sc-forks version of pyet
7676
directory. `dir` allows you to define a relative path from the root directory to those assets.
7777
`dir: "./<dirname>"` would tell solidity-coverage to look for `./<dirname>/contracts/` and `./<dirname>/test/`
7878
+ **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.
79+
+ **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.
7980

8081
**Example .solcover.js config file**
8182
```javascript
@@ -97,7 +98,7 @@ the extra events. If this is the case, then the coverage may be incomplete. To a
9798

9899
**Using `require` in `migrations.js` files**: Truffle overloads Node's `require` function but
99100
implements a simplified search algorithm for node_modules packages
100-
([see Truffle issue #383](https://github.com/trufflesuite/truffle/issues/383)).
101+
([see Truffle issue #383](https://github.com/trufflesuite/truffle/issues/383)).
101102
Because solidity-coverage copies an instrumented version of your project into a temporary folder, `require`
102103
statements handled by Truffle internally won't resolve correctly.
103104

bin/exec.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const workingDir = config.dir || '.'; // Relative path to contracts folder
6262
let port = config.port || 8555; // Port testrpc listens on
6363
const accounts = config.accounts || 35; // Number of accounts to testrpc launches with
6464
const copyNodeModules = config.copyNodeModules || false; // Whether we copy node_modules when making coverage environment
65+
let skipFiles = config.skipFiles || []; // Which files should be skipped during instrumentation
6566

6667
// Silence shell and script logging (for solcover's unit tests / CI)
6768
if (config.silent) {
@@ -89,7 +90,7 @@ try {
8990
// Coverage network opts specified: use port if declared
9091
if (truffleConfig && truffleConfig.networks && truffleConfig.networks.coverage) {
9192
port = truffleConfig.networks.coverage.port || port;
92-
93+
9394
// Coverage network opts NOT specified: default to the development network w/ modified
9495
// port, gasLimit, gasPrice. Export the config object only.
9596
} else {
@@ -114,18 +115,19 @@ try {
114115
cleanUp(msg + err);
115116
}
116117

117-
// For each contract except migrations.sol:
118+
// For each contract except migrations.sol (or those in skipFiles):
118119
// 1. Generate file path reference for coverage report
119120
// 2. Load contract as string
120121
// 3. Instrument contract
121122
// 4. Save instrumented contract in the coverage environment folder where covered tests will run
122123
// 5. Add instrumentation info to the coverage map
124+
skipFiles = skipFiles.map(contract => `${coverageDir}/contracts/` + contract);
125+
skipFiles.push(`${coverageDir}/contracts/Migrations.sol`);
126+
123127
let currentFile;
124128
try {
125129
shell.ls(`${coverageDir}/contracts/**/*.sol`).forEach(file => {
126-
const migrations = `${coverageDir}/contracts/Migrations.sol`;
127-
128-
if (file !== migrations) {
130+
if (!skipFiles.includes(file)) {
129131
log('Instrumenting ', file);
130132
currentFile = file;
131133

@@ -135,6 +137,8 @@ try {
135137
const instrumentedContractInfo = getInstrumentedVersion(contract, canonicalPath);
136138
fs.writeFileSync(contractPath, instrumentedContractInfo.contract);
137139
coverage.addContract(instrumentedContractInfo, canonicalPath);
140+
} else {
141+
log('Skipping instrumentation of ', file);
138142
}
139143
});
140144
} catch (err) {

test/cli.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,28 @@ describe('cli', () => {
242242
collectGarbage();
243243
});
244244

245+
it('contracts are skipped: should generate coverage, cleanup & exit(0)', () => {
246+
// Skip instrumentation of some contracts
247+
assert(pathExists('./coverage') === false, 'should start without: coverage');
248+
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json');
249+
const testConfig = Object.assign({}, config);
250+
251+
testConfig.skipFiles = ['Owned.sol'];
252+
mock.installInheritanceTest(testConfig);
253+
254+
shell.exec(script);
255+
assert(shell.error() === null, 'script should not error');
256+
257+
assert(pathExists('./coverage') === true, 'script should gen coverage folder');
258+
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json');
259+
260+
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8'));
261+
const firstKey = Object.keys(produced)[0];
262+
assert(Object.keys(produced).length === 1, 'coverage.json should only contain instrumentation for one contract');
263+
assert(firstKey.substr(firstKey.length - 9) === 'Proxy.sol', 'coverage.json should only contain instrumentation for Proxy.sol');
264+
collectGarbage();
265+
});
266+
245267
it('truffle tests failing: should generate coverage, cleanup & exit(1)', () => {
246268
assert(pathExists('./coverage') === false, 'should start without: coverage');
247269
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json');

0 commit comments

Comments
 (0)