From ef53189fe965f628543af0b90430410070b94680 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sun, 13 Oct 2019 16:15:55 -0700 Subject: [PATCH 1/2] Update test fixtures and plugin utils for buidler plugin --- dist/plugin-assets/plugin.utils.js | 209 +----------------- dist/plugin-assets/truffle.utils.js | 191 ++++++++++++++++ dist/truffle.plugin.js | 30 ++- lib/validator.js | 5 - .../assets/SimpleError.sol | 0 .../{truffle => generic}/assets/asset.js | 0 .../contracts/Migrations.sol | 0 .../migrations/1_initial.js | 0 .../{truffle => generic}/test/.marker | 0 .../projects/bad-solcoverjs/buidler.config.js | 1 + .../projects/import-paths/buidler.config.js | 1 + .../projects/libraries/buidler.config.js | 1 + .../projects/libraries/test/libraries.js | 20 +- .../multiple-migrations/buidler.config.js | 1 + .../projects/no-sources/buidler.config.js | 1 + .../projects/skipping/buidler.config.js | 1 + .../projects/test-files/buidler.config.js | 1 + .../projects/test-files/test/globby_b.js | 2 +- .../projects/test-files/test/globby_c.js | 2 +- .../projects/test-files/test/specific_a.js | 2 +- test/sources/js/block-gas-limit.js | 4 +- test/sources/js/empty.js | 11 +- test/sources/js/inheritance.js | 16 +- test/sources/js/only-call.js | 20 +- test/sources/js/pureview.js | 6 +- test/sources/js/simple.js | 2 +- test/sources/js/sol-parse-fail.js | 17 -- test/sources/js/testrpc-options.js | 13 +- test/sources/js/totallyPure.js | 19 +- test/sources/js/truffle-crash.js | 4 +- test/sources/js/truffle-test-fail.js | 15 +- test/sources/js/wallet.js | 2 +- test/sources/solidity/contracts/app/Proxy.sol | 2 +- test/units/truffle/errors.js | 2 +- test/units/truffle/flags.js | 2 +- test/units/truffle/standard.js | 6 +- ...{integration.truffle.js => integration.js} | 85 +++++-- 37 files changed, 367 insertions(+), 327 deletions(-) create mode 100644 dist/plugin-assets/truffle.utils.js rename test/integration/{truffle => generic}/assets/SimpleError.sol (100%) rename test/integration/{truffle => generic}/assets/asset.js (100%) rename test/integration/{truffle => generic}/contracts/Migrations.sol (100%) rename test/integration/{truffle => generic}/migrations/1_initial.js (100%) rename test/integration/{truffle => generic}/test/.marker (100%) create mode 100644 test/integration/projects/bad-solcoverjs/buidler.config.js create mode 100644 test/integration/projects/import-paths/buidler.config.js create mode 100644 test/integration/projects/libraries/buidler.config.js create mode 100644 test/integration/projects/multiple-migrations/buidler.config.js create mode 100644 test/integration/projects/no-sources/buidler.config.js create mode 100644 test/integration/projects/skipping/buidler.config.js create mode 100644 test/integration/projects/test-files/buidler.config.js delete mode 100644 test/sources/js/sol-parse-fail.js rename test/util/{integration.truffle.js => integration.js} (71%) diff --git a/dist/plugin-assets/plugin.utils.js b/dist/plugin-assets/plugin.utils.js index 948013a3..cabbf0c7 100644 --- a/dist/plugin-assets/plugin.utils.js +++ b/dist/plugin-assets/plugin.utils.js @@ -10,11 +10,7 @@ const PluginUI = require('./truffle.ui'); const path = require('path'); const fs = require('fs-extra'); -const dir = require('node-dir'); -const globby = require('globby'); const shell = require('shelljs'); -const globalModules = require('global-modules'); -const TruffleProvider = require('@truffle/provider'); // === // UI @@ -83,7 +79,7 @@ function toRelativePath(pathToFile, pathToParent){ * @return {Object} temp paths */ function getTempLocations(config){ - const cwd = config.working_directory; + const cwd = config.workingDir; const contractsDirName = '.coverage_contracts'; const artifactsDirName = config.temp || '.coverage_artifacts'; @@ -100,9 +96,9 @@ function getTempLocations(config){ function checkContext(config, tempContractsDir, tempArtifactsDir){ const ui = new PluginUI(config.logger.log); - if (!shell.test('-e', config.contracts_directory)){ + if (!shell.test('-e', config.contractsDir)){ - const msg = ui.generate('sources-fail', [config.contracts_directory]) + const msg = ui.generate('sources-fail', [config.contractsDir]) throw new Error(msg); } @@ -135,7 +131,7 @@ function assembleFiles(config, skipFiles=[]){ shell.mkdir(tempContractsDir); shell.mkdir(tempArtifactsDir); - targets = shell.ls(`${config.contracts_directory}/**/*.sol`); + targets = shell.ls(`${config.contractsDir}/**/*.sol`); skipFiles = assembleSkipped(config, targets, skipFiles); @@ -145,7 +141,7 @@ function assembleFiles(config, skipFiles=[]){ function assembleTargets(config, targets=[], skipFiles=[]){ const skipped = []; const filtered = []; - const cd = config.contracts_directory; + const cd = config.contractsDir; for (let target of targets){ if (skipFiles.includes(target)){ @@ -176,11 +172,8 @@ function assembleTargets(config, targets=[], skipFiles=[]){ * Parses the skipFiles option (which also accepts folders) */ function assembleSkipped(config, targets, skipFiles=[]){ - const cd = config.contracts_directory; - // Make paths absolute - skipFiles = skipFiles.map(contract => `${cd}/${contract}`); - skipFiles.push(`${cd}/Migrations.sol`); + skipFiles = skipFiles.map(contract => `${config.contractsDir}/${contract}`); // Enumerate files in skipped folders const skipFolders = skipFiles.filter(item => path.extname(item) !== '.sol') @@ -195,183 +188,6 @@ function assembleSkipped(config, targets, skipFiles=[]){ return skipFiles; } -// ======== -// Truffle -// ======== - -/** - * Returns a list of test files to pass to mocha. - * @param {Object} config truffleConfig - * @return {String[]} list of files to pass to mocha - */ -function getTestFilePaths(config){ - let target; - let ui = new PluginUI(config.logger.log); - - - // Handle --file cli option (subset of tests) - (typeof config.file === 'string') - ? target = globby.sync([config.file]) - : target = dir.files(config.test_directory, { sync: true }) || []; - - // Filter native solidity tests and warn that they're skipped - const solregex = /.*\.(sol)$/; - const hasSols = target.filter(f => f.match(solregex) != null); - - if (hasSols.length > 0) ui.report('sol-tests', [hasSols.length]); - - // Return list of test files - const testregex = /.*\.(js|ts|es|es6|jsx)$/; - return target.filter(f => f.match(testregex) != null); -} - - -/** - * Configures the network. Runs before the server is launched. - * User can request a network from truffle-config with "--network ". - * There are overlapiing options in solcoverjs (like port and providerOptions.network_id). - * Where there are mismatches user is warned & the truffle network settings are preferred. - * - * Also generates a default config & sets the default gas high / gas price low. - * - * @param {TruffleConfig} config - * @param {SolidityCoverage} api - */ -function setNetwork(config, api){ - const ui = new PluginUI(config.logger.log); - - // --network - if (config.network){ - const network = config.networks[config.network]; - - // Check network: - if (!network){ - throw new Error(ui.generate('no-network', [config.network])); - } - - // Check network id - if (!isNaN(parseInt(network.network_id))){ - - // Warn: non-matching provider options id and network id - if (api.providerOptions.network_id && - api.providerOptions.network_id !== parseInt(network.network_id)){ - - ui.report('id-clash', [ parseInt(network.network_id) ]); - } - - // Prefer network defined id. - api.providerOptions.network_id = parseInt(network.network_id); - - } else { - network.network_id = "*"; - } - - // Check port: use solcoverjs || default if undefined - if (!network.port) { - ui.report('no-port', [api.port]); - network.port = api.port; - } - - // Warn: port conflicts - if (api.port !== api.defaultPort && api.port !== network.port){ - ui.report('port-clash', [ network.port ]) - } - - // Prefer network port if defined; - api.port = network.port; - - network.gas = api.gasLimit; - network.gasPrice = api.gasPrice; - - setOuterConfigKeys(config, api, network.network_id); - return; - } - - // Default Network Configuration - config.network = 'soliditycoverage'; - setOuterConfigKeys(config, api, "*"); - - config.networks[config.network] = { - network_id: "*", - port: api.port, - host: api.host, - gas: api.gasLimit, - gasPrice: api.gasPrice - } -} - -/** - * Sets the default `from` account field in the truffle network that will be used. - * This needs to be done after accounts are fetched from the launched client. - * @param {TruffleConfig} config - * @param {Array} accounts - */ -function setNetworkFrom(config, accounts){ - if (!config.networks[config.network].from){ - config.networks[config.network].from = accounts[0]; - } -} - -// Truffle complains that these outer keys *are not* set when running plugin fn directly. -// But throws saying they *cannot* be manually set when running as truffle command. -function setOuterConfigKeys(config, api, id){ - try { - config.network_id = id; - config.port = api.port; - config.host = api.host; - config.provider = TruffleProvider.create(config); - } catch (err){} -} - -/** - * Tries to load truffle module library and reports source. User can force use of - * a non-local version using cli flags (see option). It's necessary to maintain - * a fail-safe lib because feature was only introduced in 5.0.30. Load order is: - * - * 1. local node_modules - * 2. global node_modules - * 3. fail-safe (truffle lib v 5.0.31 at ./plugin-assets/truffle.library) - * - * @param {Object} truffleConfig config - * @return {Module} - */ -function loadTruffleLibrary(config){ - const ui = new PluginUI(config.logger.log); - - // Local - try { - if (config.useGlobalTruffle || config.usePluginTruffle) throw null; - - const lib = require("truffle"); - ui.report('lib-local'); - return lib; - - } catch(err) {}; - - // Global - try { - if (config.usePluginTruffle) throw null; - - const globalTruffle = path.join(globalModules, 'truffle'); - const lib = require(globalTruffle); - ui.report('lib-global'); - return lib; - - } catch(err) {}; - - // Plugin Copy @ v 5.0.31 - try { - if (config.forceLibFailure) throw null; // For err unit testing - - ui.report('lib-warn'); - return require("./truffle.library") - - } catch(err) { - throw new Error(ui.generate('lib-fail', [err])); - }; - -} - function loadSolcoverJS(config){ let solcoverjs; let coverageConfig; @@ -380,8 +196,8 @@ function loadSolcoverJS(config){ // Handle --solcoverjs flag (config.solcoverjs) - ? solcoverjs = path.join(config.working_directory, config.solcoverjs) - : solcoverjs = path.join(config.working_directory, '.solcover.js'); + ? solcoverjs = path.join(config.workingDir, config.solcoverjs) + : solcoverjs = path.join(config.workingDir, '.solcover.js'); // Catch solcoverjs syntax errors if (shell.test('-e', solcoverjs)){ @@ -400,8 +216,8 @@ function loadSolcoverJS(config){ // Truffle writes to coverage config coverageConfig.log = config.logger.log; - coverageConfig.cwd = config.working_directory; - coverageConfig.originalContractsDir = config.contracts_directory; + coverageConfig.cwd = config.workingDir; + coverageConfig.originalContractsDir = config.contractsDir; // Solidity-Coverage writes to Truffle config config.mocha = config.mocha || {}; @@ -446,15 +262,10 @@ module.exports = { checkContext: checkContext, finish: finish, getTempLocations: getTempLocations, - getTestFilePaths: getTestFilePaths, loadSource: loadSource, loadSolcoverJS: loadSolcoverJS, - loadTruffleLibrary: loadTruffleLibrary, reportSkipped: reportSkipped, save: save, - setNetwork: setNetwork, - setNetworkFrom: setNetworkFrom, - setOuterConfigKeys: setOuterConfigKeys, checkContext: checkContext, toRelativePath: toRelativePath } diff --git a/dist/plugin-assets/truffle.utils.js b/dist/plugin-assets/truffle.utils.js new file mode 100644 index 00000000..7bee861b --- /dev/null +++ b/dist/plugin-assets/truffle.utils.js @@ -0,0 +1,191 @@ +const PluginUI = require('./truffle.ui'); + +const globalModules = require('global-modules'); +const TruffleProvider = require('@truffle/provider'); +const dir = require('node-dir'); +const globby = require('globby'); +const path = require('path'); + +// ============================= +// Truffle Specific Plugin Utils +// ============================== + +/** + * Returns a list of test files to pass to mocha. + * @param {Object} config truffleConfig + * @return {String[]} list of files to pass to mocha + */ +function getTestFilePaths(config){ + let target; + let ui = new PluginUI(config.logger.log); + + + // Handle --file cli option (subset of tests) + (typeof config.file === 'string') + ? target = globby.sync([config.file]) + : target = dir.files(config.testDir, { sync: true }) || []; + + // Filter native solidity tests and warn that they're skipped + const solregex = /.*\.(sol)$/; + const hasSols = target.filter(f => f.match(solregex) != null); + + if (hasSols.length > 0) ui.report('sol-tests', [hasSols.length]); + + // Return list of test files + const testregex = /.*\.(js|ts|es|es6|jsx)$/; + return target.filter(f => f.match(testregex) != null); +} + + +/** + * Configures the network. Runs before the server is launched. + * User can request a network from truffle-config with "--network ". + * There are overlapiing options in solcoverjs (like port and providerOptions.network_id). + * Where there are mismatches user is warned & the truffle network settings are preferred. + * + * Also generates a default config & sets the default gas high / gas price low. + * + * @param {TruffleConfig} config + * @param {SolidityCoverage} api + */ +function setNetwork(config, api){ + const ui = new PluginUI(config.logger.log); + + // --network + if (config.network){ + const network = config.networks[config.network]; + + // Check network: + if (!network){ + throw new Error(ui.generate('no-network', [config.network])); + } + + // Check network id + if (!isNaN(parseInt(network.network_id))){ + + // Warn: non-matching provider options id and network id + if (api.providerOptions.network_id && + api.providerOptions.network_id !== parseInt(network.network_id)){ + + ui.report('id-clash', [ parseInt(network.network_id) ]); + } + + // Prefer network defined id. + api.providerOptions.network_id = parseInt(network.network_id); + + } else { + network.network_id = "*"; + } + + // Check port: use solcoverjs || default if undefined + if (!network.port) { + ui.report('no-port', [api.port]); + network.port = api.port; + } + + // Warn: port conflicts + if (api.port !== api.defaultPort && api.port !== network.port){ + ui.report('port-clash', [ network.port ]) + } + + // Prefer network port if defined; + api.port = network.port; + + network.gas = api.gasLimit; + network.gasPrice = api.gasPrice; + + setOuterConfigKeys(config, api, network.network_id); + return; + } + + // Default Network Configuration + config.network = 'soliditycoverage'; + setOuterConfigKeys(config, api, "*"); + + config.networks[config.network] = { + network_id: "*", + port: api.port, + host: api.host, + gas: api.gasLimit, + gasPrice: api.gasPrice + } +} + +/** + * Sets the default `from` account field in the truffle network that will be used. + * This needs to be done after accounts are fetched from the launched client. + * @param {TruffleConfig} config + * @param {Array} accounts + */ +function setNetworkFrom(config, accounts){ + if (!config.networks[config.network].from){ + config.networks[config.network].from = accounts[0]; + } +} + +// Truffle complains that these outer keys *are not* set when running plugin fn directly. +// But throws saying they *cannot* be manually set when running as truffle command. +function setOuterConfigKeys(config, api, id){ + try { + config.network_id = id; + config.port = api.port; + config.host = api.host; + config.provider = TruffleProvider.create(config); + } catch (err){} +} + +/** + * Tries to load truffle module library and reports source. User can force use of + * a non-local version using cli flags (see option). It's necessary to maintain + * a fail-safe lib because feature was only introduced in 5.0.30. Load order is: + * + * 1. local node_modules + * 2. global node_modules + * 3. fail-safe (truffle lib v 5.0.31 at ./plugin-assets/truffle.library) + * + * @param {Object} truffleConfig config + * @return {Module} + */ +function loadLibrary(config){ + const ui = new PluginUI(config.logger.log); + + // Local + try { + if (config.useGlobalTruffle || config.usePluginTruffle) throw null; + + const lib = require("truffle"); + ui.report('lib-local'); + return lib; + + } catch(err) {}; + + // Global + try { + if (config.usePluginTruffle) throw null; + + const globalTruffle = path.join(globalModules, 'truffle'); + const lib = require(globalTruffle); + ui.report('lib-global'); + return lib; + + } catch(err) {}; + + // Plugin Copy @ v 5.0.31 + try { + if (config.forceLibFailure) throw null; // For err unit testing + + ui.report('lib-warn'); + return require("./truffle.library") + + } catch(err) { + throw new Error(ui.generate('lib-fail', [err])); + }; + +} + +module.exports = { + getTestFilePaths: getTestFilePaths, + setNetwork: setNetwork, + setNetworkFrom: setNetworkFrom, + loadLibrary: loadLibrary, +} diff --git a/dist/truffle.plugin.js b/dist/truffle.plugin.js index aaef2e8a..77bb9461 100644 --- a/dist/truffle.plugin.js +++ b/dist/truffle.plugin.js @@ -1,5 +1,6 @@ const API = require('./../lib/api'); const utils = require('./plugin-assets/plugin.utils'); +const truffleUtils = require('./plugin-assets/truffle.utils'); const PluginUI = require('./plugin-assets/truffle.ui'); const pkg = require('./../package.json'); @@ -23,14 +24,16 @@ async function plugin(config){ try { death(utils.finish.bind(null, config, api)); // Catch interrupt signals + config = normalizeConfig(config); + ui = new PluginUI(config.logger.log); if(config.help) return ui.report('help'); // Exit if --help - truffle = utils.loadTruffleLibrary(config); + truffle = truffleUtils.loadLibrary(config); api = new API(utils.loadSolcoverJS(config)); - utils.setNetwork(config, api); + truffleUtils.setNetwork(config, api); // Server launch const address = await api.ganache(truffle.ganache); @@ -40,7 +43,7 @@ async function plugin(config){ const nodeInfo = await web3.eth.getNodeInfo(); const ganacheVersion = nodeInfo.split('/')[1]; - utils.setNetworkFrom(config, accounts); + truffleUtils.setNetworkFrom(config, accounts); // Version Info ui.report('versions', [ @@ -62,10 +65,13 @@ async function plugin(config){ await api.onServerReady(config); // Instrument + const skipFiles = api.skipFiles || []; + skipFiles.push('Migrations.sol'); + let { targets, skipped - } = utils.assembleFiles(config, api.skipFiles); + } = utils.assembleFiles(config, skipFiles); targets = api.instrument(targets); utils.reportSkipped(config, skipped); @@ -88,7 +94,7 @@ async function plugin(config){ ); config.all = true; - config.test_files = utils.getTestFilePaths(config); + config.test_files = truffleUtils.getTestFilePaths(config); config.compilers.solc.settings.optimizer.enabled = false; // Compile Instrumented Contracts @@ -118,4 +124,18 @@ async function plugin(config){ if (failures > 0) throw new Error(ui.generate('tests-fail', [failures])); } +/** + * Maps truffle specific keys for the paths to things like sources to the generic + * keys required by the plugin utils + * @return {Object} truffle-config.js + */ +function normalizeConfig(config){ + config.workingDir = config.working_directory; + config.contractsDir = config.contracts_directory; + config.testDir = config.test_directory; + config.artifactsDir = config.build_directory; + + return config; +} + module.exports = plugin; diff --git a/lib/validator.js b/lib/validator.js index b5d84415..cdc5b624 100644 --- a/lib/validator.js +++ b/lib/validator.js @@ -2,11 +2,6 @@ const Validator = require('jsonschema').Validator; const AppUI = require('./ui').AppUI; const util = require('util') - -function isFunction(input){ - -} - Validator.prototype.customFormats.isFunction = function(input) { return typeof input === "function" }; diff --git a/test/integration/truffle/assets/SimpleError.sol b/test/integration/generic/assets/SimpleError.sol similarity index 100% rename from test/integration/truffle/assets/SimpleError.sol rename to test/integration/generic/assets/SimpleError.sol diff --git a/test/integration/truffle/assets/asset.js b/test/integration/generic/assets/asset.js similarity index 100% rename from test/integration/truffle/assets/asset.js rename to test/integration/generic/assets/asset.js diff --git a/test/integration/truffle/contracts/Migrations.sol b/test/integration/generic/contracts/Migrations.sol similarity index 100% rename from test/integration/truffle/contracts/Migrations.sol rename to test/integration/generic/contracts/Migrations.sol diff --git a/test/integration/truffle/migrations/1_initial.js b/test/integration/generic/migrations/1_initial.js similarity index 100% rename from test/integration/truffle/migrations/1_initial.js rename to test/integration/generic/migrations/1_initial.js diff --git a/test/integration/truffle/test/.marker b/test/integration/generic/test/.marker similarity index 100% rename from test/integration/truffle/test/.marker rename to test/integration/generic/test/.marker diff --git a/test/integration/projects/bad-solcoverjs/buidler.config.js b/test/integration/projects/bad-solcoverjs/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/bad-solcoverjs/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/import-paths/buidler.config.js b/test/integration/projects/import-paths/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/import-paths/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/libraries/buidler.config.js b/test/integration/projects/libraries/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/libraries/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/libraries/test/libraries.js b/test/integration/projects/libraries/test/libraries.js index e41ff19b..971d5d73 100644 --- a/test/integration/projects/libraries/test/libraries.js +++ b/test/integration/projects/libraries/test/libraries.js @@ -2,60 +2,60 @@ const UsesPure = artifacts.require('UsesPure'); contract('UsesPure', accounts => { it('calls imported, inherited pure/view functions within its own function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); await instance.usesThem(); }); it('calls a library method', async() => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.usesLibrary(); assert.equal(value.toNumber(), 1); }); it('calls an imported, inherited pure function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.isPure(4, 5); assert.equal(value.toNumber(), 20); }); it('calls an imported, inherited view function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.isView(); assert.equal(value.toNumber(), 5); }); it('overrides an imported, inherited abstract pure function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.bePure(4, 5); assert.equal(value.toNumber(), 9); }); it('overrides an imported, inherited abstract view function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.beView(); assert.equal(value.toNumber(), 99); }); it('calls a pure method implemented in an inherited class', async() => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.inheritedPure(4, 5); assert.equal(value.toNumber(), 9); }); it('calls a view method implemented in an inherited class', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.inheritedView(); assert.equal(value.toNumber(), 5); }); it('calls a view method whose modifiers span lines', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.multiline(5, 7) assert.equal(value.toNumber(), 99); }); it('calls a method who signature is defined by an interface', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); await instance.cry(); }); diff --git a/test/integration/projects/multiple-migrations/buidler.config.js b/test/integration/projects/multiple-migrations/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/multiple-migrations/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/no-sources/buidler.config.js b/test/integration/projects/no-sources/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/no-sources/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/skipping/buidler.config.js b/test/integration/projects/skipping/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/skipping/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/test-files/buidler.config.js b/test/integration/projects/test-files/buidler.config.js new file mode 100644 index 00000000..0e563633 --- /dev/null +++ b/test/integration/projects/test-files/buidler.config.js @@ -0,0 +1 @@ +modules.exports={}; diff --git a/test/integration/projects/test-files/test/globby_b.js b/test/integration/projects/test-files/test/globby_b.js index 14b4cc27..42d8cb84 100644 --- a/test/integration/projects/test-files/test/globby_b.js +++ b/test/integration/projects/test-files/test/globby_b.js @@ -3,7 +3,7 @@ const ContractB = artifacts.require("ContractB"); contract("contractB", function(accounts) { let instance; - before(async () => instance = await ContractB.deployed()) + before(async () => instance = await ContractB.new()) it('sends', async function(){ await instance.sendFn(); diff --git a/test/integration/projects/test-files/test/globby_c.js b/test/integration/projects/test-files/test/globby_c.js index 124f47aa..9b3d950d 100644 --- a/test/integration/projects/test-files/test/globby_c.js +++ b/test/integration/projects/test-files/test/globby_c.js @@ -3,7 +3,7 @@ const ContractC = artifacts.require("ContractC"); contract("contractc", function(accounts) { let instance; - before(async () => instance = await ContractC.deployed()) + before(async () => instance = await ContractC.new()) it('sends', async function(){ await instance.sendFn(); diff --git a/test/integration/projects/test-files/test/specific_a.js b/test/integration/projects/test-files/test/specific_a.js index 0559b95e..7cab74b8 100644 --- a/test/integration/projects/test-files/test/specific_a.js +++ b/test/integration/projects/test-files/test/specific_a.js @@ -3,7 +3,7 @@ const ContractA = artifacts.require("ContractA"); contract("contracta", function(accounts) { let instance; - before(async () => instance = await ContractA.deployed()) + before(async () => instance = await ContractA.new()) it('sends', async function(){ await instance.sendFn(); diff --git a/test/sources/js/block-gas-limit.js b/test/sources/js/block-gas-limit.js index 8256c0f6..43568333 100644 --- a/test/sources/js/block-gas-limit.js +++ b/test/sources/js/block-gas-limit.js @@ -1,7 +1,7 @@ -const Expensive = artifacts.require('./Expensive.sol'); +const Expensive = artifacts.require('Expensive'); contract('Expensive', () => { - it('should deploy', async () => { + it('should deploy', async function() { const instance = await Expensive.new() const hash = instance.transactionHash; const receipt = await web3.eth.getTransactionReceipt(hash); diff --git a/test/sources/js/empty.js b/test/sources/js/empty.js index def0cd05..33835e1d 100644 --- a/test/sources/js/empty.js +++ b/test/sources/js/empty.js @@ -1,8 +1,7 @@ -/* eslint-env node, mocha */ -/* global artifacts, contract */ +const Empty = artifacts.require('Empty'); -const Empty = artifacts.require('./Empty.sol'); - -contract('Empty', () => { - it('should deploy', () => Empty.deployed()); +contract('Empty', function() { + it('should deploy', async function (){ + await Empty.new() + }); }); diff --git a/test/sources/js/inheritance.js b/test/sources/js/inheritance.js index d2546246..04a6af7f 100644 --- a/test/sources/js/inheritance.js +++ b/test/sources/js/inheritance.js @@ -1,11 +1,11 @@ -const Owned = artifacts.require('./Owned.sol'); -const Proxy = artifacts.require('./Proxy.sol'); +const Owned = artifacts.require('Owned'); +const Proxy = artifacts.require('Proxy'); contract('Proxy', accounts => { - it('Should compile and run when one contract inherits from another', () => Owned.deployed() - .then(() => Proxy.deployed()) - .then(instance => instance.isOwner.call({ - from: accounts[0], - })) - .then(val => assert.equal(val, true))); + it('when one contract inherits from another', async function(){ + const owned = await Owned.new(); + const proxy = await Proxy.new(); + const val = await proxy.isOwner({from: accounts[0]}); + assert.equal(val, true); + }) }); diff --git a/test/sources/js/only-call.js b/test/sources/js/only-call.js index da72716b..931f9b7c 100644 --- a/test/sources/js/only-call.js +++ b/test/sources/js/only-call.js @@ -1,17 +1,9 @@ -/* eslint-env node, mocha */ -/* global artifacts, contract, assert */ - -const OnlyCall = artifacts.require('./OnlyCall.sol'); +const OnlyCall = artifacts.require('OnlyCall'); contract('OnlyCall', accounts => { - it('should return val + 2', done => { - OnlyCall.deployed().then(instance => { - instance.addTwo.call(5, { - from: accounts[0], - }).then(val => { - assert.equal(val, 7); - done(); - }); - }); - }); + it('should return val + 2', async function(){ + const onlycall = await OnlyCall.new(); + const val = await onlycall.addTwo(5); + assert.equal(val.toNumber(), 7); + }) }); diff --git a/test/sources/js/pureview.js b/test/sources/js/pureview.js index d2aee69a..1cb78b5b 100644 --- a/test/sources/js/pureview.js +++ b/test/sources/js/pureview.js @@ -1,17 +1,17 @@ /* eslint-env node, mocha */ /* global artifacts, contract, assert */ -const PureView = artifacts.require('./PureView.sol'); +const PureView = artifacts.require('PureView'); contract('PureView', accounts => { it('calls a pure function', async function(){ - const instance = await PureView.deployed(); + const instance = await PureView.new(); const value = await instance.isPure(4,5); }); it('calls a view function', async function(){ - const instance = await PureView.deployed(); + const instance = await PureView.new(); const value = await instance.isView(); }) }); \ No newline at end of file diff --git a/test/sources/js/simple.js b/test/sources/js/simple.js index 12281931..6edc385e 100644 --- a/test/sources/js/simple.js +++ b/test/sources/js/simple.js @@ -2,7 +2,7 @@ const Simple = artifacts.require('Simple'); contract('Simple', () => { it('should set x to 5', async function(){ - const simple = await Simple.deployed() + const simple = await Simple.new() await simple.test(5); const val = await simple.getX.call(); assert.equal(val.toNumber(), 5); diff --git a/test/sources/js/sol-parse-fail.js b/test/sources/js/sol-parse-fail.js deleted file mode 100644 index ff17dbaa..00000000 --- a/test/sources/js/sol-parse-fail.js +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-env node, mocha */ -/* global artifacts, contract, assert */ - -const Simple = artifacts.require('./Simple.sol'); - -// This test is constructed correctly but the SimpleError.sol has a syntax error -contract('SimpleError', () => { - it('should set x to 5', () => { - let simple; - return Simple.deployed().then(instance => { - simple = instance; - return simple.test(5); - }) - .then(() => simple.getX.call()) - .then(val => assert.equal(val, 5)); - }); -}); diff --git a/test/sources/js/testrpc-options.js b/test/sources/js/testrpc-options.js index b2112303..452df67e 100644 --- a/test/sources/js/testrpc-options.js +++ b/test/sources/js/testrpc-options.js @@ -1,4 +1,4 @@ -const Simple = artifacts.require('./Simple.sol'); +const Simple = artifacts.require('Simple'); contract('Simple', accounts => { @@ -7,15 +7,4 @@ contract('Simple', accounts => { balance = web3.utils.fromWei(balance); assert(parseInt(balance) >= 776) }); - - // Generate some coverage so the script doesn't exit(1) because there are no events - it('should set x to 5', () => { - let simple; - return Simple.deployed().then(instance => { - simple = instance; - return simple.test(5); - }) - .then(() => simple.getX.call()) - .then(val => assert.equal(val.toNumber(), 5)); - }); }); diff --git a/test/sources/js/totallyPure.js b/test/sources/js/totallyPure.js index 7688a3f9..6b257107 100644 --- a/test/sources/js/totallyPure.js +++ b/test/sources/js/totallyPure.js @@ -2,55 +2,54 @@ const UsesPure = artifacts.require('UsesPure'); contract('UsesPure', accounts => { it('calls imported, inherited pure/view functions within its own function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); await instance.usesThem(); }); it('calls an imported, inherited pure function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.isPure(4, 5); assert.equal(value.toNumber(), 20); }); it('calls an imported, inherited view function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.isView(); assert.equal(value.toNumber(), 5); }); it('overrides an imported, inherited abstract pure function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.bePure(4, 5); assert.equal(value.toNumber(), 9); }); it('overrides an imported, inherited abstract view function', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.beView(); assert.equal(value.toNumber(), 99); }); it('calls a pure method implemented in an inherited class', async() => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.inheritedPure(4, 5); assert.equal(value.toNumber(), 9); }); it('calls a view method implemented in an inherited class', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.inheritedView(); assert.equal(value.toNumber(), 5); }); it('calls a view method whose modifiers span lines', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); const value = await instance.multiline(5, 7) assert.equal(value.toNumber(), 99); }); it('calls a method who signature is defined by an interface', async () => { - const instance = await UsesPure.deployed(); + const instance = await UsesPure.new(); await instance.cry(); }); - }); \ No newline at end of file diff --git a/test/sources/js/truffle-crash.js b/test/sources/js/truffle-crash.js index 33633aa9..92b3adc6 100644 --- a/test/sources/js/truffle-crash.js +++ b/test/sources/js/truffle-crash.js @@ -1,11 +1,11 @@ /* eslint-env node, mocha */ /* global artifacts, contract */ -var Simple = artifacts.require('./Simple.sol'); +var Simple = artifacts.require('Simple'); // This test should break truffle because it has a syntax error. contract('Simple', () => { it('should crash', function(){ - return Simple.deployed().then.why. + return Simple.new().then.why. }) }) \ No newline at end of file diff --git a/test/sources/js/truffle-test-fail.js b/test/sources/js/truffle-test-fail.js index e9457d01..cb08d550 100644 --- a/test/sources/js/truffle-test-fail.js +++ b/test/sources/js/truffle-test-fail.js @@ -1,16 +1,13 @@ /* eslint-env node, mocha */ /* global artifacts, contract, assert */ -const Simple = artifacts.require('./Simple.sol'); +const Simple = artifacts.require('Simple'); contract('Simple', () => { - it('should set x to 5', () => { - let simple; - return Simple.deployed().then(instance => { - simple = instance; - return simple.test(5); - }) - .then(() => simple.getX.call()) - .then(val => assert.equal(val.toNumber(), 4)); // <-- Wrong result: test fails + it('should set x to 5', async function() { + let simple = await Simple.new(); + await simple.test(5); + const val = await simple.getX(); + assert.equal(val.toNumber(), 4) // <-- Wrong result: test fails }); }); diff --git a/test/sources/js/wallet.js b/test/sources/js/wallet.js index 827a4001..144f3b71 100644 --- a/test/sources/js/wallet.js +++ b/test/sources/js/wallet.js @@ -1,4 +1,4 @@ -const Wallet = artifacts.require('./Wallet.sol'); +const Wallet = artifacts.require('Wallet'); contract('Wallet', accounts => { it('should should allow transfers and sends', async () => { diff --git a/test/sources/solidity/contracts/app/Proxy.sol b/test/sources/solidity/contracts/app/Proxy.sol index f6557ed3..b3109a5c 100644 --- a/test/sources/solidity/contracts/app/Proxy.sol +++ b/test/sources/solidity/contracts/app/Proxy.sol @@ -3,7 +3,7 @@ pragma solidity ^0.5.0; import "./Owned.sol"; contract Proxy is Owned { - function isOwner() public returns (bool) { + function isOwner() public view returns (bool) { if (msg.sender == owner) { return true; } else { diff --git a/test/units/truffle/errors.js b/test/units/truffle/errors.js index b39a00fa..dbbf6cc3 100644 --- a/test/units/truffle/errors.js +++ b/test/units/truffle/errors.js @@ -6,7 +6,7 @@ const shell = require('shelljs'); const ganache = require('ganache-core-sc'); const verify = require('../../util/verifiers') -const mock = require('../../util/integration.truffle'); +const mock = require('../../util/integration'); const plugin = require('../../../dist/truffle.plugin'); // ======= diff --git a/test/units/truffle/flags.js b/test/units/truffle/flags.js index 18d3c79e..92757d5c 100644 --- a/test/units/truffle/flags.js +++ b/test/units/truffle/flags.js @@ -4,7 +4,7 @@ const path = require('path') const shell = require('shelljs'); const verify = require('../../util/verifiers') -const mock = require('../../util/integration.truffle'); +const mock = require('../../util/integration'); const plugin = require('../../../dist/truffle.plugin'); // ======================= diff --git a/test/units/truffle/standard.js b/test/units/truffle/standard.js index 4a19e238..4b767bc2 100644 --- a/test/units/truffle/standard.js +++ b/test/units/truffle/standard.js @@ -4,7 +4,7 @@ const path = require('path') const shell = require('shelljs'); const verify = require('../../util/verifiers') -const mock = require('../../util/integration.truffle'); +const mock = require('../../util/integration'); const plugin = require('../../../dist/truffle.plugin'); // ======================= @@ -46,7 +46,9 @@ describe('Truffle Plugin: standard use cases', function() { ); }); - it('with many unbracketed statements (time check)', async function() { + // Instrumentation speed is fine - but this takes solc almost a minute to compile + // so annoying. Unskip whenever modifying the instrumentation files though..... + it.skip('with many unbracketed statements (time check)', async function() { truffleConfig.compilers.solc.version = "0.4.24"; mock.install('Oraclize', 'oraclize.js', solcoverConfig, truffleConfig, true); diff --git a/test/util/integration.truffle.js b/test/util/integration.js similarity index 71% rename from test/util/integration.truffle.js rename to test/util/integration.js index 98b823b9..049069e2 100644 --- a/test/util/integration.truffle.js +++ b/test/util/integration.js @@ -11,11 +11,12 @@ const decache = require('decache'); const temp = './sc_temp'; const truffleConfigName = 'truffle-config.js'; +const buidlerConfigName = 'buidler.config.js'; const configPath = `${temp}/.solcover.js`; const testPath = './test/sources/js/'; const sourcesPath = './test/sources/solidity/contracts/app/'; const migrationPath = `${temp}/migrations/2_deploy.js`; -const templatePath = './test/integration/truffle/*'; +const templatePath = './test/integration/generic/*'; const projectPath = './test/integration/projects/' @@ -25,6 +26,7 @@ const projectPath = './test/integration/projects/' function decacheConfigs(){ decache(`${process.cwd()}/${temp}/.solcover.js`); decache(`${process.cwd()}/${temp}/${truffleConfigName}`); + decache(`${process.cwd()}/${temp}/${buidlerConfigName}`); } function clean() { @@ -48,7 +50,7 @@ function getOutput(truffleConfig){ } // ========================== -// Configuration +// Truffle Configuration // ========================== function getDefaultTruffleConfig(){ const logger = process.env.SILENT ? { log: () => {} } : console; @@ -82,14 +84,62 @@ function getDefaultTruffleConfig(){ return (new TruffleConfig()).with(vals); } +function getTruffleConfigJS(config){ + if (config) { + return `module.exports = ${JSON.stringify(config, null, ' ')}`; + } else { + return `module.exports = ${JSON.stringify(getDefaultTruffleConfig(), null, ' ')}`; + } +} + +// ========================== +// Buidler Configuration +// ========================== +function getDefaultBuidlerConfig() { + const logger = process.env.SILENT ? { log: () => {} } : console; + const reporter = process.env.SILENT ? 'dot' : 'spec'; + + const mockwd = path.join(process.cwd(), temp); + const vals = { + root: mockwd, + artifacts: path.join(mockwd, 'artifacts'), + cache: path.join(mockwd, 'cache'), + sources: path.join(mockwd, 'contracts'), + tests: path.join(mockwd, 'test'), + logger: logger, + mocha: { + reporter: reporter + }, + networks: { + development: { + url: "http://127.0.0.1:8545", + } + }, + solc: { + version: "0.5.3", + optimizer: {} + } + + } + + return vals; +} + +function getBuidlerConfigJS(config){ + if (config) { + return `module.exports = ${JSON.stringify(config, null, ' ')}` + } else { + return `module.exports = ${JSON.stringify(getDefaultBuidlerConfig(), null, ' ')}` + } +} + +// ========================== +// .solcover.js Configuration +// ========================== function getSolcoverJS(config){ return `module.exports = ${JSON.stringify(config, null, ' ')}` } -function getTruffleConfigJS(config){ - if (config) return `module.exports = ${JSON.stringify(config, null, ' ')}` - return `module.exports = ${JSON.stringify(getDefaultTruffleConfig(), null, ' ')}` -} // ========================== // Migration Generators @@ -117,7 +167,7 @@ function deployDouble(contractNames){ // Project Installers // ========================== /** - * Installs mock truffle project at ./temp with a single contract + * Installs mock truffle/buidler project at ./temp with a single contract * and test specified by the params. * @param {String} contract located in /test/sources/cli/ * @param {[type]} test located in /test/cli/ @@ -125,15 +175,16 @@ function deployDouble(contractNames){ function install( contract, test, - config, - _truffleConfig, + solcoverConfig, + devPlatformConfig, noMigrations ) { let configjs; - if(config) configjs = getSolcoverJS(config); + if(solcoverConfig) solcoverJS = getSolcoverJS(solcoverConfig); - const trufflejs = getTruffleConfigJS(_truffleConfig); + const trufflejs = getTruffleConfigJS(devPlatformConfig); + const buidlerjs = getBuidlerConfigJS(devPlatformConfig); const migration = deploySingle(contract); // Scaffold @@ -151,15 +202,14 @@ function install( // Configs fs.writeFileSync(`${temp}/${truffleConfigName}`, trufflejs); - if(config) fs.writeFileSync(configPath, configjs); + fs.writeFileSync(`${temp}/${buidlerConfigName}`, buidlerjs); + if(solcoverConfig) fs.writeFileSync(configPath, solcoverJS); decacheConfigs(); - }; /** - * Installs mock truffle project with two contracts (for inheritance, libraries, etc) - * + * Installs mock truffle/buidler project with two contracts (for inheritance, libraries, etc) */ function installDouble(contracts, test, config) { const configjs = getSolcoverJS(config); @@ -182,11 +232,15 @@ function installDouble(contracts, test, config) { // Configs fs.writeFileSync(`${temp}/${truffleConfigName}`, getTruffleConfigJS()); + fs.writeFileSync(`${temp}/${buidlerConfigName}`, getBuidlerConfigJS()); fs.writeFileSync(configPath, configjs); decacheConfigs(); }; +/** + * Installs full truffle/buidler project + */ function installFullProject(name, config) { shell.mkdir(temp); shell.cp('-Rf', `${projectPath}${name}/{.,}*`, temp); @@ -219,6 +273,7 @@ module.exports = { testLogger: testLogger, loggerOutput: loggerOutput, getDefaultTruffleConfig: getDefaultTruffleConfig, + getDefaultBuidlerConfig: getDefaultBuidlerConfig, install: install, installDouble: installDouble, installFullProject: installFullProject, From 7a3a8ae54d7f23353a69dac466212391b47b0b3b Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sun, 13 Oct 2019 16:27:40 -0700 Subject: [PATCH 2/2] Cleanup --- dist/plugin-assets/truffle.utils.js | 15 +++++++++++++++ dist/truffle.plugin.js | 16 +--------------- test/util/integration.js | 1 - 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/dist/plugin-assets/truffle.utils.js b/dist/plugin-assets/truffle.utils.js index 7bee861b..3f430bdd 100644 --- a/dist/plugin-assets/truffle.utils.js +++ b/dist/plugin-assets/truffle.utils.js @@ -183,9 +183,24 @@ function loadLibrary(config){ } +/** + * Maps truffle specific keys for the paths to things like sources to the generic + * keys required by the plugin utils + * @return {Object} truffle-config.js + */ +function normalizeConfig(config){ + config.workingDir = config.working_directory; + config.contractsDir = config.contracts_directory; + config.testDir = config.test_directory; + config.artifactsDir = config.build_directory; + + return config; +} + module.exports = { getTestFilePaths: getTestFilePaths, setNetwork: setNetwork, setNetworkFrom: setNetworkFrom, loadLibrary: loadLibrary, + normalizeConfig: normalizeConfig, } diff --git a/dist/truffle.plugin.js b/dist/truffle.plugin.js index 77bb9461..62c4ad33 100644 --- a/dist/truffle.plugin.js +++ b/dist/truffle.plugin.js @@ -24,7 +24,7 @@ async function plugin(config){ try { death(utils.finish.bind(null, config, api)); // Catch interrupt signals - config = normalizeConfig(config); + config = truffleUtils.normalizeConfig(config); ui = new PluginUI(config.logger.log); @@ -124,18 +124,4 @@ async function plugin(config){ if (failures > 0) throw new Error(ui.generate('tests-fail', [failures])); } -/** - * Maps truffle specific keys for the paths to things like sources to the generic - * keys required by the plugin utils - * @return {Object} truffle-config.js - */ -function normalizeConfig(config){ - config.workingDir = config.working_directory; - config.contractsDir = config.contracts_directory; - config.testDir = config.test_directory; - config.artifactsDir = config.build_directory; - - return config; -} - module.exports = plugin; diff --git a/test/util/integration.js b/test/util/integration.js index 049069e2..8a50dcc6 100644 --- a/test/util/integration.js +++ b/test/util/integration.js @@ -119,7 +119,6 @@ function getDefaultBuidlerConfig() { version: "0.5.3", optimizer: {} } - } return vals;