Browse Source

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.
Nicolás Venturo 7 years ago
parent
commit
a9f910d34f

+ 1 - 1
contracts/crowdsale/price/IncreasingPriceCrowdsale.sol

@@ -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;
   }

+ 1 - 8
contracts/ownership/Heritable.sol

@@ -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;
   }

+ 41 - 38
test/crowdsale/CappedCrowdsale.test.js

@@ -19,55 +19,58 @@ 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 () {
-      await expectThrow(
-        CappedCrowdsale.new(rate, wallet, 0, this.token.address),
-        EVMRevert,
-      );
-    });
+  it('rejects a cap of zero', async function () {
+    await expectThrow(
+      CappedCrowdsale.new(rate, wallet, this.token.address, 0),
+      EVMRevert,
+    );
   });
 
-  describe('accepting payments', function () {
-    it('should accept payments within cap', async function () {
-      await this.crowdsale.send(cap.minus(lessThanCap));
-      await this.crowdsale.send(lessThanCap);
+  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);
     });
 
-    it('should reject payments outside cap', async function () {
-      await this.crowdsale.send(cap);
-      await expectThrow(
-        this.crowdsale.send(1),
-        EVMRevert,
-      );
-    });
+    describe('accepting payments', function () {
+      it('should accept payments within cap', async function () {
+        await this.crowdsale.send(cap.minus(lessThanCap));
+        await this.crowdsale.send(lessThanCap);
+      });
 
-    it('should reject payments that exceed cap', async function () {
-      await expectThrow(
-        this.crowdsale.send(cap.plus(1)),
-        EVMRevert,
-      );
-    });
-  });
+      it('should reject payments outside cap', async function () {
+        await this.crowdsale.send(cap);
+        await expectThrow(
+          this.crowdsale.send(1),
+          EVMRevert,
+        );
+      });
 
-  describe('ending', function () {
-    it('should not reach cap if sent under cap', async function () {
-      await this.crowdsale.send(lessThanCap);
-      (await this.crowdsale.capReached()).should.equal(false);
+      it('should reject payments that exceed cap', async function () {
+        await expectThrow(
+          this.crowdsale.send(cap.plus(1)),
+          EVMRevert,
+        );
+      });
     });
 
-    it('should not reach cap if sent just under cap', async function () {
-      await this.crowdsale.send(cap.minus(1));
-      (await this.crowdsale.capReached()).should.equal(false);
-    });
+    describe('ending', function () {
+      it('should not reach cap if sent under cap', async function () {
+        await this.crowdsale.send(lessThanCap);
+        (await this.crowdsale.capReached()).should.equal(false);
+      });
+
+      it('should not reach cap if sent just under cap', async function () {
+        await this.crowdsale.send(cap.minus(1));
+        (await this.crowdsale.capReached()).should.equal(false);
+      });
 
-    it('should reach cap if cap sent', async function () {
-      await this.crowdsale.send(cap);
-      (await this.crowdsale.capReached()).should.equal(true);
+      it('should reach cap if cap sent', async function () {
+        await this.crowdsale.send(cap);
+        (await this.crowdsale.capReached()).should.equal(true);
+      });
     });
   });
 });

+ 54 - 36
test/crowdsale/IncreasingPriceCrowdsale.test.js

@@ -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,52 +33,69 @@ 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();
-      this.crowdsale = await IncreasingPriceCrowdsale.new(
-        this.startTime, this.closingTime, wallet, this.token.address, initialRate, finalRate
-      );
-      await this.token.transfer(this.crowdsale.address, tokenSupply);
     });
 
