Skip to content

Commit

Permalink
Apps: Use shared TimeHelpersMock for tests (aragon#786)
Browse files Browse the repository at this point in the history
  • Loading branch information
facuspagnuolo authored Apr 17, 2019
1 parent 9272c33 commit 102c0e8
Show file tree
Hide file tree
Showing 15 changed files with 176 additions and 187 deletions.
3 changes: 2 additions & 1 deletion apps/finance/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
norpc: true,
copyPackages: ['@aragon/os', '@aragon/apps-vault'],
copyPackages: ['@aragon/os', '@aragon/apps-vault', '@aragon/test-helpers'],
skipFiles: [
'test',
'@aragon/test-helpers/contracts/TimeHelpersMock.sol',
]
}
10 changes: 4 additions & 6 deletions apps/finance/contracts/test/mocks/FinanceMock.sol
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
pragma solidity 0.4.24;

import "../../Finance.sol";
import "@aragon/test-helpers/contracts/TimeHelpersMock.sol";


contract FinanceMock is Finance {
uint64 mockTime;
contract FinanceMock is Finance, TimeHelpersMock {
uint64 mockMaxPeriodTransitions = MAX_UINT64;

function getMaxUint64() public pure returns (uint64) { return MAX_UINT64; }

function mock_setMaxPeriodTransitions(uint64 i) public { mockMaxPeriodTransitions = i; }
function mock_setTimestamp(uint64 i) public { mockTime = i; }

function getMaxPeriodTransitions() internal view returns (uint64) { return mockMaxPeriodTransitions; }
function getTimestamp64() internal view returns (uint64) { return mockTime; }

function getMaxUint64() public pure returns (uint64) { return MAX_UINT64; }
}
240 changes: 115 additions & 125 deletions apps/finance/test/finance.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion apps/survey/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
norpc: true,
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime'],
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime', '@aragon/test-helpers'],
skipFiles: [
'test',
'@aragon/test-helpers/contracts/TimeHelpersMock.sol',
]
}
3 changes: 2 additions & 1 deletion apps/survey/contracts/test/mocks/SurveyMock.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
pragma solidity 0.4.24;

import "../../Survey.sol";
import "@aragon/test-helpers/contracts/TimeHelpersMock.sol";


