Skip to content

Commit cc3e18a

Browse files
kandrianovcgewecke
authored andcommitted
Istanbul reporter (#388)
* Make istanbul reporter configurable * Add coverage expectations to plugin integration tests * Add kandrianov to contributors list
1 parent 3f59e8a commit cc3e18a

File tree

7 files changed

+108
-7
lines changed

7 files changed

+108
-7
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ a local dependency, please see [this section](https://github.com/sc-forks/solidi
3838
### Network Configuration
3939

4040
By default, this tool connects to a coverage-enabled fork of ganache-cli
41-
called **testrpc-sc** on port 8555.
41+
called **testrpc-sc** on port 8555.
4242
+ it's a dependency - there's nothing extra to download.
4343
+ the solidity-coverage command launches it automatically in the background. (See [this section of the FAQ](https://github.com/sc-forks/solidity-coverage/blob/master/docs/faq.md#running-testrpc-sc-on-its-own) if you need to launch it separately yourself)
4444

@@ -95,7 +95,8 @@ module.exports = {
9595
| skipFiles | *Array* | `['Migrations.sol']` | Array of contracts or folders (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. |
9696
| deepSkip | boolean | false | Use this if instrumentation hangs on large, skipped files (like Oraclize). It's faster. |
9797
| dir | *String* | `.` | Solidity-coverage copies all the assets in your root directory (except `node_modules`) to a special folder where it instruments the contracts and executes the tests. `dir` allows you to define a relative path from the root directory to those assets. Useful if your contracts & tests are within their own folder as part of a larger project.|
98-
| buildDirPath | *String* | `/build/contracts` | Build directory path for compiled smart contracts
98+
| buildDirPath | *String* | `/build/contracts` | Build directory path for compiled smart contracts |
99+
| istanbulReporter | *Array* | ['html', 'lcov', 'text'] | Coverage reporters for Istanbul. Optional reporter replaces the default reporters. |
99100

100101
### FAQ
101102

@@ -146,3 +147,4 @@ $ yarn
146147
+ [@pinkiebell](https://github.com/pinkiebell)
147148
+ [@obernardovieira](https://github.com/obernardovieira)
148149
+ [@angus-hamill](https://github.com/angus-hamill)
150+
+ [@kandrianov](https://github.com/kandrianov)

lib/app.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class App {
4242
this.gasLimit = 0xfffffffffff;
4343
this.gasLimitString = "0xfffffffffff";
4444
this.gasPrice = 0x01;
45+
46+
this.istanbulReporter = config.istanbulReporter || ['html', 'lcov', 'text'];
4547
}
4648

4749
// -------------------------------------- Methods -----------------------------------------------
@@ -122,9 +124,8 @@ class App {
122124
this.saveCoverage(relativeMapping);
123125

124126
collector.add(relativeMapping);
125-
reporter.add('html');
126-
reporter.add('lcov');
127-
reporter.add('text');
127+
128+
this.istanbulReporter.forEach(report => reporter.add(report));
128129

129130
reporter.write(collector, true, () => {
130131
this.log('Istanbul coverage reports generated');
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
module.exports = {
22
silent: process.env.SILENT ? true : false,
3-
};
3+
istanbulReporter: ['json-summary', 'text']
4+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
module.exports = {
22
silent: process.env.SILENT ? true : false,
3+
istanbulReporter: ['json-summary', 'text']
34
};
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module.exports = {
22
silent: process.env.SILENT ? true : false,
3-
skipFiles: ['skipped-folder']
3+
skipFiles: ['skipped-folder'],
4+
istanbulReporter: ['json-summary', 'text']
45
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
module.exports = {
22
silent: process.env.SILENT ? true : false,
3+
istanbulReporter: ['json-summary', 'text']
34
}

test/units/app.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,20 @@ const opts = { compact: false, depth: 5, breakLength: 80 };
1212
// =======
1313
function pathExists(path) { return shell.test('-e', path); }
1414

15+
function pathToContract(config, file) {
16+
return path.join('contracts', file);
17+
}
18+
19+
function assertLineCoverage(expected=[]){
20+
let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json'));
21+
expected.forEach(item => assert(summary[item.file].lines.pct === item.pct))
22+
}
23+
24+
function assertCoverageMissing(expected=[]){
25+
let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json'));
26+
expected.forEach(item => assert(summary[item.file] === undefined))
27+
}
28+
1529
function assertCleanInitialState(){
1630
assert(pathExists('./coverage') === false, 'should start without: coverage');
1731
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json');
@@ -88,12 +102,41 @@ describe('app', function() {
88102
assertCleanInitialState();
89103
mock.installFullProject('multiple-migrations');
90104
await plugin(truffleConfig);
105+
106+
const expected = [
107+
{
108+
file: pathToContract(truffleConfig, 'ContractA.sol'),
109+
pct: 100
110+
},
111+
{
112+
file: pathToContract(truffleConfig, 'ContractB.sol'),
113+
pct: 100,
114+
},
115+
{
116+
file: pathToContract(truffleConfig, 'ContractC.sol'),
117+
pct: 100,
118+
},
119+
];
120+
121+
assertLineCoverage(expected);
91122
});
92123

93124
it('project skips a folder', async function() {
94125
assertCleanInitialState();
95126
mock.installFullProject('skipping');
96127
await plugin(truffleConfig);
128+
129+
const expected = [{
130+
file: pathToContract(truffleConfig, 'ContractA.sol'),
131+
pct: 100
132+
}];
133+
134+
const missing = [{
135+
file: pathToContract(truffleConfig, 'ContractB.sol'),
136+
}];
137+
138+
assertLineCoverage(expected);
139+
assertCoverageMissing(missing);
97140
});
98141

99142
it('project with relative path solidity imports', async function() {
@@ -109,6 +152,23 @@ describe('app', function() {
109152
truffleConfig.file = testPath;
110153
mock.installFullProject('test-files');
111154
await plugin(truffleConfig);
155+
156+
const expected = [
157+
{
158+
file: pathToContract(truffleConfig, 'ContractA.sol'),
159+
pct: 100
160+
},
161+
{
162+
file: pathToContract(truffleConfig, 'ContractB.sol'),
163+
pct: 0,
164+
},
165+
{
166+
file: pathToContract(truffleConfig, 'ContractC.sol'),
167+
pct: 0,
168+
},
169+
];
170+
171+
assertLineCoverage(expected);
112172
});
113173

114174
it('truffle run coverage --file test/<glob*>', async function() {
@@ -118,6 +178,23 @@ describe('app', function() {
118178
truffleConfig.file = testPath;
119179
mock.installFullProject('test-files');
120180
await plugin(truffleConfig);
181+
182+
const expected = [
183+
{
184+
file: pathToContract(truffleConfig, 'ContractA.sol'),
185+
pct: 0,
186+
},
187+
{
188+
file: pathToContract(truffleConfig, 'ContractB.sol'),
189+
pct: 100,
190+
},
191+
{
192+
file: pathToContract(truffleConfig, 'ContractC.sol'),
193+
pct: 100,
194+
},
195+
];
196+
197+
assertLineCoverage(expected);
121198
});
122199

123200
it('truffle run coverage --file test/gl{o,b}*.js', async function() {
@@ -127,6 +204,23 @@ describe('app', function() {
127204
truffleConfig.file = testPath;
128205
mock.installFullProject('test-files');
129206
await plugin(truffleConfig);
207+
208+
const expected = [
209+
{
210+
file: pathToContract(truffleConfig, 'ContractA.sol'),
211+
pct: 0,
212+
},
213+
{
214+
file: pathToContract(truffleConfig, 'ContractB.sol'),
215+
pct: 100,
216+
},
217+
{
218+
file: pathToContract(truffleConfig, 'ContractC.sol'),
219+
pct: 100,
220+
},
221+
];
222+
223+
assertLineCoverage(expected);
130224
});
131225

132226
it('contract only uses ".call"', async function(){

0 commit comments

Comments
 (0)