Organize test files following contracts folders structure

This commit is contained in:
Facundo Spagnuolo
2018-01-09 12:34:29 -03:00
parent 7532dab17d
commit b925b2dae6
31 changed files with 55 additions and 56 deletions

View File

@ -0,0 +1,33 @@
import assertRevert from '../helpers/assertRevert';
var BasicTokenMock = artifacts.require('mocks/BasicTokenMock.sol');
contract('BasicToken', function (accounts) {
it('should return the correct totalSupply after construction', async function () {
let token = await BasicTokenMock.new(accounts[0], 100);
let totalSupply = await token.totalSupply();
assert.equal(totalSupply, 100);
});
it('should return correct balances after transfer', async function () {
let token = await BasicTokenMock.new(accounts[0], 100);
await token.transfer(accounts[1], 100);
let firstAccountBalance = await token.balanceOf(accounts[0]);
assert.equal(firstAccountBalance, 0);
let secondAccountBalance = await token.balanceOf(accounts[1]);
assert.equal(secondAccountBalance, 100);
});
it('should throw an error when trying to transfer more than balance', async function () {
let token = await BasicTokenMock.new(accounts[0], 100);
await assertRevert(token.transfer(accounts[1], 101));
});
it('should throw an error when trying to transfer to 0x0', async function () {
let token = await BasicTokenMock.new(accounts[0], 100);
await assertRevert(token.transfer(0x0, 100));
});
});

View File

@ -0,0 +1,38 @@
const EVMRevert = require('../helpers/EVMRevert.js');
const BurnableTokenMock = artifacts.require('mocks/BurnableTokenMock.sol');
const BigNumber = web3.BigNumber;
require('chai')
.use(require('chai-as-promised'))
.use(require('chai-bignumber')(BigNumber))
.should();
const expect = require('chai').expect;
contract('BurnableToken', function (accounts) {
let token;
let expectedTokenSupply = new BigNumber(999);
beforeEach(async function () {
token = await BurnableTokenMock.new(accounts[0], 1000);
});
it('owner should be able to burn tokens', async function () {
const { logs } = await token.burn(1, { from: accounts[0] });
const balance = await token.balanceOf(accounts[0]);
balance.should.be.bignumber.equal(expectedTokenSupply);
const totalSupply = await token.totalSupply();
totalSupply.should.be.bignumber.equal(expectedTokenSupply);
const event = logs.find(e => e.event === 'Burn');
expect(event).to.exist;
});
it('cannot burn more tokens than your balance', async function () {
await token.burn(2000, { from: accounts[0] })
.should.be.rejectedWith(EVMRevert);
});
});

View File

@ -0,0 +1,36 @@
import expectThrow from '../helpers/expectThrow';
import ether from '../helpers/ether';
var CappedToken = artifacts.require('../contracts/Tokens/CappedToken.sol');
contract('Capped', function (accounts) {
const cap = ether(1000);
let token;
beforeEach(async function () {
token = await CappedToken.new(cap);
});
it('should start with the correct cap', async function () {
let _cap = await token.cap();
assert(cap.eq(_cap));
});
it('should mint when amount is less than cap', async function () {
const result = await token.mint(accounts[0], 100);
assert.equal(result.logs[0].event, 'Mint');
});
it('should fail to mint if the ammount exceeds the cap', async function () {
await token.mint(accounts[0], cap.sub(1));
await expectThrow(token.mint(accounts[0], 100));
});
it('should fail to mint after cap is reached', async function () {
await token.mint(accounts[0], cap);
await expectThrow(token.mint(accounts[0], 1));
});
});

View File

@ -0,0 +1,35 @@
const BigNumber = web3.BigNumber;
require('chai')
.use(require('chai-as-promised'))
.use(require('chai-bignumber')(BigNumber))
.should();
const DetailedERC20Mock = artifacts.require('mocks/DetailedERC20Mock.sol');
contract('DetailedERC20', accounts => {
let detailedERC20 = null;
const _name = 'My Detailed ERC20';
const _symbol = 'MDT';
const _decimals = 18;
beforeEach(async function () {
detailedERC20 = await DetailedERC20Mock.new(_name, _symbol, _decimals);
});
it('has a name', async function () {
const name = await detailedERC20.name();
name.should.be.equal(_name);
});
it('has a symbol', async function () {
const symbol = await detailedERC20.symbol();
symbol.should.be.equal(_symbol);
});
it('has an amount of decimals', async function () {
const decimals = await detailedERC20.decimals();
decimals.should.be.bignumber.equal(_decimals);
});
});

View File

