parent
b150500e47
commit
2ee0f59955
@ -0,0 +1,2 @@ |
|||||||
|
TODO |
||||||
|
node_modules/ |
@ -0,0 +1,17 @@ |
|||||||
|
pragma solidity ^0.4.7; |
||||||
|
contract SimpleStorage { |
||||||
|
uint public storedData; |
||||||
|
|
||||||
|
function SimpleStorage() public { |
||||||
|
storedData = 100; |
||||||
|
} |
||||||
|
|
||||||
|
function set(uint x) public { |
||||||
|
storedData = x; |
||||||
|
} |
||||||
|
|
||||||
|
function get() public view returns (uint retVal) { |
||||||
|
return storedData; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
pragma solidity ^0.4.7; |
||||||
|
import "./tests.sol"; |
||||||
|
import "./simple_storage.sol"; |
||||||
|
|
||||||
|
contract MyTest { |
||||||
|
SimpleStorage foo; |
||||||
|
|
||||||
|
function beforeAll() { |
||||||
|
foo = new SimpleStorage(); |
||||||
|
} |
||||||
|
|
||||||
|
function initialValueShouldBe100() public constant returns (bool) { |
||||||
|
return Assert.equal(foo.get(), 100, "initial value is not correct"); |
||||||
|
} |
||||||
|
|
||||||
|
function initialValueShouldBe200() public constant returns (bool) { |
||||||
|
return Assert.equal(foo.get(), 200, "initial value is not correct"); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
@ -0,0 +1,10 @@ |
|||||||
|
pragma solidity ^0.4.7; |
||||||
|
|
||||||
|
library Assert { |
||||||
|
|
||||||
|
function equal(uint a, uint b, string text) { |
||||||
|
//return a == b; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
@ -0,0 +1,40 @@ |
|||||||
|
var async = require('async'); |
||||||
|
let remixLib = require('remix-lib'); |
||||||
|
|
||||||
|
let Compiler = require('./src/compiler.js'); |
||||||
|
let Deployer = require('./src/deployer.js'); |
||||||
|
let web3Instance = require('./src/web3Instance.js'); |
||||||
|
let TestRunner = require('./src/testRunner.js'); |
||||||
|
|
||||||
|
var runTest = function(filename) { |
||||||
|
let result, web3, accounts, contracts; |
||||||
|
|
||||||
|
async.waterfall([ |
||||||
|
function compile(next) { |
||||||
|
result = Compiler.compileAll(); |
||||||
|
next(); |
||||||
|
}, |
||||||
|
function initWeb3(next) { |
||||||
|
web3 = web3Instance(); |
||||||
|
next(); |
||||||
|
}, |
||||||
|
function getAccountList(next) { |
||||||
|
web3.eth.getAccounts((err, _accounts) => { |
||||||
|
accounts = _accounts; |
||||||
|
next(); |
||||||
|
}); |
||||||
|
}, |
||||||
|
function deployAllContracts(next) { |
||||||
|
Deployer.deployAll(result, web3, accounts, next); |
||||||
|
}, |
||||||
|
function runTests(contracts, next) { |
||||||
|
let test = contracts.MyTest; |
||||||
|
TestRunner.runTest("SimpleStorage", test, accounts, next); |
||||||
|
} |
||||||
|
], function() { |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
runTest: runTest |
||||||
|
}; |
@ -0,0 +1,13 @@ |
|||||||
|
const commander = require('commander'); |
||||||
|
const RemixTests = require('./index.js'); |
||||||
|
|
||||||
|
commander.action(function (filename) { |
||||||
|
RemixTests.runTest(filename); |
||||||
|
}); |
||||||
|
|
||||||
|
if (!process.argv.slice(2).length) { |
||||||
|
console.log("please specify filename"); |
||||||
|
} |
||||||
|
|
||||||
|
commander.parse(process.argv); |
||||||
|
|
@ -0,0 +1,21 @@ |
|||||||
|
let fs = require('fs'); |
||||||
|
let solc = require('solc'); |
||||||
|
|
||||||
|
// TODO: replace this with remix's own compiler code
|
||||||
|
function compileAll() { |
||||||
|
const input = { |
||||||
|
"simple_storage.sol": fs.readFileSync("examples/simple_storage.sol").toString(), |
||||||
|
"tests.sol": fs.readFileSync("examples/tests.sol").toString(), |
||||||
|
"simple_storage_test.sol": fs.readFileSync("examples/simple_storage_test.sol").toString() |
||||||
|
}; |
||||||
|
|
||||||
|
const optimize = 1; |
||||||
|
result = solc.compile({sources: input}, optimize); |
||||||
|
|
||||||
|
return result.contracts; |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
compileAll: compileAll |
||||||
|
} |
||||||
|
|
@ -0,0 +1,66 @@ |
|||||||
|
var async = require('async'); |
||||||
|
|
||||||
|
// TODO: replace this with remix's own deployer code
|
||||||
|
|
||||||
|
function deployAll(compileResult, web3, accounts, callback) { |
||||||
|
let compiledObject = {}, contracts = {}; |
||||||
|
for (let contractName in compileResult) { |
||||||
|
let contract = compileResult[contractName]; |
||||||
|
|
||||||
|
const regex = /(.*):(.*)/; |
||||||
|
const className = contractName.match(regex)[2]; |
||||||
|
const filename = contractName.match(regex)[1]; |
||||||
|
|
||||||
|
let abi = JSON.parse(contract.interface); |
||||||
|
let code = contract.bytecode; |
||||||
|
|
||||||
|
compiledObject[className] = {}; |
||||||
|
compiledObject[className].abi = abi; |
||||||
|
compiledObject[className].code = code; |
||||||
|
compiledObject[className].filename = filename; |
||||||
|
compiledObject[className].className = className; |
||||||
|
} |
||||||
|
|
||||||
|
async.eachOfLimit(compiledObject, 1, function(contract, contractName, next) { |
||||||
|
let contractObject = new web3.eth.Contract(contract.abi); |
||||||
|
|
||||||
|
let contractCode = "0x" + contract.code; |
||||||
|
|
||||||
|
// TODO: temporary code, and terrible if the contracts are not in order...
|
||||||
|
for (let name in compiledObject) { |
||||||
|
let contractObj = compiledObject[name]; |
||||||
|
let linkReference = '__' + contractObj.filename + ":" + contractObj.className; |
||||||
|
let toReplace = linkReference + "_".repeat(40 - linkReference.length); |
||||||
|
|
||||||
|
if (contractCode.indexOf(linkReference) < 0) { |
||||||
|
continue |
||||||
|
} |
||||||
|
|
||||||
|
if (!contractObj.deployedAddress) { |
||||||
|
throw new Error("linking not found for " + name + " when deploying " + contractName); |
||||||
|
} |
||||||
|
|
||||||
|
contractCode = contractCode.replace(new RegExp(toReplace, "g"), contractObj.deployedAddress) |
||||||
|
} |
||||||
|
|
||||||
|
contractObject.deploy({arguments: [], data: contractCode}).send({ |
||||||
|
from: accounts[0], |
||||||
|
gas: 4000 * 1000 |
||||||
|
}).on('receipt', function(receipt) { |
||||||
|
contractObject.options.address = receipt.contractAddress; |
||||||
|
contractObject.options.from = accounts[0]; |
||||||
|
contractObject.options.gas = 4000*1000; |
||||||
|
compiledObject[contractName].deployedAddress = receipt.contractAddress; |
||||||
|
|
||||||
|
contracts[contractName] = contractObject; |
||||||
|
|
||||||
|
next(); |
||||||
|
}); |
||||||
|
}, function() { |
||||||
|
callback(null, contracts); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
deployAll: deployAll |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
var async = require('async'); |
||||||
|
var changeCase = require('change-case'); |
||||||
|
require('colors'); |
||||||
|
|
||||||
|
function runTest(testName, testObject, accounts, callback) { |
||||||
|
let runList = []; |
||||||
|
let specialFunctions = ['beforeAll']; |
||||||
|
let availableFunctions = testObject._jsonInterface.filter((x) => x.type === 'function').map((x) => x.name); |
||||||
|
let testFunctions = testObject._jsonInterface.filter((x) => specialFunctions.indexOf(x.name) < 0 && x.type === 'function'); |
||||||
|
|
||||||
|
if (availableFunctions.indexOf("beforeAll")) { |
||||||
|
runList.push({name: 'beforeAll', type: 'internal', constant: false}); |
||||||
|
} |
||||||
|
|
||||||
|
for (let func of testFunctions) { |
||||||
|
runList.push({name: func.name, type: 'test', constant: func.constant}); |
||||||
|
} |
||||||
|
|
||||||
|
console.log("#" + testName); |
||||||
|
async.eachOfLimit(runList, 1, function(func, index, next) { |
||||||
|
let method = testObject.methods[func.name].apply(testObject.methods[func.name], []); |
||||||
|
if (func.constant) { |
||||||
|
method.call().then((result) => { |
||||||
|
if (result) { |
||||||
|
// TODO: should instead be returned in a callback, the caller can
|
||||||
|
// decide how to handle the output (so works both in console and
|
||||||
|
// browser)
|
||||||
|
console.log("\t✓ ".green.bold + changeCase.sentenceCase(func.name).grey); |
||||||
|
} else { |
||||||
|
console.log("\t✘ ".bold.red + changeCase.sentenceCase(func.name).red); |
||||||
|
} |
||||||
|
next(); |
||||||
|
}); |
||||||
|
} else { |
||||||
|
method.send().then(() => { |
||||||
|
next(); |
||||||
|
}); |
||||||
|
} |
||||||
|
}, function() { |
||||||
|
console.log("1 passing".green); |
||||||
|
console.log("1 failing".red); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
runTest: runTest |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
let Web3 = require('web3'); |
||||||
|
var EthJSVM = require('ethereumjs-vm') |
||||||
|
|
||||||
|
// TODO: this whole file is temporary and should disapear one the code is
|
||||||
|
// refactored
|
||||||
|
|
||||||
|
function web3Instance() { |
||||||
|
let web3 = new Web3(); |
||||||
|
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')); |
||||||
|
//var vm = new EthJSVM({
|
||||||
|
// enableHomestead: true,
|
||||||
|
// activatePrecompiles: true
|
||||||
|
//});
|
||||||
|
//
|
||||||
|
//var Web3VMProvider = remixLib.vm.Web3VMProvider;
|
||||||
|
//
|
||||||
|
//let web3 = new Web3VMProvider();
|
||||||
|
//web3.setVM(vm);
|
||||||
|
return web3; |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = web3Instance; |
Loading…
Reference in new issue