diff --git a/contracts/mocks/RBACCappedTokenMock.sol b/contracts/mocks/RBACCappedTokenMock.sol new file mode 100644 index 000000000..9a30ba05d --- /dev/null +++ b/contracts/mocks/RBACCappedTokenMock.sol @@ -0,0 +1,13 @@ +pragma solidity ^0.4.23; + +import "../token/ERC20/RBACMintableToken.sol"; +import "../token/ERC20/CappedToken.sol"; + +contract RBACCappedTokenMock is CappedToken, RBACMintableToken { + constructor( + uint256 _cap + ) + CappedToken(_cap) + public + {} +} \ No newline at end of file diff --git a/contracts/token/ERC20/CappedToken.sol b/contracts/token/ERC20/CappedToken.sol index d8e67ac63..1e1df4b15 100644 --- a/contracts/token/ERC20/CappedToken.sol +++ b/contracts/token/ERC20/CappedToken.sol @@ -26,8 +26,6 @@ contract CappedToken is MintableToken { address _to, uint256 _amount ) - onlyOwner - canMint public returns (bool) { diff --git a/test/token/ERC20/CappedToken.behaviour.js b/test/token/ERC20/CappedToken.behaviour.js new file mode 100644 index 000000000..9dadc40f2 --- /dev/null +++ b/test/token/ERC20/CappedToken.behaviour.js @@ -0,0 +1,28 @@ +import expectThrow from '../../helpers/expectThrow'; + +export default function ([owner, anotherAccount, minter, cap]) { + describe('capped token', function () { + const from = minter; + + it('should start with the correct cap', async function () { + let _cap = await this.token.cap(); + + assert(cap.eq(_cap)); + }); + + it('should mint when amount is less than cap', async function () { + const result = await this.token.mint(owner, cap.sub(1), { from }); + assert.equal(result.logs[0].event, 'Mint'); + }); + + it('should fail to mint if the ammount exceeds the cap', async function () { + await this.token.mint(owner, cap.sub(1), { from }); + await expectThrow(this.token.mint(owner, 100, { from })); + }); + + it('should fail to mint after cap is reached', async function () { + await this.token.mint(owner, cap, { from }); + await expectThrow(this.token.mint(owner, 1, { from })); + }); + }); +} diff --git a/test/token/ERC20/CappedToken.test.js b/test/token/ERC20/CappedToken.test.js index c3fa5af6b..4eae4b800 100644 --- a/test/token/ERC20/CappedToken.test.js +++ b/test/token/ERC20/CappedToken.test.js @@ -1,36 +1,17 @@ - -import expectThrow from '../../helpers/expectThrow'; import ether from '../../helpers/ether'; +import shouldBehaveLikeMintableToken from './MintableToken.behaviour'; +import shouldBehaveLikeCappedToken from './CappedToken.behaviour'; var CappedToken = artifacts.require('CappedToken'); -contract('Capped', function (accounts) { - const cap = ether(1000); - - let token; - +contract('Capped', function ([owner, anotherAccount]) { + const _cap = ether(1000); + beforeEach(async function () { - token = await CappedToken.new(cap); + this.token = await CappedToken.new(_cap, { from: owner }); }); - it('should start with the correct cap', async function () { - let _cap = await token.cap(); + shouldBehaveLikeCappedToken([owner, anotherAccount, owner, _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)); - }); + shouldBehaveLikeMintableToken([owner, anotherAccount, owner]); }); diff --git a/test/token/ERC20/RBACCappedToken.test.js b/test/token/ERC20/RBACCappedToken.test.js new file mode 100644 index 000000000..2bf915714 --- /dev/null +++ b/test/token/ERC20/RBACCappedToken.test.js @@ -0,0 +1,19 @@ +import ether from '../../helpers/ether'; +import shouldBehaveLikeRBACMintableToken from './RBACMintableToken.behaviour'; +import shouldBehaveLikeMintableToken from './MintableToken.behaviour'; +import shouldBehaveLikeCappedToken from './CappedToken.behaviour'; + +const RBACCappedTokenMock = artifacts.require('RBACCappedTokenMock'); + +contract('RBACCappedToken', function ([owner, anotherAccount, minter]) { + const _cap = ether(1000); + + beforeEach(async function () { + this.token = await RBACCappedTokenMock.new(_cap, { from: owner }); + await this.token.addMinter(minter, { from: owner }); + }); + + shouldBehaveLikeMintableToken([owner, anotherAccount, minter]); + shouldBehaveLikeRBACMintableToken([owner, anotherAccount]); + shouldBehaveLikeCappedToken([owner, anotherAccount, minter, _cap]); +}); diff --git a/test/token/ERC20/RBACMintableToken.behaviour.js b/test/token/ERC20/RBACMintableToken.behaviour.js new file mode 100644 index 000000000..006e2e06b --- /dev/null +++ b/test/token/ERC20/RBACMintableToken.behaviour.js @@ -0,0 +1,28 @@ +import expectThrow from '../../helpers/expectThrow'; + +const ROLE_MINTER = 'minter'; + +export default function ([owner, anotherAccount]) { + describe('handle roles', function () { + it('owner can add and remove a minter role', async function () { + await this.token.addMinter(anotherAccount, { from: owner }); + let hasRole = await this.token.hasRole(anotherAccount, ROLE_MINTER); + assert.equal(hasRole, true); + + await this.token.removeMinter(anotherAccount, { from: owner }); + hasRole = await this.token.hasRole(anotherAccount, ROLE_MINTER); + assert.equal(hasRole, false); + }); + + it('another account can\'t add or remove a minter role', async function () { + await expectThrow( + this.token.addMinter(anotherAccount, { from: anotherAccount }) + ); + + await this.token.addMinter(anotherAccount, { from: owner }); + await expectThrow( + this.token.removeMinter(anotherAccount, { from: anotherAccount }) + ); + }); + }); +}; diff --git a/test/token/ERC20/RBACMintableToken.test.js b/test/token/ERC20/RBACMintableToken.test.js index fafca745d..ff95b4a5a 100644 --- a/test/token/ERC20/RBACMintableToken.test.js +++ b/test/token/ERC20/RBACMintableToken.test.js @@ -1,8 +1,7 @@ -import expectThrow from '../../helpers/expectThrow'; +import shouldBehaveLikeRBACMintableToken from './RBACMintableToken.behaviour'; import shouldBehaveLikeMintableToken from './MintableToken.behaviour'; -const RBACMintableToken = artifacts.require('RBACMintableToken'); -const ROLE_MINTER = 'minter'; +const RBACMintableToken = artifacts.require('RBACMintableToken'); contract('RBACMintableToken', function ([owner, anotherAccount, minter]) { beforeEach(async function () { @@ -10,28 +9,6 @@ contract('RBACMintableToken', function ([owner, anotherAccount, minter]) { await this.token.addMinter(minter, { from: owner }); }); - describe('handle roles', function () { - it('owner can add and remove a minter role', async function () { - await this.token.addMinter(anotherAccount, { from: owner }); - let hasRole = await this.token.hasRole(anotherAccount, ROLE_MINTER); - assert.equal(hasRole, true); - - await this.token.removeMinter(anotherAccount, { from: owner }); - hasRole = await this.token.hasRole(anotherAccount, ROLE_MINTER); - assert.equal(hasRole, false); - }); - - it('another account can\'t add or remove a minter role', async function () { - await expectThrow( - this.token.addMinter(anotherAccount, { from: anotherAccount }) - ); - - await this.token.addMinter(anotherAccount, { from: owner }); - await expectThrow( - this.token.removeMinter(anotherAccount, { from: anotherAccount }) - ); - }); - }); - + shouldBehaveLikeRBACMintableToken([owner, anotherAccount, minter]); shouldBehaveLikeMintableToken([owner, anotherAccount, minter]); });