From 087578c8e6fd07759a01ed008a83c9b24cea4047 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Thu, 12 Jan 2017 20:42:33 -0500 Subject: [PATCH] add spec for contracs config; fix contracts arguments when it's an instanceOf --- lib/contracts.js | 7 +- test/console.js | 2 +- test/contracts.js | 161 +++++++++++++++++++++++++++++++ test/contracts/token_storage.sol | 67 +++++++++++++ 4 files changed, 233 insertions(+), 4 deletions(-) create mode 100644 test/contracts.js create mode 100644 test/contracts/token_storage.sol diff --git a/lib/contracts.js b/lib/contracts.js index 73252b84..76ba7d74 100644 --- a/lib/contracts.js +++ b/lib/contracts.js @@ -38,11 +38,11 @@ ContractsManager.prototype.build = function(done) { function compileContracts(callback) { var compiler = new Compiler(); try { - self.compiledContracts = compiler.compile_solidity(self.contractFiles); - return callback(); + self.compiledContracts = compiler.compile_solidity(self.contractFiles); } catch(err) { return callback(new Error(err.message)); } + return callback(); }, function prepareContractsFromConfig(callback) { var className, contract; @@ -110,7 +110,7 @@ ContractsManager.prototype.build = function(done) { continue; } - if (parentContract.args && parentContract.args.length > 0 && contract.args === []) { + if (parentContract.args && parentContract.args.length > 0 && ((contract.args && contract.args.length === 0) || contract.args === undefined)) { contract.args = parentContract.args; } @@ -126,6 +126,7 @@ ContractsManager.prototype.build = function(done) { contract.gas = contract.gas || parentContract.gas; contract.gasPrice = contract.gasPrice || parentContract.gasPrice; + contract.type = 'instance'; } callback(); diff --git a/test/console.js b/test/console.js index 05c3045b..91a76750 100644 --- a/test/console.js +++ b/test/console.js @@ -9,7 +9,7 @@ describe('embark.Console', function() { describe('command: help', function() { - it('i should provide a help text', function(done) { + it('it should provide a help text', function(done) { console.executeCmd('help', function(output) { var lines = output.split('\n'); assert.equal(lines[0], 'Welcome to Embark 2'); diff --git a/test/contracts.js b/test/contracts.js new file mode 100644 index 00000000..fee7c441 --- /dev/null +++ b/test/contracts.js @@ -0,0 +1,161 @@ +/*globals describe, it*/ +var ContractsManager = require('../lib/contracts.js'); +var Logger = require('../lib/logger.js'); +var assert = require('assert'); +var fs = require('fs'); + +var readFile = function(file) { + return {filename: file, content: fs.readFileSync(file).toString()}; +}; + +describe('embark.Contratcs', function() { + describe('simple', function() { + var contractsManager = new ContractsManager({ + contractFiles: [ + readFile('test/contracts/simple_storage.sol'), + readFile('test/contracts/token.sol') + ], + contractsConfig: { + "gas": "auto", + "contracts": { + "Token": { + "args": [ + 100 + ] + }, + "SimpleStorage": { + "args": [ + 200 + ] + } + } + }, + logger: new Logger({}) + }); + + describe('#build', function() { + it('generate contracts', function() { + contractsManager.build(function(err, result) { + if (err) { + throw err; + } + }); + + var contracts = contractsManager.listContracts(); + assert.equal(contracts.length, 2); + + assert.equal(contracts[0].deploy, true); + assert.deepEqual(contracts[0].args, [100]); + assert.equal(contracts[0].className, "Token"); + assert.deepEqual(contracts[0].gas, 700000); + //assert.equal(contracts[0].gasPrice, []); // TODO: test this one + assert.equal(contracts[0].type, 'file'); + //assert.equal(contracts[0].abiDefinition, ''); + //assert.equal(contracts[0].code, ''); + //assert.equal(contracts[0].runtimeBytecode, ''); + + assert.equal(contracts[1].deploy, true); + assert.deepEqual(contracts[1].args, [200]); + assert.equal(contracts[1].className, "SimpleStorage"); + assert.deepEqual(contracts[1].gas, 700000); + //assert.equal(contracts[1].gasPrice, []); // TODO: test this one + assert.equal(contracts[1].type, 'file'); + //assert.equal(contracts[1].abiDefinition, ''); + //assert.equal(contracts[1].code, ''); + //assert.equal(contracts[1].runtimeBytecode, ''); + }); + }); + }); + + describe('config with contract instances', function() { + var contractsManager = new ContractsManager({ + contractFiles: [ + readFile('test/contracts/simple_storage.sol'), + readFile('test/contracts/token_storage.sol') + ], + contractsConfig: { + "gas": "auto", + "contracts": { + "TokenStorage": { + "args": [ + 100, + "$SimpleStorage" + ] + }, + "MySimpleStorage": { + "instanceOf": "SimpleStorage", + "args": [ + 300 + ] + }, + "SimpleStorage": { + "args": [ + 200 + ] + }, + "AnotherSimpleStorage": { + "instanceOf": "SimpleStorage" + } + } + }, + logger: new Logger({}) + }); + + describe('#build', function() { + it('generate contracts', function() { + contractsManager.build(function(err, result) { + if (err) { + throw err; + } + }); + + var contracts = contractsManager.listContracts(); + assert.equal(contracts.length, 4); + + assert.equal(contracts[0].className, "MySimpleStorage"); + assert.equal(contracts[1].className, "AnotherSimpleStorage"); + assert.equal(contracts[2].className, "SimpleStorage"); + assert.equal(contracts[3].className, "TokenStorage"); + + // TokenStorage + assert.equal(contracts[3].deploy, true); + assert.deepEqual(contracts[3].args, [100, '$SimpleStorage']); + assert.deepEqual(contracts[3].gas, 700000); + assert.equal(contracts[3].type, 'file'); + //assert.equal(contracts[3].abiDefinition, ''); + //assert.equal(contracts[3].code, ''); + //assert.equal(contracts[3].runtimeBytecode, ''); + + var parentContract = contracts[2]; + + //MySimpleStorage + assert.equal(contracts[0].deploy, true); + assert.deepEqual(contracts[0].args, [300]); + assert.deepEqual(contracts[0].gas, 700000); + assert.equal(contracts[0].type, 'instance'); + assert.equal(contracts[0].abiDefinition, parentContract.abiDefinition); + assert.equal(contracts[0].code, parentContract.code); + assert.equal(contracts[0].runtimeBytecode, parentContract.runtimeBytecode); + + // SimpleStorage + assert.equal(contracts[2].deploy, true); + assert.deepEqual(contracts[2].args, [200]); + assert.deepEqual(contracts[2].gas, 700000); + assert.equal(contracts[2].type, 'file'); + //assert.equal(contracts[2].abiDefinition, ''); + //assert.equal(contracts[2].code, ''); + //assert.equal(contracts[2].runtimeBytecode, ''); + + // AnotherSimpleStorage + assert.equal(contracts[1].deploy, true); + assert.deepEqual(contracts[1].args, [200]); + assert.deepEqual(contracts[1].gas, 700000); + assert.equal(contracts[1].type, 'instance'); + assert.equal(contracts[1].abiDefinition, parentContract.abiDefinition); + assert.equal(contracts[1].code, parentContract.code); + assert.equal(contracts[1].runtimeBytecode, parentContract.runtimeBytecode); + }); + }); + }); + +}); diff --git a/test/contracts/token_storage.sol b/test/contracts/token_storage.sol new file mode 100644 index 00000000..dade953f --- /dev/null +++ b/test/contracts/token_storage.sol @@ -0,0 +1,67 @@ +// https://github.com/nexusdev/erc20/blob/master/contracts/base.sol + +pragma solidity ^0.4.7; +contract TokenStorage { + + event Transfer(address indexed from, address indexed to, uint value); + event Approval( address indexed owner, address indexed spender, uint value); + + mapping( address => uint ) _balances; + mapping( address => mapping( address => uint ) ) _approvals; + uint _supply; + address public addr; + function TokenStorage( uint initial_balance, address _addr) { + _balances[msg.sender] = initial_balance; + _supply = initial_balance; + addr = _addr; + } + function totalSupply() constant returns (uint supply) { + return _supply; + } + function balanceOf( address who ) constant returns (uint value) { + return _balances[who]; + } + function transfer( address to, uint value) returns (bool ok) { + if( _balances[msg.sender] < value ) { + throw; + } + if( !safeToAdd(_balances[to], value) ) { + throw; + } + _balances[msg.sender] -= value; + _balances[to] += value; + Transfer( msg.sender, to, value ); + return true; + } + function transferFrom( address from, address to, uint value) returns (bool ok) { + // if you don't have enough balance, throw + if( _balances[from] < value ) { + throw; + } + // if you don't have approval, throw + if( _approvals[from][msg.sender] < value ) { + throw; + } + if( !safeToAdd(_balances[to], value) ) { + throw; + } + // transfer and return true + _approvals[from][msg.sender] -= value; + _balances[from] -= value; + _balances[to] += value; + Transfer( from, to, value ); + return true; + } + function approve(address spender, uint value) returns (bool ok) { + // TODO: should increase instead + _approvals[msg.sender][spender] = value; + Approval( msg.sender, spender, value ); + return true; + } + function allowance(address owner, address spender) constant returns (uint _allowance) { + return _approvals[owner][spender]; + } + function safeToAdd(uint a, uint b) internal returns (bool) { + return (a + b >= a); + } +}