Skip to content

Commit

Permalink
Calculate winners ignores ignored choices #247 (#311)
Browse files Browse the repository at this point in the history
* Calculate winners ignores ignored choices #247
  • Loading branch information
szirbucz authored and magwas committed Apr 11, 2019
1 parent 9d5b181 commit 6a60c1d
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.rulez.demokracia.pdengine;

import java.util.List;

public interface CanCalculateWinners {

List<String> calculateWinners(List<String> ignoredChoices);
}
35 changes: 34 additions & 1 deletion src/main/java/org/rulez/demokracia/pdengine/ComputedVote.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,27 @@

import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

public class ComputedVote implements ComputedVoteInterface, Serializable {
import org.rulez.demokracia.pdengine.dataobjects.Pair;

import jersey.repackaged.com.google.common.collect.Sets;
import jersey.repackaged.com.google.common.collect.Sets.SetView;

public class ComputedVote implements CanCalculateWinners, ComputedVoteInterface, Serializable {

private static final long serialVersionUID = 1L;
private BeatTable beatTable;
private final Vote vote;
private BeatTable beatPathTable;

private transient WinnerCalculator winnerCalculator;

public ComputedVote(final Vote vote) {
this.vote = vote;
winnerCalculator = new WinnerCalculatorImpl();
}

@Override
Expand All @@ -31,11 +40,35 @@ public void computeVote() {
beatPathTable.computeTransitiveClosure();
}

@Override
public List<String> calculateWinners(final List<String> ignoredChoices) {
BeatTable filteredBeatTable = ignoreChoices(ignoredChoices);
return winnerCalculator.calculateWinners(filteredBeatTable);
}

public BeatTable getBeatTable() {
return beatTable;
}

public BeatTable getBeatPathTable() {
return beatPathTable;
}

public void setWinnerCalculator(final WinnerCalculatorImpl winnerCalculator) {
this.winnerCalculator = winnerCalculator;
}

private BeatTable ignoreChoices(final List<String> ignoredChoices) {
SetView<String> activeChoices = Sets.difference(Sets.newHashSet(beatPathTable.getKeyCollection()),
Sets.newHashSet(ignoredChoices));
BeatTable filteredBeatTable = new BeatTable(activeChoices);
for (String key1 : activeChoices) {
for (String key2 : activeChoices) {
Pair source = beatTable.getElement(key1, key2);
if (Objects.nonNull(source))
filteredBeatTable.setElement(key1, key2, source);
}
}
return filteredBeatTable;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.rulez.demokracia.pdengine;

import java.util.List;

public interface WinnerCalculator {

List<String> calculateWinners(final BeatTable beatTable);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.rulez.demokracia.pdengine;

import java.util.List;

public class WinnerCalculatorImpl implements WinnerCalculator {

@Override
public List<String> calculateWinners(final BeatTable beatTable) {
throw new UnsupportedOperationException();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.rulez.demokracia.pdengine;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.stubbing.Answer;
import org.rulez.demokracia.pdengine.annotations.TestedBehaviour;
import org.rulez.demokracia.pdengine.annotations.TestedFeature;
import org.rulez.demokracia.pdengine.annotations.TestedOperation;
import org.rulez.demokracia.pdengine.testhelpers.CreatedDefaultCastVoteWithRankedChoices;

@TestedFeature("Vote")
@TestedOperation("calculate winners")
public class CalculateWinnersTest extends CreatedDefaultCastVoteWithRankedChoices {

private final Answer<?> answerKeyCollection = (invocation) -> {
BeatTable beatTable = (BeatTable) invocation.getArguments()[0];
return beatTable.getKeyCollection().stream().collect(Collectors.toList());
};

private ComputedVote computedVote;
private final ArgumentCaptor<BeatTable> captor = ArgumentCaptor.forClass(BeatTable.class);

@Override
@Before
public void setUp() {
super.setUp();
getTheVote().votesCast = castVote;
WinnerCalculatorImpl winnerCalculator = mock(WinnerCalculatorImpl.class);
when(winnerCalculator.calculateWinners(captor.capture())).thenAnswer(answerKeyCollection);

computedVote = new ComputedVote(getTheVote());
computedVote.computeVote();
computedVote.setWinnerCalculator(winnerCalculator);
}

@TestedBehaviour("only choices not in ignoredChoices are considered")
@Test
public void calculate_winners_returns_none_of_the_ignored_choices() {
List<String> winners = computedVote.calculateWinners(Arrays.asList("A"));
assertFalse(winners.contains("A"));

}

@TestedBehaviour("only choices not in ignoredChoices are considered")
@Test
public void calculate_winners_returns_not_ignored_winner() {
List<String> winners = computedVote.calculateWinners(Arrays.asList("C"));
assertBeatTableContainChoice(winners, "A");
}

private void assertBeatTableContainChoice(final List<String> winners, final String choice) {
assertTrue(winners.contains(choice));
BeatTable capturedBeatTable = captor.getValue();
assertNotNull(capturedBeatTable.getElement(choice, "B"));
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ public class UnimplementedTests extends ThrowableTester {
public void the_getAssurances_method_is_not_implemented_yet() {
assertUnimplemented(() -> new CastVote("proxyId", new ArrayList<>()).getAssurances());
}

@Test
public void the_calculateWinners_method_is_not_implemented_yet() {
assertUnimplemented(() -> new WinnerCalculatorImpl().calculateWinners(null));
}
}

0 comments on commit 6a60c1d

Please sign in to comment.