@ -0,0 +1,44 @@
import expectThrow from '../helpers/expectThrow';
var MintableToken = artifacts.require('../contracts/Tokens/MintableToken.sol');
contract('Mintable', function (accounts) {
let token;
beforeEach(async function () {
token = await MintableToken.new();
});
it('should start with a totalSupply of 0', async function () {
let totalSupply = await token.totalSupply();
assert.equal(totalSupply, 0);
});
it('should return mintingFinished false after construction', async function () {
let mintingFinished = await token.mintingFinished();
assert.equal(mintingFinished, false);
});
it('should mint a given amount of tokens to a given address', async function () {
const result = await token.mint(accounts[0], 100);
assert.equal(result.logs[0].event, 'Mint');
assert.equal(result.logs[0].args.to.valueOf(), accounts[0]);
assert.equal(result.logs[0].args.amount.valueOf(), 100);
assert.equal(result.logs[1].event, 'Transfer');
assert.equal(result.logs[1].args.from.valueOf(), 0x0);
let balance0 = await token.balanceOf(accounts[0]);
assert(balance0, 100);
let totalSupply = await token.totalSupply();
assert(totalSupply, 100);
});
it('should fail to mint after call to finishMinting', async function () {
await token.finishMinting();
assert.equal(await token.mintingFinished(), true);
await expectThrow(token.mint(accounts[0], 100));
});
});

View File

@ -0,0 +1,63 @@
'user strict';
import assertRevert from '../helpers/assertRevert';
var PausableTokenMock = artifacts.require('./mocks/PausableTokenMock.sol');
contract('PausableToken', function (accounts) {
let token;
beforeEach(async function () {
token = await PausableTokenMock.new(accounts[0], 100);
});
it('should return paused false after construction', async function () {
let paused = await token.paused();
assert.equal(paused, false);
});
it('should return paused true after pause', async function () {
await token.pause();
let paused = await token.paused();
assert.equal(paused, true);
});
it('should return paused false after pause and unpause', async function () {
await token.pause();
await token.unpause();
let paused = await token.paused();
assert.equal(paused, false);
});
it('should be able to transfer if transfers are unpaused', async function () {
await token.transfer(accounts[1], 100);
let balance0 = await token.balanceOf(accounts[0]);
assert.equal(balance0, 0);
let balance1 = await token.balanceOf(accounts[1]);
assert.equal(balance1, 100);
});
it('should be able to transfer after transfers are paused and unpaused', async function () {
await token.pause();
await token.unpause();
await token.transfer(accounts[1], 100);
let balance0 = await token.balanceOf(accounts[0]);
assert.equal(balance0, 0);
let balance1 = await token.balanceOf(accounts[1]);
assert.equal(balance1, 100);
});
it('should throw an error trying to transfer while transactions are paused', async function () {
await token.pause();
await assertRevert(token.transfer(accounts[1], 100));
});
it('should throw an error trying to transfer from another account while transactions are paused', async function () {
await token.pause();
await assertRevert(token.transferFrom(accounts[0], accounts[1], 100));
});
});

View File

@ -0,0 +1,37 @@
import EVMThrow from '../helpers/EVMThrow';
require('chai')
.use(require('chai-as-promised'))
.should();
const SafeERC20Helper = artifacts.require('mocks/SafeERC20Helper.sol');
contract('SafeERC20', function () {
beforeEach(async function () {
this.helper = await SafeERC20Helper.new();
});
it('should throw on failed transfer', async function () {
await this.helper.doFailingTransfer().should.be.rejectedWith(EVMThrow);
});
it('should throw on failed transferFrom', async function () {
await this.helper.doFailingTransferFrom().should.be.rejectedWith(EVMThrow);
});
it('should throw on failed approve', async function () {
await this.helper.doFailingApprove().should.be.rejectedWith(EVMThrow);
});
it('should not throw on succeeding transfer', async function () {
await this.helper.doSucceedingTransfer().should.be.fulfilled;
});
it('should not throw on succeeding transferFrom', async function () {
await this.helper.doSucceedingTransferFrom().should.be.fulfilled;
});
it('should not throw on succeeding approve', async function () {
await this.helper.doSucceedingApprove().should.be.fulfilled;
});
});

View File

