Skip to content

Commit

Permalink
tests: refactor calculate votes percentages and create tests (#5691)
Browse files Browse the repository at this point in the history
* refactor: extract calculate percentages function to a separate file

* creates tests
  • Loading branch information
jeeanribeiro committed Jan 30, 2023
1 parent 109f83a commit 6300d85
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@
isOpened={openedQuestionIndex === questionIndex}
selectedAnswerValue={selectedAnswerValues[questionIndex]}
votedAnswerValue={votedAnswerValues[questionIndex]}
allVotes={proposalState?.questions[questionIndex]?.answers}
answerStatuses={proposalState?.questions[questionIndex]?.answers}
on:clickQuestion={handleQuestionClick}
on:clickAnswer={handleAnswerClick}
/>
Expand Down
31 changes: 8 additions & 23 deletions packages/shared/components/ProposalQuestion.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,31 @@
import { selectedProposal } from '@contexts/governance/stores'
import { Icon as IconEnum } from '@auxiliary/icon'
import { Position } from './enums'
import { getPercentagesFromAnswerStatuses } from '@contexts/governance'
const dispatch = createEventDispatcher()
export let allVotes: AnswerStatus[] = undefined
export let answerStatuses: AnswerStatus[] = []
export let questionIndex: number = undefined
export let isOpened = false
export let question: Question
export let selectedAnswerValue: number = undefined
export let votedAnswerValue: number = undefined
let percentages: string[]
let percentages: { [key: number]: string } = {}
let winnerAnswerIndex: number
$: answers = [...question?.answers, { value: 0, text: 'Abstain', additionalInfo: '' }]
$: allVotes, calculatePercentagesFromAllVotes()
$: percentages = getPercentagesFromAnswerStatuses(answerStatuses)
$: disabled =
$selectedProposal.status === ProposalStatus.Upcoming || $selectedProposal.status === ProposalStatus.Ended
$: allVotes, setWinnerAnswerIndex()
$: answerStatuses, setWinnerAnswerIndex()
$: showMargin =
isOpened ||
((votedAnswerValue || votedAnswerValue === ABSTAIN_VOTE_VALUE) && !isOpened) ||
((selectedAnswerValue || selectedAnswerValue === ABSTAIN_VOTE_VALUE) && !isOpened) ||
winnerAnswerIndex !== undefined
function calculatePercentagesFromAllVotes(): void {
if (
$selectedProposal?.status === ProposalStatus.Upcoming ||
$selectedProposal?.status === ProposalStatus.Commencing
) {
return
}
const totalVotes = allVotes?.reduce((acc, answer) => acc + answer.accumulated, 0)
percentages = answers?.map((currentAnswer) => {
const answerVotes = allVotes?.find((answer) => answer.value === currentAnswer.value)?.accumulated
const divisionResult = answerVotes / totalVotes
return Number.isNaN(divisionResult) ? '0%' : `${Math.round(divisionResult * 100)}%`
})
}
function handleAnswerClick(answerValue: number): void {
dispatch('clickAnswer', { answerValue, questionIndex })
}
Expand All @@ -57,7 +42,7 @@
function setWinnerAnswerIndex(): void {
if ($selectedProposal.status === ProposalStatus.Ended) {
const answersAccumulated = allVotes?.map((answer) => answer.accumulated)
const answersAccumulated = answerStatuses?.map((answer) => answer.accumulated)
const maxAccumulated = Math.max(...answersAccumulated)
winnerAnswerIndex = answersAccumulated?.indexOf(maxAccumulated)
}
Expand Down Expand Up @@ -104,11 +89,11 @@
{selectedAnswerValue}
{disabled}
hidden={!isOpened}
percentage={percentages?.[answerIndex]}
percentage={percentages[answer.value]}
isWinner={answerIndex === winnerAnswerIndex}
proposalStatus={$selectedProposal.status}
truncate={!isOpened}
on:click={handleAnswerClick(answer?.value)}
on:click={handleAnswerClick(answer.value)}
/>
{/each}
</proposal-answers>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { AnswerStatus } from '@iota/wallet'

export function getPercentagesFromAnswerStatuses(answerStatuses: AnswerStatus[]): { [key: number]: string } {
const totalVotes = answerStatuses.reduce((acc, answerStatus) => acc + answerStatus.accumulated, 0)
if (totalVotes === 0 || Number.isNaN(totalVotes)) {
return
}

let percentages: { [key: number]: string } = {}
answerStatuses.forEach((answerStatus) => {
if (answerStatus.value !== undefined) {
const divisionResult = (answerStatus.accumulated ?? 0) / totalVotes
percentages = {
...percentages,
[answerStatus.value]: Number.isNaN(divisionResult) ? '0%' : `${Math.round(divisionResult * 100)}%`,
}
}
})

return percentages
}
1 change: 1 addition & 0 deletions packages/shared/lib/contexts/governance/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export * from './getNumberOfTotalProposals'
export * from './getNumberOfVotedProposals'
export * from './getNumberOfVotingProposals'
export * from './getParticipationsForProposal'
export * from './getPercentagesFromAnswerStatuses'
export * from './isAnyAccountVotingForSelectedProposal'
export * from './isParticipationOutput'
export * from './isProposalActive'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import '@mocks/i18n.mock'
import type { AnswerStatus } from '@iota/wallet'

import { getPercentagesFromAnswerStatuses } from '../getPercentagesFromAnswerStatuses'

describe('File: getPercentagesFromAnswerStatuses.ts', () => {
describe('Function: getPercentagesFromAnswerStatuses', () => {
const ANSWER_STATUSES: AnswerStatus[] = [
{
value: 0,
current: 0,
accumulated: 1000,
},
{
value: 1,
current: 0,
accumulated: 2000,
},
{
value: 2,
current: 0,
accumulated: 3000,
},
]

it('should return percentages from valid arguments', () => {
expect(getPercentagesFromAnswerStatuses(ANSWER_STATUSES)).toEqual({ 0: '17%', 1: '33%', 2: '50%' })
})
it('should return undefined from invalid arguments', () => {
expect(getPercentagesFromAnswerStatuses([{} as AnswerStatus])).toBeUndefined()
})
it('should return undefined from empty arguments', () => {
expect(getPercentagesFromAnswerStatuses([])).toBeUndefined()
})
})
})

0 comments on commit 6300d85

Please sign in to comment.