Skip to content

Commit 77628b0

Browse files
authored
Add mocha options to solcoverjs (#401)
* Add mocha options in solcoverjs (for skipping tests) * Plugin tests cleanup
1 parent 3bd99ab commit 77628b0

File tree

9 files changed

+115
-37
lines changed

9 files changed

+115
-37
lines changed

dist/truffle.plugin.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ async function plugin(truffleConfig){
2222
let app;
2323
let error;
2424
let truffle;
25+
let solcoverjs;
2526
let testsErrored = false;
2627

2728
// This needs it's own try block because this logic
@@ -221,6 +222,16 @@ function loadSolcoverJS(ui, truffleConfig){
221222
coverageConfig.cwd = truffleConfig.working_directory;
222223
coverageConfig.originalContractsDir = truffleConfig.contracts_directory;
223224

225+
//Merge solcoverjs mocha opts into truffle's
226+
truffleConfig.mocha = truffleConfig.mocha || {};
227+
228+
if (coverageConfig.mocha && typeof coverageConfig.mocha === 'object'){
229+
truffleConfig.mocha = Object.assign(
230+
truffleConfig.mocha,
231+
coverageConfig.mocha
232+
);
233+
}
234+
224235
return coverageConfig;
225236
}
226237

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
module.exports = {
2-
silent: process.env.SILENT ? true : false,
3-
istanbulReporter: ['json-summary', 'text']
4-
};
2+
"silent": false,
3+
"istanbulReporter": [ "json-summary", "text"]
4+
}

test/integration/projects/multiple-migrations/test/contracta.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ contract("contracta", function(accounts) {
55

66
before(async () => instance = await ContractA.deployed())
77

8-
it('sends', async function(){
8+
it('sends [ @skipForCoverage ]', async function(){
99
await instance.sendFn();
1010
});
1111

12-
it('calls', async function(){
12+
it('calls [ @skipForCoverage ]', async function(){
1313
await instance.callFn();
1414
})
1515
});

test/integration/projects/multiple-migrations/test/contractb.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const ContractB = artifacts.require("ContractB");
22

3-
contract("contractB", function(accounts) {
3+
contract("contractB [ @skipForCoverage ]", function(accounts) {
44
let instance;
55

66
before(async () => instance = await ContractB.deployed())

test/units/truffle/errors.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ const verify = require('../../util/verifiers')
77
const mock = require('../../util/integration.truffle');
88
const plugin = require('../../../dist/truffle.plugin');
99

10+
// =======
11+
// Errors
12+
// =======
13+
1014
describe('Truffle Plugin: error cases', function() {
1115
let truffleConfig;
1216
let solcoverConfig;
@@ -31,12 +35,12 @@ describe('Truffle Plugin: error cases', function() {
3135
} catch(err){
3236
assert(
3337
err.message.includes('Cannot locate expected contract sources folder'),
34-
`Should error when contract sources cannot be found: (output --> ${err.message}`
38+
`Should error when contract sources cannot be found:: ${err.message}`
3539
);
3640

3741
assert(
3842
err.message.includes('sc_temp/contracts'),
39-
`Error message should contain path: (output --> ${err.message}`
43+
`Error message should contain path:: ${err.message}`
4044
);
4145
}
4246

@@ -53,7 +57,7 @@ describe('Truffle Plugin: error cases', function() {
5357
} catch(err){
5458
assert(
5559
err.message.includes('Could not load .solcover.js config file.'),
56-
`Should notify when solcoverjs has syntax error: (output --> ${err.message}`
60+
`Should notify when solcoverjs has syntax error:: ${err.message}`
5761
);
5862
}
5963

@@ -72,8 +76,8 @@ describe('Truffle Plugin: error cases', function() {
7276
assert.fail()
7377
} catch (err) {
7478
assert(
75-
err.message.includes('Unable to load plugin copy of Truffle library module'),
76-
`Should error on failed lib module load (output --> ${err.message}`
79+
err.message.includes('Unable to load plugin copy'),
80+
`Should error on failed lib module load: ${err.message}`
7781
);
7882
}
7983
});
@@ -140,7 +144,7 @@ describe('Truffle Plugin: error cases', function() {
140144
} catch(err){
141145
assert(
142146
err.toString().includes('/Unparseable.sol.'),
143-
`Should throw instrumentation errors with file name (output --> ${err.toString()}`
147+
`Should throw instrumentation errors with file name: ${err.toString()}`
144148
);
145149

146150
assert(err.stack !== undefined, 'Should have error trace')

test/units/truffle/flags.js

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const mock = require('../../util/integration.truffle');
88
const plugin = require('../../../dist/truffle.plugin');
99

1010
// =======================
11-
// Standard Use-case Tests
11+
// CLI Options / Flags
1212
// =======================
1313

1414
describe('Truffle Plugin: command line options', function() {
@@ -28,8 +28,11 @@ describe('Truffle Plugin: command line options', function() {
2828
it('truffle run coverage --file test/<fileName>', async function() {
2929
verify.cleanInitialState();
3030

31-
const testPath = path.join(truffleConfig.working_directory, 'test/specific_a.js');
32-
truffleConfig.file = testPath;
31+
truffleConfig.file = path.join(
32+
truffleConfig.working_directory,
33+
'test/specific_a.js'
34+
);
35+
3336
mock.installFullProject('test-files');
3437
await plugin(truffleConfig);
3538

@@ -54,8 +57,11 @@ describe('Truffle Plugin: command line options', function() {
5457
it('truffle run coverage --file test/<glob*>', async function() {
5558
verify.cleanInitialState();
5659

57-
const testPath = path.join(truffleConfig.working_directory, 'test/globby*');
58-
truffleConfig.file = testPath;
60+
truffleConfig.file = path.join(
61+
truffleConfig.working_directory,
62+
'test/globby*'
63+
);
64+
5965
mock.installFullProject('test-files');
6066
await plugin(truffleConfig);
6167

@@ -80,8 +86,11 @@ describe('Truffle Plugin: command line options', function() {
8086
it('truffle run coverage --file test/gl{o,b}*.js', async function() {
8187
verify.cleanInitialState();
8288

83-
const testPath = path.join(truffleConfig.working_directory, 'test/gl{o,b}*.js');
84-
truffleConfig.file = testPath;
89+
truffleConfig.file = path.join(
90+
truffleConfig.working_directory,
91+
'test/gl{o,b}*.js'
92+
);
93+
8594
mock.installFullProject('test-files');
8695
await plugin(truffleConfig);
8796

@@ -110,17 +119,20 @@ describe('Truffle Plugin: command line options', function() {
110119
silent: process.env.SILENT ? true : false,
111120
istanbulReporter: ['json-summary', 'text']
112121
};
113-
fs.writeFileSync('.solcover.js', `module.exports=${JSON.stringify(solcoverConfig)}`);
114122

115-
// This relative path has to be ./ prefixed
116-
// (because it's path.joined to truffle's working_directory)
123+
// Write solcoverjs to parent dir of sc_temp (where the test project is installed)
124+
fs.writeFileSync(
125+
'.solcover.js',
126+
`module.exports=${JSON.stringify(solcoverConfig)}`
127+
);
128+
129+
// This relative path has to be ./ prefixed (it's path.joined to truffle's working_directory)
117130
truffleConfig.solcoverjs = './../.solcover.js';
118131

119132
mock.install('Simple', 'simple.js');
120133
await plugin(truffleConfig);
121134

122-
// The relative solcoverjs uses the json-summary reporter which
123-
// this assertion requires
135+
// The relative solcoverjs uses the json-summary reporter
124136
const expected = [{
125137
file: mock.pathToContract(truffleConfig, 'Simple.sol'),
126138
pct: 100
@@ -132,68 +144,72 @@ describe('Truffle Plugin: command line options', function() {
132144

133145
it('truffle run coverage --help', async function(){
134146
verify.cleanInitialState();
135-
truffleConfig.help = "true";
136147

148+
truffleConfig.help = "true";
137149
truffleConfig.logger = mock.testLogger;
150+
138151
mock.install('Simple', 'simple.js', solcoverConfig);
139152
await plugin(truffleConfig);
140153

141154
assert(
142155
mock.loggerOutput.val.includes('Usage'),
143-
`Should output help with Usage instruction (output --> ${mock.loggerOutput.val}`
156+
`Should output help with Usage instruction : ${mock.loggerOutput.val}`
144157
);
145158
})
146159

147160
it('truffle run coverage --version', async function(){
148161
verify.cleanInitialState();
149-
truffleConfig.version = "true";
150162

163+
truffleConfig.version = "true";
151164
truffleConfig.logger = mock.testLogger;
165+
152166
mock.install('Simple', 'simple.js', solcoverConfig);
153167
await plugin(truffleConfig);
154168

155169
assert(
156170
mock.loggerOutput.val.includes('truffle'),
157-
`Should output truffle version (output --> ${mock.loggerOutput.val}`
171+
`Should output truffle version: ${mock.loggerOutput.val}`
158172
);
159173

160174
assert(
161175
mock.loggerOutput.val.includes('ganache-core'),
162-
`Should output ganache-core version (output --> ${mock.loggerOutput.val}`
176+
`Should output ganache-core version: ${mock.loggerOutput.val}`
163177
);
164178

165179
assert(
166180
mock.loggerOutput.val.includes('solidity-coverage'),
167-
`Should output solidity-coverage version (output --> ${mock.loggerOutput.val}`
181+
`Should output solidity-coverage version: ${mock.loggerOutput.val}`
168182
);
169183

170184
})
171185

172186
it('truffle run coverage --useGlobalTruffle', async function(){
173187
verify.cleanInitialState();
174-
truffleConfig.useGlobalTruffle = true;
175188

189+
truffleConfig.useGlobalTruffle = true;
176190
truffleConfig.logger = mock.testLogger;
191+
177192
mock.install('Simple', 'simple.js', solcoverConfig);
178193
await plugin(truffleConfig);
179194

180195
assert(
181196
mock.loggerOutput.val.includes('global node_modules'),
182-
`Should notify it's using global truffle (output --> ${mock.loggerOutput.val}`
197+
`Should notify it's using global truffle: ${mock.loggerOutput.val}`
183198
);
184199
});
185200

186201
it('truffle run coverage --usePluginTruffle', async function(){
187202
verify.cleanInitialState();
188-
truffleConfig.usePluginTruffle = true;
189203

204+
truffleConfig.usePluginTruffle = true;
190205
truffleConfig.logger = mock.testLogger;
206+
191207
mock.install('Simple', 'simple.js', solcoverConfig);
192208
await plugin(truffleConfig);
193209

194210
assert(
195211
mock.loggerOutput.val.includes('fallback Truffle library module'),
196-
`Should notify it's using plugin truffle lib copy (output --> ${mock.loggerOutput.val}`
212+
`Should notify it's using plugin truffle lib copy: ${mock.loggerOutput.val}`
197213
);
198214
});
199215
});

test/units/truffle/standard.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,40 @@ describe('Truffle Plugin: standard use cases', function() {
8282
verify.lineCoverage(expected);
8383
});
8484

85+
// This project has [ @skipForCoverage ] tags in the test descriptions
86+
// at selected 'contract' and 'it' blocks.
87+
it('uses solcoverjs mocha options', async function() {
88+
verify.cleanInitialState();
89+
90+
solcoverConfig.mocha = {
91+
grep: '@skipForCoverage',
92+
invert: true,
93+
};
94+
95+
solcoverConfig.silent = process.env.SILENT ? true : false,
96+
solcoverConfig.istanbulReporter = ['json-summary', 'text']
97+
98+
mock.installFullProject('multiple-migrations', solcoverConfig);
99+
await plugin(truffleConfig);
100+
101+
const expected = [
102+
{
103+
file: mock.pathToContract(truffleConfig, 'ContractA.sol'),
104+
pct: 0
105+
},
106+
{
107+
file: mock.pathToContract(truffleConfig, 'ContractB.sol'),
108+
pct: 0,
109+
},
110+
{
111+
file: mock.pathToContract(truffleConfig, 'ContractC.sol'),
112+
pct: 100,
113+
},
114+
];
115+
116+
verify.lineCoverage(expected);
117+
});
118+
85119
it('project skips a folder', async function() {
86120
verify.cleanInitialState();
87121
mock.installFullProject('skipping');
@@ -116,7 +150,7 @@ describe('Truffle Plugin: standard use cases', function() {
116150

117151
assert(
118152
mock.loggerOutput.val.includes('native solidity tests'),
119-
`Should warn it is skipping native solidity tests (output --> ${mock.loggerOutput.val}`
153+
`Should warn it is skipping native solidity tests: ${mock.loggerOutput.val}`
120154
);
121155
});
122156

test/util/integration.truffle.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,15 @@ function installDouble(contracts, test, config) {
187187
decacheConfigs();
188188
};
189189

190-
function installFullProject(name) {
190+
function installFullProject(name, config) {
191191
shell.mkdir(temp);
192192
shell.cp('-Rf', `${projectPath}${name}/{.,}*`, temp);
193193

194+
if (config){
195+
const configjs = getSolcoverJS(config);
196+
fs.writeFileSync(`${temp}/.solcover.js`, configjs);
197+
}
198+
194199
decacheConfigs();
195200
}
196201

test/util/verifiers.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@ function pathExists(path) { return shell.test('-e', path); }
77

88
function lineCoverage(expected=[]){
99
let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json'));
10-
expected.forEach(item => assert(summary[item.file].lines.pct === item.pct))
10+
11+
expected.forEach((item, idx) => {
12+
assert(
13+
summary[item.file].lines.pct === item.pct,
14+
15+
`For condition ${idx} - expected ${item.pct} %,` +
16+
`saw - ${summary[item.file].lines.pct} %`
17+
)
18+
});
1119
}
1220

1321
function coverageMissing(expected=[]){

0 commit comments

Comments
 (0)