@ -0,0 +1,103 @@
import assertRevert from '../helpers/assertRevert';
var StandardTokenMock = artifacts.require('mocks/StandardTokenMock.sol');
contract('StandardToken', function (accounts) {
let token;
beforeEach(async function () {
token = await StandardTokenMock.new(accounts[0], 100);
});
it('should return the correct totalSupply after construction', async function () {
let totalSupply = await token.totalSupply();
assert.equal(totalSupply, 100);
});
it('should return the correct allowance amount after approval', async function () {
let token = await StandardTokenMock.new();
await token.approve(accounts[1], 100);
let allowance = await token.allowance(accounts[0], accounts[1]);
assert.equal(allowance, 100);
});
it('should return correct balances after transfer', async function () {
let token = await StandardTokenMock.new(accounts[0], 100);
await token.transfer(accounts[1], 100);
let balance0 = await token.balanceOf(accounts[0]);
assert.equal(balance0, 0);
let balance1 = await token.balanceOf(accounts[1]);
assert.equal(balance1, 100);
});
it('should throw an error when trying to transfer more than balance', async function () {
let token = await StandardTokenMock.new(accounts[0], 100);
await assertRevert(token.transfer(accounts[1], 101));
});
it('should return correct balances after transfering from another account', async function () {
let token = await StandardTokenMock.new(accounts[0], 100);
await token.approve(accounts[1], 100);
await token.transferFrom(accounts[0], accounts[2], 100, { from: accounts[1] });
let balance0 = await token.balanceOf(accounts[0]);
assert.equal(balance0, 0);
let balance1 = await token.balanceOf(accounts[2]);
assert.equal(balance1, 100);
let balance2 = await token.balanceOf(accounts[1]);
assert.equal(balance2, 0);
});
it('should throw an error when trying to transfer more than allowed', async function () {
await token.approve(accounts[1], 99);
await assertRevert(token.transferFrom(accounts[0], accounts[2], 100, { from: accounts[1] }));
});
it('should throw an error when trying to transferFrom more than _from has', async function () {
let balance0 = await token.balanceOf(accounts[0]);
await token.approve(accounts[1], 99);
await assertRevert(token.transferFrom(accounts[0], accounts[2], balance0 + 1, { from: accounts[1] }));
});
describe('validating allowance updates to spender', function () {
let preApproved;
it('should start with zero', async function () {
preApproved = await token.allowance(accounts[0], accounts[1]);
assert.equal(preApproved, 0);
});
it('should increase by 50 then decrease by 10', async function () {
await token.increaseApproval(accounts[1], 50);
let postIncrease = await token.allowance(accounts[0], accounts[1]);
preApproved.plus(50).should.be.bignumber.equal(postIncrease);
await token.decreaseApproval(accounts[1], 10);
let postDecrease = await token.allowance(accounts[0], accounts[1]);
postIncrease.minus(10).should.be.bignumber.equal(postDecrease);
});
});
it('should increase by 50 then set to 0 when decreasing by more than 50', async function () {
await token.approve(accounts[1], 50);
await token.decreaseApproval(accounts[1], 60);
let postDecrease = await token.allowance(accounts[0], accounts[1]);
postDecrease.should.be.bignumber.equal(0);
});
it('should throw an error when trying to transfer to 0x0', async function () {
let token = await StandardTokenMock.new(accounts[0], 100);
await assertRevert(token.transfer(0x0, 100));
});
it('should throw an error when trying to transferFrom to 0x0', async function () {
let token = await StandardTokenMock.new(accounts[0], 100);
await token.approve(accounts[1], 100);
await assertRevert(token.transferFrom(accounts[0], 0x0, 100, { from: accounts[1] }));
});
});

View File

@ -0,0 +1,54 @@
import latestTime from '../helpers/latestTime';
import { increaseTimeTo, duration } from '../helpers/increaseTime';
const BigNumber = web3.BigNumber;
require('chai')
.use(require('chai-as-promised'))
.use(require('chai-bignumber')(BigNumber))
.should();
const MintableToken = artifacts.require('MintableToken');
const TokenTimelock = artifacts.require('TokenTimelock');
contract('TokenTimelock', function ([_, owner, beneficiary]) {
const amount = new BigNumber(100);
beforeEach(async function () {
this.token = await MintableToken.new({ from: owner });
this.releaseTime = latestTime() + duration.years(1);
this.timelock = await TokenTimelock.new(this.token.address, beneficiary, this.releaseTime);
await this.token.mint(this.timelock.address, amount, { from: owner });
});
it('cannot be released before time limit', async function () {
await this.timelock.release().should.be.rejected;
});
it('cannot be released just before time limit', async function () {
await increaseTimeTo(this.releaseTime - duration.seconds(3));
await this.timelock.release().should.be.rejected;
});
it('can be released just after limit', async function () {
await increaseTimeTo(this.releaseTime + duration.seconds(1));
await this.timelock.release().should.be.fulfilled;
const balance = await this.token.balanceOf(beneficiary);
balance.should.be.bignumber.equal(amount);
});
it('can be released after time limit', async function () {
await increaseTimeTo(this.releaseTime + duration.years(1));
await this.timelock.release().should.be.fulfilled;
const balance = await this.token.balanceOf(beneficiary);
balance.should.be.bignumber.equal(amount);
});
it('cannot be released twice', async function () {
await increaseTimeTo(this.releaseTime + duration.years(1));
await this.timelock.release().should.be.fulfilled;
await this.timelock.release().should.be.rejected;
const balance = await this.token.balanceOf(beneficiary);
balance.should.be.bignumber.equal(amount);
});
});

