commit
88a8988a71
File diff suppressed because one or more lines are too long
@ -0,0 +1,108 @@ |
||||
var CmdLine = require('./src/cmdline/index.js') |
||||
// var compilation = require('./compilation.json')
|
||||
|
||||
var solc = require('solc') |
||||
var fs = require('fs') |
||||
|
||||
var filename = 'test/sol/simple_storage.sol' |
||||
var shortFilename = 'simple_storage.sol' |
||||
|
||||
var inputJson = { |
||||
language: 'Solidity', |
||||
sources: { |
||||
}, |
||||
settings: { |
||||
optimizer: { |
||||
enabled: true, |
||||
runs: 200 |
||||
}, |
||||
outputSelection: { |
||||
'*': { |
||||
'': [ 'legacyAST' ], |
||||
'*': [ 'abi', 'metadata', 'devdoc', 'userdoc', 'evm.legacyAssembly', 'evm.bytecode', 'evm.deployedBytecode', 'evm.methodIdentifiers', 'evm.gasEstimates' ] |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
inputJson.sources[shortFilename] = {content: fs.readFileSync(filename).toString()} |
||||
|
||||
console.dir(inputJson) |
||||
|
||||
console.log('compiling...') |
||||
|
||||
let compilationData = JSON.parse(solc.compileStandardWrapper(JSON.stringify(inputJson))) |
||||
console.dir(Object.keys(compilationData)) |
||||
var compilation = {} |
||||
compilation.data = compilationData |
||||
compilation.source = { sources: inputJson.sources } |
||||
console.dir(compilation) |
||||
console.dir(compilation.data.errors) |
||||
|
||||
var cmdLine = new CmdLine() |
||||
cmdLine.connect('http', 'http://localhost:8545') |
||||
cmdLine.loadCompilationResult(compilation) |
||||
cmdLine.initDebugger() |
||||
|
||||
// var deployContract = function (cb) {
|
||||
// let _web3 = cmdLine.debugger.debugger.web3
|
||||
//
|
||||
// let blockNumber = null
|
||||
// let txNumber = null
|
||||
// let tx = null
|
||||
//
|
||||
// let code = compilation.data.contracts[shortFilename].SimpleStorage.evm.bytecode.object
|
||||
// console.dir('deploying...')
|
||||
// console.dir(code)
|
||||
// _web3.eth.sendTransaction({data: '0x' + code, from: _web3.eth.accounts[0], gas: 800000}, cb)
|
||||
// }
|
||||
|
||||
// let _web3 = cmdLine.debugger.debugger.web3
|
||||
var tx = '0xf510c4f0b1d9ee262d7b9e9e87b4262f275fe029c2c733feef7dfa1e2b1e32aa' |
||||
|
||||
// deployContract((err, tx) => {
|
||||
cmdLine.startDebug(tx, shortFilename) |
||||
|
||||
cmdLine.events.on('source', () => { |
||||
cmdLine.getSource().forEach(console.dir) |
||||
}) |
||||
// })
|
||||
// })
|
||||
|
||||
const repl = require('repl') |
||||
|
||||
repl.start({ |
||||
prompt: '> ', |
||||
eval: (cmd, context, filename, cb) => { |
||||
let command = cmd.trim() |
||||
if (command === 'next' || command === 'n') { |
||||
cmdLine.stepOverForward(true) |
||||
} |
||||
if (command === 'previous' || command === 'p' || command === 'prev') { |
||||
cmdLine.stepOverBack(true) |
||||
} |
||||
if (command === 'step' || command === 's') { |
||||
cmdLine.stepIntoForward(true) |
||||
} |
||||
if (command === 'stepback' || command === 'sb') { |
||||
cmdLine.stepIntoBack(true) |
||||
} |
||||
if (command === 'exit' || command === 'quit') { |
||||
process.exit(0) |
||||
} |
||||
if (command === 'var local' || command === 'v l' || command === 'vl') { |
||||
cmdLine.displayLocals() |
||||
} |
||||
if (command === 'var global' || command === 'v g' || command === 'vg') { |
||||
cmdLine.displayGlobals() |
||||
} |
||||
if (command.split(' ')[0] === 'jump') { |
||||
let stepIndex = parseInt(command.split(' ')[1], 10) |
||||
cmdLine.jumpTo(stepIndex) |
||||
} |
||||
cb(null, '') |
||||
} |
||||
}) |
||||
|
||||
module.exports = cmdLine |
||||
|
@ -0,0 +1,60 @@ |
||||
var remixLib = require('remix-lib') |
||||
|
||||
var EventManager = remixLib.EventManager |
||||
var executionContext = remixLib.execution.executionContext |
||||
var Web3Providers = remixLib.vm.Web3Providers |
||||
var DummyProvider = remixLib.vm.DummyProvider |
||||
var init = remixLib.init |
||||
|
||||
class ContextManager { |
||||
constructor () { |
||||
this.executionContext = executionContext |
||||
this.web3 = this.executionContext.web3() |
||||
this.event = new EventManager() |
||||
} |
||||
|
||||
initProviders () { |
||||
this.web3Providers = new Web3Providers() |
||||
this.addProvider('DUMMYWEB3', new DummyProvider()) |
||||
this.switchProvider('DUMMYWEB3') |
||||
|
||||
this.addProvider('vm', this.executionContext.vm()) |
||||
this.addProvider('injected', this.executionContext.internalWeb3()) |
||||
this.addProvider('web3', this.executionContext.internalWeb3()) |
||||
this.switchProvider(this.executionContext.getProvider()) |
||||
} |
||||
|
||||
getWeb3 () { |
||||
return this.web3 |
||||
} |
||||
|
||||
addProvider (type, obj) { |
||||
this.web3Providers.addProvider(type, obj) |
||||
this.event.trigger('providerAdded', [type]) |
||||
} |
||||
|
||||
switchProvider (type, cb) { |
||||
var self = this |
||||
this.web3Providers.get(type, function (error, obj) { |
||||
if (error) { |
||||
// console.log('provider ' + type + ' not defined')
|
||||
} else { |
||||
self.web3 = obj |
||||
self.executionContext.detectNetwork((error, network) => { |
||||
if (error || !network) { |
||||
self.web3 = obj |
||||
} else { |
||||
var webDebugNode = init.web3DebugNode(network.name) |
||||
self.web3 = (!webDebugNode ? obj : webDebugNode) |
||||
} |
||||
self.event.trigger('providerChanged', [type, self.web3]) |
||||
if (cb) return cb() |
||||
}) |
||||
self.event.trigger('providerChanged', [type, self.web3]) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
} |
||||
|
||||
module.exports = ContextManager |
@ -0,0 +1,215 @@ |
||||
var Web3 = require('web3') |
||||
var Debugger = require('../debugger/debugger.js') |
||||
var ContextManager = require('./contextManager.js') |
||||
var EventManager = require('events') |
||||
|
||||
class CmdLine { |
||||
|
||||
constructor () { |
||||
this.events = new EventManager() |
||||
this.lineColumnPos = null |
||||
this.rawLocation = null |
||||
} |
||||
|
||||
connect (providerType, url) { |
||||
if (providerType !== 'http') throw new Error('unsupported provider type') |
||||
this.web3 = new Web3(new Web3.providers.HttpProvider(url)) |
||||
} |
||||
|
||||
loadCompilationData (inputJson, outputJson) { |
||||
let data = {} |
||||
data.data = outputJson |
||||
data.source = { sources: inputJson.sources } |
||||
this.loadCompilationResult(data) |
||||
} |
||||
|
||||
loadCompilationResult (compilationResult) { |
||||
this.compilation = {} |
||||
this.compilation.lastCompilationResult = compilationResult |
||||
} |
||||
|
||||
initDebugger (cb) { |
||||
const self = this |
||||
this.contextManager = new ContextManager() |
||||
|
||||
this.debugger = new Debugger({ |
||||
web3: this.contextManager.getWeb3(), |
||||
compiler: this.compilation |
||||
}) |
||||
|
||||
this.contextManager.event.register('providerChanged', () => { |
||||
self.debugger.updateWeb3(self.contextManager.getWeb3()) |
||||
}) |
||||
|
||||
this.contextManager.initProviders() |
||||
|
||||
this.contextManager.addProvider('debugger_web3', this.web3) |
||||
this.contextManager.switchProvider('debugger_web3', cb) |
||||
} |
||||
|
||||
getSource () { |
||||
const self = this |
||||
|
||||
let lineColumnPos = this.lineColumnPos |
||||
|
||||
if (!lineColumnPos || !lineColumnPos.start) return [] |
||||
|
||||
let content = self.compilation.lastCompilationResult.source.sources[this.filename].content.split('\n') |
||||
|
||||
let source = [] |
||||
|
||||
let line |
||||
line = content[lineColumnPos.start.line - 2] |
||||
if (line !== undefined) { |
||||
source.push(' ' + (lineColumnPos.start.line - 1) + ': ' + line) |
||||
} |
||||
line = content[lineColumnPos.start.line - 1] |
||||
if (line !== undefined) { |
||||
source.push(' ' + lineColumnPos.start.line + ': ' + line) |
||||
} |
||||
|
||||
let currentLineNumber = lineColumnPos.start.line |
||||
let currentLine = content[currentLineNumber] |
||||
source.push('=> ' + (currentLineNumber + 1) + ': ' + currentLine) |
||||
|
||||
let startLine = lineColumnPos.start.line |
||||
for (var i = 1; i < 4; i++) { |
||||
let line = content[startLine + i] |
||||
source.push(' ' + (startLine + i + 1) + ': ' + line) |
||||
} |
||||
|
||||
return source |
||||
} |
||||
|
||||
getCurrentLine () { |
||||
let lineColumnPos = this.lineColumnPos |
||||
if (!lineColumnPos) return '' |
||||
let currentLineNumber = lineColumnPos.start.line |
||||
let content = this.compilation.lastCompilationResult.source.sources[this.filename].content.split('\n') |
||||
return content[currentLineNumber] |
||||
} |
||||
|
||||
startDebug (txNumber, filename, cb) { |
||||
const self = this |
||||
this.filename = filename |
||||
this.txHash = txNumber |
||||
this.debugger.debug(null, txNumber, null, () => { |
||||
self.debugger.event.register('newSourceLocation', function (lineColumnPos, rawLocation) { |
||||
self.lineColumnPos = lineColumnPos |
||||
self.rawLocation = rawLocation |
||||
self.events.emit('source', [lineColumnPos, rawLocation]) |
||||
}) |
||||
|
||||
self.debugger.vmDebuggerLogic.event.register('solidityState', (data) => { |
||||
self.solidityState = data |
||||
self.events.emit('globals', data) |
||||
}) |
||||
|
||||
// TODO: this doesnt work too well, it should request the data instead...
|
||||
self.debugger.vmDebuggerLogic.event.register('solidityLocals', (data) => { |
||||
if (JSON.stringify(data) === '{}') return |
||||
self.solidityLocals = data |
||||
self.events.emit('locals', data) |
||||
}) |
||||
|
||||
if (cb) { |
||||
// TODO: this should be an onReady event
|
||||
setTimeout(cb, 1000) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
getVars () { |
||||
return { |
||||
locals: this.solidityLocals, |
||||
contract: this.solidityState |
||||
} |
||||
} |
||||
|
||||
triggerSourceUpdate () { |
||||
this.events.emit('source', [this.lineColumnPos, this.rawLocation]) |
||||
} |
||||
|
||||
stepJumpNextBreakpoint () { |
||||
this.debugger.step_manager.jumpNextBreakpoint() |
||||
} |
||||
|
||||
stepJumpPreviousBreakpoint () { |
||||
this.debugger.step_manager.jumpPreviousBreakpoint() |
||||
} |
||||
|
||||
stepOverForward (solidityMode) { |
||||
this.debugger.step_manager.stepOverForward(solidityMode) |
||||
} |
||||
|
||||
stepOverBack (solidityMode) { |
||||
this.debugger.step_manager.stepOverBack(solidityMode) |
||||
} |
||||
|
||||
stepIntoForward (solidityMode) { |
||||
this.debugger.step_manager.stepIntoForward(solidityMode) |
||||
} |
||||
|
||||
stepIntoBack (solidityMode) { |
||||
this.debugger.step_manager.stepIntoBack(solidityMode) |
||||
} |
||||
|
||||
jumpTo (step) { |
||||
this.debugger.step_manager.jumpTo(step) |
||||
} |
||||
|
||||
getTraceLength () { |
||||
if (!this.debugger.step_manager) return 0 |
||||
return this.debugger.step_manager.traceLength |
||||
} |
||||
|
||||
getCodeFirstStep () { |
||||
if (!this.debugger.step_manager) return 0 |
||||
return this.debugger.step_manager.calculateFirstStep() |
||||
} |
||||
|
||||
getCodeTraceLength () { |
||||
if (!this.debugger.step_manager) return 0 |
||||
return this.debugger.step_manager.calculateCodeLength() |
||||
} |
||||
|
||||
nextStep () { |
||||
if (!this.debugger.step_manager) return 0 |
||||
return this.debugger.step_manager.nextStep() |
||||
} |
||||
|
||||
previousStep () { |
||||
if (!this.debugger.step_manager) return 0 |
||||
return this.debugger.step_manager.previousStep() |
||||
} |
||||
|
||||
currentStep () { |
||||
if (!this.debugger.step_manager) return 0 |
||||
return this.debugger.step_manager.currentStepIndex |
||||
} |
||||
|
||||
canGoNext () { |
||||
return this.currentStep() < this.getCodeTraceLength() |
||||
} |
||||
|
||||
canGoPrevious () { |
||||
return this.currentStep() > this.getCodeFirstStep() |
||||
} |
||||
|
||||
unload () { |
||||
return this.debugger.unload() |
||||
} |
||||
|
||||
displayLocals () { |
||||
console.dir('= displayLocals') |
||||
console.dir(this.solidityLocals) |
||||
} |
||||
|
||||
displayGlobals () { |
||||
console.dir('= displayGlobals') |
||||
console.dir(this.solidityState) |
||||
} |
||||
} |
||||
|
||||
module.exports = CmdLine |
||||
|
@ -0,0 +1,65 @@ |
||||
pragma solidity ^0.4.0; |
||||
contract Ballot { |
||||
|
||||
struct Voter { |
||||
uint weight; |
||||
bool voted; |
||||
uint8 vote; |
||||
address delegate; |
||||
} |
||||
struct Proposal { |
||||
uint voteCount; |
||||
} |
||||
|
||||
address chairperson; |
||||
mapping(address => Voter) voters; |
||||
Proposal[] proposals; |
||||
|
||||
/// Create a new ballot with $(_numProposals) different proposals. |
||||
function Ballot(uint8 _numProposals) public { |
||||
chairperson = msg.sender; |
||||
voters[chairperson].weight = 1; |
||||
proposals.length = _numProposals; |
||||
} |
||||
|
||||
/// Give $(toVoter) the right to vote on this ballot. |
||||
/// May only be called by $(chairperson). |
||||
function giveRightToVote(address toVoter) public { |
||||
if (msg.sender != chairperson || voters[toVoter].voted) return; |
||||
voters[toVoter].weight = 1; |
||||
} |
||||
|
||||
/// Delegate your vote to the voter $(to). |
||||
function delegate(address to) public { |
||||
Voter storage sender = voters[msg.sender]; // assigns reference |
||||
if (sender.voted) return; |
||||
while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender) |
||||
to = voters[to].delegate; |
||||
if (to == msg.sender) return; |
||||
sender.voted = true; |
||||
sender.delegate = to; |
||||
Voter storage delegateTo = voters[to]; |
||||
if (delegateTo.voted) |
||||
proposals[delegateTo.vote].voteCount += sender.weight; |
||||
else |
||||
delegateTo.weight += sender.weight; |
||||
} |
||||
|
||||
/// Give a single vote to proposal $(toProposal). |
||||
function vote(uint8 toProposal) public { |
||||
Voter storage sender = voters[msg.sender]; |
||||
if (sender.voted || toProposal >= proposals.length) return; |
||||
sender.voted = true; |
||||
sender.vote = toProposal; |
||||
proposals[toProposal].voteCount += sender.weight; |
||||
} |
||||
|
||||
function winningProposal() public constant returns (uint8 _winningProposal) { |
||||
uint256 winningVoteCount = 0; |
||||
for (uint8 prop = 0; prop < proposals.length; prop++) |
||||
if (proposals[prop].voteCount > winningVoteCount) { |
||||
winningVoteCount = proposals[prop].voteCount; |
||||
_winningProposal = prop; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,22 @@ |
||||
pragma solidity ^0.4.25; |
||||
|
||||
contract SimpleStorage { |
||||
uint public storedData; |
||||
address owner; |
||||
|
||||
constructor(uint initialValue) public { |
||||
storedData = initialValue; |
||||
owner = msg.sender; |
||||
} |
||||
|
||||
function set(uint x) public { |
||||
storedData = x; |
||||
require(msg.sender != owner); |
||||
storedData = x + 2; |
||||
} |
||||
|
||||
function get() public view returns (uint retVal) { |
||||
return storedData; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,32 @@ |
||||
'use strict' |
||||
var SourceMappingDecoder = require('./sourceMappingDecoder') |
||||
|
||||
function offsetToColumnConverter (compilerEvent) { |
||||
this.lineBreakPositionsByContent = {} |
||||
this.sourceMappingDecoder = new SourceMappingDecoder() |
||||
var self = this |
||||
if (compilerEvent) { |
||||
compilerEvent.register('compilationFinished', function (success, data, source) { |
||||
self.clear() |
||||
}) |
||||
} |
||||
} |
||||
|
||||
offsetToColumnConverter.prototype.offsetToLineColumn = function (rawLocation, file, sources, asts) { |
||||
if (!this.lineBreakPositionsByContent[file]) { |
||||
for (var filename in asts) { |
||||
var source = asts[filename] |
||||
if (source.id === file) { |
||||
this.lineBreakPositionsByContent[file] = this.sourceMappingDecoder.getLinebreakPositions(sources[filename].content) |
||||
break |
||||
} |
||||
} |
||||
} |
||||
return this.sourceMappingDecoder.convertOffsetToLineColumn(rawLocation, this.lineBreakPositionsByContent[file]) |
||||
} |
||||
|
||||
offsetToColumnConverter.prototype.clear = function () { |
||||
this.lineBreakPositionsByContent = {} |
||||
} |
||||
|
||||
module.exports = offsetToColumnConverter |
@ -0,0 +1,20 @@ |
||||
// Extend fs
|
||||
var fs = require('fs') |
||||
const path = require('path') |
||||
|
||||
// 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
|
||||
} |
||||
var abspath = path.join(start, name) |
||||
if (fs.statSync(abspath).isDirectory()) { |
||||
fs.walkSync(abspath, callback) |
||||
} else { |
||||
callback(abspath) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
module.exports = fs |
@ -0,0 +1,133 @@ |
||||
const async = require('async') |
||||
const path = require('path') |
||||
const fs = require('./fs') |
||||
const TestRunner = require('./testRunner.js') |
||||
require('colors') |
||||
|
||||
let Compiler = require('./compiler.js') |
||||
let Deployer = require('./deployer.js') |
||||
|
||||
const 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(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 () { |
||||
}) |
||||
} |
||||
|
||||
module.exports = runTestFiles |
@ -0,0 +1,107 @@ |
||||
const async = require('async') |
||||
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 |
||||
} |
||||
|
||||
const 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, 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) |
||||
} |
||||
|
||||
module.exports = runTestSources |
Loading…
Reference in new issue