From e0a5350b0618363f491c2e2e0a92c96183c5acf7 Mon Sep 17 00:00:00 2001 From: Josh Levine Date: Sun, 10 May 2020 16:11:30 -0400 Subject: [PATCH] add basic irv tests --- .../test/GovPollingService.test.js | 34 ++++++- .../dai-plugin-governance/test/fixtures.js | 93 +++++++++++++++++++ .../test/helpers/index.js | 13 ++- 3 files changed, 137 insertions(+), 3 deletions(-) diff --git a/packages/dai-plugin-governance/test/GovPollingService.test.js b/packages/dai-plugin-governance/test/GovPollingService.test.js index a0bc92455..a2bacc462 100644 --- a/packages/dai-plugin-governance/test/GovPollingService.test.js +++ b/packages/dai-plugin-governance/test/GovPollingService.test.js @@ -9,7 +9,11 @@ import { dummyAllPollsData, dummyOption, dummyWeight, - dummyNumUnique + dummyNumUnique, + dummyBallotNoMajority, + dummyBallotNoMajorityExpect, + dummyBallotWithMajority, + dummyBallotWithMajorityExpect } from './fixtures'; import { MKR } from '../src/utils/constants'; @@ -140,3 +144,31 @@ test('getPercentageMkrVoted', async () => { expect(mockFn).toBeCalled(); expect(percentage).toBe(40); }); + +test('ranked choice tallying algorithm with majority', async () => { + govQueryApiService.getMkrSupportRankedChoice = jest.fn( + () => dummyBallotWithMajority + ); + govPollingService._getPoll = jest.fn(() => ({ + endDate: 123 + })); + const tally = await govPollingService.getTallyRankedChoiceIrv(); + + expect(JSON.stringify(tally)).toBe( + JSON.stringify(dummyBallotWithMajorityExpect) + ); +}); + +test('ranked choice tallying algorithm with no majority', async () => { + govQueryApiService.getMkrSupportRankedChoice = jest.fn( + () => dummyBallotNoMajority + ); + govPollingService._getPoll = jest.fn(() => ({ + endDate: 123 + })); + const tally = await govPollingService.getTallyRankedChoiceIrv(); + + expect(JSON.stringify(tally)).toBe( + JSON.stringify(dummyBallotNoMajorityExpect) + ); +}); diff --git a/packages/dai-plugin-governance/test/fixtures.js b/packages/dai-plugin-governance/test/fixtures.js index a97710594..1ac23df78 100644 --- a/packages/dai-plugin-governance/test/fixtures.js +++ b/packages/dai-plugin-governance/test/fixtures.js @@ -1,4 +1,5 @@ import { MKR } from '../src/utils/constants'; +import { createBallot } from './helpers/index'; export const dummyMkrSupportData = [ { @@ -80,3 +81,95 @@ export const parsedDummyEsmData = [ time: new Date('2019-11-13T15:03:28+00:00') } ]; + +// --- + +export const dummyBallotWithMajority = [ + { + optionIdRaw: '769', + mkrSupport: '60.025000000000000000', + ballot: createBallot([1, 3]) // [1st choice, 2nd choice, ...] + }, + { + optionIdRaw: '259', + mkrSupport: '200.598801867883985831', + ballot: createBallot([3, 1]) + }, + { + optionIdRaw: '770', + mkrSupport: '64.068823529411764706', + ballot: createBallot([2, 3]) + } +]; + +export const dummyBallotWithMajorityExpect = { + rounds: 1, + winner: '3', + totalMkrParticipation: '324.692625397295750537', + options: { + '1': { + firstChoice: '60.025', + transfer: '0', + winner: false, + eliminated: false + }, + '2': { + firstChoice: '64.068823529411764706', + transfer: '0', + winner: false, + eliminated: false + }, + '3': { + firstChoice: '200.598801867883985831', + transfer: '0', + winner: true, + eliminated: false + } + } +}; + +// --- + +export const dummyBallotNoMajority = [ + { + optionIdRaw: '769', + mkrSupport: '60.025000000000000000', + ballot: createBallot([1, 3]) // [1st choice, 2nd choice, ...] + }, + { + optionIdRaw: '259', + mkrSupport: '102.598801867883985831', + ballot: createBallot([3, 1]) + }, + { + optionIdRaw: '770', + mkrSupport: '64.068823529411764706', + ballot: createBallot([2, 3]) + } +]; + +export const dummyBallotNoMajorityExpect = { + rounds: 2, + winner: '3', + totalMkrParticipation: '226.692625397295750537', + options: { + '1': { + firstChoice: '60.025', + transfer: '0', + winner: false, + eliminated: true + }, + '2': { + firstChoice: '64.068823529411764706', + transfer: '0', + winner: false, + eliminated: false + }, + '3': { + firstChoice: '102.598801867883985831', + transfer: '60.025', + winner: true, + eliminated: false + } + } +}; diff --git a/packages/dai-plugin-governance/test/helpers/index.js b/packages/dai-plugin-governance/test/helpers/index.js index d78ad9c48..b2949eb18 100644 --- a/packages/dai-plugin-governance/test/helpers/index.js +++ b/packages/dai-plugin-governance/test/helpers/index.js @@ -3,6 +3,7 @@ import Maker from '@makerdao/dai'; import govPlugin from '../../src/index'; import configPlugin from '@makerdao/dai-plugin-config'; import { createCurrency } from '@makerdao/currency'; +import { paddedArray } from '../../src/utils/helpers'; const infuraProjectId = 'c3f0f26a4c1742e0949d8eedfc47be67'; @@ -61,7 +62,7 @@ export async function restoreSnapshotOriginal(snapId) { } } -export const setupMakerOld = async (network) => { +export const setupMakerOld = async network => { const accounts = { owner: { type: 'privateKey', @@ -82,7 +83,7 @@ export const setupMakerOld = async (network) => { }; let url; - if(network==='ganache') url = 'http://localhost:2000'; + if (network === 'ganache') url = 'http://localhost:2000'; const preset = network === 'ganache' ? 'http' : network; const maker = await Maker.create(preset, { plugins: [[govPlugin, { network }]], @@ -211,3 +212,11 @@ export const setUpAllowance = async (maker, address) => { }; export const addressRegex = /^0x[a-fA-F0-9]{40}$/; + +export const createBallot = preferenceList => { + const reversedPreferenceList = preferenceList.reverse(); + return paddedArray( + 32 - reversedPreferenceList.length, + reversedPreferenceList + ); +};