-    it('at start', async function () {
-      await increaseTimeTo(this.startTime);
-      await this.crowdsale.buyTokens(investor, { value, from: purchaser });
-      (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(initialRate));
+    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('at time 150', async function () {
-      await increaseTimeTo(this.startTime + 150);
-      await this.crowdsale.buyTokens(investor, { value, from: purchaser });
-      (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime150));
+    it('rejects a final rate of zero', async function () {
+      await assertRevert(IncreasingPriceCrowdsale.new(
+        this.startTime, this.closingTime, wallet, this.token.address, initialRate, 0
+      ));
     });
 
-    it('at time 300', async function () {
-      await increaseTimeTo(this.startTime + 300);
-      await this.crowdsale.buyTokens(investor, { value, from: purchaser });
-      (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime300));
-    });
+    context('with crowdsale', function () {
+      beforeEach(async function () {
+        this.crowdsale = await IncreasingPriceCrowdsale.new(
+          this.startTime, this.closingTime, wallet, this.token.address, initialRate, finalRate
+        );
+        await this.token.transfer(this.crowdsale.address, tokenSupply);
+      });
 
-    it('at time 1500', async function () {
-      await increaseTimeTo(this.startTime + 1500);
-      await this.crowdsale.buyTokens(investor, { value, from: purchaser });
-      (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime1500));
-    });
+      it('at start', async function () {
+        await increaseTimeTo(this.startTime);
+        await this.crowdsale.buyTokens(investor, { value, from: purchaser });
+        (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(initialRate));
+      });
 
-    it('at time 30', async function () {
-      await increaseTimeTo(this.startTime + 30);
-      await this.crowdsale.buyTokens(investor, { value, from: purchaser });
-      (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime30));
-    });
+      it('at time 150', async function () {
+        await increaseTimeTo(this.startTime + 150);
+        await this.crowdsale.buyTokens(investor, { value, from: purchaser });
+        (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime150));
+      });
 
-    it('at time 150000', async function () {
-      await increaseTimeTo(this.startTime + 150000);
-      await this.crowdsale.buyTokens(investor, { value, from: purchaser });
-      (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime150000));
-    });
+      it('at time 300', async function () {
+        await increaseTimeTo(this.startTime + 300);
+        await this.crowdsale.buyTokens(investor, { value, from: purchaser });
+        (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime300));
+      });
+
+      it('at time 1500', async function () {
+        await increaseTimeTo(this.startTime + 1500);
+        await this.crowdsale.buyTokens(investor, { value, from: purchaser });
+        (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime1500));
+      });
+
+      it('at time 30', async function () {
+        await increaseTimeTo(this.startTime + 30);
+        await this.crowdsale.buyTokens(investor, { value, from: purchaser });
+        (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime30));
+      });
+
+      it('at time 150000', async function () {
+        await increaseTimeTo(this.startTime + 150000);
+        await this.crowdsale.buyTokens(investor, { value, from: purchaser });
+        (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime150000));
+      });
 
-    it('at time 450000', async function () {
-      await increaseTimeTo(this.startTime + 450000);
-      await this.crowdsale.buyTokens(investor, { value, from: purchaser });
-      (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime450000));
+      it('at time 450000', async function () {
+        await increaseTimeTo(this.startTime + 450000);
+        await this.crowdsale.buyTokens(investor, { value, from: purchaser });
+        (await this.token.balanceOf(investor)).should.be.bignumber.equal(value.mul(rateAtTime450000));
+      });
     });
   });
 });

+ 17 - 0
test/crowdsale/MintedCrowdsale.test.js

@@ -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 }));
+    });
+  });
 });

+ 33 - 24
test/crowdsale/PostDeliveryCrowdsale.test.js

@@ -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 () {
-    await increaseTimeTo(this.openingTime);
-    await this.crowdsale.buyTokens(investor, { value: value, from: purchaser });
-    (await this.token.balanceOf(investor)).should.be.bignumber.equal(0);
-  });
+  context('after opening time', function () {
+    beforeEach(async function () {
+      await increaseTimeTo(this.openingTime);
+    });
 
-  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 });
-    await expectThrow(this.crowdsale.withdrawTokens({ from: investor }), EVMRevert);
-  });
+    context('with bought tokens', function () {
+      const value = ether(42);
 
-  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 });
-    await increaseTimeTo(this.afterClosingTime);
-    await this.crowdsale.withdrawTokens({ from: investor });
-  });
+      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('does not allow beneficiaries to withdraw tokens before crowdsale ends', async function () {
+        await expectThrow(this.crowdsale.withdrawTokens({ from: investor }), EVMRevert);
+      });
+
+      context('after closing time', function () {
+        beforeEach(async function () {
+          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('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);
-    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);
+        });
+      });
+    });
   });
 });

+ 69 - 40
test/crowdsale/RefundableCrowdsale.test.js