contract SurveyMock is Survey {
contract SurveyMock is Survey, TimeHelpersMock {
// Mint a token and create a vote in the same transaction to test snapshot block values are correct
function newTokenAndSurvey(address _holder, uint256 _tokenAmount, string _metadata, uint256 _options)
external
Expand Down
9 changes: 4 additions & 5 deletions apps/survey/test/survey.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const { assertRevert } = require('@aragon/test-helpers/assertThrow')
const getBlockNumber = require('@aragon/test-helpers/blockNumber')(web3)
const timeTravel = require('@aragon/test-helpers/timeTravel')(web3)

const getContract = name => artifacts.require(name)
const pct16 = x => new web3.BigNumber(x).times(new web3.BigNumber(10).toPower(16))
Expand Down Expand Up @@ -29,7 +28,7 @@ contract('Survey app', accounts => {
const kernelBase = await getContract('Kernel').new(true) // petrify immediately
const aclBase = await getContract('ACL').new()
daoFact = await getContract('DAOFactory').new(kernelBase.address, aclBase.address, NULL_ADDRESS)
surveyBase = await getContract('Survey').new()
surveyBase = await getContract('SurveyMock').new()

// Setup constants
ANY_ENTITY = await aclBase.ANY_ENTITY()
Expand All @@ -47,7 +46,7 @@ contract('Survey app', accounts => {
await acl.createPermission(root, dao.address, APP_MANAGER_ROLE, root, { from: root })

const receipt = await dao.newAppInstance(SURVEY_APP_ID, surveyBase.address, '0x', false, { from: root })
survey = getContract('Survey').at(receipt.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy)
survey = getContract('SurveyMock').at(receipt.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy)

await acl.createPermission(ANY_ENTITY, survey.address, CREATE_SURVEYS_ROLE, root, { from: root })
await acl.createPermission(ANY_ENTITY, survey.address, MODIFY_PARTICIPATION_ROLE, root, { from: root })
Expand Down Expand Up @@ -210,7 +209,7 @@ contract('Survey app', accounts => {
it('changing min participation doesnt affect survey min participation', async () => {
await survey.changeMinAcceptParticipationPct(pct16(50))

await timeTravel(surveyTime + 1)
await survey.mockIncreaseTime(surveyTime + 1)

const state = await survey.getSurvey(surveyId)
assert.deepEqual(state[3], minimumAcceptanceParticipationPct, 'acceptance participation in survey should stay equal')
Expand All @@ -233,7 +232,7 @@ contract('Survey app', accounts => {
})

it('throws when voting after survey closes', async () => {
await timeTravel(surveyTime + 1)
await survey.mockIncreaseTime(surveyTime + 1)
await assertRevert(async () => {
await survey.voteOption(surveyId, 1, { from: holder31 })
})
Expand Down
3 changes: 2 additions & 1 deletion apps/token-manager/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
norpc: true,
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime'],
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime', '@aragon/test-helpers'],
skipFiles: [
'test',
'@aragon/test-helpers/contracts/TimeHelpersMock.sol',
]
}
9 changes: 3 additions & 6 deletions apps/token-manager/contracts/test/mocks/TokenManagerMock.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
pragma solidity 0.4.24;

import "../../TokenManager.sol";
import "@aragon/test-helpers/contracts/TimeHelpersMock.sol";


contract TokenManagerMock is TokenManager {
uint256 mockTime;

function mock_setTimestamp(uint256 i) public { mockTime = i; }
function getTimestamp() internal view returns (uint256) { return mockTime; }
}
/* solium-disable-next-line no-empty-blocks */
contract TokenManagerMock is TokenManager, TimeHelpersMock {}
36 changes: 20 additions & 16 deletions apps/token-manager/test/tokenmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ contract('Token Manager', accounts => {
let MINT_ROLE, ISSUE_ROLE, ASSIGN_ROLE, REVOKE_VESTINGS_ROLE, BURN_ROLE
let ETH

const NOW_TIME = 1
const NOW = 1

const root = accounts[0]
const holder = accounts[1]
Expand Down Expand Up @@ -59,7 +59,7 @@ contract('Token Manager', accounts => {

const receipt = await dao.newAppInstance('0x1234', tokenManagerBase.address, '0x', false, { from: root })
tokenManager = TokenManager.at(receipt.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy)
tokenManager.mock_setTimestamp(NOW_TIME)
tokenManager.mockSetTimestamp(NOW)

await acl.createPermission(ANY_ADDR, tokenManager.address, MINT_ROLE, root, { from: root })
await acl.createPermission(ANY_ADDR, tokenManager.address, ISSUE_ROLE, root, { from: root })
Expand Down Expand Up @@ -348,9 +348,12 @@ contract('Token Manager', accounts => {
})

context('assigning vested tokens', () => {
const startDate = NOW_TIME + 1000
const cliffDate = NOW_TIME + 2000
const vestingDate = NOW_TIME + 5000
const CLIFF_DURATION = 2000
const VESTING_DURATION = 5000

const startDate = NOW + 1000
const cliffDate = NOW + CLIFF_DURATION
const vestingDate = NOW + VESTING_DURATION

const totalTokens = 40
const revokable = true
Expand All @@ -376,22 +379,23 @@ contract('Token Manager', accounts => {
})

it('can start transferring on cliff', async () => {
await tokenManager.mock_setTimestamp(cliffDate)
await tokenManager.mockIncreaseTime(CLIFF_DURATION)

await token.transfer(holder2, 10, { from: holder })
assert.equal(await token.balanceOf(holder2), 10, 'should have received tokens')
assert.equal(await tokenManager.spendableBalanceOf(holder), 0, 'should not be able to spend more tokens')
assert.equal((await token.balanceOf(holder2)).toString(), 10, 'should have received tokens')
assert.equal((await tokenManager.spendableBalanceOf(holder)).toString(), 0, 'should not be able to spend more tokens')
})

it('can transfer all tokens after vesting', async () => {
await tokenManager.mock_setTimestamp(vestingDate)
await tokenManager.mockIncreaseTime(VESTING_DURATION)

await token.transfer(holder2, totalTokens, { from: holder })
assert.equal(await token.balanceOf(holder2), totalTokens, 'should have received tokens')
})

it('can transfer half mid vesting', async () => {
await tokenManager.mock_setTimestamp(startDate + (vestingDate - startDate) / 2)
await tokenManager.mockSetTimestamp(startDate)
await tokenManager.mockIncreaseTime((vestingDate - startDate) / 2)

await token.transfer(holder2, 20, { from: holder })

Expand All @@ -413,22 +417,22 @@ contract('Token Manager', accounts => {
})

it('cannot transfer all tokens right before vesting', async () => {
await tokenManager.mock_setTimestamp(vestingDate - 10)
await tokenManager.mockIncreaseTime(VESTING_DURATION - 10)

return assertRevert(async () => {
await token.transfer(holder2, totalTokens, { from: holder })
})
})

it('can be revoked and not vested tokens are transfered to token manager', async () => {
await tokenManager.mock_setTimestamp(cliffDate)
await tokenManager.mockIncreaseTime(CLIFF_DURATION)
await tokenManager.revokeVesting(holder, 0)

await token.transfer(holder2, 5, { from: holder })

assert.equal(await token.balanceOf(holder), 5, 'should have kept vested tokens')
assert.equal(await token.balanceOf(holder2), 5, 'should have kept vested tokens')
assert.equal(await token.balanceOf(tokenManager.address), totalTokens - 10, 'should have received unvested')
assert.equal((await token.balanceOf(holder)).toString(), 5, 'should have kept vested tokens')
assert.equal((await token.balanceOf(holder2)).toString(), 5, 'should have kept vested tokens')
assert.equal((await token.balanceOf(tokenManager.address)).toString(), totalTokens - 10, 'should have received unvested')
})

it('cannot assign a vesting to itself', async () => {
Expand Down Expand Up @@ -459,7 +463,7 @@ contract('Token Manager', accounts => {
})

// Can't create a new vesting even after other vestings have finished
await tokenManager.mock_setTimestamp(vestingDate)
await tokenManager.mockIncreaseTime(VESTING_DURATION)
await assertRevert(async () => {
await tokenManager.assignVested(holder, 1, startDate, cliffDate, vestingDate, false)
})
Expand Down
3 changes: 2 additions & 1 deletion apps/voting/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
norpc: true,
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime'],
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime', '@aragon/test-helpers'],
skipFiles: [
'test',
'@aragon/test-helpers/contracts/TimeHelpersMock.sol',
]
}
8 changes: 2 additions & 6 deletions apps/voting/contracts/test/mocks/VotingMock.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
pragma solidity 0.4.24;

import "../../Voting.sol";
import "@aragon/test-helpers/contracts/TimeHelpersMock.sol";


contract VotingMock is Voting {
uint64 mockTime;

function mock_setTimestamp(uint64 i) public { mockTime = i; }
function getTimestamp64() internal view returns (uint64) { return mockTime; }

contract VotingMock is Voting, TimeHelpersMock {
/* Ugly hack to work around this issue:
* https://github.com/trufflesuite/truffle/issues/569
* https://github.com/trufflesuite/truffle/issues/737
Expand Down
24 changes: 8 additions & 16 deletions apps/voting/test/voting.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const sha3 = require('solidity-sha3').default

const { assertRevert } = require('@aragon/test-helpers/assertThrow')
const getBlockNumber = require('@aragon/test-helpers/blockNumber')(web3)
const { encodeCallScript, EMPTY_SCRIPT } = require('@aragon/test-helpers/evmScript')
Expand Down Expand Up @@ -35,9 +33,8 @@ contract('Voting App', accounts => {
let APP_MANAGER_ROLE
let CREATE_VOTES_ROLE, MODIFY_SUPPORT_ROLE, MODIFY_QUORUM_ROLE

const startTime = 1
const NOW = 1
const votingDuration = 1000
const votingEnd = startTime + votingDuration + 1
const root = accounts[0]

before(async () => {
Expand All @@ -63,19 +60,14 @@ contract('Voting App', accounts => {

const receipt = await dao.newAppInstance('0x1234', votingBase.address, '0x', false, { from: root })
voting = Voting.at(receipt.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy)
await voting.mock_setTimestamp(startTime)
await voting.mockSetTimestamp(NOW)

await acl.createPermission(ANY_ADDR, voting.address, CREATE_VOTES_ROLE, root, { from: root })
await acl.createPermission(ANY_ADDR, voting.address, MODIFY_SUPPORT_ROLE, root, { from: root })
await acl.createPermission(ANY_ADDR, voting.address, MODIFY_QUORUM_ROLE, root, { from: root })
})

context('normal token supply, common tests', () => {
const holder20 = accounts[0]
const holder29 = accounts[1]
const holder51 = accounts[2]
const nonHolder = accounts[4]

const neededSupport = pct16(50)
const minimumAcceptanceQuorum = pct16(20)

Expand Down Expand Up @@ -252,7 +244,7 @@ contract('Voting App', accounts => {
await voting.vote(voteId, true, false, { from: holder51 })
await voting.vote(voteId, true, false, { from: holder20 })
await voting.vote(voteId, false, false, { from: holder29 })
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)

const state = await voting.getVote(voteId)
assert.equal(state[4].toString(), neededSupport.toString(), 'required support in vote should stay equal')
Expand All @@ -267,7 +259,7 @@ contract('Voting App', accounts => {
// it will succeed

await voting.vote(voteId, true, true, { from: holder29 })
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)

const state = await voting.getVote(voteId)
assert.equal(state[5].toString(), minimumAcceptanceQuorum.toString(), 'acceptance quorum in vote should stay equal')
Expand Down Expand Up @@ -310,7 +302,7 @@ contract('Voting App', accounts => {
})

it('throws when voting after voting closes', async () => {
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)
return assertRevert(async () => {
await voting.vote(voteId, true, true, { from: holder29 })
})
Expand All @@ -319,14 +311,14 @@ contract('Voting App', accounts => {
it('can execute if vote is approved with support and quorum', async () => {
await voting.vote(voteId, true, true, { from: holder29 })
await voting.vote(voteId, false, true, { from: holder20 })
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)
await voting.executeVote(voteId)
assert.equal(await executionTarget.counter(), 2, 'should have executed result')
})

it('cannot execute vote if not enough quorum met', async () => {
await voting.vote(voteId, true, true, { from: holder20 })
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)
return assertRevert(async () => {
await voting.executeVote(voteId)
})
Expand All @@ -335,7 +327,7 @@ contract('Voting App', accounts => {
it('cannot execute vote if not support met', async () => {
await voting.vote(voteId, false, true, { from: holder29 })
await voting.vote(voteId, false, true, { from: holder20 })
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)
return assertRevert(async () => {
await voting.executeVote(voteId)
})
Expand Down
3 changes: 2 additions & 1 deletion future-apps/payroll/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
norpc: true,
copyPackages: ['@aragon/os', '@aragon/apps-finance', '@aragon/apps-vault'],
copyPackages: ['@aragon/os', '@aragon/apps-finance', '@aragon/apps-vault', '@aragon/test-helpers'],
skipFiles: [
'test',
'@aragon/test-helpers/contracts/TimeHelpersMock.sol',
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ contract('Payroll gas costs', ([owner, employee, anotherEmployee]) => {

beforeEach('initialize payroll app', async () => {
await payroll.initialize(finance.address, denominationToken.address, priceFeed.address, RATE_EXPIRATION_TIME, { from: owner })
await payroll.mockSetTimestamp(NOW)

const startDate = NOW - ONE_MONTH
const salary = annualSalaryPerSecond(100000, TOKEN_DECIMALS)
Expand Down
8 changes: 8 additions & 0 deletions shared/test-helpers/contracts/TimeHelpersMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ contract TimeHelpersMock is TimeHelpers {
else mockedTimestamp = block.timestamp.add(_seconds);
}

/**
* @dev Decreases the mocked timestamp value, used only for testing purposes
*/
function mockDecreaseTime(uint256 _seconds) public {
if (mockedTimestamp != 0) mockedTimestamp = mockedTimestamp.sub(_seconds);
else mockedTimestamp = block.timestamp.sub(_seconds);
}

/**
* @dev Advances the mocked block number value, used only for testing purposes
*/
Expand Down

0 comments on commit 102c0e8

Please sign in to comment.