Increase test coverage (#1237)
* Fixed a SplitPayment test * Deleted unnecessary function. * Improved PostDeliveryCrowdsale tests. * Improved RefundableCrowdsale tests. * Improved MintedCrowdsale tests. * Improved IncreasingPriceCrowdsale tests. * Fixed a CappedCrowdsale test. * Improved TimedCrowdsale tests. * Improved descriptions of added tests.
This commit is contained in:
committed by
Francisco Giordano
parent
a466e76d26
commit
a9f910d34f
@ -22,8 +22,8 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale {
|
||||
* @param _finalRate Number of tokens a buyer gets per wei at the end of the crowdsale
|
||||
*/
|
||||
constructor(uint256 _initialRate, uint256 _finalRate) public {
|
||||
require(_initialRate >= _finalRate);
|
||||
require(_finalRate > 0);
|
||||
require(_initialRate >= _finalRate);
|
||||
initialRate = _initialRate;
|
||||
finalRate = _finalRate;
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ contract Heritable is Ownable {
|
||||
* before the heir can take ownership.
|
||||
*/
|
||||
constructor(uint256 _heartbeatTimeout) public {
|
||||
setHeartbeatTimeout(_heartbeatTimeout);
|
||||
heartbeatTimeout_ = _heartbeatTimeout;
|
||||
}
|
||||
|
||||
function setHeir(address _newHeir) public onlyOwner {
|
||||
@ -113,13 +113,6 @@ contract Heritable is Ownable {
|
||||
timeOfDeath_ = 0;
|
||||
}
|
||||
|
||||
function setHeartbeatTimeout(uint256 _newHeartbeatTimeout)
|
||||
internal onlyOwner
|
||||
{
|
||||
require(ownerLives());
|
||||
heartbeatTimeout_ = _newHeartbeatTimeout;
|
||||
}
|
||||
|
||||
function ownerLives() internal view returns (bool) {
|
||||
return timeOfDeath_ == 0;
|
||||
}
|
||||
|
||||
@ -19,17 +19,19 @@ contract('CappedCrowdsale', function ([_, wallet]) {
|
||||
|
||||
beforeEach(async function () {
|
||||
this.token = await SimpleToken.new();
|
||||
this.crowdsale = await CappedCrowdsale.new(rate, wallet, this.token.address, cap);
|
||||
await this.token.transfer(this.crowdsale.address, tokenSupply);
|
||||
});
|
||||
|
||||
describe('creating a valid crowdsale', function () {
|
||||
it('should fail with zero cap', async function () {
|
||||
it('rejects a cap of zero', async function () {
|
||||
await expectThrow(
|
||||
CappedCrowdsale.new(rate, wallet, 0, this.token.address),
|
||||
CappedCrowdsale.new(rate, wallet, this.token.address, 0),
|
||||
EVMRevert,
|
||||
);
|
||||
});
|
||||
|
||||
context('with crowdsale', function () {
|
||||
beforeEach(async function () {
|
||||
this.crowdsale = await CappedCrowdsale.new(rate, wallet, this.token.address, cap);
|
||||
await this.token.transfer(this.crowdsale.address, tokenSupply);
|
||||
});
|
||||
|
||||
describe('accepting payments', function () {
|
||||
@ -71,3 +73,4 @@ contract('CappedCrowdsale', function ([_, wallet]) {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -2,6 +2,7 @@ const { ether } = require('../helpers/ether');
|
||||
const { advanceBlock } = require('../helpers/advanceToBlock');
|
||||
const { increaseTimeTo, duration } = require('../helpers/increaseTime');
|
||||
const { latestTime } = require('../helpers/latestTime');
|
||||
const { assertRevert } = require('../helpers/assertRevert');
|
||||
|
||||
const BigNumber = web3.BigNumber;
|
||||
|
||||
@ -32,6 +33,22 @@ contract('IncreasingPriceCrowdsale', function ([_, investor, wallet, purchaser])
|
||||
this.closingTime = this.startTime + duration.weeks(1);
|
||||
this.afterClosingTime = this.closingTime + duration.seconds(1);
|
||||
this.token = await SimpleToken.new();
|
||||
});
|
||||
|
||||
it('rejects a final rate larger than the initial rate', async function () {
|
||||
await assertRevert(IncreasingPriceCrowdsale.new(
|
||||
this.startTime, this.closingTime, wallet, this.token.address, initialRate, initialRate.plus(1)
|
||||
));
|
||||
});
|
||||
|
||||
it('rejects a final rate of zero', async function () {
|
||||
await assertRevert(IncreasingPriceCrowdsale.new(
|
||||
this.startTime, this.closingTime, wallet, this.token.address, initialRate, 0
|
||||
));
|
||||
});
|
||||
|
||||
context('with crowdsale', function () {
|
||||
beforeEach(async function () {
|
||||
this.crowdsale = await IncreasingPriceCrowdsale.new(
|
||||
this.startTime, this.closingTime, wallet, this.token.address, initialRate, finalRate
|
||||
);
|
||||
@ -81,3 +98,4 @@ contract('IncreasingPriceCrowdsale', function ([_, investor, wallet, purchaser])
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
const { shouldBehaveLikeMintedCrowdsale } = require('./MintedCrowdsale.behavior');
|
||||
const { ether } = require('../helpers/ether');
|
||||
const { assertRevert } = require('../helpers/assertRevert');
|
||||
|
||||
const BigNumber = web3.BigNumber;
|
||||
|
||||
const MintedCrowdsale = artifacts.require('MintedCrowdsaleImpl');
|
||||
const MintableToken = artifacts.require('MintableToken');
|
||||
const RBACMintableToken = artifacts.require('RBACMintableToken');
|
||||
const StandardToken = artifacts.require('StandardToken');
|
||||
|
||||
contract('MintedCrowdsale', function ([_, investor, wallet, purchaser]) {
|
||||
const rate = new BigNumber(1000);
|
||||
@ -40,4 +42,19 @@ contract('MintedCrowdsale', function ([_, investor, wallet, purchaser]) {
|
||||
|
||||
shouldBehaveLikeMintedCrowdsale([_, investor, wallet, purchaser], rate, value);
|
||||
});
|
||||
|
||||
describe('using non-mintable token', function () {
|
||||
beforeEach(async function () {
|
||||
this.token = await StandardToken.new();
|
||||
this.crowdsale = await MintedCrowdsale.new(rate, wallet, this.token.address);
|
||||
});
|
||||
|
||||
it('rejects bare payments', async function () {
|
||||
await assertRevert(this.crowdsale.send(value));
|
||||
});
|
||||
|
||||
it('rejects token purchases', async function () {
|
||||
await assertRevert(this.crowdsale.buyTokens(investor, { value: value, from: purchaser }));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -16,7 +16,6 @@ const SimpleToken = artifacts.require('SimpleToken');
|
||||
|
||||
contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) {
|
||||
const rate = new BigNumber(1);
|
||||
const value = ether(42);
|
||||
const tokenSupply = new BigNumber('1e22');
|
||||
|
||||
before(async function () {
|
||||
@ -27,7 +26,6 @@ contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) {
|
||||
beforeEach(async function () {
|
||||
this.openingTime = (await latestTime()) + duration.weeks(1);
|
||||
this.closingTime = this.openingTime + duration.weeks(1);
|
||||
this.beforeEndTime = this.closingTime - duration.hours(1);
|
||||
this.afterClosingTime = this.closingTime + duration.seconds(1);
|
||||
this.token = await SimpleToken.new();
|
||||
this.crowdsale = await PostDeliveryCrowdsale.new(
|
||||
@ -36,30 +34,41 @@ contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) {
|
||||
await this.token.transfer(this.crowdsale.address, tokenSupply);
|
||||
});
|
||||
|
||||
it('should not immediately assign tokens to beneficiary', async function () {
|
||||
context('after opening time', function () {
|
||||
beforeEach(async function () {
|
||||
await increaseTimeTo(this.openingTime);
|
||||
});
|
||||
|
||||
context('with bought tokens', function () {
|
||||
const value = ether(42);
|
||||
|
||||
beforeEach(async function () {
|
||||
await this.crowdsale.buyTokens(investor, { value: value, from: purchaser });
|
||||
});
|
||||
|
||||
it('does not immediately assign tokens to beneficiaries', async function () {
|
||||
(await this.token.balanceOf(investor)).should.be.bignumber.equal(0);
|
||||
});
|
||||
|
||||
it('should not allow beneficiaries to withdraw tokens before crowdsale ends', async function () {
|
||||
await increaseTimeTo(this.beforeEndTime);
|
||||
await this.crowdsale.buyTokens(investor, { value: value, from: purchaser });
|
||||
it('does not allow beneficiaries to withdraw tokens before crowdsale ends', async function () {
|
||||
await expectThrow(this.crowdsale.withdrawTokens({ from: investor }), EVMRevert);
|
||||
});
|
||||
|
||||
it('should allow beneficiaries to withdraw tokens after crowdsale ends', async function () {
|
||||
await increaseTimeTo(this.openingTime);
|
||||
await this.crowdsale.buyTokens(investor, { value: value, from: purchaser });
|
||||
context('after closing time', function () {
|
||||
beforeEach(async function () {
|
||||
await increaseTimeTo(this.afterClosingTime);
|
||||
await this.crowdsale.withdrawTokens({ from: investor });
|
||||
});
|
||||
|
||||
it('should return the amount of tokens bought', async function () {
|
||||
await increaseTimeTo(this.openingTime);
|
||||
await this.crowdsale.buyTokens(investor, { value: value, from: purchaser });
|
||||
await increaseTimeTo(this.afterClosingTime);
|
||||
it('allows beneficiaries to withdraw tokens', async function () {
|
||||
await this.crowdsale.withdrawTokens({ from: investor });
|
||||
(await this.token.balanceOf(investor)).should.be.bignumber.equal(value);
|
||||
});
|
||||
|
||||
it('rejects multiple withdrawals', async function () {
|
||||
await this.crowdsale.withdrawTokens({ from: investor });
|
||||
await expectThrow(this.crowdsale.withdrawTokens({ from: investor }), EVMRevert);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -30,16 +30,12 @@ contract('RefundableCrowdsale', function ([_, owner, wallet, investor, purchaser
|
||||
this.openingTime = (await latestTime()) + duration.weeks(1);
|
||||
this.closingTime = this.openingTime + duration.weeks(1);
|
||||
this.afterClosingTime = this.closingTime + duration.seconds(1);
|
||||
this.preWalletBalance = await ethGetBalance(wallet);
|
||||
|
||||
this.token = await SimpleToken.new();
|
||||
this.crowdsale = await RefundableCrowdsale.new(
|
||||
this.openingTime, this.closingTime, rate, wallet, this.token.address, goal, { from: owner }
|
||||
);
|
||||
await this.token.transfer(this.crowdsale.address, tokenSupply);
|
||||
});
|
||||
|
||||
describe('creating a valid crowdsale', function () {
|
||||
it('should fail with zero goal', async function () {
|
||||
it('rejects a goal of zero', async function () {
|
||||
await expectThrow(
|
||||
RefundableCrowdsale.new(
|
||||
this.openingTime, this.closingTime, rate, wallet, this.token.address, 0, { from: owner }
|
||||
@ -47,39 +43,72 @@ contract('RefundableCrowdsale', function ([_, owner, wallet, investor, purchaser
|
||||
EVMRevert,
|
||||
);
|
||||
});
|
||||
|
||||
context('with crowdsale', function () {
|
||||
beforeEach(async function () {
|
||||
this.crowdsale = await RefundableCrowdsale.new(
|
||||
this.openingTime, this.closingTime, rate, wallet, this.token.address, goal, { from: owner }
|
||||
);
|
||||
|
||||
await this.token.transfer(this.crowdsale.address, tokenSupply);
|
||||
});
|
||||
|
||||
it('should deny refunds before end', async function () {
|
||||
context('before opening time', function () {
|
||||
it('denies refunds', async function () {
|
||||
await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert);
|
||||
});
|
||||
});
|
||||
|
||||
context('after opening time', function () {
|
||||
beforeEach(async function () {
|
||||
await increaseTimeTo(this.openingTime);
|
||||
});
|
||||
|
||||
it('denies refunds', async function () {
|
||||
await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert);
|
||||
});
|
||||
|
||||
it('should deny refunds after end if goal was reached', async function () {
|
||||
await increaseTimeTo(this.openingTime);
|
||||
await this.crowdsale.sendTransaction({ value: goal, from: investor });
|
||||
await increaseTimeTo(this.afterClosingTime);
|
||||
await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert);
|
||||
});
|
||||
|
||||
it('should allow refunds after end if goal was not reached', async function () {
|
||||
await increaseTimeTo(this.openingTime);
|
||||
context('with unreached goal', function () {
|
||||
beforeEach(async function () {
|
||||
await this.crowdsale.sendTransaction({ value: lessThanGoal, from: investor });
|
||||
});
|
||||
|
||||
context('after closing time and finalization', function () {
|
||||
beforeEach(async function () {
|
||||
await increaseTimeTo(this.afterClosingTime);
|
||||
await this.crowdsale.finalize({ from: owner });
|
||||
});
|
||||
|
||||
it('refunds', async function () {
|
||||
const pre = await ethGetBalance(investor);
|
||||
await this.crowdsale.claimRefund({ from: investor, gasPrice: 0 });
|
||||
const post = await ethGetBalance(investor);
|
||||
post.minus(pre).should.be.bignumber.equal(lessThanGoal);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should forward funds to wallet after end if goal was reached', async function () {
|
||||
await increaseTimeTo(this.openingTime);
|
||||
context('with reached goal', function () {
|
||||
beforeEach(async function () {
|
||||
await this.crowdsale.sendTransaction({ value: goal, from: investor });
|
||||
});
|
||||
|
||||
context('after closing time and finalization', function () {
|
||||
beforeEach(async function () {
|
||||
await increaseTimeTo(this.afterClosingTime);
|
||||
const pre = await ethGetBalance(wallet);
|
||||
await this.crowdsale.finalize({ from: owner });
|
||||
const post = await ethGetBalance(wallet);
|
||||
post.minus(pre).should.be.bignumber.equal(goal);
|
||||
});
|
||||
|
||||
it('denies refunds', async function () {
|
||||
await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert);
|
||||
});
|
||||
|
||||
it('forwards funds to wallet', async function () {
|
||||
const postWalletBalance = await ethGetBalance(wallet);
|
||||
postWalletBalance.minus(this.preWalletBalance).should.be.bignumber.equal(goal);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -29,6 +29,22 @@ contract('TimedCrowdsale', function ([_, investor, wallet, purchaser]) {
|
||||
this.closingTime = this.openingTime + duration.weeks(1);
|
||||
this.afterClosingTime = this.closingTime + duration.seconds(1);
|
||||
this.token = await SimpleToken.new();
|
||||
});
|
||||
|
||||
it('rejects an opening time in the past', async function () {
|
||||
await expectThrow(TimedCrowdsale.new(
|
||||
(await latestTime()) - duration.days(1), this.closingTime, rate, wallet, this.token.address
|
||||
), EVMRevert);
|
||||
});
|
||||
|
||||
it('rejects a closing time before the opening time', async function () {
|
||||
await expectThrow(TimedCrowdsale.new(
|
||||
this.openingTime, this.openingTime - duration.seconds(1), rate, wallet, this.token.address
|
||||
), EVMRevert);
|
||||
});
|
||||
|
||||
context('with crowdsale', function () {
|
||||
beforeEach(async function () {
|
||||
this.crowdsale = await TimedCrowdsale.new(this.openingTime, this.closingTime, rate, wallet, this.token.address);
|
||||
await this.token.transfer(this.crowdsale.address, tokenSupply);
|
||||
});
|
||||
@ -58,3 +74,4 @@ contract('TimedCrowdsale', function ([_, investor, wallet, purchaser]) {
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -14,28 +14,28 @@ contract('SplitPayment', function ([_, owner, payee1, payee2, payee3, nonpayee1,
|
||||
const amount = web3.toWei(1.0, 'ether');
|
||||
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
|
||||
it('cannot be created with no payees', async function () {
|
||||
it('rejects an empty set of payees', async function () {
|
||||
await expectThrow(SplitPayment.new([], []), EVMRevert);
|
||||
});
|
||||
|
||||
it('requires shares for each payee', async function () {
|
||||
it('rejects more payees than shares', async function () {
|
||||
await expectThrow(SplitPayment.new([payee1, payee2, payee3], [20, 30]), EVMRevert);
|
||||
});
|
||||
|
||||
it('requires a payee for each share', async function () {
|
||||
it('rejects more shares than payees', async function () {
|
||||
await expectThrow(SplitPayment.new([payee1, payee2], [20, 30, 40]), EVMRevert);
|
||||
});
|
||||
|
||||
it('requires non-null payees', async function () {
|
||||
it('rejects null payees', async function () {
|
||||
await expectThrow(SplitPayment.new([payee1, ZERO_ADDRESS], [20, 30]), EVMRevert);
|
||||
});
|
||||
|
||||
it('requires non-zero shares', async function () {
|
||||
it('rejects zero-valued shares', async function () {
|
||||
await expectThrow(SplitPayment.new([payee1, payee2], [20, 0]), EVMRevert);
|
||||
});
|
||||
|
||||
it('rejects repeated payees', async function () {
|
||||
await expectThrow(SplitPayment.new([payee1, payee1], [20, 0]), EVMRevert);
|
||||
await expectThrow(SplitPayment.new([payee1, payee1], [20, 30]), EVMRevert);
|
||||
});
|
||||
|
||||
context('once deployed', function () {
|
||||
|
||||
Reference in New Issue
Block a user