@@ -30,56 +30,85 @@ 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 }
+  });
+
+  it('rejects a goal of zero', async function () {
+    await expectThrow(
+      RefundableCrowdsale.new(
+        this.openingTime, this.closingTime, rate, wallet, this.token.address, 0, { from: owner }
+      ),
+      EVMRevert,
     );
-    await this.token.transfer(this.crowdsale.address, tokenSupply);
   });
 
-  describe('creating a valid crowdsale', function () {
-    it('should fail with zero goal', async function () {
-      await expectThrow(
-        RefundableCrowdsale.new(
-          this.openingTime, this.closingTime, rate, wallet, this.token.address, 0, { from: owner }
-        ),
-        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 () {
-    await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert);
-    await increaseTimeTo(this.openingTime);
-    await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert);
-  });
+    context('before opening time', function () {
+      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);
-  });
+    context('after opening time', function () {
+      beforeEach(async function () {
+        await increaseTimeTo(this.openingTime);
+      });
 
-  it('should allow refunds after end if goal was not reached', async function () {
-    await increaseTimeTo(this.openingTime);
-    await this.crowdsale.sendTransaction({ value: lessThanGoal, from: investor });
-    await increaseTimeTo(this.afterClosingTime);
-    await this.crowdsale.finalize({ from: owner });
-    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('denies refunds', async function () {
+        await expectThrow(this.crowdsale.claimRefund({ from: investor }), EVMRevert);
+      });
 
-  it('should forward funds to wallet after end if goal was reached', async function () {
-    await increaseTimeTo(this.openingTime);
-    await this.crowdsale.sendTransaction({ value: goal, from: investor });
-    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);
+      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);
+          });
+        });
+      });
+
+      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);
+            await this.crowdsale.finalize({ from: owner });
+          });
+
+          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);
+          });
+        });
+      });
+    });
   });
 });

+ 35 - 18
test/crowdsale/TimedCrowdsale.test.js

@@ -29,32 +29,49 @@ 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();
-    this.crowdsale = await TimedCrowdsale.new(this.openingTime, this.closingTime, rate, wallet, this.token.address);
-    await this.token.transfer(this.crowdsale.address, tokenSupply);
   });
 
-  it('should be ended only after end', async function () {
-    (await this.crowdsale.hasClosed()).should.equal(false);
-    await increaseTimeTo(this.afterClosingTime);
-    (await this.crowdsale.hasClosed()).should.equal(true);
+  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);
   });
 
-  describe('accepting payments', function () {
-    it('should reject payments before start', async function () {
-      await expectThrow(this.crowdsale.send(value), EVMRevert);
-      await expectThrow(this.crowdsale.buyTokens(investor, { from: purchaser, value: value }), 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);
+  });
 
-    it('should accept payments after start', async function () {
-      await increaseTimeTo(this.openingTime);
-      await this.crowdsale.send(value);
-      await this.crowdsale.buyTokens(investor, { value: value, from: purchaser });
+  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);
     });
 
-    it('should reject payments after end', async function () {
+    it('should be ended only after end', async function () {
+      (await this.crowdsale.hasClosed()).should.equal(false);
       await increaseTimeTo(this.afterClosingTime);
-      await expectThrow(this.crowdsale.send(value), EVMRevert);
-      await expectThrow(this.crowdsale.buyTokens(investor, { value: value, from: purchaser }), EVMRevert);
+      (await this.crowdsale.hasClosed()).should.equal(true);
+    });
+
+    describe('accepting payments', function () {
+      it('should reject payments before start', async function () {
+        await expectThrow(this.crowdsale.send(value), EVMRevert);
+        await expectThrow(this.crowdsale.buyTokens(investor, { from: purchaser, value: value }), EVMRevert);
+      });
+
+      it('should accept payments after start', async function () {
+        await increaseTimeTo(this.openingTime);
+        await this.crowdsale.send(value);
+        await this.crowdsale.buyTokens(investor, { value: value, from: purchaser });
+      });
+
+      it('should reject payments after end', async function () {
+        await increaseTimeTo(this.afterClosingTime);
+        await expectThrow(this.crowdsale.send(value), EVMRevert);
+        await expectThrow(this.crowdsale.buyTokens(investor, { value: value, from: purchaser }), EVMRevert);
+      });
     });
   });
 });

+ 6 - 6
test/payment/SplitPayment.test.js

@@ -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 () {