View File

@ -0,0 +1,113 @@
import EVMRevert from '../helpers/EVMRevert';
import latestTime from '../helpers/latestTime';
import { increaseTimeTo, duration } from '../helpers/increaseTime';
const BigNumber = web3.BigNumber;
require('chai')
.use(require('chai-as-promised'))
.use(require('chai-bignumber')(BigNumber))
.should();
const MintableToken = artifacts.require('MintableToken');
const TokenVesting = artifacts.require('TokenVesting');
contract('TokenVesting', function ([_, owner, beneficiary]) {
const amount = new BigNumber(1000);
beforeEach(async function () {
this.token = await MintableToken.new({ from: owner });
this.start = latestTime() + duration.minutes(1); // +1 minute so it starts after contract instantiation
this.cliff = duration.years(1);
this.duration = duration.years(2);
this.vesting = await TokenVesting.new(beneficiary, this.start, this.cliff, this.duration, true, { from: owner });
await this.token.mint(this.vesting.address, amount, { from: owner });
});
it('cannot be released before cliff', async function () {
await this.vesting.release(this.token.address).should.be.rejectedWith(EVMRevert);
});
it('can be released after cliff', async function () {
await increaseTimeTo(this.start + this.cliff + duration.weeks(1));
await this.vesting.release(this.token.address).should.be.fulfilled;
});
it('should release proper amount after cliff', async function () {
await increaseTimeTo(this.start + this.cliff);
const { receipt } = await this.vesting.release(this.token.address);
const releaseTime = web3.eth.getBlock(receipt.blockNumber).timestamp;
const balance = await this.token.balanceOf(beneficiary);
balance.should.bignumber.equal(amount.mul(releaseTime - this.start).div(this.duration).floor());
});
it('should linearly release tokens during vesting period', async function () {
const vestingPeriod = this.duration - this.cliff;
const checkpoints = 4;
for (let i = 1; i <= checkpoints; i++) {
const now = this.start + this.cliff + i * (vestingPeriod / checkpoints);
await increaseTimeTo(now);
await this.vesting.release(this.token.address);
const balance = await this.token.balanceOf(beneficiary);
const expectedVesting = amount.mul(now - this.start).div(this.duration).floor();
balance.should.bignumber.equal(expectedVesting);
}
});
it('should have released all after end', async function () {
await increaseTimeTo(this.start + this.duration);
await this.vesting.release(this.token.address);
const balance = await this.token.balanceOf(beneficiary);
balance.should.bignumber.equal(amount);
});
it('should be revoked by owner if revocable is set', async function () {
await this.vesting.revoke(this.token.address, { from: owner }).should.be.fulfilled;
});
it('should fail to be revoked by owner if revocable not set', async function () {
const vesting = await TokenVesting.new(beneficiary, this.start, this.cliff, this.duration, false, { from: owner });
await vesting.revoke(this.token.address, { from: owner }).should.be.rejectedWith(EVMRevert);
});
it('should return the non-vested tokens when revoked by owner', async function () {
await increaseTimeTo(this.start + this.cliff + duration.weeks(12));
const vested = await this.vesting.vestedAmount(this.token.address);
await this.vesting.revoke(this.token.address, { from: owner });
const ownerBalance = await this.token.balanceOf(owner);
ownerBalance.should.bignumber.equal(amount.sub(vested));
});
it('should keep the vested tokens when revoked by owner', async function () {
await increaseTimeTo(this.start + this.cliff + duration.weeks(12));
const vestedPre = await this.vesting.vestedAmount(this.token.address);
await this.vesting.revoke(this.token.address, { from: owner });
const vestedPost = await this.vesting.vestedAmount(this.token.address);
vestedPre.should.bignumber.equal(vestedPost);
});
it('should fail to be revoked a second time', async function () {
await increaseTimeTo(this.start + this.cliff + duration.weeks(12));
await this.vesting.vestedAmount(this.token.address);
await this.vesting.revoke(this.token.address, { from: owner });
await this.vesting.revoke(this.token.address, { from: owner }).should.be.rejectedWith(EVMRevert);
});
});