Skip to content

Commit c8de349

Browse files
committed
Working truffle plugin draft w/ integration tests
1 parent e52a3ab commit c8de349

37 files changed

+802
-5359
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ node_modules/
55
.DS_Store
66
test/artifacts
77
test/cache
8+
yarn.lock

dist/truffle.plugin.js

Lines changed: 88 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -27,71 +27,128 @@
2727

2828
const App = require('./../lib/app');
2929
const req = require('req-cwd');
30-
31-
module.exports = async (truffleConfig) =>
30+
const path = require('path');
31+
const dir = require('node-dir');
32+
const Web3 = require('web3');
33+
const util = require('util');
34+
const ganache = require('ganache-core-sc');
35+
36+
module.exports = async function(truffleConfig){
37+
let app;
3238
let error;
39+
let testsErrored = false;
3340

3441
try {
35-
3642
// Load truffle lib & coverage config
3743
const truffle = loadTruffleLibrary();
38-
const coverageConfig = req.silent('./.solcover.js') || {};
44+
45+
const coverageConfigPath = path.join(truffleConfig.working_directory, '.solcover.js');
46+
const coverageConfig = req.silent(coverageConfigPath) || {};
47+
48+
coverageConfig.cwd = truffleConfig.working_directory;
49+
coverageConfig.contractsDir = truffleConfig.contracts_directory;
3950

4051
// Start
41-
const app = new App(coverageConfig);
52+
app = new App(coverageConfig);
4253

4354
// Write instrumented sources to temp folder
44-
app.contractsDirectory = coveragePaths.contracts(truffleConfig, app);
45-
app.generateEnvironment(truffleConfig.contracts_directory, app.contractsDirectory);
4655
app.instrument();
4756

48-
// Have truffle use temp folders
49-
truffleConfig.contracts_directory = app.contractsDirectory;
50-
truffleConfig.build_directory = coveragePaths.artifacts.root(truffleConfig, app);
51-
truffleConfig.contracts_build_directory = coveragePaths.artifacts.contracts(truffleConfig, app);
57+
// Ask truffle to use temp folders
58+
truffleConfig.contracts_directory = paths.contracts(app);
59+
truffleConfig.build_directory = paths.build(app);
60+
truffleConfig.contracts_build_directory = paths.artifacts(truffleConfig, app);
5261

53-
// Compile w/out optimization
54-
truffleConfig.compilers.solc.settings.optimization.enabled = false;
62+
// Additional config
63+
truffleConfig.all = true;
64+
truffleConfig.test_files = tests(truffleConfig);
65+
truffleConfig.compilers.solc.settings.optimizer.enabled = false;
66+
67+
// Compile
5568
await truffle.contracts.compile(truffleConfig);
5669

57-
// Launch provider & run tests
58-
truffleConfig.provider = await app.getCoverageProvider(truffle);
70+
// Launch in-process provider
71+
const networkName = 'soliditycoverage';
72+
const provider = await app.provider(ganache);
73+
const accounts = await (new Web3(provider)).eth.getAccounts();
74+
75+
truffleConfig.provider = provider;
76+
truffleConfig.network = networkName;
77+
truffleConfig.network_id = "*";
78+
truffleConfig.networks[networkName] = {
79+
network_id: truffleConfig.network_id,
80+
provider: truffleConfig.provider,
81+
gas: app.gasLimit,
82+
gasPrice: app.gasPrice,
83+
from: accounts[0]
84+
}
85+
86+
// Run tests
5987
try {
60-
await truffle.test.run(truffleConfig)
88+
failures = await truffle.test.run(truffleConfig)
6189
} catch (e) {
62-
error = e;
63-
app.testsErrored = true;
90+
error = e.stack;
6491
}
6592

66-
// Produce report
67-
app.generateCoverage();
93+
// Run Istanbul
94+
await app.report();
6895

6996
} catch(e){
7097
error = e;
7198
}
7299

73100
// Finish
74-
return app.cleanUp(error);
101+
await app.cleanUp();
102+
103+
if (error !== undefined) throw new Error(error)
104+
if (failures > 0) throw new Error(`${failures} test(s) failed under coverage.`)
75105
}
76106

77107
// -------------------------------------- Helpers --------------------------------------------------
108+
109+
function tests(truffle){
110+
const regex = /.*\.(js|ts|es|es6|jsx|sol)$/;
111+
const files = dir.files(truffle.test_directory, { sync: true }) || [];
112+
return files.filter(f => f.match(regex) != null);
113+
}
114+
115+
78116
function loadTruffleLibrary(){
79117

80118
try { return require("truffle") } catch(err) {};
81119
try { return require("./truffle.library")} catch(err) {};
82120

83-
throw new Error(utils.errors.NO_TRUFFLE_LIB)
121+
throw new Error('Missing truffle lib...')
84122
}
85123

86-
const coveragePaths = {
87-
contracts: (t, c) => path.join(path.dirname(t.contracts_directory), c.contractsDirName)),
88-
89-
artifacts: {
90-
root: (t, c) => path.join(path.dirname(t.build_directory), c.artifactsDirName),
91-
contracts: (t, c) => {
92-
const root = path.join(path.dirname(t.build_directory), c.artifactsDirName);
93-
return path.join(root, path.basename(t.contracts_build_directory));
94-
}
124+
/**
125+
* Functions to generate substitute paths for instrumented contracts and artifacts.
126+
* @type {Object}
127+
*/
128+
const paths = {
129+
// "contracts_directory":
130+
contracts: (app) => {
131+
return path.join(
132+
app.coverageDir,
133+
app.contractsDirName
134+
)
135+
},
136+
137+
// "build_directory":
138+
build: (app) => {
139+
return path.join(
140+
app.coverageDir,
141+
app.artifactsDirName
142+
)
143+
},
144+
145+
// "contracts_build_directory":
146+
artifacts: (truffle, app) => {
147+
return path.join(
148+
app.coverageDir,
149+
app.artifactsDirName,
150+
path.basename(truffle.contracts_build_directory)
151+
)
95152
}
96153
}
97154

0 commit comments

Comments
 (0)