class TestParticipant(unittest.TestCase): def setUp(self): self.p = Participant(TokenBatch(100, 100)) def test_buy(self): """ Test that the function works. If we set the probability to 1, Participant should buy in. If we set the probability to 0, 0 will be returned. """ with patch('entities.probability') as mock: mock.return_value = True # Must set Participant's sentiment artificially high, because of Zargham's force calculation self.p.sentiment = 1 delta_holdings = self.p.buy() self.assertGreater(delta_holdings, 0) with patch('entities.probability') as mock: mock.return_value = False delta_holdings = self.p.buy() self.assertEqual(delta_holdings, 0) def test_sell(self): """ Test that the function works. If we set the probability to 1, Participant should buy in. If we set the probability to 0, 0 will be returned. """ with patch('entities.probability') as mock: mock.return_value = True self.p.sentiment = 0.1 delta_holdings = self.p.sell() self.assertLess(delta_holdings, 0) with patch('entities.probability') as mock: mock.return_value = False delta_holdings = self.p.sell() self.assertEqual(delta_holdings, 0) def test_create_proposal(self): """ Test that the function works. If we set the probability to 1, we should get True. If not, we should get False. """ with patch('entities.probability') as mock: mock.return_value = True self.assertTrue(self.p.create_proposal(10000, 0.5, 100000)) with patch('entities.probability') as mock: mock.return_value = False self.assertFalse(self.p.create_proposal(10000, 0.5, 100000)) def test_vote_on_candidate_proposals(self): """ Test that the function works. If we set the probability to 1, we should get a dict of Proposal UUIDs that the Participant would vote on. If not, we should get an empty dict. """ candidate_proposals = { 0: 1.0, 1: 1.0, 2: 1.0, } with patch('entities.probability') as mock: mock.return_value = False ans = self.p.vote_on_candidate_proposals(candidate_proposals) self.assertFalse(ans) with patch('entities.probability') as mock: mock.return_value = True ans = self.p.vote_on_candidate_proposals(candidate_proposals) self.assertEqual(len(ans), 3) def test_vote_on_candidate_proposals_zargham_algorithm(self): """ Test that Zargham's algorithm works as intended. A cutoff value is set based on your affinity to your favourite Proposal. If there are other Proposals that you like almost as much, you will vote for them too, otherwise if they don't meet the cutoff value you will only vote for your favourite Proposal. """ candidate_proposals = { 0: 1.0, 1: 0.9, 2: 0.8, 3: 0.4, } with patch('entities.probability') as mock: mock.return_value = True ans = self.p.vote_on_candidate_proposals(candidate_proposals) reference = {0: 1.0, 1: 0.9, 2: 0.8} self.assertEqual(ans, reference) def test_stake_across_all_supported_proposals(self): """ Test that the rebalancing code works as intended. Given 4 Proposals which the Participant has affinity 0.9, 0.9, 0.8, 0.6 to, we should expect an allocation of 0.28125, 0.28125, 02.5, 0.1872 respectively. The calculation should also include vesting and nonvesting TokenBatches. """ supported_proposals = [ (0.9, 0), (0.9, 1), (0.8, 2), (0.6, 3), ] self.p.holdings = TokenBatch(500, 500) ans = self.p.stake_across_all_supported_proposals(supported_proposals) reference = { 0: 281.25000000000006, 1: 281.25000000000006, 2: 250.00000000000006, 3: 187.5, } self.assertEqual(ans, reference)
class TestParticipant(unittest.TestCase): def setUp(self): self.params = { "probability_func": new_probability_func(seed=None), "random_number_func": new_random_number_func(seed=None) } self.p = Participant(TokenBatch(100, 100), self.params["probability_func"], self.params["random_number_func"]) def test_buy(self): """ Test that the function works. If we set the probability to 1, Participant should buy in. If we set the probability to 0, 0 will be returned. """ # Must set Participant's sentiment artificially high, because of Zargham's force calculation self.p.sentiment = 1 self.p._probability_func = always delta_holdings = self.p.buy() self.assertGreater(delta_holdings, 0) self.p._probability_func = never delta_holdings = self.p.buy() self.assertEqual(delta_holdings, 0) def test_sell(self): """ Test that the function works. If we set the probability to 1, Participant should buy in. If we set the probability to 0, 0 will be returned. """ self.p._probability_func = always self.p.sentiment = 0.1 delta_holdings = self.p.sell() self.assertGreater(delta_holdings, 0) self.p._probability_func = never delta_holdings = self.p.sell() self.assertEqual(delta_holdings, 0) def test_increase_holdings(self): """ Test that the function works. The result nonvesting holdings should be the initial nonvesting holdings plus the added nonvesting holdings. The vesting and the vesting_spent holdings should not me modified. """ added_nonvesting_holdings = 50 inital_nonvesting_holdings = self.p.holdings.nonvesting initial_vesting_holdings = self.p.holdings.vesting initial_vesting_spent_holdings = self.p.holdings.vesting_spent self.p.increase_holdings(added_nonvesting_holdings) self.assertEqual(self.p.holdings.nonvesting, added_nonvesting_holdings + inital_nonvesting_holdings) # Test if vesting and vesting_spent holdings are unchanged self.assertEqual(self.p.holdings.vesting, initial_vesting_holdings) self.assertEqual(self.p.holdings.vesting_spent, initial_vesting_spent_holdings) def test_spend(self): """ Test that the function works. It simply tests it spend() behaviours as a front to TokenBatch.spend() returning a tuple with vesting, vesting_spent and nonvesting. """ self.assertEqual(self.p.spend(50), (self.p.holdings.vesting, self.p.holdings.vesting_spent, self.p.holdings.nonvesting)) def test_create_proposal(self): """ Test that the function works. If we set the probability to 1, we should get True. If not, we should get False. """ self.p._probability_func = always self.assertTrue(self.p.create_proposal(10000, 0.5, 100000)) self.p._probability_func = never self.assertFalse(self.p.create_proposal(10000, 0.5, 100000)) def test_vote_on_candidate_proposals(self): """ Test that the function works. If we set the probability to 1, we should get a dict of Proposal UUIDs that the Participant would vote on. If not, we should get an empty dict. """ candidate_proposals = { 0: 1.0, 1: 1.0, 2: 1.0, } self.p._probability_func = never ans = self.p.vote_on_candidate_proposals(candidate_proposals) self.assertFalse(ans) self.p._probability_func = always ans = self.p.vote_on_candidate_proposals(candidate_proposals) self.assertEqual(len(ans), 3) def test_vote_on_candidate_proposals_zargham_algorithm(self): """ Test that Zargham's algorithm works as intended. A cutoff value is set based on your affinity to your favourite Proposal. If there are other Proposals that you like almost as much, you will vote for them too, otherwise if they don't meet the cutoff value you will only vote for your favourite Proposal. """ candidate_proposals = { 0: 1.0, 1: 0.9, 2: 0.8, 3: 0.4, } self.p._probability_func = always ans = self.p.vote_on_candidate_proposals(candidate_proposals) reference = { 0: 1.0, 1: 0.9, 2: 0.8 } self.assertEqual(ans, reference) def test_stake_across_all_supported_proposals(self): """ Test that the rebalancing code works as intended. Given 4 Proposals which the Participant has affinity 0.9, 0.9, 0.8, 0.6 to, we should expect an allocation of 0.28125, 0.28125, 02.5, 0.1872 respectively. The calculation should also include vesting and nonvesting TokenBatches. """ supported_proposals = [ (0.9, 0), (0.9, 1), (0.8, 2), (0.6, 3), ] self.p.holdings = TokenBatch(500, 500) ans = self.p.stake_across_all_supported_proposals(supported_proposals) reference = { 0: 281.25000000000006, 1: 281.25000000000006, 2: 250.00000000000006, 3: 187.5, } self.assertEqual(ans, reference) def test_update_token_batch_age(self): """ Test that the participant token batch is updated by 1 day after running Participant.update_token_batch_age() """ old_age_days = self.p.holdings.age_days new_age_days = self.p.update_token_batch_age() self.assertEqual(new_age_days, old_age_days + 1) def test_wants_to_exit(self): """ Test that the function works. First force the probability to be True and check if the participant wanted to exit. Then force the probability to be False and check if the participant do not wanted to exit. """ # Set a sentiment below the exit threshold self.p.sentiment = 0.2 self.p._probability_func = always # A participant with vesting should not be able to exit self.assertFalse(self.p.wants_to_exit()) self.p.holdings.vesting = 0 # After the participant has no vesting, he can exit self.assertTrue(self.p.wants_to_exit()) self.p._probability_func = never self.assertFalse(self.p.wants_to_exit())
class TestParticipant(unittest.TestCase): def setUp(self): self.p = Participant() def test_buy(self): """ Test that the function works. If we set the probability to 1, Participant should buy in. If we set the probability to 0, 0 will be returned. """ with patch('entities.probability') as mock: mock.return_value = True # Must set Participant's sentiment artificially high, because of Zargham's force calculation self.p.sentiment = 1 delta_holdings = self.p.buy() self.assertGreater(delta_holdings, 0) with patch('entities.probability') as mock: mock.return_value = False delta_holdings = self.p.buy() self.assertEqual(delta_holdings, 0) def test_sell(self): """ Test that the function works. If we set the probability to 1, Participant should buy in. If we set the probability to 0, 0 will be returned. """ with patch('entities.probability') as mock: mock.return_value = True self.p.sentiment = 0.1 delta_holdings = self.p.sell() self.assertLess(delta_holdings, 0) with patch('entities.probability') as mock: mock.return_value = False delta_holdings = self.p.sell() self.assertEqual(delta_holdings, 0) def test_create_proposal(self): """ Test that the function works. If we set the probability to 1, we should get True. If not, we should get False. """ with patch('entities.probability') as mock: mock.return_value = True self.assertTrue(self.p.create_proposal(10000, 0.5, 100000)) with patch('entities.probability') as mock: mock.return_value = False self.assertFalse(self.p.create_proposal(10000, 0.5, 100000)) def test_vote_on_candidate_proposals(self): """ Test that the function works. If we set the probability to 1, we should get a dict of Proposal UUIDs that the Participant would vote on. If not, we should get an empty dict. """ candidate_proposals = { uuid.UUID(int=179821351946450230734044638685583215499): 1.0, uuid.UUID(int=215071290061070589371009813111193284959): 1.0, uuid.UUID(int=20468923874830131214536379780280861909): 1.0, } with patch('entities.probability') as mock: mock.return_value = False ans = self.p.vote_on_candidate_proposals(candidate_proposals) self.assertFalse(ans) with patch('entities.probability') as mock: mock.return_value = True ans = self.p.vote_on_candidate_proposals(candidate_proposals) self.assertEqual(len(ans), 3) def test_vote_on_candidate_proposals_zargham_algorithm(self): """ Test that Zargham's algorithm works as intended. A cutoff value is set based on your affinity to your favourite Proposal. If there are other Proposals that you like almost as much, you will vote for them too, otherwise if they don't meet the cutoff value you will only vote for your favourite Proposal. """ candidate_proposals = { uuid.UUID(int=179821351946450230734044638685583215499): 1.0, uuid.UUID(int=215071290061070589371009813111193284959): 0.9, uuid.UUID(int=20468923874830131214536379780280861909): 0.8, uuid.UUID(int=268821512376988039567204465930241984322): 0.4, } with patch('entities.probability') as mock: mock.return_value = True ans = self.p.vote_on_candidate_proposals(candidate_proposals) self.assertIn( uuid.UUID(int=179821351946450230734044638685583215499), ans) self.assertIn( uuid.UUID(int=215071290061070589371009813111193284959), ans) self.assertIn( uuid.UUID(int=20468923874830131214536379780280861909), ans) self.assertNotIn( uuid.UUID(int=268821512376988039567204465930241984322), ans) def test_stake_across_all_supported_proposals(self): """ Test that the rebalancing code works as intended. Given 4 Proposals which the Participant has affinity 0.9, 0.9, 0.8, 0.6 to, we should expect an allocation of 0.28125, 0.28125, 02.5, 0.1872 respectively. The calculation should also include vesting and nonvesting TokenBatches. """ p = [Proposal(0, 0) for _ in range(4)] p[0].uuid = uuid.UUID(int=179821351946450230734044638685583215499) p[1].uuid = uuid.UUID(int=215071290061070589371009813111193284959) p[2].uuid = uuid.UUID(int=20468923874830131214536379780280861909) p[3].uuid = uuid.UUID(int=268821512376988039567204465930241984322) supported_proposals = [ (0.9, p[0]), (0.9, p[1]), (0.8, p[2]), (0.6, p[3]), ] self.p.holdings_vesting = TokenBatch(500) self.p.holdings_nonvesting = TokenBatch(500) ans = self.p.stake_across_all_supported_proposals(supported_proposals) print(ans) self.assertEqual( ans[uuid.UUID(int=179821351946450230734044638685583215499)], 281.25000000000006) self.assertEqual( ans[uuid.UUID(int=215071290061070589371009813111193284959)], 281.25000000000006) self.assertEqual( ans[uuid.UUID(int=20468923874830131214536379780280861909)], 250.00000000000006) self.assertEqual( ans[uuid.UUID(int=268821512376988039567204465930241984322)], 187.5)