diff --git a/remix-tests/src/compiler.js b/remix-tests/src/compiler.js index 392dcc81a7..b45aef5184 100644 --- a/remix-tests/src/compiler.js +++ b/remix-tests/src/compiler.js @@ -37,55 +37,49 @@ function compileFileOrFiles (filename, isDirectory, opts, cb) { // TODO: for now assumes filepath dir contains all tests, later all this // should be replaced with remix's & browser solidity compiler code - // https://github.com/mikeal/node-utils/blob/master/file/lib/main.js - fs.walkSync = function (start, callback) { - fs.readdirSync(start).forEach(name => { - if (name === 'node_modules') { - return // hack + // This logic is wrong + // We should only look into current file if a full file name with path is given + // We should only walk through directory if a directory name is passed + try { + filepath = (isDirectory ? filename : path.dirname(filename)) + // walkSync only if it is a directory + fs.walkSync(filepath, foundpath => { + // only process .sol files + if (foundpath.split('.').pop() === 'sol') { + let c = fs.readFileSync(foundpath).toString() + const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm + if (foundpath.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { + c = c.replace(/(pragma solidity \^?\d+\.\d+\.\d+;)/, '$1\nimport \'remix_tests.sol\';') + } + sources[foundpath] = { content: c } } - var abspath = path.join(start, name) - if (fs.statSync(abspath).isDirectory()) { - fs.walkSync(abspath, callback) - } else { - callback(abspath) + }) + } catch (e) { + throw e + } finally { + async.waterfall([ + function loadCompiler (next) { + compiler = new RemixCompiler() + compiler.onInternalCompilerLoaded() + // compiler.event.register('compilerLoaded', this, function (version) { + next() + // }); + }, + function doCompilation (next) { + compiler.event.register('compilationFinished', this, function (success, data, source) { + next(null, data) + }) + compiler.compile(sources, false) + } + ], function (err, result) { + let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') + if (errors.length > 0) { + if (!isBrowser) require('signale').fatal(errors) + return cb(new Error('errors compiling')) } + cb(err, result.contracts) }) } - - fs.walkSync(filepath, foundpath => { - // only process .sol files - if (foundpath.split('.').pop() === 'sol') { - let c = fs.readFileSync(foundpath).toString() - const s = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm - if (foundpath.indexOf('_test.sol') > 0 && c.regexIndexOf(s) < 0) { - c = c.replace(/(pragma solidity \^?\d+\.\d+\.\d+;)/, '$1\nimport \'remix_tests.sol\';') - } - sources[foundpath] = { content: c } - } - }) - - async.waterfall([ - function loadCompiler (next) { - compiler = new RemixCompiler() - compiler.onInternalCompilerLoaded() - // compiler.event.register('compilerLoaded', this, function (version) { - next() - // }); - }, - function doCompilation (next) { - compiler.event.register('compilationFinished', this, function (success, data, source) { - next(null, data) - }) - compiler.compile(sources, false) - } - ], function (err, result) { - let errors = (result.errors || []).filter((e) => e.type === 'Error' || e.severity === 'error') - if (errors.length > 0) { - if (!isBrowser) require('signale').fatal(errors) - return cb(new Error('errors compiling')) - } - cb(err, result.contracts) - }) } function compileContractSources (sources, importFileCb, opts, cb) { diff --git a/remix-tests/src/index.js b/remix-tests/src/index.js index 7e430bcacf..b2b64a0430 100644 --- a/remix-tests/src/index.js +++ b/remix-tests/src/index.js @@ -1,247 +1,6 @@ -const async = require('async') -const path = require('path') -const fs = require('fs') -require('colors') - -let Compiler = require('./compiler.js') -let Deployer = require('./deployer.js') -let TestRunner = require('./testRunner.js') - -const Web3 = require('web3') -const Provider = require('remix-simulator').Provider - -var createWeb3Provider = function () { - let web3 = new Web3() - web3.setProvider(new Provider()) - return web3 -} - -var runTestSources = function (contractSources, testCallback, resultCallback, finalCallback, importFileCb, opts) { - opts = opts || {} - let web3 = opts.web3 || createWeb3Provider() - let accounts = opts.accounts || null - async.waterfall([ - function getAccountList (next) { - if (accounts) return next() - web3.eth.getAccounts((_err, _accounts) => { - accounts = _accounts - next() - }) - }, - function compile (next) { - Compiler.compileContractSources(contractSources, importFileCb, { accounts }, next) - }, - function deployAllContracts (compilationResult, next) { - Deployer.deployAll(compilationResult, web3, function (err, contracts) { - if (err) { - next(err) - } - - next(null, compilationResult, contracts) - }) - }, - function determineTestContractsToRun (compilationResult, contracts, next) { - let contractsToTest = [] - let contractsToTestDetails = [] - - for (let filename in compilationResult) { - if (filename.indexOf('_test.sol') < 0) { - continue - } - Object.keys(compilationResult[filename]).forEach(contractName => { - contractsToTestDetails.push(compilationResult[filename][contractName]) - contractsToTest.push(contractName) - }) - } - - next(null, contractsToTest, contractsToTestDetails, contracts) - }, - function runTests (contractsToTest, contractsToTestDetails, contracts, next) { - let totalPassing = 0 - let totalFailing = 0 - let totalTime = 0 - let errors = [] - - var _testCallback = function (result) { - if (result.type === 'testFailure') { - errors.push(result) - } - testCallback(result) - } - - var _resultsCallback = function (_err, result, cb) { - resultCallback(_err, result, () => {}) - totalPassing += result.passingNum - totalFailing += result.failureNum - totalTime += result.timePassed - cb() - } - - async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => { - TestRunner.runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, _testCallback, (err, result) => { - if (err) { - return cb(err) - } - _resultsCallback(null, result, cb) - }) - }, function (err, _results) { - if (err) { - return next(err) - } - - let finalResults = {} - - finalResults.totalPassing = totalPassing || 0 - finalResults.totalFailing = totalFailing || 0 - finalResults.totalTime = totalTime || 0 - finalResults.errors = [] - - errors.forEach((error, _index) => { - finalResults.errors.push({context: error.context, value: error.value, message: error.errMsg}) - }) - - next(null, finalResults) - }) - } - ], finalCallback) -} - -var runTestFiles = function (filepath, isDirectory, web3, opts) { - opts = opts || {} - const { Signale } = require('signale') - // signale configuration - const options = { - types: { - result: { - badge: '\t✓', - label: '', - color: 'greenBright' - }, - name: { - badge: '\n\t◼', - label: '', - color: 'white' - }, - error: { - badge: '\t✘', - label: '', - color: 'redBright' - } - } - } - const signale = new Signale(options) - let accounts = opts.accounts || null - async.waterfall([ - function getAccountList (next) { - if (accounts) return next(null) - web3.eth.getAccounts((_err, _accounts) => { - accounts = _accounts - next(null) - }) - }, - function compile (next) { - Compiler.compileFileOrFiles(filepath, isDirectory, { accounts }, next) - }, - function deployAllContracts (compilationResult, next) { - Deployer.deployAll(compilationResult, web3, function (err, contracts) { - if (err) { - next(err) - } - next(null, compilationResult, contracts) - }) - }, - function determineTestContractsToRun (compilationResult, contracts, next) { - let contractsToTest = [] - let contractsToTestDetails = [] - const gatherContractsFrom = (filename) => { - if (filename.indexOf('_test.sol') < 0) { - return - } - Object.keys(compilationResult[path.basename(filename)]).forEach(contractName => { - contractsToTest.push(contractName) - contractsToTestDetails.push(compilationResult[path.basename(filename)][contractName]) - }) - } - - if (isDirectory) { - fs.walkSync = function (start, callback) { - fs.readdirSync(start).forEach(name => { - if (name === 'node_modules') { - return // hack - } - var abspath = path.join(start, name) - if (fs.statSync(abspath).isDirectory()) { - fs.walkSync(abspath, callback) - } else { - callback(abspath) - } - }) - } - fs.walkSync(filepath, foundpath => { - gatherContractsFrom(foundpath) - }) - } else { - gatherContractsFrom(filepath) - } - next(null, contractsToTest, contractsToTestDetails, contracts) - }, - function runTests (contractsToTest, contractsToTestDetails, contracts, next) { - let totalPassing = 0 - let totalFailing = 0 - let totalTime = 0 - let errors = [] - - var testCallback = function (result) { - if (result.type === 'contract') { - signale.name(result.value.white) - } else if (result.type === 'testPass') { - signale.result(result.value) - } else if (result.type === 'testFailure') { - signale.result(result.value.red) - errors.push(result) - } - } - var resultsCallback = function (_err, result, cb) { - totalPassing += result.passingNum - totalFailing += result.failureNum - totalTime += result.timePassed - cb() - } - - async.eachOfLimit(contractsToTest, 1, (contractName, index, cb) => { - TestRunner.runTest(contractName, contracts[contractName], contractsToTestDetails[index], { accounts }, testCallback, (err, result) => { - if (err) { - return cb(err) - } - resultsCallback(null, result, cb) - }) - }, function (err, _results) { - if (err) { - return next(err) - } - - console.log('\n') - if (totalPassing > 0) { - console.log((' ' + totalPassing + ' passing ').green + ('(' + totalTime + 's)').grey) - } - if (totalFailing > 0) { - console.log((' ' + totalFailing + ' failing').red) - } - console.log('') - - errors.forEach((error, index) => { - console.log(' ' + (index + 1) + ') ' + error.context + ' ' + error.value) - console.log('') - console.log(('\t error: ' + error.errMsg).red) - }) - console.log('') - - next() - }) - } - ], function () { - }) -} +const runTestFiles = require('./runTestFiles.js') +const runTestSources = require('./runTestSources.js') +const TestRunner = require('./testRunner.js') module.exports = { runTestFiles: runTestFiles,