mirror of https://github.com/embarklabs/embark.git
test(@embark): move solidity test to folder structure matching src/; add compiler test
This commit is contained in:
parent
caf97af0f5
commit
ac32cdbfc7
|
@ -0,0 +1,78 @@
|
|||
/*globals describe, it*/
|
||||
const assert = require('assert');
|
||||
|
||||
// TODO: need to rethink i18n and how that is required in each module
|
||||
require('../../../lib/core/i18n/i18n');
|
||||
|
||||
const Compiler = require('../../../lib/modules/compiler');
|
||||
const File = require('../../../lib/core/file.js');
|
||||
const Plugins = require('../../../lib/core/plugins.js');
|
||||
const TestLogger = require('../../../lib/utils/test_logger');
|
||||
const Events = require('../../../lib/core/events');
|
||||
|
||||
const readFile = function(file) {
|
||||
return new File({filename: file, type: File.types.dapp_file, path: file});
|
||||
};
|
||||
|
||||
const currentSolcVersion = require('../../../../package.json').dependencies.solc;
|
||||
const TestEvents = {
|
||||
request: (cmd, cb) => {
|
||||
cb(currentSolcVersion);
|
||||
},
|
||||
emit: (_ev, _data) => {}
|
||||
};
|
||||
|
||||
describe('embark.Compiler', function() {
|
||||
this.timeout(0);
|
||||
|
||||
describe('command: compiler:contracts', function() {
|
||||
let plugins = new Plugins({
|
||||
logger: new TestLogger({}),
|
||||
events: TestEvents,
|
||||
config: {
|
||||
contractDirectories: ['app/contracts/'],
|
||||
embarkConfig: {
|
||||
options: {
|
||||
solc: {
|
||||
"optimize": true,
|
||||
"optimize-runs": 200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
plugins.createPlugin("sol", {}).registerCompiler(".sol", (_matchingFiles, options, cb) => { return cb(null, {contractA: "solResult"}); });
|
||||
plugins.createPlugin("vyp", {}).registerCompiler(".vy", (_matchingFiles, options, cb) => { return cb(null, {contractB: "vyResult"}); });
|
||||
|
||||
const events = new Events();
|
||||
const embarkObject = {
|
||||
registerAPICall: () => {},
|
||||
events: events,
|
||||
logger: plugins.logger,
|
||||
embarkConfig: {
|
||||
options: {
|
||||
solc: {
|
||||
"optimize": true,
|
||||
"optimize-runs": 200
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const compiler = new Compiler(embarkObject, {plugins: plugins});
|
||||
|
||||
it("should return aggregated result", (done) => {
|
||||
events.request("compiler:contracts", [
|
||||
readFile('dist/test/contracts/simple_storage.sol'),
|
||||
readFile('dist/test/contracts/token.sol'),
|
||||
readFile('dist/test/contracts/erc20.vy')
|
||||
], {}, (err, compiledObject) => {
|
||||
assert.deepEqual(compiledObject, { contractA: 'solResult', contractB: 'vyResult' })
|
||||
done();
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
});
|
|
@ -0,0 +1,139 @@
|
|||
# @dev Implementation of ERC-20 token standard.
|
||||
# @author Takayuki Jimba (@yudetamago)
|
||||
|
||||
Transfer: event({_from: indexed(address), _to: indexed(address), _value: uint256})
|
||||
Approval: event({_owner: indexed(address), _spender: indexed(address), _value: uint256})
|
||||
|
||||
name: public(bytes32)
|
||||
symbol: public(bytes32)
|
||||
decimals: public(uint256)
|
||||
balances: map(address, uint256)
|
||||
allowances: map(address, map(address, uint256))
|
||||
total_supply: uint256
|
||||
minter: address
|
||||
|
||||
@public
|
||||
def __init__(_name: bytes32, _symbol: bytes32, _decimals: uint256, _supply: uint256):
|
||||
init_supply: uint256 = _supply * 10 ** _decimals
|
||||
sender: address = msg.sender
|
||||
self.name = _name
|
||||
self.symbol = _symbol
|
||||
self.decimals = _decimals
|
||||
self.balances[sender] = init_supply
|
||||
self.total_supply = init_supply
|
||||
self.minter = sender
|
||||
log.Transfer(ZERO_ADDRESS, sender, init_supply)
|
||||
|
||||
|
||||
# @dev Total number of tokens in existence.
|
||||
@public
|
||||
@constant
|
||||
def totalSupply() -> uint256:
|
||||
return self.total_supply
|
||||
|
||||
|
||||
# @dev Gets the balance of the specified address.
|
||||
# @param _owner The address to query the balance of.
|
||||
# @return An uint256 representing the amount owned by the passed address.
|
||||
@public
|
||||
@constant
|
||||
def balanceOf(_owner : address) -> uint256:
|
||||
return self.balances[_owner]
|
||||
|
||||
|
||||
# @dev Function to check the amount of tokens that an owner allowed to a spender.
|
||||
# @param _owner The address which owns the funds.
|
||||
# @param _spender The address which will spend the funds.
|
||||
# @return An uint256 specifying the amount of tokens still available for the spender.
|
||||
@public
|
||||
@constant
|
||||
def allowance(_owner : address, _spender : address) -> uint256:
|
||||
return self.allowances[_owner][_spender]
|
||||
|
||||
|
||||
# @dev Transfer token for a specified address
|
||||
# @param _to The address to transfer to.
|
||||
# @param _value The amount to be transferred.
|
||||
@public
|
||||
def transfer(_to : address, _value : uint256) -> bool:
|
||||
_sender: address = msg.sender
|
||||
self.balances[_sender] = self.balances[_sender] - _value
|
||||
self.balances[_to] = self.balances[_to] + _value
|
||||
log.Transfer(_sender, _to, _value)
|
||||
return True
|
||||
|
||||
|
||||
# @dev Transfer tokens from one address to another.
|
||||
# Note that while this function emits an Approval event, this is not required as per the specification,
|
||||
# and other compliant implementations may not emit the event.
|
||||
# @param _from address The address which you want to send tokens from
|
||||
# @param _to address The address which you want to transfer to
|
||||
# @param _value uint256 the amount of tokens to be transferred
|
||||
@public
|
||||
def transferFrom(_from : address, _to : address, _value : uint256) -> bool:
|
||||
_sender: address = msg.sender
|
||||
allowance: uint256 = self.allowances[_from][_sender]
|
||||
self.balances[_from] = self.balances[_from] - _value
|
||||
self.balances[_to] = self.balances[_to] + _value
|
||||
self.allowances[_from][_sender] = allowance - _value
|
||||
log.Transfer(_from, _to, _value)
|
||||
return True
|
||||
|
||||
|
||||
# @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
|
||||
# Beware that changing an allowance with this method brings the risk that someone may use both the old
|
||||
# and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
|
||||
# race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
|
||||
# https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
|
||||
# @param _spender The address which will spend the funds.
|
||||
# @param _value The amount of tokens to be spent.
|
||||
@public
|
||||
def approve(_spender : address, _value : uint256) -> bool:
|
||||
_sender: address = msg.sender
|
||||
self.allowances[_sender][_spender] = _value
|
||||
log.Approval(_sender, _spender, _value)
|
||||
return True
|
||||
|
||||
|
||||
# @dev Mint an amount of the token and assigns it to an account.
|
||||
# This encapsulates the modification of balances such that the
|
||||
# proper events are emitted.
|
||||
# @param _to The account that will receive the created tokens.
|
||||
# @param _value The amount that will be created.
|
||||
@public
|
||||
def mint(_to: address, _value: uint256):
|
||||
assert msg.sender == self.minter
|
||||
assert _to != ZERO_ADDRESS
|
||||
self.total_supply = self.total_supply + _value
|
||||
self.balances[_to] = self.balances[_to] + _value
|
||||
log.Transfer(ZERO_ADDRESS, _to, _value)
|
||||
|
||||
|
||||
# @dev Internal function that burns an amount of the token of a given
|
||||
# account.
|
||||
# @param _to The account whose tokens will be burned.
|
||||
# @param _value The amount that will be burned.
|
||||
@private
|
||||
def _burn(_to: address, _value: uint256):
|
||||
assert _to != ZERO_ADDRESS
|
||||
self.total_supply = self.total_supply - _value
|
||||
self.balances[_to] = self.balances[_to] - _value
|
||||
log.Transfer(_to, ZERO_ADDRESS, _value)
|
||||
|
||||
|
||||
# @dev Burn an amount of the token of msg.sender.
|
||||
# @param _value The amount that will be burned.
|
||||
@public
|
||||
def burn(_value: uint256):
|
||||
self._burn(msg.sender, _value)
|
||||
|
||||
|
||||
# @dev Burn an amount of the token from a given account.
|
||||
# @param _to The account whose tokens will be burned.
|
||||
# @param _value The amount that will be burned.
|
||||
@public
|
||||
def burnFrom(_to: address, _value: uint256):
|
||||
_sender: address = msg.sender
|
||||
self.allowances[_to][_sender] = self.allowances[_to][_sender] - _value
|
||||
self._burn(_to, _value)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
pragma solidity ^0.5.0;
|
||||
|
||||
contract SimpleStorage {
|
||||
uint public storedData;
|
||||
|
||||
constructor(uint initialValue) public {
|
||||
storedData = initialValue;
|
||||
}
|
||||
|
||||
function set(uint x) public {
|
||||
storedData = x;
|
||||
}
|
||||
|
||||
function get() public view returns (uint retVal) {
|
||||
return storedData;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// https://github.com/nexusdev/erc20/blob/master/contracts/base.sol
|
||||
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
contract Token {
|
||||
|
||||
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;
|
||||
|
||||
constructor(uint initial_balance) public {
|
||||
_balances[msg.sender] = initial_balance;
|
||||
_supply = initial_balance;
|
||||
}
|
||||
|
||||
function totalSupply() public view returns (uint supply) {
|
||||
return _supply;
|
||||
}
|
||||
|
||||
function balanceOf(address who) public view returns (uint value) {
|
||||
return _balances[who];
|
||||
}
|
||||
|
||||
function transfer(address to, uint value) public returns (bool ok) {
|
||||
if( _balances[msg.sender] < value ) {
|
||||
revert();
|
||||
}
|
||||
if( !safeToAdd(_balances[to], value) ) {
|
||||
revert();
|
||||
}
|
||||
_balances[msg.sender] -= value;
|
||||
_balances[to] += value;
|
||||
emit Transfer( msg.sender, to, value );
|
||||
return true;
|
||||
}
|
||||
|
||||
function transferFrom(address from, address to, uint value) public returns (bool ok) {
|
||||
// if you don't have enough balance, throw
|
||||
if( _balances[from] < value ) {
|
||||
revert();
|
||||
}
|
||||
// if you don't have approval, throw
|
||||
if( _approvals[from][msg.sender] < value ) {
|
||||
revert();
|
||||
}
|
||||
if( !safeToAdd(_balances[to], value) ) {
|
||||
revert();
|
||||
}
|
||||
// transfer and return true
|
||||
_approvals[from][msg.sender] -= value;
|
||||
_balances[from] -= value;
|
||||
_balances[to] += value;
|
||||
emit Transfer( from, to, value );
|
||||
return true;
|
||||
}
|
||||
|
||||
function approve(address spender, uint value) public returns (bool ok) {
|
||||
// TODO: should increase instead
|
||||
_approvals[msg.sender][spender] = value;
|
||||
emit Approval( msg.sender, spender, value );
|
||||
return true;
|
||||
}
|
||||
|
||||
function allowance(address owner, address spender) public view returns (uint _allowance) {
|
||||
return _approvals[owner][spender];
|
||||
}
|
||||
|
||||
function safeToAdd(uint a, uint b) internal pure returns (bool) {
|
||||
return (a + b >= a);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
/*globals describe, it*/
|
||||
let SolidityCompiler = require('../lib/modules/solidity');
|
||||
let TestLogger = require('../lib/utils/test_logger');
|
||||
let File = require('../lib/core/file.js');
|
||||
let Ipc = require('../lib/core/ipc.js');
|
||||
let SolidityCompiler = require('../../../lib/modules/solidity');
|
||||
let TestLogger = require('../../../lib/utils/test_logger');
|
||||
let File = require('../../../lib/core/file.js');
|
||||
let Ipc = require('../../../lib/core/ipc.js');
|
||||
let assert = require('assert');
|
||||
|
||||
let readFile = function(file) {
|
||||
|
@ -44,7 +44,7 @@ let generateApiObject = function() {
|
|||
return apiObject;
|
||||
}
|
||||
|
||||
describe('embark.Compiler', function() {
|
||||
describe('embark.Solidity', function() {
|
||||
describe('#compile_solidity', function() {
|
||||
this.timeout(0);
|
||||
|
||||
|
@ -61,7 +61,7 @@ describe('embark.Compiler', function() {
|
|||
"gasEstimates":{"creation":{"codeDepositCost":"45000","executionCost":"20141","totalCost":"65141"},"external":{"get()":"428","set(uint256)":"20161","storedData()":"384"}},
|
||||
"functionHashes":{"get()":"6d4ce63c","set(uint256)":"60fe47b1","storedData()":"2a1afcd9"},
|
||||
"abiDefinition":[{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"initialValue","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}],
|
||||
"filename":"dist/test/contracts/simple_storage.sol"
|
||||
"filename":"dist/test/modules/solidity/contracts/simple_storage.sol"
|
||||
};
|
||||
|
||||
expectedObject["Token"] = {
|
||||
|
@ -72,13 +72,13 @@ describe('embark.Compiler', function() {
|
|||
"gasEstimates":{"creation":{"codeDepositCost":"209600","executionCost":"40385","totalCost":"249985"},"external":{"allowance(address,address)":"818","approve(address,uint256)":"22332","balanceOf(address)":"675","totalSupply()":"406","transfer(address,uint256)":"43544","transferFrom(address,address,uint256)":"64387"},"internal":{"safeToAdd(uint256,uint256)":"24"}},
|
||||
"functionHashes":{"allowance(address,address)":"dd62ed3e","approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","totalSupply()":"18160ddd","transfer(address,uint256)":"a9059cbb","transferFrom(address,address,uint256)":"23b872dd"},
|
||||
"abiDefinition":[{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"supply","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"value","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"_allowance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"initial_balance","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}],
|
||||
"filename":"dist/test/contracts/token.sol"
|
||||
"filename":"dist/test/modules/solidity/contracts/token.sol"
|
||||
};
|
||||
|
||||
it('should generate compiled code and abi', function(done) {
|
||||
compiler.compile_solidity([
|
||||
readFile('dist/test/contracts/simple_storage.sol'),
|
||||
readFile('dist/test/contracts/token.sol')
|
||||
readFile('dist/test/modules/solidity/contracts/simple_storage.sol'),
|
||||
readFile('dist/test/modules/solidity/contracts/token.sol')
|
||||
], {}, function(err, compiledContracts) {
|
||||
//assert.deepEqual(compiledContracts, expectedObject);
|
||||
done();
|
||||
|
@ -104,7 +104,7 @@ describe('embark.Compiler', function() {
|
|||
"gasEstimates":{"creation":{"codeDepositCost":"55800","executionCost":"20205","totalCost":"76005"},"external":{"get()":"446","set(uint256)":"20227","storedData()":"394"}},
|
||||
"functionHashes":{"get()":"6d4ce63c","set(uint256)":"60fe47b1","storedData()":"2a1afcd9"},
|
||||
"abiDefinition":[{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"initialValue","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}],
|
||||
"filename":"dist/test/contracts/simple_storage.sol"
|
||||
"filename":"dist/test/modules/solidity/contracts/simple_storage.sol"
|
||||
};
|
||||
|
||||
expectedObject["Token"] = {
|
||||
|
@ -115,13 +115,13 @@ describe('embark.Compiler', function() {
|
|||
"gasEstimates":{"creation":{"codeDepositCost":"470000","executionCost":"40708","totalCost":"510708"},"external":{"allowance(address,address)":"794","approve(address,uint256)":"22331","balanceOf(address)":"625","totalSupply()":"424","transfer(address,uint256)":"43562","transferFrom(address,address,uint256)":"64373"},"internal":{"safeToAdd(uint256,uint256)":"45"}},
|
||||
"functionHashes":{"allowance(address,address)":"dd62ed3e","approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","totalSupply()":"18160ddd","transfer(address,uint256)":"a9059cbb","transferFrom(address,address,uint256)":"23b872dd"},
|
||||
"abiDefinition":[{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"supply","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"value","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"ok","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"_allowance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"initial_balance","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}],
|
||||
"filename":"dist/test/contracts/token.sol"
|
||||
"filename":"dist/test/modules/solidity/contracts/token.sol"
|
||||
};
|
||||
|
||||
it('should generate compiled code and abi', function(done) {
|
||||
compiler.compile_solidity([
|
||||
readFile('dist/test/contracts/simple_storage.sol'),
|
||||
readFile('dist/test/contracts/token.sol')
|
||||
readFile('dist/test/modules/solidity/contracts/simple_storage.sol'),
|
||||
readFile('dist/test/modules/solidity/contracts/token.sol')
|
||||
], {}, function(err, compiledContracts) {
|
||||
//assert.deepEqual(compiledContracts, expectedObject);
|
||||
done();
|
Loading…
Reference in New Issue