r3708 - in trunk: . pollen-persistence pollen-persistence/src/main/java/org/chorem/pollen/business/persistence pollen-services pollen-services/src/main/java/org/chorem/pollen pollen-services/src/main/java/org/chorem/pollen/entities/migration pollen-services/src/main/java/org/chorem/pollen/services pollen-services/src/main/java/org/chorem/pollen/services/impl pollen-services/src/test/java/org/chorem/pollen/services pollen-ui-struts2 pollen-ui-struts2/src/main/java/org/chorem/pollen/ui pollen
Author: tchemit Date: 2012-09-29 14:36:25 +0200 (Sat, 29 Sep 2012) New Revision: 3708 Url: http://chorem.org/repositories/revision/pollen/3708 Log: refs #590: Refactor votecounting module (improve voteCounting api : distinguish voteCounting and his voteCoutning strategy) Added: trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/votecounting/ trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/votecounting/strategy/ trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingFactoryTest.java trunk/pollen-ui-struts2/src/test/resources/log4j.properties trunk/pollen-votecounting-aggregator/ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCounting.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCounting.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingFactory.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingNotFound.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingStrategy.java trunk/pollen-votecounting-api/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java trunk/pollen-votecounting-borda/ trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCounting.java trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java trunk/pollen-votecounting-borda/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java trunk/pollen-votecounting-condorcet/ trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCounting.java trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java trunk/pollen-votecounting-condorcet/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java trunk/pollen-votecounting-coombs/ trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCounting.java trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java trunk/pollen-votecounting-coombs/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java trunk/pollen-votecounting-instant-runoff/ trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCounting.java trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java trunk/pollen-votecounting-instant-runoff/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java trunk/pollen-votecounting-normal/ trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java trunk/pollen-votecounting-normal/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java trunk/pollen-votecounting-number/ trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCounting.java trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java trunk/pollen-votecounting-number/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java trunk/pollen-votecounting-percentage/ trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java trunk/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategyTest.java trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java Removed: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/AbstractVoteCountingStrategy.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountigStrategyNotFound.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategy.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProvider.java trunk/pollen-votecounting-api/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/strategy/BordaStrategy.java trunk/pollen-votecounting-borda/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/strategy/BordaStrategyTest.java trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/strategy/CondorcetStrategy.java trunk/pollen-votecounting-condorcet/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/strategy/CondorcetStrategyTest.java trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/strategy/CoombsStrategy.java trunk/pollen-votecounting-coombs/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/strategy/CoombsStrategyTest.java trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/strategy/InstantRunoffStrategy.java trunk/pollen-votecounting-instant-runoff/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/strategy/InstantRunoffStrategyTest.java trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/strategy/NormalStrategy.java trunk/pollen-votecounting-normal/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/strategy/NormalStrategyTest.java trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/strategy/NumberStrategy.java trunk/pollen-votecounting-number/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/strategy/NumberStrategyTest.java trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/strategy/PercentageStrategy.java trunk/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/strategy/PercentageStrategyTest.java trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java trunk/pollen-votecounting-strategy-borda/ trunk/pollen-votecounting-strategy-condorcet/ trunk/pollen-votecounting-strategy-coombs/ trunk/pollen-votecounting-strategy-instant-runoff/ trunk/pollen-votecounting-strategy-normal/ trunk/pollen-votecounting-strategy-number/ trunk/pollen-votecounting-strategy-percentage/ trunk/pollen-votecounting-strategy/ trunk/pollen-votecounting/ Modified: trunk/pollen-persistence/pom.xml trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/Polls.java trunk/pollen-services/pom.xml trunk/pollen-services/src/main/java/org/chorem/pollen/PollenApplicationContext.java trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4.java trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_5.java trunk/pollen-services/src/main/java/org/chorem/pollen/services/DefaultPollenServiceContext.java trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenServiceContext.java trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollVoteCountingService.java trunk/pollen-services/src/test/java/org/chorem/pollen/services/FakeServiceContext.java trunk/pollen-ui-struts2/pom.xml trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenApplicationListener.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupport.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ResultForPoll.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/form/AbstractPollForm.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/vote/AbstractVoteAction.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/vote/VoteForPoll.java trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/AbstractPollenAuthorization.java trunk/pollen-votecounting-aggregator/pom.xml trunk/pollen-votecounting-api/pom.xml trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/ChoiceScore.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/GroupVoteCountingResult.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/SimpleVoterBuilder.java trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java trunk/pollen-votecounting-borda/pom.xml trunk/pollen-votecounting-condorcet/pom.xml trunk/pollen-votecounting-coombs/pom.xml trunk/pollen-votecounting-instant-runoff/pom.xml trunk/pollen-votecounting-normal/pom.xml trunk/pollen-votecounting-number/pom.xml trunk/pollen-votecounting-percentage/pom.xml trunk/pom.xml Modified: trunk/pollen-persistence/pom.xml =================================================================== --- trunk/pollen-persistence/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-persistence/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -15,6 +15,8 @@ <groupId>org.chorem.pollen</groupId> <artifactId>pollen-persistence</artifactId> + <name>Pollen :: Persistence</name> + <description>Pollen Persistence Layer</description> <dependencies> @@ -73,24 +75,13 @@ </dependency> <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> </dependency> + </dependencies> - <!-- ************************************************************* --> - <!-- *** Project Information ************************************* --> - <!-- ************************************************************* --> - - <name>Pollen :: Persistence</name> - <description>Pollen Persistence Layer</description> - - <properties> - <!-- no site generation --> - <maven.site.skip>true</maven.site.skip> - <maven.site.deploy.skip>true</maven.site.deploy.skip> - </properties> - <build> <plugins> Modified: trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/Polls.java =================================================================== --- trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/Polls.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-persistence/src/main/java/org/chorem/pollen/business/persistence/Polls.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -31,8 +31,8 @@ import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; import org.chorem.pollen.votecounting.model.Voter; import org.chorem.pollen.votecounting.model.VoterBuilder; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategy; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategyProvider; +import org.chorem.pollen.votecounting.VoteCounting; +import org.chorem.pollen.votecounting.VoteCountingFactory; import java.util.Map; import java.util.Set; @@ -121,13 +121,13 @@ return result; } - public static VoteCountingStrategy getVoteCountingStrategy(VoteCountingStrategyProvider provider, Poll poll) { - Preconditions.checkNotNull(provider); + public static VoteCounting getVoteCounting(VoteCountingFactory factory, Poll poll) { + Preconditions.checkNotNull(factory); Preconditions.checkNotNull(poll); - int strategyId = poll.getVoteCountingType(); - VoteCountingStrategy result = provider.getStrategy(strategyId); + int id = poll.getVoteCountingType(); + VoteCounting result = factory.getVoteCounting(id); Preconditions.checkNotNull( - result, "Could not find strategry for id " + strategyId); + result, "Could not find vote counting for id " + id); return result; } Modified: trunk/pollen-services/pom.xml =================================================================== --- trunk/pollen-services/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-services/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -5,10 +5,6 @@ <modelVersion>4.0.0</modelVersion> - <!-- ************************************************************* --> - <!-- *** POM Relationships *************************************** --> - <!-- ************************************************************* --> - <parent> <groupId>org.chorem</groupId> <artifactId>pollen</artifactId> @@ -17,6 +13,8 @@ <groupId>org.chorem.pollen</groupId> <artifactId>pollen-services</artifactId> + <name>Pollen :: Services</name> + <description>Pollen Service Layer</description> <dependencies> @@ -94,30 +92,26 @@ <groupId>org.nuiton.topia</groupId> <artifactId>topia-service-migration</artifactId> </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + + <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>test</scope> </dependency> + <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> </dependency> + </dependencies> - <!-- ************************************************************* --> - <!-- *** Project Information ************************************* --> - <!-- ************************************************************* --> - - <name>Pollen :: Services</name> - <description>Pollen Service Layer</description> - - <properties> - <!-- no site generation --> - <maven.site.skip>true</maven.site.skip> - <maven.site.deploy.skip>true</maven.site.deploy.skip> - </properties> - <build> <plugins> Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/PollenApplicationContext.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/PollenApplicationContext.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/PollenApplicationContext.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -24,7 +24,7 @@ import com.opensymphony.xwork2.ActionContext; import org.chorem.pollen.services.PollenNotifierWorker; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategyProvider; +import org.chorem.pollen.votecounting.VoteCountingFactory; import org.nuiton.topia.TopiaContext; import javax.servlet.ServletContext; @@ -46,7 +46,7 @@ protected PollenNotifierWorker pollenNotifierWorker; - protected VoteCountingStrategyProvider voteCountingStrategyProvider; + protected VoteCountingFactory voteCountingFactory; public static PollenApplicationContext get(ActionContext actionContext) { Map<String, Object> application = actionContext.getApplication(); @@ -102,11 +102,11 @@ this.pollenNotifierWorker = pollenNotifierWorker; } - public VoteCountingStrategyProvider getVoteCountingStrategyProvider() { - return voteCountingStrategyProvider; + public VoteCountingFactory getVoteCountingFactory() { + return voteCountingFactory; } - public void setVoteCountingStrategyProvider(VoteCountingStrategyProvider voteCountingStrategyProvider) { - this.voteCountingStrategyProvider = voteCountingStrategyProvider; + public void setVoteCountingFactory(VoteCountingFactory voteCountingFactory) { + this.voteCountingFactory = voteCountingFactory; } } Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_4.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -140,7 +140,7 @@ tx, configuration, serviceFactory, - applicationContext.getVoteCountingStrategyProvider() + applicationContext.getVoteCountingFactory() ); List<Pair<String, String>> choiceIds = @@ -215,7 +215,7 @@ tx, configuration, serviceFactory, - applicationContext.getVoteCountingStrategyProvider() + applicationContext.getVoteCountingFactory() ); PollFeedService feedService = sContext.newService(PollFeedService.class); Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_5.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_5.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/entities/migration/PollenMigrationCallbackV1_5.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -88,7 +88,7 @@ tx, applicationContext.getConfiguration(), new PollenServiceFactory(), - applicationContext.getVoteCountingStrategyProvider() + applicationContext.getVoteCountingFactory() ); // clean pollAccount for votes Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/DefaultPollenServiceContext.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/services/DefaultPollenServiceContext.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/DefaultPollenServiceContext.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -24,7 +24,7 @@ import com.google.common.base.Preconditions; import org.chorem.pollen.PollenConfiguration; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategyProvider; +import org.chorem.pollen.votecounting.VoteCountingFactory; import org.nuiton.topia.TopiaContext; import java.net.URL; @@ -48,7 +48,7 @@ protected Locale locale; - protected VoteCountingStrategyProvider voteCountingStrategyProvider; + protected VoteCountingFactory voteCountingFactory; public static PollenServiceContext newContext( PollenServiceContext serviceContext, @@ -57,7 +57,7 @@ transaction, serviceContext.getConfiguration(), serviceContext.getServiceFactory(), - serviceContext.getVoteCountingStrategyProvider() + serviceContext.getVoteCountingFactory() ); } @@ -67,12 +67,12 @@ TopiaContext transaction, PollenConfiguration configuration, PollenServiceFactory serviceFactory, - VoteCountingStrategyProvider voteCountingStrategyProvider) { + VoteCountingFactory voteCountingFactory) { return new DefaultPollenServiceContext(locale, transaction, configuration, serviceFactory, - voteCountingStrategyProvider); + voteCountingFactory); } protected DefaultPollenServiceContext( @@ -80,12 +80,12 @@ TopiaContext transaction, PollenConfiguration configuration, PollenServiceFactory serviceFactory, - VoteCountingStrategyProvider voteCountingStrategyProvider) { + VoteCountingFactory voteCountingFactory) { this.locale = locale; this.transaction = transaction; this.configuration = configuration; this.serviceFactory = serviceFactory; - this.voteCountingStrategyProvider = voteCountingStrategyProvider; + this.voteCountingFactory = voteCountingFactory; } @Override @@ -135,8 +135,8 @@ } @Override - public VoteCountingStrategyProvider getVoteCountingStrategyProvider() { - return voteCountingStrategyProvider; + public VoteCountingFactory getVoteCountingFactory() { + return voteCountingFactory; } @Override Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenServiceContext.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenServiceContext.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/PollenServiceContext.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -26,7 +26,7 @@ import org.chorem.pollen.PollenConfiguration; import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.business.persistence.PollAccount; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategyProvider; +import org.chorem.pollen.votecounting.VoteCountingFactory; import org.nuiton.topia.TopiaContext; import java.net.URL; @@ -62,7 +62,7 @@ /** @return the current date */ Date getCurrentTime(); - VoteCountingStrategyProvider getVoteCountingStrategyProvider(); + VoteCountingFactory getVoteCountingFactory(); /** * Generates a unique id usable for {@link Poll#getPollId()} or Modified: trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollVoteCountingService.java =================================================================== --- trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollVoteCountingService.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-services/src/main/java/org/chorem/pollen/services/impl/PollVoteCountingService.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -31,7 +31,8 @@ import org.chorem.pollen.votecounting.model.GroupOfVoter; import org.chorem.pollen.votecounting.model.GroupVoteCountingResult; import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategy; +import org.chorem.pollen.votecounting.VoteCounting; +import org.chorem.pollen.votecounting.VoteCountingStrategy; /** * New Poll vote counting service. @@ -55,9 +56,10 @@ public VoteCountingResult getSimpleResult(Poll poll) { Preconditions.checkNotNull(poll); - VoteCountingStrategy strategy = Polls.getVoteCountingStrategy( - serviceContext.getVoteCountingStrategyProvider(), poll); - Preconditions.checkNotNull(strategy); + VoteCounting voteCounting = Polls.getVoteCounting( + serviceContext.getVoteCountingFactory(), poll); + Preconditions.checkNotNull(voteCounting); + VoteCountingStrategy strategy = voteCounting.newVoteCountingStrategy(); // create vote counting model GroupOfVoter group = Polls.toSimpleVotersGroup(poll); @@ -70,9 +72,11 @@ public GroupVoteCountingResult getGroupResult(Poll poll) { Preconditions.checkNotNull(poll); - VoteCountingStrategy strategy = Polls.getVoteCountingStrategy( - serviceContext.getVoteCountingStrategyProvider(), poll); - Preconditions.checkNotNull(strategy); + Preconditions.checkNotNull(poll); + VoteCounting voteCounting = Polls.getVoteCounting( + serviceContext.getVoteCountingFactory(), poll); + Preconditions.checkNotNull(voteCounting); + VoteCountingStrategy strategy = voteCounting.newVoteCountingStrategy(); // Create a groupVoter including of the root voters GroupOfVoter group = Polls.toGroupOfVoters(poll); Modified: trunk/pollen-services/src/test/java/org/chorem/pollen/services/FakeServiceContext.java =================================================================== --- trunk/pollen-services/src/test/java/org/chorem/pollen/services/FakeServiceContext.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-services/src/test/java/org/chorem/pollen/services/FakeServiceContext.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -28,7 +28,7 @@ import org.chorem.pollen.PollenConfiguration; import org.chorem.pollen.PollenIOUtil; import org.chorem.pollen.PollenTopiaRootContextFactory; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategyProvider; +import org.chorem.pollen.votecounting.VoteCountingFactory; import org.junit.rules.TestWatcher; import org.junit.runner.Description; import org.nuiton.topia.TopiaContext; @@ -130,7 +130,7 @@ } @Override - public VoteCountingStrategyProvider getVoteCountingStrategyProvider() { + public VoteCountingFactory getVoteCountingFactory() { return null; } Modified: trunk/pollen-ui-struts2/pom.xml =================================================================== --- trunk/pollen-ui-struts2/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-ui-struts2/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -3,10 +3,6 @@ <modelVersion>4.0.0</modelVersion> - <!-- ************************************************************* --> - <!-- *** POM Relationships *************************************** --> - <!-- ************************************************************* --> - <parent> <groupId>org.chorem</groupId> <artifactId>pollen</artifactId> @@ -15,7 +11,29 @@ <groupId>org.chorem.pollen</groupId> <artifactId>pollen-ui-struts2</artifactId> + <name>Pollen :: UI (struts2)</name> + <description>Interface Graphique Struts2 pour Pollen</description> + <packaging>war</packaging> + + <properties> + <i18n.silent>true</i18n.silent> + <i18n.bundleOutputName>${pollenI18nBundle}</i18n.bundleOutputName> + + <redmine.releaseFiles> + target/${project.build.finalName}.war, + target/${project.build.finalName}-bin.zip + </redmine.releaseFiles> + + <deployFiles>target/${project.build.finalName}.war</deployFiles> + + <defaultWebContextPath>pollen</defaultWebContextPath> + <defaultSiteUrl> + http://localhost:8080/${defaultWebContextPath} + </defaultSiteUrl> + <defaultLogDir>${basedir}/target</defaultLogDir> + </properties> + <dependencies> <dependency> @@ -38,7 +56,7 @@ <dependency> <groupId>${project.groupId}</groupId> - <artifactId>pollen-votecounting-strategy</artifactId> + <artifactId>pollen-votecounting-aggregator</artifactId> <version>${project.version}</version> <type>pom</type> <scope>runtime</scope> @@ -241,40 +259,14 @@ <scope>provided</scope> </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + </dependencies> - <!-- ************************************************************* --> - <!-- *** Project Information ************************************* --> - <!-- ************************************************************* --> - - <name>Pollen :: UI (struts2)</name> - <description>Interface Graphique Struts2 pour Pollen</description> - - - <!-- ************************************************************* --> - <!-- *** Build Settings ****************************************** --> - <!-- ************************************************************* --> - - <packaging>war</packaging> - - <properties> - <i18n.silent>true</i18n.silent> - <i18n.bundleOutputName>${pollenI18nBundle}</i18n.bundleOutputName> - - <redmine.releaseFiles> - target/${project.build.finalName}.war, - target/${project.build.finalName}-bin.zip - </redmine.releaseFiles> - - <deployFiles>target/${project.build.finalName}.war</deployFiles> - - <defaultWebContextPath>pollen</defaultWebContextPath> - <defaultSiteUrl> - http://localhost:8080/${defaultWebContextPath} - </defaultSiteUrl> - <defaultLogDir>${basedir}/target</defaultLogDir> - </properties> - <build> <!-- call result war : pollen-xxx.war --> Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenApplicationListener.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenApplicationListener.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenApplicationListener.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -38,7 +38,7 @@ import org.chorem.pollen.services.PollenServiceContext; import org.chorem.pollen.services.PollenServiceFactory; import org.chorem.pollen.services.impl.UserService; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategyProvider; +import org.chorem.pollen.votecounting.VoteCountingFactory; import org.nuiton.i18n.I18n; import org.nuiton.i18n.init.DefaultI18nInitializer; import org.nuiton.topia.TopiaContext; @@ -101,7 +101,7 @@ log.info("Base url " + configuration.getApplicationUrl()); } applicationContext.setConfiguration(configuration); - applicationContext.setVoteCountingStrategyProvider(new VoteCountingStrategyProvider()); + applicationContext.setVoteCountingFactory(new VoteCountingFactory()); File temporaryDirectory = configuration.getTemporaryDirectory(); try { @@ -202,7 +202,7 @@ null, applicationContext.getConfiguration(), new PollenServiceFactory(), - applicationContext.getVoteCountingStrategyProvider() + applicationContext.getVoteCountingFactory() ); PollenNotifierWorker pollenNotifierWorker = new PollenNotifierWorker( serviceContext, @@ -277,7 +277,7 @@ transaction, configuration, serviceFactory, - applicationContext.getVoteCountingStrategyProvider() + applicationContext.getVoteCountingFactory() ); UserService service = Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupport.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupport.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/PollenActionSupport.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -54,8 +54,8 @@ import org.chorem.pollen.ui.PollenSession; import org.chorem.pollen.ui.interceptors.PollenSecurityInterceptor; import org.chorem.pollen.ui.security.AbstractPollenAuthorization; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategy; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategyProvider; +import org.chorem.pollen.votecounting.VoteCounting; +import org.chorem.pollen.votecounting.VoteCountingFactory; import org.nuiton.topia.TopiaContext; import org.nuiton.web.filter.TopiaTransactionFilter; import org.nuiton.web.struts2.BaseAction; @@ -262,8 +262,8 @@ return result; } - public VoteCountingStrategyProvider getVoteCountingStrategyProvider() { - return getPollenApplicationContext().getVoteCountingStrategyProvider(); + public VoteCountingFactory getVoteCountingFactory() { + return getPollenApplicationContext().getVoteCountingFactory(); } public TopiaContext getTransaction() { @@ -458,9 +458,8 @@ return parameters; } - protected VoteCountingStrategy getVoteCountingStrategy(Poll poll) { - return Polls.getVoteCountingStrategy(getVoteCountingStrategyProvider(), - poll); + protected VoteCounting getVoteCounting(Poll poll) { + return Polls.getVoteCounting(getVoteCountingFactory(), poll); } /** @@ -476,7 +475,7 @@ getTransaction(), getConfiguration(), serviceFactory, - getVoteCountingStrategyProvider() + getVoteCountingFactory() ); } return serviceContext; Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ResultForPoll.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ResultForPoll.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/ResultForPoll.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -47,7 +47,7 @@ import org.chorem.pollen.votecounting.model.ChoiceScore; import org.chorem.pollen.votecounting.model.GroupVoteCountingResult; import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategy; +import org.chorem.pollen.votecounting.VoteCounting; import org.nuiton.topia.persistence.TopiaId; import java.net.URL; @@ -131,14 +131,14 @@ } public String getVoteCountingTypeName() { - VoteCountingStrategy strategy = getVoteCountingStrategy(getPoll()); - String result = strategy.getStrategyName(getLocale()); + VoteCounting voteCounting = getVoteCounting(getPoll()); + String result = voteCounting.getStrategyName(getLocale()); return result; } public String getVoteCountingTypeHelp() { - VoteCountingStrategy strategy = getVoteCountingStrategy(getPoll()); - String result = strategy.getStrategyHelp(getLocale()); + VoteCounting voteCounting = getVoteCounting(getPoll()); + String result = voteCounting.getStrategyHelp(getLocale()); return result; } Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/form/AbstractPollForm.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/form/AbstractPollForm.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/form/AbstractPollForm.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -46,6 +46,7 @@ import org.chorem.pollen.business.persistence.Choice; import org.chorem.pollen.business.persistence.ChoiceImpl; import org.chorem.pollen.business.persistence.ChoiceType; +import org.chorem.pollen.business.persistence.I18nAble; import org.chorem.pollen.business.persistence.PersonToList; import org.chorem.pollen.business.persistence.PersonToListImpl; import org.chorem.pollen.business.persistence.Poll; @@ -58,7 +59,6 @@ import org.chorem.pollen.business.persistence.UserAccount; import org.chorem.pollen.business.persistence.VotingList; import org.chorem.pollen.business.persistence.VotingListImpl; -import org.chorem.pollen.business.persistence.I18nAble; import org.chorem.pollen.services.PollenServiceFunctions; import org.chorem.pollen.services.exceptions.PollNotFoundException; import org.chorem.pollen.services.impl.PollService; @@ -66,8 +66,8 @@ import org.chorem.pollen.ui.actions.FileUploadAware; import org.chorem.pollen.ui.actions.PollenActionSupportForEdition; import org.chorem.pollen.ui.converters.DateConverter; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategy; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategyProvider; +import org.chorem.pollen.votecounting.VoteCounting; +import org.chorem.pollen.votecounting.VoteCountingFactory; import org.nuiton.util.StringUtil; import java.io.File; @@ -714,11 +714,8 @@ public String getVoteCountingHelp() { StringBuilder builder = new StringBuilder(); - VoteCountingStrategyProvider strategyProvider = - getVoteCountingStrategyProvider(); - Set<Integer> strategyIds = strategyProvider.getStrategyIds(); - for (Integer strategyId : strategyIds) { - VoteCountingStrategy strategy = strategyProvider.getStrategy(strategyId); + VoteCountingFactory voteCountingFactory = getVoteCountingFactory(); + for (VoteCounting strategy : voteCountingFactory) { String strategyHelp = strategy.getStrategyHelp(getLocale()); builder.append(strategyHelp).append("<br/><br/>"); } @@ -734,15 +731,11 @@ pollVoteVisibilities = decorateToName(PollVoteVisibility.values()); voteCountingTypes = Maps.newTreeMap(); - VoteCountingStrategyProvider strategyProvider = - getVoteCountingStrategyProvider(); - Set<Integer> strategyIds = strategyProvider.getStrategyIds(); - for (Integer strategyId : strategyIds) { - VoteCountingStrategy strategy = strategyProvider.getStrategy(strategyId); + VoteCountingFactory voteCountingFactory = getVoteCountingFactory(); + for (VoteCounting strategy : voteCountingFactory) { String strategyHelp = strategy.getStrategyName(getLocale()); - voteCountingTypes.put(strategyId + "", strategyHelp); + voteCountingTypes.put(strategy.getId() + "", strategyHelp); } -// decorateToName(VoteCountingType.values()); textChoices = Lists.newArrayList(); imageChoices = Lists.newArrayList(); Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/vote/AbstractVoteAction.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/vote/AbstractVoteAction.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/vote/AbstractVoteAction.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -36,11 +36,11 @@ import org.chorem.pollen.business.persistence.Poll; import org.chorem.pollen.business.persistence.PollAccount; import org.chorem.pollen.business.persistence.PollCommentVisibility; +import org.chorem.pollen.business.persistence.PollType; import org.chorem.pollen.business.persistence.PollVoteVisibility; import org.chorem.pollen.business.persistence.UserAccount; import org.chorem.pollen.business.persistence.Vote; import org.chorem.pollen.business.persistence.VoteToChoice; -import org.chorem.pollen.business.persistence.PollType; import org.chorem.pollen.services.exceptions.PollAccountNotFound; import org.chorem.pollen.services.exceptions.PollNotFoundException; import org.chorem.pollen.ui.PollenUIUtils; @@ -48,7 +48,7 @@ import org.chorem.pollen.ui.actions.PollUriAware; import org.chorem.pollen.ui.actions.PollenActionSupport; import org.chorem.pollen.ui.actions.PollenUserSecurityAware; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategy; +import org.chorem.pollen.votecounting.VoteCounting; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -168,14 +168,14 @@ } public String getVoteCountingTypeName() { - VoteCountingStrategy strategy = getVoteCountingStrategy(getPoll()); - String result = strategy.getStrategyName(getLocale()); + VoteCounting voteCounting = getVoteCounting(getPoll()); + String result = voteCounting.getStrategyName(getLocale()); return result; } public String getVoteCountingTypeHelp() { - VoteCountingStrategy strategy = getVoteCountingStrategy(getPoll()); - String result = strategy.getStrategyHelp(getLocale()); + VoteCounting voteCounting = getVoteCounting(getPoll()); + String result = voteCounting.getStrategyHelp(getLocale()); return result; } @@ -212,41 +212,15 @@ * @return true si le choix est dans le vote */ public boolean isChoiceInVote(VoteToChoice choice) { - VoteCountingStrategy strategy = getVoteCountingStrategy(getPoll()); - boolean result = strategy.isChoiceInVote(choice.getVoteValue()); + VoteCounting voteCounting = getVoteCounting(getPoll()); + boolean result = voteCounting.isChoiceInVote(choice.getVoteValue()); return result; -// Integer voteValue = choice.getVoteValue(); -// boolean result = false; -// if (choice != null) { -// switch (poll.getVoteCountingType()) { -// case NORMAL: -// result = voteValue > 0; -// break; -// case PERCENTAGE: -// result = true; -// break; -// case CONDORCET: -// result = voteValue < 100; -// break; -// case NUMBER: -// result = voteValue >= 0; -// } -// } -// return result; } public String getChoiceValue(VoteToChoice choice) { - VoteCountingStrategy strategy = getVoteCountingStrategy(getPoll()); - String result = strategy.getDisplayVoteValue(choice.getVoteValue()); + VoteCounting voteCounting = getVoteCounting(getPoll()); + String result = voteCounting.getDisplayVoteValue(choice.getVoteValue()); return result; -// switch (poll.getVoteCountingType()) { -// case NORMAL: -// result = "OK"; -// break; -// default: -// result = choice.getVoteValue() + ""; -// } -// return result; } public String getCommentAuthor() { @@ -408,9 +382,9 @@ } public String getChoiceFragment() { - VoteCountingStrategy strategy = getVoteCountingStrategy(poll); + VoteCounting voteCounting = getVoteCounting(poll); String result = - "displayVote_" + strategy.getVoteValueEditorType().name() + ".jsp"; + "displayVote_" + voteCounting.getVoteValueEditorType().name() + ".jsp"; return result; } Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/vote/VoteForPoll.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/vote/VoteForPoll.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/vote/VoteForPoll.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -33,7 +33,7 @@ import org.chorem.pollen.business.persistence.Vote; import org.chorem.pollen.business.persistence.VoteToChoice; import org.chorem.pollen.services.impl.VoteService; -import org.chorem.pollen.votecounting.strategy.VoteCountingStrategy; +import org.chorem.pollen.votecounting.VoteCounting; import static org.nuiton.i18n.I18n.n_; @@ -99,7 +99,7 @@ } // check if the votingId is available - if (!getVoteService().isVotingIdFree(poll, pollAccount.getTopiaId(),name)) { + if (!getVoteService().isVotingIdFree(poll, pollAccount.getTopiaId(), name)) { addFieldError("pollAccount.votingId", _("pollen.error.user.alreadyVoted", name)); } @@ -108,7 +108,7 @@ int nbVotes = 0; int totalValues = 0; - VoteCountingStrategy strategy = getVoteCountingStrategy(getPoll()); + VoteCounting voteCounting = getVoteCounting(getPoll()); boolean voteValid = true; int voteNumber = -1; @@ -122,7 +122,7 @@ // check value if same as the one return by request // otherwise it means there is a conversion error String[] values = getParameters().get("vote.choiceVoteToChoice[" + voteNumber + "].voteValue"); - String paramValue = values==null || values.length<1?null:values[0]; + String paramValue = values == null || values.length < 1 ? null : values[0]; if (StringUtils.isNotBlank(paramValue)) { @@ -135,7 +135,7 @@ } } // check if vote is null ? - boolean voteNull = strategy.isVoteValueNull(value); + boolean voteNull = voteCounting.isVoteValueNull(value); if (voteNull) { // null vote, can skip his validation @@ -143,7 +143,7 @@ } // check if vote value is valid ? - boolean valid = strategy.isVoteValueValid(value); + boolean valid = voteCounting.isVoteValueValid(value); if (valid) { @@ -154,7 +154,7 @@ // not a valid vote value, mark it and skip other fields validation String validMessage = - strategy.getVoteValueNotValidMessage(getLocale()); + voteCounting.getVoteValueNotValidMessage(getLocale()); addFieldError("vote.choices", validMessage); voteValid = false; break; @@ -170,11 +170,11 @@ } // check that total vote value is ok - if (!strategy.isTotalVoteValueValid(totalValues)) { + if (!voteCounting.isTotalVoteValueValid(totalValues)) { // not valid String errorMessage = - strategy.getTotalVoteValueNotValidMessage(getLocale()); + voteCounting.getTotalVoteValueNotValidMessage(getLocale()); addFieldError("vote.choices", errorMessage); } } Modified: trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/AbstractPollenAuthorization.java =================================================================== --- trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/AbstractPollenAuthorization.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/security/AbstractPollenAuthorization.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -233,7 +233,7 @@ transaction, applicationContext.getConfiguration(), serviceFactory, - applicationContext.getVoteCountingStrategyProvider() + applicationContext.getVoteCountingFactory() ); return serviceContext.newService(SecurityService.class); Added: trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingFactoryTest.java =================================================================== --- trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingFactoryTest.java (rev 0) +++ trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingFactoryTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,50 @@ +package org.chorem.pollen.votecounting.strategy; + +import org.chorem.pollen.votecounting.BordaVoteCounting; +import org.chorem.pollen.votecounting.CondorcetVoteCounting; +import org.chorem.pollen.votecounting.CoombsVoteCounting; +import org.chorem.pollen.votecounting.InstantRunoffVoteCounting; +import org.chorem.pollen.votecounting.NormalVoteCounting; +import org.chorem.pollen.votecounting.NumberVoteCounting; +import org.chorem.pollen.votecounting.PercentageVoteCounting; +import org.chorem.pollen.votecounting.VoteCounting; +import org.chorem.pollen.votecounting.VoteCountingFactory; +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests the {@link VoteCountingFactory}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class VoteCountingFactoryTest { + + @Test + public void getVoteCounting() throws Exception { + + VoteCountingFactory factory = new VoteCountingFactory(); + VoteCounting voteCounting; + + voteCounting = factory.getVoteCounting(BordaVoteCounting.ID); + Assert.assertNotNull(voteCounting); + + voteCounting = factory.getVoteCounting(CondorcetVoteCounting.ID); + Assert.assertNotNull(voteCounting); + + voteCounting = factory.getVoteCounting(CoombsVoteCounting.ID); + Assert.assertNotNull(voteCounting); + + voteCounting = factory.getVoteCounting(InstantRunoffVoteCounting.ID); + Assert.assertNotNull(voteCounting); + + voteCounting = factory.getVoteCounting(NormalVoteCounting.ID); + Assert.assertNotNull(voteCounting); + + voteCounting = factory.getVoteCounting(NumberVoteCounting.ID); + Assert.assertNotNull(voteCounting); + + voteCounting = factory.getVoteCounting(PercentageVoteCounting.ID); + Assert.assertNotNull(voteCounting); + } +} Property changes on: trunk/pollen-ui-struts2/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingFactoryTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/pollen-ui-struts2/src/test/resources/log4j.properties (from rev 3707, trunk/pollen-votecounting-strategy-borda/src/test/resources/log4j.properties) =================================================================== --- trunk/pollen-ui-struts2/src/test/resources/log4j.properties (rev 0) +++ trunk/pollen-ui-struts2/src/test/resources/log4j.properties 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,8 @@ +# Global logging configuration +log4j.rootLogger=WARN, stdout +# Console output... +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d %5p [%t] (%F:%L) %M - %m%n +# package level +log4j.logger.org.chorem.pollen=INFO Property changes on: trunk/pollen-ui-struts2/src/test/resources/log4j.properties ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/pollen-votecounting-aggregator/pom.xml =================================================================== --- trunk/pollen-votecounting-strategy/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-aggregator/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,12 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> - <!-- ************************************************************* --> - <!-- *** POM Relationships *************************************** --> - <!-- ************************************************************* --> - <parent> <groupId>org.chorem</groupId> <artifactId>pollen</artifactId> @@ -14,62 +12,62 @@ </parent> <groupId>org.chorem.pollen</groupId> - <artifactId>pollen-votecounting-strategy</artifactId> + <artifactId>pollen-votecounting-aggregator</artifactId> + <name>Pollen :: VoteCounting (Aggregator)</name> + <description> + Aggregator of all implementations of votecounting offers by Pollen + </description> + + <packaging>pom</packaging> + <modules> - <module>../pollen-votecounting-strategy-normal</module> - <module>../pollen-votecounting-strategy-percentage</module> - <module>../pollen-votecounting-strategy-condorcet</module> - <module>../pollen-votecounting-strategy-number</module> - <module>../pollen-votecounting-strategy-borda</module> - <module>../pollen-votecounting-strategy-instant-runoff</module> - <module>../pollen-votecounting-strategy-coombs</module> + <module>../pollen-votecounting-normal</module> + <module>../pollen-votecounting-percentage</module> + <module>../pollen-votecounting-condorcet</module> + <module>../pollen-votecounting-number</module> + <module>../pollen-votecounting-borda</module> + <module>../pollen-votecounting-instant-runoff</module> + <module>../pollen-votecounting-coombs</module> </modules> <dependencies> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>pollen-votecounting-strategy-normal</artifactId> + <artifactId>pollen-votecounting-normal</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>pollen-votecounting-strategy-percentage</artifactId> + <artifactId>pollen-votecounting-percentage</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>pollen-votecounting-strategy-condorcet</artifactId> + <artifactId>pollen-votecounting-condorcet</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>pollen-votecounting-strategy-number</artifactId> + <artifactId>pollen-votecounting-number</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>pollen-votecounting-strategy-borda</artifactId> + <artifactId>pollen-votecounting-borda</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>pollen-votecounting-strategy-instant-runoff</artifactId> + <artifactId>pollen-votecounting-instant-runoff</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> - <artifactId>pollen-votecounting-strategy-coombs</artifactId> + <artifactId>pollen-votecounting-coombs</artifactId> <version>${project.version}</version> </dependency> </dependencies> - <name>Pollen :: VoteCounting strategy</name> - <description> - Aggregator of all implementations of votecounting strategy - </description> - - <packaging>pom</packaging> - </project> Modified: trunk/pollen-votecounting-api/pom.xml =================================================================== --- trunk/pollen-votecounting-api/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-api/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -14,7 +14,7 @@ <groupId>org.chorem.pollen</groupId> <artifactId>pollen-votecounting-api</artifactId> - <name>Pollen :: VoteCounting Api</name> + <name>Pollen :: VoteCounting (Api)</name> <description>Define Api to votecount</description> <dependencies> @@ -23,23 +23,28 @@ <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> </dependency> + <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </dependency> + <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> + <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> </dependency> + <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> <scope>test</scope> </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> Added: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCounting.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCounting.java (rev 0) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCounting.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,71 @@ +package org.chorem.pollen.votecounting; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.l_; + +/** + * Base abstract implementation of a {@link VoteCounting}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6 + */ +public abstract class AbstractVoteCounting<S extends VoteCountingStrategy> implements VoteCounting<S> { + + protected final int strategyId; + + protected final Class<S> strategyType; + + protected final String i18nName; + + protected final String i18nHelp; + + public AbstractVoteCounting(int strategyId, + Class<S> strategyType, + String i18nName, + String i18nHelp) { + this.strategyId = strategyId; + this.strategyType = strategyType; + this.i18nName = i18nName; + this.i18nHelp = i18nHelp; + } + + @Override + public final S newVoteCountingStrategy() { + try { + return strategyType.newInstance(); + } catch (Exception e) { + throw new RuntimeException("Could not instanciate strategy", e); + } + } + + @Override + public final String getStrategyName(Locale locale) { + String result = l_(locale, getI18nName()); + return result; + } + + @Override + public final String getStrategyHelp(Locale locale) { + String voteName = l_(locale, getI18nName()); + String voteHelp = l_(locale, getI18nHelp()); + String result = l_(locale, "pollen.voteCountingType.help", voteName, voteHelp); + return result; + } + + @Override + public final int getId() { + return strategyId; + } + + @Override + public final String getI18nName() { + return i18nName; + } + + @Override + public final String getI18nHelp() { + return i18nHelp; + } + +} Property changes on: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCounting.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java (from rev 3707, trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/AbstractVoteCountingStrategy.java) =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java (rev 0) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,187 @@ +/* + * #%L + * Pollen :: VoteCounting Api + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.chorem.pollen.votecounting.model.ChoiceIdAble; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.GroupOfVoter; +import org.chorem.pollen.votecounting.model.GroupVoteCountingResult; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.VoteForChoice; +import org.chorem.pollen.votecounting.model.Voter; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; + +/** + * Base abstract implementation of a {@link VoteCountingStrategy}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public abstract class AbstractVoteCountingStrategy implements VoteCountingStrategy { + + public static final BigDecimal ZERO_D = BigDecimal.valueOf(0.); + + @Override + public final GroupVoteCountingResult votecount(GroupOfVoter group) { + + Set<GroupOfVoter> groups = Sets.newHashSet(); + voteCount(group, groups); + + GroupVoteCountingResult result = GroupVoteCountingResult.newResult( + group, groups); + return result; + } + + public SortedMap<String, ChoiceScore> votersToResult(Set<Voter> voters) { + // get all choice Id + Set<String> choiceIds = getAllChoiceIds(voters); + + SortedMap<String, ChoiceScore> resultByChoice = Maps.newTreeMap(); + + // creates all empty result for choice + for (String choiceId : choiceIds) { + ChoiceScore choiceScore = ChoiceScore.newScore(choiceId, null); + resultByChoice.put(choiceId, choiceScore); + } + return resultByChoice; + } + + public VoteCountingResult resultToList(Map<String, ChoiceScore> resultByChoice) { + List<ChoiceScore> score = toChoiceScore(resultByChoice); + return VoteCountingResult.newResult(score); + } + + public List<ChoiceScore> toChoiceScore(Map<String, ChoiceScore> resultByChoice) { + List<ChoiceScore> score = Lists.newArrayList(resultByChoice.values()); + Collections.sort(score); + Collections.reverse(score); + return score; + } + + public Set<String> getAllChoiceIds(Set<Voter> voters) { + ChoiceIdAble.ChoiceIdAbleById function = new ChoiceIdAble.ChoiceIdAbleById(); + Set<String> result = Sets.newHashSet(); + for (Voter voter : voters) { + Iterable<String> transform = Iterables.transform( + voter.getVoteForChoices(), function); + Iterables.addAll(result, transform); + + } + return result; + } + + public Map<Voter, List<Set<String>>> buildVoterSortedChoices(Set<Voter> voters) { + + VoteForChoiceComparator comparator = new VoteForChoiceComparator(); + + Map<Voter, List<Set<String>>> voterSortedChoices = Maps.newHashMap(); + + for (Voter voter : voters) { + + List<Set<String>> sortedChoices = sortVoteForChoices( + voter.getVoteForChoices(), comparator); + voterSortedChoices.put(voter, sortedChoices); + } + return voterSortedChoices; + } + + public List<Set<String>> sortVoteForChoices(Set<VoteForChoice> voteForChoices, + Comparator<VoteForChoice> comparator) { + // get sort vote for choices + List<VoteForChoice> sortedChoices = Lists.newArrayList(voteForChoices); + Collections.sort(sortedChoices, comparator); + + // build ranks + List<Set<String>> result = Lists.newArrayList(); + + Set<String> set = Sets.newHashSet(); + result.add(set); + VoteForChoice lastVoteForChoice = null; + for (VoteForChoice voteForChoice : sortedChoices) { + if (lastVoteForChoice != null && + comparator.compare(lastVoteForChoice, voteForChoice) != 0) { + + // new rank found + // register it + result.add(set = Sets.newHashSet()); + } + + set.add(voteForChoice.getChoiceId()); + lastVoteForChoice = voteForChoice; + } + return result; + } + + protected void voteCount(GroupOfVoter group, Set<GroupOfVoter> groups) { + + groups.add(group); + + // all childs of this group + Set<Voter> voters = group.getVoters(); + + // treat before all his group childs + for (Voter voter : voters) { + if (voter instanceof GroupOfVoter) { + + // treat group child before all + voteCount((GroupOfVoter) voter, groups); + } + } + + // once here, all childs has been treated, can votecount this group + VoteCountingResult voteCountingResult = votecount(voters); + + // store the result for this group + group.setResult(voteCountingResult); + } + + public static class VoteForChoiceComparator implements Comparator<VoteForChoice>, Serializable { + + private static final long serialVersionUID = 1L; + + @Override + public int compare(VoteForChoice o1, VoteForChoice o2) { + Double v1 = o1.getVoteValue(); + Double v2 = o2.getVoteValue(); + if (v1 == null) { + v1 = Double.MAX_VALUE; + } + if (v2 == null) { + v2 = Double.MAX_VALUE; + } + return v1.intValue() - v2.intValue(); + } + } +} Property changes on: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/AbstractVoteCountingStrategy.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCounting.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCounting.java (rev 0) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCounting.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,127 @@ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; + +import java.util.Locale; + +/** + * Contract of a vote counting. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6 + */ +public interface VoteCounting<S extends VoteCountingStrategy> { + + /** + * Obtains a fresh instance of a vote coutning strategy. + * + * @return a new instance of vote counting strategy for this type + * of vote counting. + */ + S newVoteCountingStrategy(); + + /** + * Obtains the unique id of this strategy. + * + * @return the unique id of this strategy. + */ + int getId(); + + /** + * Obtains the i18n name of this strategy. + * + * @return the i18n name of this strategy. + */ + String getI18nName(); + + /** + * Obtains the i18n help of this strategy. + * + * @return the i18n help of this strategy. + */ + String getI18nHelp(); + + /** + * Get the value to display for a given vote value in the vote page. + * + * @param voteValue the vote value to display + * @return the string representation of a vote value + */ + String getDisplayVoteValue(Integer voteValue); + + /** + * Test if the given value is a vote value (says users has filled it). + * + * @param voteValue the vote value to test + * @return {@code true} if the given value is persisted. + */ + boolean isChoiceInVote(Integer voteValue); + + /** + * Get the vote counting strategy name to display in UI. + * + * @param locale the locale used to render the strategy name + * @return the localized vote counting strategy name + */ + String getStrategyName(Locale locale); + + /** + * Get the vote counting strategy help to display in UI. + * + * @param locale the locale used to render the strategy name + * @return the localized vote counting strategy help + */ + String getStrategyHelp(Locale locale); + + /** + * Tests if the given vote value is valid. + * + * @param voteValue the vote value to test + * @return {@code true} if the given vote value is valid, {@code false} + * otherwise. + */ + boolean isVoteValueValid(Integer voteValue); + + /** + * If a vote value is not valid, gets the localized message of the error. + * + * @param locale the locale used to render the error message + * @return the localized validation message + */ + String getVoteValueNotValidMessage(Locale locale); + + /** + * Tests if the total values of a vote is valid. + * + * @param totalValues the given total values + * @return {@code true} if the total values of a vote is valid, + * {@code false} otherwhise. + */ + boolean isTotalVoteValueValid(int totalValues); + + /** + * If the total values of a vote is not valid, gets the localized error + * message. + * + * @param locale the locale used to render the error message + * @return the localized validation message + */ + String getTotalVoteValueNotValidMessage(Locale locale); + + /** + * Tests if a given vote value is null or not. + * + * @param value the vote value to test + * @return {@code true} if the given vote value is null (or considered as + * null), {@code false} otherwise. + */ + boolean isVoteValueNull(Integer value); + + /** + * Gets the type of editor used to render a vote value. + * + * @return the type of editor used to render a vote value. + * @see ChoiceToVoteRenderType + */ + ChoiceToVoteRenderType getVoteValueEditorType(); +} Property changes on: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCounting.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingFactory.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingFactory.java (rev 0) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingFactory.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,69 @@ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Maps; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Iterator; +import java.util.Map; +import java.util.ServiceLoader; + +/** + * Factory of {@link VoteCounting}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6 + */ +public class VoteCountingFactory implements Iterable<VoteCounting> { + + /** Logger. */ + private static final Log log = LogFactory.getLog(VoteCountingFactory.class); + + /** + * List of available vote counting detected via the {@link ServiceLoader} + * mecanism no contract {@link VoteCounting}. + */ + private final Map<Integer, VoteCounting> voteCountings; + + public VoteCountingFactory() { + voteCountings = Maps.newHashMap(); + + ServiceLoader<VoteCounting> loader = + ServiceLoader.load(VoteCounting.class); + + for (VoteCounting strategy : loader) { + int id = strategy.getId(); + + if (voteCountings.containsKey(id)) { + throw new IllegalStateException( + "Strategy [" + + strategy.getI18nName() + "] with id " + id + + ", can not be used since the id is already used " + + "by strategy [" + voteCountings.get(id).getI18nName() + "] "); + } + if (log.isInfoEnabled()) { + log.info("Detected strategy [" + id + "-" + + strategy.getI18nName() + "] : " + + strategy.getClass().getName()); + } + voteCountings.put(id, strategy); + } + + + } + + public VoteCounting getVoteCounting(int strategyId) throws VoteCountingNotFound { + VoteCounting type = voteCountings.get(strategyId); + + if (type == null) { + throw new VoteCountingNotFound( + "Could not find strategy with id " + strategyId); + } + return type; + } + + @Override + public Iterator<VoteCounting> iterator() { + return voteCountings.values().iterator(); + } +} Property changes on: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingFactory.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingNotFound.java (from rev 3707, trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountigStrategyNotFound.java) =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingNotFound.java (rev 0) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingNotFound.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,41 @@ +/* + * #%L + * Pollen :: VoteCounting Api + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +/** + * Exception when a vote counting could not be found. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class VoteCountingNotFound extends RuntimeException { + private static final long serialVersionUID = 1L; + + public VoteCountingNotFound(String message) { + super(message); + } + + public VoteCountingNotFound(String message, Throwable cause) { + super(message, cause); + } +} Property changes on: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingNotFound.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingStrategy.java (from rev 3707, trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategy.java) =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingStrategy.java (rev 0) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,57 @@ +/* + * #%L + * Pollen :: VoteCounting Api + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.GroupOfVoter; +import org.chorem.pollen.votecounting.model.GroupVoteCountingResult; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; + +import java.util.Set; + +/** + * Strategy of a vote counting. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public interface VoteCountingStrategy { + + /** + * Vote count for the given {@code group} of voters and return the + * result of it. + * + * @param group the group of voters and their votes. + * @return the result of the group vote counting for the given voter. + */ + GroupVoteCountingResult votecount(GroupOfVoter group); + + /** + * Vote count for the given {@code voter} and return the result of it. + * + * @param voter the voter and their votes. + * @return the result of the vote counting for the given voter. + */ + VoteCountingResult votecount(Set<Voter> voter); + +} Property changes on: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/VoteCountingStrategy.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/ChoiceScore.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/ChoiceScore.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/ChoiceScore.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -26,21 +26,24 @@ import java.math.BigDecimal; /** - * ChoiceScore for a given choice. + * Score for a given choice. * * @author tchemit <chemit@codelutin.com> * @since 1.4.5 */ -public class ChoiceScore implements ChoiceIdAble, Comparable<ChoiceScore>,Serializable { +public class ChoiceScore implements ChoiceIdAble, Comparable<ChoiceScore>, Serializable { private static final long serialVersionUID = 1L; /** Id of the choice. */ private String choiceId; - /** Score for this choice. */ + /** Global score for this choice (in some poll does not mean a lot...). */ private BigDecimal scoreValue; + /** Order of this score (0 is winner, 1, second,...). */ + private int scoreOrder; + public static ChoiceScore newScore(String choiceId, BigDecimal scoreValue) { ChoiceScore choiceScore = new ChoiceScore(); choiceScore.setChoiceId(choiceId); @@ -57,6 +60,14 @@ return scoreValue; } + public int getScoreOrder() { + return scoreOrder; + } + + public void setScoreOrder(int scoreOrder) { + this.scoreOrder = scoreOrder; + } + public void setChoiceId(String choiceId) { this.choiceId = choiceId; } Modified: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/GroupVoteCountingResult.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/GroupVoteCountingResult.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/GroupVoteCountingResult.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -60,6 +60,7 @@ public Set<String> getGroupIds() { return Sets.newHashSet(groups.keySet()); } + public VoteCountingResult getGroupResult(String groupId) { GroupOfVoter groupOfVoter = groups.get(groupId); VoteCountingResult result = groupOfVoter.getResult(); Modified: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/SimpleVoterBuilder.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/SimpleVoterBuilder.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/SimpleVoterBuilder.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -49,7 +49,7 @@ @Override public SimpleVoterBuilder addVoteForChoice(String choiceId, Double voteValue) { - Preconditions.checkState(voter != null,"No voter defined, use method newVoter before this one"); + Preconditions.checkState(voter != null, "No voter defined, use method newVoter before this one"); VoteForChoice voteForChoice = VoteForChoice.newVote(choiceId, voteValue); voter.addVoteForChoice(voteForChoice); return this; Modified: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/model/VoteCountingResult.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -42,9 +42,15 @@ private static final long serialVersionUID = 1L; - /** Results for each choice. */ + /** + * Results for each choice. + * <p/> + * <strong>Note:</strong> Natural order is used to describe choice scores + * (first is winner,...). + */ private List<ChoiceScore> scores; + /** Get the winners (could be more than one of it). */ private Set<ChoiceScore> topRanking; public static VoteCountingResult newResult(List<ChoiceScore> scores) { Deleted: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/AbstractVoteCountingStrategy.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/AbstractVoteCountingStrategy.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/AbstractVoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,227 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting Api - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.chorem.pollen.votecounting.model.ChoiceIdAble; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.GroupOfVoter; -import org.chorem.pollen.votecounting.model.GroupVoteCountingResult; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.VoteForChoice; -import org.chorem.pollen.votecounting.model.Voter; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; - -import static org.nuiton.i18n.I18n.l_; - -/** - * Base abstract implementation of a {@link VoteCountingStrategy}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public abstract class AbstractVoteCountingStrategy implements VoteCountingStrategy { - - public static final BigDecimal ZERO_D = BigDecimal.valueOf(0.); - - @Override - public final GroupVoteCountingResult votecount(GroupOfVoter group) { - - Set<GroupOfVoter> groups = Sets.newHashSet(); - voteCount(group, groups); - - GroupVoteCountingResult result = GroupVoteCountingResult.newResult( - group, groups); - return result; - } - - @Override - public String getStrategyName(Locale locale) { - String result = l_(locale, getI18nName()); - return result; - } - - @Override - public String getStrategyHelp(Locale locale) { - String voteName = l_(locale, getI18nName()); - String voteHelp = l_(locale, getI18nHelp()); - String result = l_(locale, "pollen.voteCountingType.help", voteName, voteHelp); - return result; - } - - public SortedMap<String, ChoiceScore> votersToResult(Set<Voter> voters) { - // get all choice Id - Set<String> choiceIds = getAllChoiceIds(voters); - - SortedMap<String, ChoiceScore> resultByChoice = Maps.newTreeMap(); - - // creates all empty result for choice - for (String choiceId : choiceIds) { - ChoiceScore choiceScore = ChoiceScore.newScore(choiceId, null); - resultByChoice.put(choiceId, choiceScore); - } - return resultByChoice; - } - - public VoteCountingResult resultToList(Map<String, ChoiceScore> resultByChoice) { - List<ChoiceScore> score = toChoiceScore(resultByChoice); - return VoteCountingResult.newResult(score); - } - - public List<ChoiceScore> toChoiceScore(Map<String, ChoiceScore> resultByChoice) { - List<ChoiceScore> score = Lists.newArrayList(resultByChoice.values()); - Collections.sort(score); - Collections.reverse(score); - return score; - } - - public Set<String> getAllChoiceIds(Set<Voter> voters) { - ChoiceIdAble.ChoiceIdAbleById function = new ChoiceIdAble.ChoiceIdAbleById(); - Set<String> result = Sets.newHashSet(); - for (Voter voter : voters) { - Iterable<String> transform = Iterables.transform( - voter.getVoteForChoices(), function); - Iterables.addAll(result, transform); - - } - return result; - } - - public Map<Voter, List<Set<String>>> buildVoterSortedChoices(Set<Voter> voters) { - - VoteForChoiceComparator comparator = new VoteForChoiceComparator(); - - Map<Voter, List<Set<String>>> voterSortedChoices = Maps.newHashMap(); - - for (Voter voter : voters) { - - List<Set<String>> sortedChoices = sortVoteForChoices( - voter.getVoteForChoices(), comparator); - voterSortedChoices.put(voter, sortedChoices); - } - return voterSortedChoices; - } - - public List<Set<String>> sortVoteForChoices(Set<VoteForChoice> voteForChoices, - Comparator<VoteForChoice> comparator) { - // get sort vote for choices - List<VoteForChoice> sortedChoices = Lists.newArrayList(voteForChoices); - Collections.sort(sortedChoices, comparator); - - // build ranks - List<Set<String>> result = Lists.newArrayList(); - - Set<String> set = Sets.newHashSet(); - result.add(set); - VoteForChoice lastVoteForChoice = null; - for (VoteForChoice voteForChoice : sortedChoices) { - if (lastVoteForChoice != null && - comparator.compare(lastVoteForChoice, voteForChoice) != 0) { - - // new rank found - // register it - result.add(set = Sets.newHashSet()); - } - - set.add(voteForChoice.getChoiceId()); - lastVoteForChoice = voteForChoice; - } - return result; - } - - public Set<String> getDirectWinners(Collection<List<Set<String>>> values) { - Set<String> result = null; - for (List<Set<String>> value : values) { - - Set<String> topChoices = value.get(0); - - if (result == null) { - // first time coming here - result = topChoices; - } else { - - if (!result.equals(topChoices)) { - - // not same first ranking, not direct winner - result = null; - break; - } - } - } - return result; - } - - protected void voteCount(GroupOfVoter group, Set<GroupOfVoter> groups) { - - groups.add(group); - - // all childs of this group - Set<Voter> voters = group.getVoters(); - - // treat before all his group childs - for (Voter voter : voters) { - if (voter instanceof GroupOfVoter) { - - // treat group child before all - voteCount((GroupOfVoter) voter, groups); - } - } - - // once here, all childs has been treated, can votecount this group - VoteCountingResult voteCountingResult = votecount(voters); - - // store the result for this group - group.setResult(voteCountingResult); - } - - public static class VoteForChoiceComparator implements Comparator<VoteForChoice>, Serializable { - - private static final long serialVersionUID = 1L; - - @Override - public int compare(VoteForChoice o1, VoteForChoice o2) { - Double v1 = o1.getVoteValue(); - Double v2 = o2.getVoteValue(); - if (v1 == null) { - v1 = Double.MAX_VALUE; - } - if (v2 == null) { - v2 = Double.MAX_VALUE; - } - return v1.intValue() - v2.intValue(); - } - } -} Deleted: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountigStrategyNotFound.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountigStrategyNotFound.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountigStrategyNotFound.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,41 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting Api - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -/** - * Exception when a vote counting could not be found. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class VoteCountigStrategyNotFound extends RuntimeException { - private static final long serialVersionUID = 1L; - - public VoteCountigStrategyNotFound(String message) { - super(message); - } - - public VoteCountigStrategyNotFound(String message, Throwable cause) { - super(message, cause); - } -} Deleted: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategy.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategy.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,163 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting Api - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; -import org.chorem.pollen.votecounting.model.GroupOfVoter; -import org.chorem.pollen.votecounting.model.GroupVoteCountingResult; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; - -import java.util.Locale; -import java.util.Set; - -/** - * Contract of a vote counting method. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public interface VoteCountingStrategy { - - /** - * Obtains the unique id of this strategy. - * - * @return the unique id of this strategy. - */ - int getId(); - - /** - * Obtains the i18n name of this strategy. - * - * @return the i18n name of this strategy. - */ - String getI18nName(); - - /** - * Obtains the i18n help of this strategy. - * - * @return the i18n help of this strategy. - */ - String getI18nHelp(); - - GroupVoteCountingResult votecount(GroupOfVoter group); - - /** - * Vote count for the given {@code voter} and return the result of it. - * - * @param voter the voter and their votes. - * @return the result of the vote counting for the given voter. - */ - VoteCountingResult votecount(Set<Voter> voter); - - /** - * Get the value to display for a given vote value in the vote page. - * - * @param voteValue the vote value to display - * @return the string representation of a vote value - */ - String getDisplayVoteValue(Integer voteValue); - - /** - * Test if the given value is a vote value (says users has filled it). - * - * @param voteValue the vote value to test - * @return {@code true} if the given value is persisted. - */ - boolean isChoiceInVote(Integer voteValue); - - /** - * Get the vote counting strategy name to display in UI. - * - * @param locale the locale used to render the strategy name - * @return the localized vote counting strategy name - */ - String getStrategyName(Locale locale); - - /** - * Get the vote counting strategy help to display in UI. - * - * @param locale the locale used to render the strategy name - * @return the localized vote counting strategy help - */ - String getStrategyHelp(Locale locale); - - /** - * Tests if the given vote value is valid. - * - * @param voteValue the vote value to test - * @return {@code true} if the given vote value is valid, {@code false} - * otherwise. - */ - boolean isVoteValueValid(Integer voteValue); - - /** - * If a vote value is not valid, gets the localized message of the error. - * - * @param locale the locale used to render the error message - * @return the localized validation message - */ - String getVoteValueNotValidMessage(Locale locale); - - /** - * Tests if the total values of a vote is valid. - * - * @param totalValues the given total values - * @return {@code true} if the total values of a vote is valid, - * {@code false} otherwhise. - */ - boolean isTotalVoteValueValid(int totalValues); - - /** - * If the total values of a vote is not valid, gets the localized error - * message. - * - * @param locale the locale used to render the error message - * @return the localized validation message - */ - String getTotalVoteValueNotValidMessage(Locale locale); - - /** - * Tests if a given vote value is null or not. - * - * @param value the vote value to test - * @return {@code true} if the given vote value is null (or considered as - * null), {@code false} otherwise. - */ - boolean isVoteValueNull(Integer value); - - /** - * Gets the type of editor used to render a vote value. - * - * @return the type of editor used to render a vote value. - * @see ChoiceToVoteRenderType - */ - ChoiceToVoteRenderType getVoteValueEditorType(); - - /** - * @return {@code true} if display results by choice. - * @deprecated since 1.5 (result will be offered by the strategy it-self). - */ - @Deprecated - boolean isDisplayResultsByChoice(); -} Deleted: trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProvider.java =================================================================== --- trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProvider.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-api/src/main/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProvider.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,101 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting Api - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import java.util.Map; -import java.util.ServiceLoader; -import java.util.Set; - -/** - * Provider of {@link VoteCountingStrategy}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class VoteCountingStrategyProvider { - - /** Logger. */ - private static final Log log = - LogFactory.getLog(VoteCountingStrategyProvider.class); - - /** - * List of available strageries detected via the {@link ServiceLoader} - * mecanism no contract {@link VoteCountingStrategy}. - */ - private final Map<Integer, VoteCountingStrategy> strategies; - - public VoteCountingStrategyProvider() { - strategies = load(); - } - - public Set<Integer> getStrategyIds() { - return ImmutableSet.copyOf(strategies.keySet()); - } - - public VoteCountingStrategy getStrategy(int strategyId) throws VoteCountigStrategyNotFound { - VoteCountingStrategy type = strategies.get(strategyId); - - if (type == null) { - throw new VoteCountigStrategyNotFound( - "Could not find strategy with id " + strategyId); - } - try { - //FIXME-tchemit-2012-06-24 : should we reinstanciate each time ? - return type.getClass().newInstance(); - } catch (Exception e) { - - throw new VoteCountigStrategyNotFound( - "Could not instanciate stragegy " + strategyId, e); - } - } - - protected Map<Integer, VoteCountingStrategy> load() { - Map<Integer, VoteCountingStrategy> result = Maps.newTreeMap(); - ServiceLoader<VoteCountingStrategy> loader = - ServiceLoader.load(VoteCountingStrategy.class); - - for (VoteCountingStrategy strategy : loader) { - int id = strategy.getId(); - if (result.containsKey(id)) { - throw new IllegalStateException( - "Strategy [" + - strategy.getI18nName() + "] with id " + id + - ", can not be used since the id is already used " + - "by strategy [" + result.get(id).getI18nName() + "] "); - } - if (log.isInfoEnabled()) { - log.info("Detected strategy [" + id + "-" + - strategy.getI18nName() + "] : " + - strategy.getClass().getName()); - } - result.put(id, strategy); - } - return result; - } - -} Copied: trunk/pollen-votecounting-api/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (from rev 3707, trunk/pollen-votecounting-api/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java) =================================================================== --- trunk/pollen-votecounting-api/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (rev 0) +++ trunk/pollen-votecounting-api/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,43 @@ +/* + * #%L + * Pollen :: VoteCounting Api + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests the {@link VoteCountingFactory}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class VoteCountingFactoryTest { + + @Test(expected = VoteCountingNotFound.class) + public void getVoteCounting() throws Exception { + + VoteCountingFactory factory = new VoteCountingFactory(); + VoteCounting voteCounting = factory.getVoteCounting(-1); + Assert.assertNull(voteCounting); + } +} Property changes on: trunk/pollen-votecounting-api/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-api/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java =================================================================== --- trunk/pollen-votecounting-api/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-api/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,49 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting Api - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Tests the {@link VoteCountingStrategyProvider}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class VoteCountingStrategyProviderTest { - - protected static VoteCountingStrategyProvider provider; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Test(expected = VoteCountigStrategyNotFound.class) - public void getStrategy() throws Exception { - - Assert.assertNull(provider.getStrategy(-1)); - } -} Modified: trunk/pollen-votecounting-borda/pom.xml =================================================================== --- trunk/pollen-votecounting-strategy-borda/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-borda/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -10,11 +12,10 @@ </parent> <groupId>org.chorem.pollen</groupId> - <artifactId>pollen-votecounting-strategy-borda</artifactId> + <artifactId>pollen-votecounting-borda</artifactId> + <name>Pollen :: VoteCounting :: Borda</name> + <description>Implements the borda vote counting</description> - <name>Pollen :: VoteCounting strategy :: Borda</name> - <description>Implements the borda vote counting strategy</description> - <dependencies> <dependency> @@ -39,6 +40,12 @@ </dependency> <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> Added: trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCounting.java =================================================================== --- trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCounting.java (rev 0) +++ trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCounting.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,69 @@ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.l_; +import static org.nuiton.i18n.I18n.n_; + +/** + * Borda vote counting entry point. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6 + */ +public class BordaVoteCounting extends AbstractVoteCounting<BordaVoteCountingStrategy> { + + public static final int ID = 4; + + public BordaVoteCounting() { + super(ID, + BordaVoteCountingStrategy.class, + n_("pollen.voteCountingType.borda"), + n_("pollen.voteCountingType.borda.help") + ); + } + + @Override + public String getTotalVoteValueNotValidMessage(Locale locale) { + // no validation on total value, so no message + return null; + } + + @Override + public String getVoteValueNotValidMessage(Locale locale) { + return l_(locale, "pollen.error.vote.invalidBordaVoteValue"); + } + + @Override + public String getDisplayVoteValue(Integer voteValue) { + return voteValue == null ? "" : String.valueOf(voteValue); + } + + @Override + public ChoiceToVoteRenderType getVoteValueEditorType() { + return ChoiceToVoteRenderType.TEXTFIELD; + } + + @Override + public boolean isChoiceInVote(Integer voteValue) { + return voteValue != null && voteValue > 0 && voteValue < 100; + } + + @Override + public boolean isVoteValueNull(Integer voteValue) { + return voteValue == null; + } + + @Override + public boolean isVoteValueValid(Integer voteValue) { + return voteValue != null && voteValue > 0; + } + + @Override + public boolean isTotalVoteValueValid(int totalValues) { + // no validation on total value + return true; + } +} Property changes on: trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCounting.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java (from rev 3707, trunk/pollen-votecounting-strategy-borda/src/main/java/org/chorem/pollen/votecounting/strategy/BordaStrategy.java) =================================================================== --- trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java (rev 0) +++ trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,88 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Borda + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Condorcet. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class BordaVoteCountingStrategy extends AbstractVoteCountingStrategy { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(BordaVoteCountingStrategy.class); + + @Override + public VoteCountingResult votecount(Set<Voter> voters) { + + // get empty result by choice + Map<String, ChoiceScore> resultByChoice = votersToResult(voters); + + // nb of choices + int nbChoices = resultByChoice.keySet().size(); + + if (log.isDebugEnabled()) { + log.debug("Nb choices: " + nbChoices); + } + + // calcul pour chaque votant de sa liste des choix dans son ordre préféré + + Map<Voter, List<Set<String>>> voterSortedChoices = + buildVoterSortedChoices(voters); + + // calcul des points pour chaque choix selon son ordre d'arrivé ( + // le 1er à nbChoices * weight point, le second (nbChoices-1) * weight,...) + + for (Map.Entry<Voter, List<Set<String>>> entry : voterSortedChoices.entrySet()) { + Voter voter = entry.getKey(); + double weight = voter.getWeight(); + double choiceWeight = nbChoices * weight; + for (Set<String> sortedChoiceId : entry.getValue()) { + + for (String choiceId : sortedChoiceId) { + + resultByChoice.get(choiceId).addScoreValue(choiceWeight); + } + choiceWeight -= weight; + } + } + + // transform map of result to list of them (and sort them) + VoteCountingResult result = resultToList(resultByChoice); + return result; + } + + +} Property changes on: trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategy.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/strategy/BordaStrategy.java =================================================================== --- trunk/pollen-votecounting-strategy-borda/src/main/java/org/chorem/pollen/votecounting/strategy/BordaStrategy.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-borda/src/main/java/org/chorem/pollen/votecounting/strategy/BordaStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,156 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Borda - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; - -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import static org.nuiton.i18n.I18n.l_; -import static org.nuiton.i18n.I18n.n_; - -/** - * Condorcet. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class BordaStrategy extends AbstractVoteCountingStrategy { - - public static final int ID = 4; - - /** Logger. */ - private static final Log log = LogFactory.getLog(BordaStrategy.class); - - @Override - public int getId() { - return ID; - } - - @Override - public String getI18nName() { - return n_("pollen.voteCountingType.borda"); - } - - @Override - public String getI18nHelp() { - return n_("pollen.voteCountingType.borda.help"); - } - - @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { - // no validation on total value, so no message - return null; - } - - @Override - public String getVoteValueNotValidMessage(Locale locale) { - return l_(locale, "pollen.error.vote.invalidBordaVoteValue"); - } - - @Override - public String getDisplayVoteValue(Integer voteValue) { - return voteValue == null ? "" : String.valueOf(voteValue); - } - - @Override - public ChoiceToVoteRenderType getVoteValueEditorType() { - return ChoiceToVoteRenderType.TEXTFIELD; - } - - @Override - public boolean isChoiceInVote(Integer voteValue) { - return voteValue != null && voteValue > 0 && voteValue < 100; - } - - @Override - public boolean isVoteValueNull(Integer voteValue) { - return voteValue == null; - } - - @Override - public boolean isDisplayResultsByChoice() { - return false; - } - - @Override - public boolean isVoteValueValid(Integer voteValue) { - return voteValue != null && voteValue > 0; - } - - @Override - public boolean isTotalVoteValueValid(int totalValues) { - // no validation on total value - return true; - } - - @Override - public VoteCountingResult votecount(Set<Voter> voters) { - - // get empty result by choice - Map<String, ChoiceScore> resultByChoice = votersToResult(voters); - - // nb of choices - int nbChoices = resultByChoice.keySet().size(); - - if (log.isDebugEnabled()) { - log.debug("Nb choices: " + nbChoices); - } - - // calcul pour chaque votant de sa liste des choix dans son ordre préféré - - Map<Voter, List<Set<String>>> voterSortedChoices = - buildVoterSortedChoices(voters); - - // calcul des points pour chaque choix selon son ordre d'arrivé ( - // le 1er à nbChoices *weight point, le second (nbChoices-1) * weight,...) - - for (Map.Entry<Voter, List<Set<String>>> entry : voterSortedChoices.entrySet()) { - Voter voter = entry.getKey(); - double weight = voter.getWeight(); - double choiceWeight = nbChoices * weight; - for (Set<String> sortedChoiceId : entry.getValue()) { - - for (String choiceId : sortedChoiceId) { - - resultByChoice.get(choiceId).addScoreValue(choiceWeight); - } - choiceWeight -= weight; - } - } - - // transform map of result to list of them (and sort them) - VoteCountingResult result = resultToList(resultByChoice); - return result; - } - - -} Copied: trunk/pollen-votecounting-borda/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (from rev 3707, trunk/pollen-votecounting-strategy-borda/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy) =================================================================== --- trunk/pollen-votecounting-borda/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (rev 0) +++ trunk/pollen-votecounting-borda/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1 @@ +org.chorem.pollen.votecounting.BordaVoteCounting Property changes on: trunk/pollen-votecounting-borda/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-borda/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy =================================================================== --- trunk/pollen-votecounting-strategy-borda/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-borda/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-29 12:36:25 UTC (rev 3708) @@ -1 +0,0 @@ -org.chorem.pollen.votecounting.strategy.BordaStrategy Copied: trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java (from rev 3707, trunk/pollen-votecounting-strategy-borda/src/test/java/org/chorem/pollen/votecounting/strategy/BordaStrategyTest.java) =================================================================== --- trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java (rev 0) +++ trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,326 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Borda + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.chorem.pollen.votecounting.model.ChoiceIdAble; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Tests the {@link BordaVoteCountingStrategy}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class BordaVoteCountingStrategyTest { + + public static final String CHOICE_A = "a"; + + public static final String CHOICE_B = "b"; + + public static final String CHOICE_C = "c"; + + public static final String CHOICE_D = "d"; + + protected static VoteCounting voteCounting; + + protected VoteCountingStrategy strategy; + + @BeforeClass + public static void beforeClass() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + voteCounting = factory.getVoteCounting(BordaVoteCounting.ID); + } + + @Before + public void setUp() throws Exception { + strategy = voteCounting.newVoteCountingStrategy(); + } + + @Test + public void simpleVotecount() throws Exception { + + // see http://fr.wikipedia.org/wiki/M%C3%A9thode_Borda + + // Ville 1re 2e 3e 4e Points + // A 42 0 0 58 226 (=42*4+58*1) + // B 26 42 32 0 294 (=26*4+42*3+32*2) + // C 15 43 42 0 273 (=15*4+43*3+42*2) + // D 17 15 26 42 207 (=17*4+15*3+26*2+42) + + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("Ville A", 42.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 3.). + addVoteForChoice(CHOICE_D, 4.). + newVoter("Ville B", 26.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 2.). + addVoteForChoice(CHOICE_D, 3.). + addVoteForChoice(CHOICE_A, 4.). + newVoter("Ville C", 15.). + addVoteForChoice(CHOICE_C, 1.). + addVoteForChoice(CHOICE_D, 2.). + addVoteForChoice(CHOICE_B, 3.). + addVoteForChoice(CHOICE_A, 4.). + newVoter("Ville D", 17.). + addVoteForChoice(CHOICE_D, 1.). + addVoteForChoice(CHOICE_C, 2.). + addVoteForChoice(CHOICE_B, 3.). + addVoteForChoice(CHOICE_A, 4.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(4, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(294.)); + assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(273.)); + assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(226.)); + assertChoiceScore(scores.get(3), CHOICE_D, BigDecimal.valueOf(207.)); + } + + @Test + public void simpleVotecount0() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=2 c=null) a(3) > b(2) > c(1) + // 2 (a=3 b=2 c=1) c(3) > b(2) > a(1) + // 3 (a=1 b=null c=2) a(3) > c(2) > b(1) + // Result a = 2*3+1=7, b =2*2+1=5, c = 1*3+1*2+1=6 + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 3.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(7.)); + assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(6.)); + assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(5.)); + } + + @Test + public void simpleVotecount2() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=2 c=null) a>b>c + // 2 (a=1 b=2 c=1) a|c>b + // 3 (a=null b=null c=2) c>a|b + // Result (a=3*2+2=8 b=2*3=6 c=1+2*3=7) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(8.)); + assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(7.)); + assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(6.)); + } + + @Test + public void simpleVotecount3() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=null c=null) a(3) > b|c(2) + // 2 (a=null b=1 c=null) b(3) > a|c(2) + // 3 (a=null b=null c=1) c(3) > a|c(2) + // Result (a=3+2*2=7 b=3+2*2=7 c=3+2*2=7) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(7.), + Sets.newHashSet(scores.get(0), + scores.get(1), + scores.get(2) + ), + CHOICE_A, CHOICE_B, CHOICE_C); + } + + @Test + public void weightedVotecount1() throws Exception { + + // poll with weighted vote + // 1 (x2) (a=1 b=null c=null) a(3) > b|c (2) + // 2 (x1) (a=null b=1 c=null) b(3) > a|c (2) + // 3 (x1) (a=null b=1 c=2) b(3) > c(2) > a(1) + // Result (a=2*3+1*2+1*1=9 b=2*2+1*3+1*3=10 c=2*2+1*2+1*2=8) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(10.)); + assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(9.)); + assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(8.)); + } + + @Test + public void weightedVotecount2() throws Exception { + + // poll with weighted vote + // 1 (x2) (a=1 b=null c=null) a(3) > b|c (2) + // 2 (x1) (a=null b=1 c=null) b(3) > a|c (2) + // 3 (x3) (a=null b=2 c=1) c(3) > b(2) > a(1) + // Result (a=1*3*2+1*2+1*1*3=11 b=2*2+1*3+3*2=13 c=2*2+1*2+3*3=15) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 3.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(15.)); + assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(13.)); + assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(11.)); + } + + public static void assertChoiceScore(ChoiceScore choiceScore, + String choiceId, + BigDecimal choiceResult) { + Assert.assertNotNull(choiceScore); + Assert.assertEquals(choiceId, choiceScore.getChoiceId()); + Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); + } + + public static void assertChoiceScoreEquals(BigDecimal choiceResult, + Set<ChoiceScore> choiceScores, + String... choiceIds) { + + Assert.assertNotNull(choiceScores); + Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( + choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); + for (String choiceId : choiceIds) { + + ChoiceScore choiceScore = choicesById.get(choiceId); + Assert.assertNotNull(choiceScore); + assertChoiceScore(choiceScore, choiceId, choiceResult); + } + } + +} Property changes on: trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/BordaVoteCountingStrategyTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (from rev 3707, trunk/pollen-votecounting-strategy-borda/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java) =================================================================== --- trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (rev 0) +++ trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,43 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Borda + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests the {@link VoteCountingFactory}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class VoteCountingFactoryTest { + + @Test + public void getVoteCounting() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + VoteCounting voteCounting = + factory.getVoteCounting(BordaVoteCounting.ID); + Assert.assertNotNull(voteCounting); + } +} Property changes on: trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/strategy/BordaStrategyTest.java =================================================================== --- trunk/pollen-votecounting-strategy-borda/src/test/java/org/chorem/pollen/votecounting/strategy/BordaStrategyTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/strategy/BordaStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,325 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Borda - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.chorem.pollen.votecounting.model.ChoiceIdAble; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Tests the {@link BordaStrategy}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class BordaStrategyTest { - - public static final String CHOICE_A = "a"; - - public static final String CHOICE_B = "b"; - - public static final String CHOICE_C = "c"; - - public static final String CHOICE_D = "d"; - - protected static VoteCountingStrategyProvider provider; - - protected VoteCountingStrategy strategy; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Before - public void setUp() throws Exception { - strategy = provider.getStrategy(BordaStrategy.ID); - } - - @Test - public void simpleVotecount() throws Exception { - - // see http://fr.wikipedia.org/wiki/M%C3%A9thode_Borda - - // Ville 1re 2e 3e 4e Points - // A 42 0 0 58 226 (=42*4+58*1) - // B 26 42 32 0 294 (=26*4+42*3+32*2) - // C 15 43 42 0 273 (=15*4+43*3+42*2) - // D 17 15 26 42 207 (=17*4+15*3+26*2+42) - - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("Ville A", 42.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 3.). - addVoteForChoice(CHOICE_D, 4.). - newVoter("Ville B", 26.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_D, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville C", 15.). - addVoteForChoice(CHOICE_C, 1.). - addVoteForChoice(CHOICE_D, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville D", 17.). - addVoteForChoice(CHOICE_D, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(4, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(294.)); - assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(273.)); - assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(226.)); - assertChoiceScore(scores.get(3), CHOICE_D, BigDecimal.valueOf(207.)); - } - - @Test - public void simpleVotecount0() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=2 c=null) a(3) > b(2) > c(1) - // 2 (a=3 b=2 c=1) c(3) > b(2) > a(1) - // 3 (a=1 b=null c=2) a(3) > c(2) > b(1) - // Result a = 2*3+1=7, b =2*2+1=5, c = 1*3+1*2+1=6 - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 3.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(7.)); - assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(6.)); - assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(5.)); - } - - @Test - public void simpleVotecount2() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=2 c=null) a>b>c - // 2 (a=1 b=2 c=1) a|c>b - // 3 (a=null b=null c=2) c>a|b - // Result (a=3*2+2=8 b=2*3=6 c=1+2*3=7) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(8.)); - assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(7.)); - assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(6.)); - } - - @Test - public void simpleVotecount3() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=null c=null) a(3) > b|c(2) - // 2 (a=null b=1 c=null) b(3) > a|c(2) - // 3 (a=null b=null c=1) c(3) > a|c(2) - // Result (a=3+2*2=7 b=3+2*2=7 c=3+2*2=7) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(7.), - Sets.newHashSet(scores.get(0), - scores.get(1), - scores.get(2) - ), - CHOICE_A, CHOICE_B, CHOICE_C); - } - - @Test - public void weightedVotecount1() throws Exception { - - // poll with weighted vote - // 1 (x2) (a=1 b=null c=null) a(3) > b|c (2) - // 2 (x1) (a=null b=1 c=null) b(3) > a|c (2) - // 3 (x1) (a=null b=1 c=2) b(3) > c(2) > a(1) - // Result (a=2*3+1*2+1*1=9 b=2*2+1*3+1*3=10 c=2*2+1*2+1*2=8) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(10.)); - assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(9.)); - assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(8.)); - } - - @Test - public void weightedVotecount2() throws Exception { - - // poll with weighted vote - // 1 (x2) (a=1 b=null c=null) a(3) > b|c (2) - // 2 (x1) (a=null b=1 c=null) b(3) > a|c (2) - // 3 (x3) (a=null b=2 c=1) c(3) > b(2) > a(1) - // Result (a=1*3*2+1*2+1*1*3=11 b=2*2+1*3+3*2=13 c=2*2+1*2+3*3=15) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(15.)); - assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(13.)); - assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(11.)); - } - - public static void assertChoiceScore(ChoiceScore choiceScore, - String choiceId, - BigDecimal choiceResult) { - Assert.assertNotNull(choiceScore); - Assert.assertEquals(choiceId, choiceScore.getChoiceId()); - Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); - } - - public static void assertChoiceScoreEquals(BigDecimal choiceResult, - Set<ChoiceScore> choiceScores, - String... choiceIds) { - - Assert.assertNotNull(choiceScores); - Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( - choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); - for (String choiceId : choiceIds) { - - ChoiceScore choiceScore = choicesById.get(choiceId); - Assert.assertNotNull(choiceScore); - assertChoiceScore(choiceScore, choiceId, choiceResult); - } - } - -} Deleted: trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java =================================================================== --- trunk/pollen-votecounting-strategy-borda/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-borda/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,49 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Borda - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Tests the {@link VoteCountingStrategyProvider}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class VoteCountingStrategyProviderTest { - - protected static VoteCountingStrategyProvider provider; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Test - public void getStrategy() throws Exception { - - Assert.assertNotNull(provider.getStrategy(BordaStrategy.ID)); - } -} Modified: trunk/pollen-votecounting-condorcet/pom.xml =================================================================== --- trunk/pollen-votecounting-strategy-condorcet/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-condorcet/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -10,11 +12,10 @@ </parent> <groupId>org.chorem.pollen</groupId> - <artifactId>pollen-votecounting-strategy-condorcet</artifactId> + <artifactId>pollen-votecounting-condorcet</artifactId> + <name>Pollen :: VoteCounting :: Condorcet</name> + <description>Implements the condorcet vote counting</description> - <name>Pollen :: VoteCounting strategy :: Condorcet</name> - <description>Implements the condorcet vote counting strategy</description> - <dependencies> <dependency> @@ -27,16 +28,24 @@ <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </dependency> + <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> + <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> </dependency> <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> Added: trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCounting.java =================================================================== --- trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCounting.java (rev 0) +++ trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCounting.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,69 @@ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.l_; +import static org.nuiton.i18n.I18n.n_; + +/** + * Coombs vote counting entry point. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6 + */ +public class CondorcetVoteCounting extends AbstractVoteCounting<CondorcetVoteCountingStrategy> { + + public static final int ID = 2; + + public CondorcetVoteCounting() { + super(ID, + CondorcetVoteCountingStrategy.class, + n_("pollen.voteCountingType.condorcet"), + n_("pollen.voteCountingType.condorcet.help") + ); + } + + @Override + public String getTotalVoteValueNotValidMessage(Locale locale) { + // no validation on total value, so no message + return null; + } + + @Override + public String getVoteValueNotValidMessage(Locale locale) { + return l_(locale, "pollen.error.vote.invalidCondorcetVoteValue"); + } + + @Override + public String getDisplayVoteValue(Integer voteValue) { + return voteValue == null ? "" : String.valueOf(voteValue); + } + + @Override + public ChoiceToVoteRenderType getVoteValueEditorType() { + return ChoiceToVoteRenderType.TEXTFIELD; + } + + @Override + public boolean isChoiceInVote(Integer voteValue) { + return voteValue != null && voteValue > 0 && voteValue < 100; + } + + @Override + public boolean isVoteValueNull(Integer voteValue) { + return voteValue == null; + } + + @Override + public boolean isVoteValueValid(Integer voteValue) { + return voteValue != null && voteValue > 0; + } + + @Override + public boolean isTotalVoteValueValid(int totalValues) { + // no validation on total value + return true; + } +} Property changes on: trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCounting.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java (from rev 3707, trunk/pollen-votecounting-strategy-condorcet/src/main/java/org/chorem/pollen/votecounting/strategy/CondorcetStrategy.java) =================================================================== --- trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java (rev 0) +++ trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,247 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Condorcet + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.pollen.votecounting.model.ChoiceIdAble; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.VoteForChoice; +import org.chorem.pollen.votecounting.model.Voter; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Condorcet. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class CondorcetVoteCountingStrategy extends AbstractVoteCountingStrategy { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(CondorcetVoteCountingStrategy.class); + + @Override + public VoteCountingResult votecount(Set<Voter> voters) { + + // get empty result by choice + Map<String, ChoiceScore> resultByChoice = votersToResult(voters); + + // get order over choices (needed to get coordinates over matrix) + List<String> choiceIds = Lists.newArrayList(resultByChoice.keySet()); + + // nb of choices + int nbChoices = choiceIds.size(); + + //matrix of pairwise + double[][] matrix = new double[nbChoices][nbChoices]; + + // compute pairwise battle matrix and try to have a direct winner(s) + Set<String> winners = computePairWiseMatrix(choiceIds, voters, matrix); + + // compute nb battles wins for each choice + // and store it as choice score value + computeNbBattlesByChoice(resultByChoice, choiceIds, matrix); + + // get choice score ordered by their number of win battles + List<ChoiceScore> choiceScores = toChoiceScore(resultByChoice); + + if (winners != null) { + + // there is winner(s), re-add them to + + if (log.isDebugEnabled()) { + log.debug("Direct winners : " + winners); + } + for (String choiceId : winners) { + ChoiceScore choiceScore = resultByChoice.get(choiceId); + choiceScores.remove(choiceScore); + choiceScores.add(0, choiceScore); + } + } else { + + // no direct winner, must resolv conflicts + + resolvConflicts(choiceScores, matrix); + } + + // transform map of result to list of them (and sort them) + VoteCountingResult result = resultToList(resultByChoice); + return result; + } + + protected void resolvConflicts(List<ChoiceScore> choiceScores, + double[][] matrix) { + + // for the moment we use only number of win battles + // so nothing more to do here... + } + + protected void computeNbBattlesByChoice(Map<String, ChoiceScore> resultByChoice, + List<String> choiceIds, + double[][] matrix) { + + int nbChoices = choiceIds.size(); + + for (String choiceId : choiceIds) { + + int i = choiceIds.indexOf(choiceId); + + double nbBattles = 0; + for (int j = 0; j < nbChoices; j++) { + double aRow = matrix[i][j]; + nbBattles += aRow; + } + + resultByChoice.get(choiceId).setScoreValue( + BigDecimal.valueOf(nbBattles)); + + if (log.isDebugEnabled()) { + log.debug("Nb battle wins for choice " + choiceId + ": " + nbBattles); + } + } + } + + private Set<String> computePairWiseMatrix(List<String> choiceIds, + Set<Voter> voters, + double[][] matrix) { + + int nbChoices = choiceIds.size(); + + Set<String> winners = null; + + VoteForChoiceComparator comparator = new VoteForChoiceComparator(); + + double[] currentVoteWinner = new double[choiceIds.size()]; + + boolean firstVoter = true; + for (Voter voter : voters) { + + if (log.isDebugEnabled()) { + log.debug("Start count for voter " + voter.getVoterId()); + } + double voterWeight = voter.getWeight(); + + Arrays.fill(currentVoteWinner, 0); + + Map<String, VoteForChoice> voteByChoiceIds = + Maps.uniqueIndex(voter.getVoteForChoices(), + new ChoiceIdAble.ChoiceIdAbleById()); + + double maxBattleWins = 0; + + for (String choiceId : choiceIds) { + + // get vote for this choice + VoteForChoice voteForChoice = voteByChoiceIds.get(choiceId); + + int x = choiceIds.indexOf(choiceId); + + for (VoteForChoice voteForChoice1 : voter.getVoteForChoices()) { + + String choiceId1 = voteForChoice1.getChoiceId(); + if (choiceId.equals(choiceId1)) { + + // can not battle same choice + continue; + } + + int y = choiceIds.indexOf(choiceId1); + + int compare = comparator.compare(voteForChoice, + voteForChoice1); + + if (compare < 0) { + + // voteForChoice wins his battle + + int pos = x * nbChoices + y; + + matrix[x][y] = matrix[x][y] + voterWeight; + if (log.isTraceEnabled()) { + log.trace("battle [" + choiceId + "<" + + voteForChoice.getVoteValue() + "> - " + + choiceId1 + "<" + + voteForChoice1.getVoteValue() + + ">] wins (store to " + pos + + ", new value=" + matrix[x][y] + ")"); + } + maxBattleWins = Math.max( + maxBattleWins, + currentVoteWinner[x] = + currentVoteWinner[x] + voterWeight); + } + } + } + + if (firstVoter || winners != null) { + + // still have a winner, le'ts compute current winner + Set<String> currentVoteWinners = Sets.newHashSet(); + + // find winners of this vote + for (int i = 0; i < currentVoteWinner.length; i++) { + if (maxBattleWins == currentVoteWinner[i]) { + + // this is a winner for this vote + String choiceId = choiceIds.get(i); + currentVoteWinners.add(choiceId); + } + } + if (log.isDebugEnabled()) { + log.debug("Winners of this vote : " + currentVoteWinners); + } + + + if (firstVoter) { + + // keep this first result + winners = currentVoteWinners; + } else if (!winners.equals(currentVoteWinners)) { + + // current vote has not same winners than previous, + // so will need resolution + winners = null; + + if (log.isDebugEnabled()) { + log.debug("Dismatch winners (will need resolv...)"); + } + } + } + + firstVoter = false; + } + return winners; + } + +} Property changes on: trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategy.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/strategy/CondorcetStrategy.java =================================================================== --- trunk/pollen-votecounting-strategy-condorcet/src/main/java/org/chorem/pollen/votecounting/strategy/CondorcetStrategy.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-condorcet/src/main/java/org/chorem/pollen/votecounting/strategy/CondorcetStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,315 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Condorcet - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.chorem.pollen.votecounting.model.ChoiceIdAble; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.VoteForChoice; -import org.chorem.pollen.votecounting.model.Voter; - -import java.math.BigDecimal; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import static org.nuiton.i18n.I18n.l_; -import static org.nuiton.i18n.I18n.n_; - -/** - * Condorcet. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class CondorcetStrategy extends AbstractVoteCountingStrategy { - - public static final int ID = 2; - - /** Logger. */ - private static final Log log = LogFactory.getLog(CondorcetStrategy.class); - - @Override - public int getId() { - return ID; - } - - @Override - public String getI18nName() { - return n_("pollen.voteCountingType.condorcet"); - } - - @Override - public String getI18nHelp() { - return n_("pollen.voteCountingType.condorcet.help"); - } - - @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { - // no validation on total value, so no message - return null; - } - - @Override - public String getVoteValueNotValidMessage(Locale locale) { - return l_(locale, "pollen.error.vote.invalidCondorcetVoteValue"); - } - - @Override - public String getDisplayVoteValue(Integer voteValue) { - return voteValue == null ? "" : String.valueOf(voteValue); - } - - @Override - public ChoiceToVoteRenderType getVoteValueEditorType() { - return ChoiceToVoteRenderType.TEXTFIELD; - } - - @Override - public boolean isChoiceInVote(Integer voteValue) { - return voteValue != null && voteValue > 0 && voteValue < 100; - } - - @Override - public boolean isVoteValueNull(Integer voteValue) { - return voteValue == null; - } - - @Override - public boolean isDisplayResultsByChoice() { - return false; - } - - @Override - public boolean isVoteValueValid(Integer voteValue) { - return voteValue != null && voteValue > 0; - } - - @Override - public boolean isTotalVoteValueValid(int totalValues) { - // no validation on total value - return true; - } - - @Override - public VoteCountingResult votecount(Set<Voter> voters) { - - // get empty result by choice - Map<String, ChoiceScore> resultByChoice = votersToResult(voters); - - // get order over choices (needed to get coordinates over matrix) - List<String> choiceIds = Lists.newArrayList(resultByChoice.keySet()); - - // nb of choices - int nbChoices = choiceIds.size(); - - //matrix of pairwise - double[][] matrix = new double[nbChoices][nbChoices]; - - // compute pairwise battle matrix and try to have a direct winner(s) - Set<String> winners = computePairWiseMatrix(choiceIds, voters, matrix); - - // compute nb battles wins for each choice - // and store it as choice score value - computeNbBattlesByChoice(resultByChoice, choiceIds, matrix); - - // get choice score ordered by their number of win battles - List<ChoiceScore> choiceScores = toChoiceScore(resultByChoice); - - if (winners != null) { - - // there is winner(s), re-add them to - - if (log.isDebugEnabled()) { - log.debug("Direct winners : " + winners); - } - for (String choiceId : winners) { - ChoiceScore choiceScore = resultByChoice.get(choiceId); - choiceScores.remove(choiceScore); - choiceScores.add(0, choiceScore); - } - } else { - - // no direct winner, must resolv conflicts - - resolvConflicts(choiceScores, matrix); - } - - // transform map of result to list of them (and sort them) - VoteCountingResult result = resultToList(resultByChoice); - return result; - } - - protected void resolvConflicts(List<ChoiceScore> choiceScores, - double[][] matrix) { - - // for the moment we use only number of win battles - // so nothing more to do here... - } - - protected void computeNbBattlesByChoice(Map<String, ChoiceScore> resultByChoice, - List<String> choiceIds, - double[][] matrix) { - - int nbChoices = choiceIds.size(); - - for (String choiceId : choiceIds) { - - int i = choiceIds.indexOf(choiceId); - - double nbBattles = 0; - for (int j = 0; j < nbChoices; j++) { - double aRow = matrix[i][j]; - nbBattles += aRow; - } - - resultByChoice.get(choiceId).setScoreValue( - BigDecimal.valueOf(nbBattles)); - - if (log.isDebugEnabled()) { - log.debug("Nb battle wins for choice " + choiceId + ": " + nbBattles); - } - } - } - - private Set<String> computePairWiseMatrix(List<String> choiceIds, - Set<Voter> voters, - double[][] matrix) { - - int nbChoices = choiceIds.size(); - - Set<String> winners = null; - - VoteForChoiceComparator comparator = new VoteForChoiceComparator(); - - double[] currentVoteWinner = new double[choiceIds.size()]; - - boolean firstVoter = true; - for (Voter voter : voters) { - - if (log.isDebugEnabled()) { - log.debug("Start count for voter " + voter.getVoterId()); - } - double voterWeight = voter.getWeight(); - - Arrays.fill(currentVoteWinner, 0); - - Map<String, VoteForChoice> voteByChoiceIds = - Maps.uniqueIndex(voter.getVoteForChoices(), - new ChoiceIdAble.ChoiceIdAbleById()); - - double maxBattleWins = 0; - - for (String choiceId : choiceIds) { - - // get vote for this choice - VoteForChoice voteForChoice = voteByChoiceIds.get(choiceId); - - int x = choiceIds.indexOf(choiceId); - - for (VoteForChoice voteForChoice1 : voter.getVoteForChoices()) { - - String choiceId1 = voteForChoice1.getChoiceId(); - if (choiceId.equals(choiceId1)) { - - // can not battle same choice - continue; - } - - int y = choiceIds.indexOf(choiceId1); - - int compare = comparator.compare(voteForChoice, - voteForChoice1); - - if (compare < 0) { - - // voteForChoice wins his battle - - int pos = x * nbChoices + y; - - matrix[x][y] = matrix[x][y] + voterWeight; - if (log.isTraceEnabled()) { - log.trace("battle [" + choiceId + "<" + - voteForChoice.getVoteValue() + "> - " + - choiceId1 + "<" + - voteForChoice1.getVoteValue() + - ">] wins (store to " + pos + - ", new value=" + matrix[x][y] + ")"); - } - maxBattleWins = Math.max( - maxBattleWins, - currentVoteWinner[x] = - currentVoteWinner[x] + voterWeight); - } - } - } - - if (firstVoter || winners != null) { - - // still have a winner, le'ts compute current winner - Set<String> currentVoteWinners = Sets.newHashSet(); - - // find winners of this vote - for (int i = 0; i < currentVoteWinner.length; i++) { - if (maxBattleWins == currentVoteWinner[i]) { - - // this is a winner for this vote - String choiceId = choiceIds.get(i); - currentVoteWinners.add(choiceId); - } - } - if (log.isDebugEnabled()) { - log.debug("Winners of this vote : " + currentVoteWinners); - } - - - if (firstVoter) { - - // keep this first result - winners = currentVoteWinners; - } else if (!winners.equals(currentVoteWinners)) { - - // current vote has not same winners than previous, - // so will need resolution - winners = null; - - if (log.isDebugEnabled()) { - log.debug("Dismatch winners (will need resolv...)"); - } - } - } - - firstVoter = false; - } - return winners; - } - -} Copied: trunk/pollen-votecounting-condorcet/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (from rev 3707, trunk/pollen-votecounting-strategy-condorcet/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy) =================================================================== --- trunk/pollen-votecounting-condorcet/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (rev 0) +++ trunk/pollen-votecounting-condorcet/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1 @@ +org.chorem.pollen.votecounting.CondorcetVoteCounting Property changes on: trunk/pollen-votecounting-condorcet/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-condorcet/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy =================================================================== --- trunk/pollen-votecounting-strategy-condorcet/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-condorcet/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-29 12:36:25 UTC (rev 3708) @@ -1 +0,0 @@ -org.chorem.pollen.votecounting.strategy.CondorcetStrategy Copied: trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java (from rev 3707, trunk/pollen-votecounting-strategy-condorcet/src/test/java/org/chorem/pollen/votecounting/strategy/CondorcetStrategyTest.java) =================================================================== --- trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java (rev 0) +++ trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,317 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Condorcet + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.chorem.pollen.votecounting.model.ChoiceIdAble; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Tests the {@link CondorcetVoteCountingStrategy}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class CondorcetVoteCountingStrategyTest { + + public static final String CHOICE_A = "a"; + + public static final String CHOICE_B = "b"; + + public static final String CHOICE_C = "c"; + + protected static VoteCounting voteCounting; + + protected VoteCountingStrategy strategy; + + @BeforeClass + public static void beforeClass() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + voteCounting = factory.getVoteCounting(CondorcetVoteCounting.ID); + } + + @Before + public void setUp() throws Exception { + strategy = voteCounting.newVoteCountingStrategy(); + } + + @Test + public void simpleVotecount() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=2 c=null) + // 2 (a=1 b=3 c=2) + // 3 (a=1 b=null c=2) + // Result (a=6 b=1 c=2) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 3.). + addVoteForChoice(CHOICE_C, 2.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(6.)); + assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(2.)); + assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(1.)); + } + + @Test + public void simpleVotecount0() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=2 c=null) + // 2 (a=3 b=2 c=1) + // 3 (a=1 b=null c=2) + // Result (a=4 b=2 c=3) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 3.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(4.)); + assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(3.)); + assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(2.)); + } + + @Test + public void simpleVotecount2() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=2 c=null) + // 2 (a=1 b=2 c=1) + // 3 (a=null b=null c=2) + // Result (a=3 b=1 c=3) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(3.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_C); + assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(1.)); + } + + @Test + public void simpleVotecount3() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=null c=null) + // 2 (a=null b=1 c=null) + // 3 (a=null b=null c=1) + // Result (a=2 b=2 c=2) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(2.), + Sets.newHashSet(scores.get(0), + scores.get(1), + scores.get(2) + ), + CHOICE_A, CHOICE_B, CHOICE_C); + } + + @Test + public void weightedVotecount1() throws Exception { + + // poll with weighted vote + // 1 (x2) (a=1 b=null c=null) + // 2 (x1) (a=null b=1 c=null) + // 3 (x1) (a=null b=1 c=2) + // Result (a=2 b=2 c=1) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(4.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_B); + assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(1.)); + } + + @Test + public void weightedVotecount2() throws Exception { + + // poll with weighted vote + // 1 (x2) (a=1 b=null c=null) + // 2 (x1) (a=null b=1 c=null) + // 3 (x3) (a=null b=2 c=1) + // Result (a=2 b=4 c=3) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 3.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(6.)); + assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(5.)); + assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(4.)); + } + + public static void assertChoiceScore(ChoiceScore choiceScore, + String choiceId, + BigDecimal choiceResult) { + Assert.assertNotNull(choiceScore); + Assert.assertEquals(choiceId, choiceScore.getChoiceId()); + Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); + } + + public static void assertChoiceScoreEquals(BigDecimal choiceResult, + Set<ChoiceScore> choiceScores, + String... choiceIds) { + + Assert.assertNotNull(choiceScores); + Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( + choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); + for (String choiceId : choiceIds) { + + ChoiceScore choiceScore = choicesById.get(choiceId); + Assert.assertNotNull(choiceScore); + assertChoiceScore(choiceScore, choiceId, choiceResult); + } + } + +} Property changes on: trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/CondorcetVoteCountingStrategyTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (from rev 3707, trunk/pollen-votecounting-strategy-condorcet/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java) =================================================================== --- trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (rev 0) +++ trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,43 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Condorcet + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests the {@link VoteCountingFactory}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class VoteCountingFactoryTest { + + @Test + public void getVoteCounting() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + VoteCounting voteCounting = + factory.getVoteCounting(CondorcetVoteCounting.ID); + Assert.assertNotNull(voteCounting); + } +} Property changes on: trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/strategy/CondorcetStrategyTest.java =================================================================== --- trunk/pollen-votecounting-strategy-condorcet/src/test/java/org/chorem/pollen/votecounting/strategy/CondorcetStrategyTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/strategy/CondorcetStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,316 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Condorcet - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.chorem.pollen.votecounting.model.ChoiceIdAble; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Tests the {@link CondorcetStrategy}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class CondorcetStrategyTest { - - public static final String CHOICE_A = "a"; - - public static final String CHOICE_B = "b"; - - public static final String CHOICE_C = "c"; - - protected static VoteCountingStrategyProvider provider; - - protected VoteCountingStrategy strategy; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Before - public void setUp() throws Exception { - strategy = provider.getStrategy(CondorcetStrategy.ID); - } - - @Test - public void simpleVotecount() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=2 c=null) - // 2 (a=1 b=3 c=2) - // 3 (a=1 b=null c=2) - // Result (a=6 b=1 c=2) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_C, 2.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(6.)); - assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(2.)); - assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(1.)); - } - - @Test - public void simpleVotecount0() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=2 c=null) - // 2 (a=3 b=2 c=1) - // 3 (a=1 b=null c=2) - // Result (a=4 b=2 c=3) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 3.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(4.)); - assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(3.)); - assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(2.)); - } - - @Test - public void simpleVotecount2() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=2 c=null) - // 2 (a=1 b=2 c=1) - // 3 (a=null b=null c=2) - // Result (a=3 b=1 c=3) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(3.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_C); - assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(1.)); - } - - @Test - public void simpleVotecount3() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=null c=null) - // 2 (a=null b=1 c=null) - // 3 (a=null b=null c=1) - // Result (a=2 b=2 c=2) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(2.), - Sets.newHashSet(scores.get(0), - scores.get(1), - scores.get(2) - ), - CHOICE_A, CHOICE_B, CHOICE_C); - } - - @Test - public void weightedVotecount1() throws Exception { - - // poll with weighted vote - // 1 (x2) (a=1 b=null c=null) - // 2 (x1) (a=null b=1 c=null) - // 3 (x1) (a=null b=1 c=2) - // Result (a=2 b=2 c=1) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(4.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_B); - assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(1.)); - } - - @Test - public void weightedVotecount2() throws Exception { - - // poll with weighted vote - // 1 (x2) (a=1 b=null c=null) - // 2 (x1) (a=null b=1 c=null) - // 3 (x3) (a=null b=2 c=1) - // Result (a=2 b=4 c=3) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(6.)); - assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(5.)); - assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(4.)); - } - - public static void assertChoiceScore(ChoiceScore choiceScore, - String choiceId, - BigDecimal choiceResult) { - Assert.assertNotNull(choiceScore); - Assert.assertEquals(choiceId, choiceScore.getChoiceId()); - Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); - } - - public static void assertChoiceScoreEquals(BigDecimal choiceResult, - Set<ChoiceScore> choiceScores, - String... choiceIds) { - - Assert.assertNotNull(choiceScores); - Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( - choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); - for (String choiceId : choiceIds) { - - ChoiceScore choiceScore = choicesById.get(choiceId); - Assert.assertNotNull(choiceScore); - assertChoiceScore(choiceScore, choiceId, choiceResult); - } - } - -} Deleted: trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java =================================================================== --- trunk/pollen-votecounting-strategy-condorcet/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-condorcet/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,49 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Condorcet - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Tests the {@link VoteCountingStrategyProvider}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class VoteCountingStrategyProviderTest { - - protected static VoteCountingStrategyProvider provider; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Test - public void getStrategy() throws Exception { - - Assert.assertNotNull(provider.getStrategy(CondorcetStrategy.ID)); - } -} Modified: trunk/pollen-votecounting-coombs/pom.xml =================================================================== --- trunk/pollen-votecounting-strategy-coombs/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-coombs/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -10,11 +12,10 @@ </parent> <groupId>org.chorem.pollen</groupId> - <artifactId>pollen-votecounting-strategy-coombs</artifactId> + <artifactId>pollen-votecounting-coombs</artifactId> + <name>Pollen :: VoteCounting :: Coombs</name> + <description>Implements the coombs vote counting</description> - <name>Pollen :: VoteCounting strategy :: Coombs</name> - <description>Implements the coombs vote counting strategy</description> - <dependencies> <dependency> @@ -39,6 +40,12 @@ </dependency> <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> Added: trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCounting.java =================================================================== --- trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCounting.java (rev 0) +++ trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCounting.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,69 @@ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.l_; +import static org.nuiton.i18n.I18n.n_; + +/** + * Coombs vote counting entry point. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6 + */ +public class CoombsVoteCounting extends AbstractVoteCounting<CoombsVoteCountingStrategy> { + + public static final int ID = 6; + + public CoombsVoteCounting() { + super(ID, + CoombsVoteCountingStrategy.class, + n_("pollen.voteCountingType.coombs"), + n_("pollen.voteCountingType.coombs.help") + ); + } + + @Override + public String getTotalVoteValueNotValidMessage(Locale locale) { + // no validation on total value, so no message + return null; + } + + @Override + public String getVoteValueNotValidMessage(Locale locale) { + return l_(locale, "pollen.error.vote.invalidCoombsVoteValue"); + } + + @Override + public String getDisplayVoteValue(Integer voteValue) { + return voteValue == null ? "" : String.valueOf(voteValue); + } + + @Override + public ChoiceToVoteRenderType getVoteValueEditorType() { + return ChoiceToVoteRenderType.TEXTFIELD; + } + + @Override + public boolean isChoiceInVote(Integer voteValue) { + return voteValue != null && voteValue > 0 && voteValue < 100; + } + + @Override + public boolean isVoteValueNull(Integer voteValue) { + return voteValue == null; + } + + @Override + public boolean isVoteValueValid(Integer voteValue) { + return voteValue != null && voteValue > 0; + } + + @Override + public boolean isTotalVoteValueValid(int totalValues) { + // no validation on total value + return true; + } +} Property changes on: trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCounting.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java (from rev 3707, trunk/pollen-votecounting-strategy-coombs/src/main/java/org/chorem/pollen/votecounting/strategy/CoombsStrategy.java) =================================================================== --- trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java (rev 0) +++ trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,241 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Coombs + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.apache.commons.collections.CollectionUtils; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; + +/** + * Coombs vote counting strategy. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class CoombsVoteCountingStrategy extends AbstractVoteCountingStrategy { + + @Override + public VoteCountingResult votecount(Set<Voter> voters) { + + // get empty result by choice + SortedMap<String, ChoiceScore> resultByChoice = votersToResult(voters); + + // calcul du score minimum pour atteindre la majorité absolue + double totalWeight = 0.; + for (Voter voter : voters) { + totalWeight += voter.getWeight(); + } + totalWeight /= 2; + + // calcul pour chaque votant de ses choix préférés + Map<Voter, List<Set<String>>> topRankChoices = + buildVoterSortedChoices(voters); + + Set<String> choiceIdsToExclude = Sets.newHashSet(); + Set<String> choiceIdsToKeep = Sets.newHashSet(resultByChoice.keySet()); + + round(topRankChoices, + choiceIdsToExclude, + choiceIdsToKeep, + resultByChoice, + totalWeight); + + + // transform map of result to list of them (and sort them) + VoteCountingResult result = resultToList(resultByChoice); + return result; + } + + public void round(Map<Voter, List<Set<String>>> topRankChoices, + Set<String> idsToExclude, + Set<String> idsToInclude, + SortedMap<String, ChoiceScore> resultByChoice, + double totalWeight) { + + List<ChoiceScore> results = applyScores(topRankChoices, + idsToExclude, + idsToInclude, + resultByChoice); + + if (!results.isEmpty()) { + + // get best score + double max = + results.get(results.size() - 1).getScoreValue().doubleValue(); + + if (max < totalWeight) { + + // pas de majorité absolue, il faut éliminer le(s) choix les plus mauvais + + guessChoiceIdsToRemove(idsToInclude, idsToExclude, topRankChoices); + + // on ne veux plus utiliser ces choix dans le tour suivant + idsToInclude.removeAll(idsToExclude); + + // nouveau tour + round(topRankChoices, + idsToExclude, + idsToInclude, + resultByChoice, + totalWeight); + + } else { + + // majorité absolue trouvée plus rien à faire en fait :) + } + } + } + + public List<ChoiceScore> applyScores(Map<Voter, List<Set<String>>> topRankChoices, + Set<String> idsToExclude, + Set<String> idsToInclude, + SortedMap<String, ChoiceScore> resultByChoice) { + + if (CollectionUtils.isNotEmpty(idsToExclude)) { + + // on supprime des classements les ids données + + for (List<Set<String>> choicesByLevel : topRankChoices.values()) { + Iterator<Set<String>> itr = choicesByLevel.iterator(); + while (itr.hasNext()) { + Set<String> choiceIds = itr.next(); + choiceIds.removeAll(idsToExclude); + if (choiceIds.isEmpty()) { + + // remove this level + itr.remove(); + } + } + } + } + + // on remet à zero les scores pour les ids a conserver + for (String id : idsToInclude) { + resultByChoice.get(id).setScoreValue(null); + } + + // on calcule les scores à partir des classements + + for (Map.Entry<Voter, List<Set<String>>> entry : topRankChoices.entrySet()) { + List<Set<String>> idsByLevel = entry.getValue(); + if (!idsByLevel.isEmpty()) { + + Set<String> winnerIds = idsByLevel.get(0); + Voter voter = entry.getKey(); + double voterWeight = voter.getWeight(); + for (String id : winnerIds) { + if (idsToInclude.contains(id)) { + ChoiceScore choiceScore = resultByChoice.get(id); + choiceScore.addScoreValue(voterWeight); + } + } + } + } + + // recopy choices to run rounds on it and eliminates choices until + // there is a choice > 50 + List<ChoiceScore> results = Lists.newArrayList(); + + for (String id : idsToInclude) { + results.add(resultByChoice.get(id)); + } + + Collections.sort(results); + + // on supprime tout score à 0 + Iterator<ChoiceScore> itr = results.iterator(); + while (itr.hasNext()) { + ChoiceScore choiceScore = itr.next(); + if (choiceScore.getScoreValue() == null || + ZERO_D.equals(choiceScore.getScoreValue())) { + itr.remove(); + } else { + // score > 0 on peut s'arreter + break; + } + } + return results; + } + + public void guessChoiceIdsToRemove(Set<String> idsToInclude, + Set<String> idsToExclude, + Map<Voter, List<Set<String>>> results) { + + // pour chaque choix restant on calcule son score lorsqu'il est le dernier + + Map<String, ChoiceScore> badScores = Maps.newTreeMap(); + for (String id : idsToInclude) { + badScores.put(id, ChoiceScore.newScore(id, null)); + } + + for (Map.Entry<Voter, List<Set<String>>> entry : results.entrySet()) { + Voter voter = entry.getKey(); + List<Set<String>> idsChoices = entry.getValue(); + if (!idsChoices.isEmpty()) { + + Set<String> lastIds = idsChoices.get(idsChoices.size() - 1); + + double voterWeight = voter.getWeight(); + + for (String lastId : lastIds) { + badScores.get(lastId).addScoreValue(voterWeight); + } + } + } + + // on construit alors la liste des scores + List<ChoiceScore> scores = Lists.newArrayList(badScores.values()); + + // que l'on trie + Collections.sort(scores); + + // puis revers (pour avoir les meilleurs scores au début) + Collections.reverse(scores); + + double maxScore = scores.get(0).getScoreValue().doubleValue(); + + idsToExclude.clear(); + + for (ChoiceScore choiceScore : scores) { + + if (maxScore == choiceScore.getScoreValue().doubleValue()) { + + idsToExclude.add(choiceScore.getChoiceId()); + } else { + // value < max, on peut s'arreter là + break; + } + } + } +} Property changes on: trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategy.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/strategy/CoombsStrategy.java =================================================================== --- trunk/pollen-votecounting-strategy-coombs/src/main/java/org/chorem/pollen/votecounting/strategy/CoombsStrategy.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-coombs/src/main/java/org/chorem/pollen/votecounting/strategy/CoombsStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,311 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Coombs - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.apache.commons.collections.CollectionUtils; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; - -import static org.nuiton.i18n.I18n.l_; -import static org.nuiton.i18n.I18n.n_; - -/** - * Coombs. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class CoombsStrategy extends AbstractVoteCountingStrategy { - - public static final int ID = 6; - - @Override - public int getId() { - return ID; - } - - @Override - public String getI18nName() { - return n_("pollen.voteCountingType.coombs"); - } - - @Override - public String getI18nHelp() { - return n_("pollen.voteCountingType.coombs.help"); - } - - @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { - // no validation on total value, so no message - return null; - } - - @Override - public String getVoteValueNotValidMessage(Locale locale) { - return l_(locale, "pollen.error.vote.invalidCoombsVoteValue"); - } - - @Override - public String getDisplayVoteValue(Integer voteValue) { - return voteValue == null ? "" : String.valueOf(voteValue); - } - - @Override - public ChoiceToVoteRenderType getVoteValueEditorType() { - return ChoiceToVoteRenderType.TEXTFIELD; - } - - @Override - public boolean isChoiceInVote(Integer voteValue) { - return voteValue != null && voteValue > 0 && voteValue < 100; - } - - @Override - public boolean isVoteValueNull(Integer voteValue) { - return voteValue == null; - } - - @Override - public boolean isDisplayResultsByChoice() { - return false; - } - - @Override - public boolean isVoteValueValid(Integer voteValue) { - return voteValue != null && voteValue > 0; - } - - @Override - public boolean isTotalVoteValueValid(int totalValues) { - // no validation on total value - return true; - } - - - @Override - public VoteCountingResult votecount(Set<Voter> voters) { - - // get empty result by choice - SortedMap<String, ChoiceScore> resultByChoice = votersToResult(voters); - - // calcul du score minimum pour atteindre la majorité absolue - double totalWeight = 0.; - for (Voter voter : voters) { - totalWeight += voter.getWeight(); - } - totalWeight /= 2; - - // calcul pour chaque votant de ses choix préférés - Map<Voter, List<Set<String>>> topRankChoices = - buildVoterSortedChoices(voters); - - Set<String> choiceIdsToExclude = Sets.newHashSet(); - Set<String> choiceIdsToKeep = Sets.newHashSet(resultByChoice.keySet()); - - round(topRankChoices, - choiceIdsToExclude, - choiceIdsToKeep, - resultByChoice, - totalWeight); - - - // transform map of result to list of them (and sort them) - VoteCountingResult result = resultToList(resultByChoice); - return result; - } - - public void round(Map<Voter, List<Set<String>>> topRankChoices, - Set<String> idsToExclude, - Set<String> idsToInclude, - SortedMap<String, ChoiceScore> resultByChoice, - double totalWeight) { - - List<ChoiceScore> results = applyScores(topRankChoices, - idsToExclude, - idsToInclude, - resultByChoice); - - if (!results.isEmpty()) { - - // get best score - double max = - results.get(results.size() - 1).getScoreValue().doubleValue(); - - if (max < totalWeight) { - - // pas de majorité absolue, il faut éliminer le(s) choix les plus mauvais - - guessChoiceIdsToRemove(idsToInclude, idsToExclude, topRankChoices); - - // on ne veux plus utiliser ces choix dans le tour suivant - idsToInclude.removeAll(idsToExclude); - - // nouveau tour - round(topRankChoices, - idsToExclude, - idsToInclude, - resultByChoice, - totalWeight); - - } else { - - // majorité absolue trouvée plus rien à faire en fait :) - } - } - } - - public List<ChoiceScore> applyScores(Map<Voter, List<Set<String>>> topRankChoices, - Set<String> idsToExclude, - Set<String> idsToInclude, - SortedMap<String, ChoiceScore> resultByChoice) { - - if (CollectionUtils.isNotEmpty(idsToExclude)) { - - // on supprime des classements les ids données - - for (List<Set<String>> choicesByLevel : topRankChoices.values()) { - Iterator<Set<String>> itr = choicesByLevel.iterator(); - while (itr.hasNext()) { - Set<String> choiceIds = itr.next(); - choiceIds.removeAll(idsToExclude); - if (choiceIds.isEmpty()) { - - // remove this level - itr.remove(); - } - } - } - } - - // on remet à zero les scores pour les ids a conserver - for (String id : idsToInclude) { - resultByChoice.get(id).setScoreValue(null); - } - - // on calcule les scores à partir des classements - - for (Map.Entry<Voter, List<Set<String>>> entry : topRankChoices.entrySet()) { - List<Set<String>> idsByLevel = entry.getValue(); - if (!idsByLevel.isEmpty()) { - - Set<String> winnerIds = idsByLevel.get(0); - Voter voter = entry.getKey(); - double voterWeight = voter.getWeight(); - for (String id : winnerIds) { - if (idsToInclude.contains(id)) { - ChoiceScore choiceScore = resultByChoice.get(id); - choiceScore.addScoreValue(voterWeight); - } - } - } - } - - // recopy choices to run rounds on it and eliminates choices until - // there is a choice > 50 - List<ChoiceScore> results = Lists.newArrayList(); - - for (String id : idsToInclude) { - results.add(resultByChoice.get(id)); - } - - Collections.sort(results); - - // on supprime tout score à 0 - Iterator<ChoiceScore> itr = results.iterator(); - while (itr.hasNext()) { - ChoiceScore choiceScore = itr.next(); - if (choiceScore.getScoreValue() == null || - ZERO_D.equals(choiceScore.getScoreValue())) { - itr.remove(); - } else { - // score > 0 on peut s'arreter - break; - } - } - return results; - } - - public void guessChoiceIdsToRemove(Set<String> idsToInclude, - Set<String> idsToExclude, - Map<Voter, List<Set<String>>> results) { - - // pour chaque choix restant on calcule son score lorsqu'il est le dernier - - Map<String, ChoiceScore> badScores = Maps.newTreeMap(); - for (String id : idsToInclude) { - badScores.put(id, ChoiceScore.newScore(id, null)); - } - - for (Map.Entry<Voter, List<Set<String>>> entry : results.entrySet()) { - Voter voter = entry.getKey(); - List<Set<String>> idsChoices = entry.getValue(); - if (!idsChoices.isEmpty()) { - - Set<String> lastIds = idsChoices.get(idsChoices.size() - 1); - - double voterWeight = voter.getWeight(); - - for (String lastId : lastIds) { - badScores.get(lastId).addScoreValue(voterWeight); - } - } - } - - // on construit alors la liste des scores - List<ChoiceScore> scores = Lists.newArrayList(badScores.values()); - - // que l'on trie - Collections.sort(scores); - - // puis revers (pour avoir les meilleurs scores au début) - Collections.reverse(scores); - - double maxScore = scores.get(0).getScoreValue().doubleValue(); - - idsToExclude.clear(); - - for (ChoiceScore choiceScore : scores) { - - if (maxScore == choiceScore.getScoreValue().doubleValue()) { - - idsToExclude.add(choiceScore.getChoiceId()); - } else { - // value < max, on peut s'arreter là - break; - } - } - } -} Copied: trunk/pollen-votecounting-coombs/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (from rev 3707, trunk/pollen-votecounting-strategy-coombs/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy) =================================================================== --- trunk/pollen-votecounting-coombs/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (rev 0) +++ trunk/pollen-votecounting-coombs/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1 @@ +org.chorem.pollen.votecounting.CoombsVoteCounting Property changes on: trunk/pollen-votecounting-coombs/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-coombs/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy =================================================================== --- trunk/pollen-votecounting-strategy-coombs/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-coombs/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-29 12:36:25 UTC (rev 3708) @@ -1 +0,0 @@ -org.chorem.pollen.votecounting.strategy.CoombsStrategy Copied: trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java (from rev 3707, trunk/pollen-votecounting-strategy-coombs/src/test/java/org/chorem/pollen/votecounting/strategy/CoombsStrategyTest.java) =================================================================== --- trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java (rev 0) +++ trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,327 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Coombs + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.chorem.pollen.votecounting.model.ChoiceIdAble; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Tests the {@link CoombsVoteCountingStrategy}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +@Ignore +public class CoombsVoteCountingStrategyTest { + + public static final String CHOICE_A = "Ville A"; + + public static final String CHOICE_B = "Ville B"; + + public static final String CHOICE_C = "Ville C"; + + public static final String CHOICE_D = "Ville D"; + + protected static VoteCounting voteCounting; + + protected VoteCountingStrategy strategy; + + @BeforeClass + public static void beforeClass() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + voteCounting = factory.getVoteCounting(CoombsVoteCounting.ID); + } + + @Before + public void setUp() throws Exception { + strategy = voteCounting.newVoteCountingStrategy(); + } + + @Test + public void simpleVotecount() throws Exception { + + // see http://fr.wikipedia.org/wiki/M%C3%A9thode_de_Coombs + + // Ville 1re 2e 3e 4e R1 R2 + // A 42 0 0 58 42 - + // B 26 42 32 0 26 26+42 + // C 15 43 42 0 15 15 + // D 17 15 26 42 17 17 + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("Ville A", 42.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 3.). + addVoteForChoice(CHOICE_D, 4.). + newVoter("Ville B", 26.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 2.). + addVoteForChoice(CHOICE_D, 3.). + addVoteForChoice(CHOICE_A, 4.). + newVoter("Ville C", 15.). + addVoteForChoice(CHOICE_C, 1.). + addVoteForChoice(CHOICE_D, 2.). + addVoteForChoice(CHOICE_B, 3.). + addVoteForChoice(CHOICE_A, 4.). + newVoter("Ville D", 17.). + addVoteForChoice(CHOICE_D, 1.). + addVoteForChoice(CHOICE_C, 2.). + addVoteForChoice(CHOICE_B, 3.). + addVoteForChoice(CHOICE_A, 4.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(4, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(68.)); + assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(42.)); + assertChoiceScore(scores.get(2), CHOICE_D, BigDecimal.valueOf(17.)); + assertChoiceScore(scores.get(3), CHOICE_C, BigDecimal.valueOf(15.)); + } + + @Test + public void simpleVotecount0() throws Exception { + + // Simple poll (all weight to 1) R1 + // 1 (a=1 b=2 c=null) a 2 + // 2 (a=3 b=2 c=1) b 1 + // 3 (a=1 b=null c=2) c - + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 3.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(2.)); + assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(1.)); + assertChoiceScore(scores.get(2), CHOICE_B, null); + } + + @Test + public void simpleVotecount2() throws Exception { + + // Simple poll (all weight to 1) R1 + // 1 (a=1 b=2 c=null) a 2 + // 2 (a=1 b=2 c=1) b - + // 3 (a=null b=null c=2) c 2 + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(2.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_C); + assertChoiceScore(scores.get(2), CHOICE_B, null); + } + + @Test + public void simpleVotecount3() throws Exception { + + // Simple poll (all weight to 1) R1 + // 1 (a=1 b=null c=null) a 1 + // 2 (a=null b=1 c=null) b 1 + // 3 (a=null b=null c=1) c 1 + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(1.), + Sets.newHashSet(scores.get(0), + scores.get(1), + scores.get(2) + ), + CHOICE_A, CHOICE_B, CHOICE_C); + } + + @Test + public void weightedVotecount1() throws Exception { + + // poll with weighted vote R1 + // 1 (x2) (a=1 b=null c=null) a 2 + // 2 (x1) (a=null b=1 c=null) b 2 + // 3 (x1) (a=null b=1 c=2) c - + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(2.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_B); + assertChoiceScore(scores.get(2), CHOICE_C, null); + } + + @Test + public void weightedVotecount2() throws Exception { + + // poll with weighted vote R1 + // 1 (x2) (a=1 b=null c=null) a 2 + // 2 (x1) (a=null b=1 c=null) b 1 + // 3 (x3) (a=null b=2 c=1) c 3 + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 3.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(3.)); + assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(2.)); + assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(1.)); + } + + public static void assertChoiceScore(ChoiceScore choiceScore, + String choiceId, + BigDecimal choiceResult) { + Assert.assertNotNull(choiceScore); + Assert.assertEquals(choiceId, choiceScore.getChoiceId()); + Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); + } + + public static void assertChoiceScoreEquals(BigDecimal choiceResult, + Set<ChoiceScore> choiceScores, + String... choiceIds) { + + Assert.assertNotNull(choiceScores); + Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( + choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); + for (String choiceId : choiceIds) { + + ChoiceScore choiceScore = choicesById.get(choiceId); + Assert.assertNotNull(choiceScore); + assertChoiceScore(choiceScore, choiceId, choiceResult); + } + } + +} Property changes on: trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/CoombsVoteCountingStrategyTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (from rev 3707, trunk/pollen-votecounting-strategy-coombs/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java) =================================================================== --- trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (rev 0) +++ trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,43 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Coombs + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests the {@link VoteCountingFactory}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class VoteCountingFactoryTest { + + @Test + public void getVoteCounting() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + VoteCounting voteCounting = + factory.getVoteCounting(CoombsVoteCounting.ID); + Assert.assertNotNull(voteCounting); + } +} Property changes on: trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/strategy/CoombsStrategyTest.java =================================================================== --- trunk/pollen-votecounting-strategy-coombs/src/test/java/org/chorem/pollen/votecounting/strategy/CoombsStrategyTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/strategy/CoombsStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,326 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Coombs - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.chorem.pollen.votecounting.model.ChoiceIdAble; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Tests the {@link CoombsStrategy}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -@Ignore -public class CoombsStrategyTest { - - public static final String CHOICE_A = "Ville A"; - - public static final String CHOICE_B = "Ville B"; - - public static final String CHOICE_C = "Ville C"; - - public static final String CHOICE_D = "Ville D"; - - protected static VoteCountingStrategyProvider provider; - - protected VoteCountingStrategy strategy; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Before - public void setUp() throws Exception { - strategy = provider.getStrategy(CoombsStrategy.ID); - } - - @Test - public void simpleVotecount() throws Exception { - - // see http://fr.wikipedia.org/wiki/M%C3%A9thode_de_Coombs - - // Ville 1re 2e 3e 4e R1 R2 - // A 42 0 0 58 42 - - // B 26 42 32 0 26 26+42 - // C 15 43 42 0 15 15 - // D 17 15 26 42 17 17 - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("Ville A", 42.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 3.). - addVoteForChoice(CHOICE_D, 4.). - newVoter("Ville B", 26.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_D, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville C", 15.). - addVoteForChoice(CHOICE_C, 1.). - addVoteForChoice(CHOICE_D, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville D", 17.). - addVoteForChoice(CHOICE_D, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(4, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(68.)); - assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(42.)); - assertChoiceScore(scores.get(2), CHOICE_D, BigDecimal.valueOf(17.)); - assertChoiceScore(scores.get(3), CHOICE_C, BigDecimal.valueOf(15.)); - } - - @Test - public void simpleVotecount0() throws Exception { - - // Simple poll (all weight to 1) R1 - // 1 (a=1 b=2 c=null) a 2 - // 2 (a=3 b=2 c=1) b 1 - // 3 (a=1 b=null c=2) c - - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 3.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(2.)); - assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(1.)); - assertChoiceScore(scores.get(2), CHOICE_B, null); - } - - @Test - public void simpleVotecount2() throws Exception { - - // Simple poll (all weight to 1) R1 - // 1 (a=1 b=2 c=null) a 2 - // 2 (a=1 b=2 c=1) b - - // 3 (a=null b=null c=2) c 2 - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(2.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_C); - assertChoiceScore(scores.get(2), CHOICE_B, null); - } - - @Test - public void simpleVotecount3() throws Exception { - - // Simple poll (all weight to 1) R1 - // 1 (a=1 b=null c=null) a 1 - // 2 (a=null b=1 c=null) b 1 - // 3 (a=null b=null c=1) c 1 - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(1.), - Sets.newHashSet(scores.get(0), - scores.get(1), - scores.get(2) - ), - CHOICE_A, CHOICE_B, CHOICE_C); - } - - @Test - public void weightedVotecount1() throws Exception { - - // poll with weighted vote R1 - // 1 (x2) (a=1 b=null c=null) a 2 - // 2 (x1) (a=null b=1 c=null) b 2 - // 3 (x1) (a=null b=1 c=2) c - - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(2.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_B); - assertChoiceScore(scores.get(2), CHOICE_C, null); - } - - @Test - public void weightedVotecount2() throws Exception { - - // poll with weighted vote R1 - // 1 (x2) (a=1 b=null c=null) a 2 - // 2 (x1) (a=null b=1 c=null) b 1 - // 3 (x3) (a=null b=2 c=1) c 3 - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(3.)); - assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(2.)); - assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(1.)); - } - - public static void assertChoiceScore(ChoiceScore choiceScore, - String choiceId, - BigDecimal choiceResult) { - Assert.assertNotNull(choiceScore); - Assert.assertEquals(choiceId, choiceScore.getChoiceId()); - Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); - } - - public static void assertChoiceScoreEquals(BigDecimal choiceResult, - Set<ChoiceScore> choiceScores, - String... choiceIds) { - - Assert.assertNotNull(choiceScores); - Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( - choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); - for (String choiceId : choiceIds) { - - ChoiceScore choiceScore = choicesById.get(choiceId); - Assert.assertNotNull(choiceScore); - assertChoiceScore(choiceScore, choiceId, choiceResult); - } - } - -} Deleted: trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java =================================================================== --- trunk/pollen-votecounting-strategy-coombs/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-coombs/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,49 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Coombs - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Tests the {@link VoteCountingStrategyProvider}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class VoteCountingStrategyProviderTest { - - protected static VoteCountingStrategyProvider provider; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Test - public void getStrategy() throws Exception { - - Assert.assertNotNull(provider.getStrategy(CoombsStrategy.ID)); - } -} Modified: trunk/pollen-votecounting-instant-runoff/pom.xml =================================================================== --- trunk/pollen-votecounting-strategy-instant-runoff/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-instant-runoff/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -10,11 +12,10 @@ </parent> <groupId>org.chorem.pollen</groupId> - <artifactId>pollen-votecounting-strategy-instant-runoff</artifactId> + <artifactId>pollen-votecounting-instant-runoff</artifactId> + <name>Pollen :: VoteCounting :: Instant Runoff</name> + <description>Implements the instant-runoff vote counting</description> - <name>Pollen :: VoteCounting strategy :: Instant Runoff</name> - <description>Implements the instant-runoff vote counting strategy</description> - <dependencies> <dependency> @@ -39,6 +40,12 @@ </dependency> <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> Added: trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCounting.java =================================================================== --- trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCounting.java (rev 0) +++ trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCounting.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,69 @@ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.l_; +import static org.nuiton.i18n.I18n.n_; + +/** + * Coombs vote counting entry point. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6 + */ +public class InstantRunoffVoteCounting extends AbstractVoteCounting<InstantRunoffVoteCountingStrategy> { + + public static final int ID = 5; + + public InstantRunoffVoteCounting() { + super(ID, + InstantRunoffVoteCountingStrategy.class, + n_("pollen.voteCountingType.instantRunoff"), + n_("pollen.voteCountingType.instantRunoff.help") + ); + } + + @Override + public String getTotalVoteValueNotValidMessage(Locale locale) { + // no validation on total value, so no message + return null; + } + + @Override + public String getVoteValueNotValidMessage(Locale locale) { + return l_(locale, "pollen.error.vote.invalidInstantRunoffVoteValue"); + } + + @Override + public String getDisplayVoteValue(Integer voteValue) { + return voteValue == null ? "" : String.valueOf(voteValue); + } + + @Override + public ChoiceToVoteRenderType getVoteValueEditorType() { + return ChoiceToVoteRenderType.TEXTFIELD; + } + + @Override + public boolean isChoiceInVote(Integer voteValue) { + return voteValue != null && voteValue > 0 && voteValue < 100; + } + + @Override + public boolean isVoteValueNull(Integer voteValue) { + return voteValue == null; + } + + @Override + public boolean isVoteValueValid(Integer voteValue) { + return voteValue != null && voteValue > 0; + } + + @Override + public boolean isTotalVoteValueValid(int totalValues) { + // no validation on total value + return true; + } +} Property changes on: trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCounting.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java (from rev 3707, trunk/pollen-votecounting-strategy-instant-runoff/src/main/java/org/chorem/pollen/votecounting/strategy/InstantRunoffStrategy.java) =================================================================== --- trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java (rev 0) +++ trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,209 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Instant Runoff + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import org.apache.commons.collections.CollectionUtils; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; + +/** + * InstantRunoff. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class InstantRunoffVoteCountingStrategy extends AbstractVoteCountingStrategy { + + @Override + public VoteCountingResult votecount(Set<Voter> voters) { + + // get empty result by choice + SortedMap<String, ChoiceScore> resultByChoice = votersToResult(voters); + + // calcul du score minimum pour atteindre la majorité absolue + double totalWeight = 0.; + for (Voter voter : voters) { + totalWeight += voter.getWeight(); + } + totalWeight /= 2; + + // calcul pour chaque votant de ses choix préférés + Map<Voter, List<Set<String>>> topRankChoices = + buildVoterSortedChoices(voters); + + Set<String> choiceIdsToExclude = Sets.newHashSet(); + Set<String> choiceIdsToKeep = Sets.newHashSet(resultByChoice.keySet()); + + round(topRankChoices, + choiceIdsToExclude, + choiceIdsToKeep, + resultByChoice, + totalWeight); + + // transform map of result to list of them (and sort them) + VoteCountingResult result = resultToList(resultByChoice); + return result; + } + + public void round(Map<Voter, List<Set<String>>> topRankChoices, + Set<String> idsToExclude, + Set<String> idsToInclude, + SortedMap<String, ChoiceScore> resultByChoice, + double totalWeight) { + + List<ChoiceScore> results = applyScores(topRankChoices, + idsToExclude, + idsToInclude, + resultByChoice); + + if (!results.isEmpty()) { + + // get best score + double max = + results.get(results.size() - 1).getScoreValue().doubleValue(); + + if (max < totalWeight) { + + // pas de majorité absolue, il faut éliminer le(s) choix les plus mauvais + + guessChoiceIdsToRemove(idsToExclude, results); + + + // on ne veux plus utiliser ces choix dans le tour suivant + idsToInclude.removeAll(idsToExclude); + + // nouveau tour + round(topRankChoices, + idsToExclude, + idsToInclude, + resultByChoice, + totalWeight); + + } else { + + // majorité absolue trouvée plus rien à faire en fait :) + } + } + } + + public List<ChoiceScore> applyScores(Map<Voter, List<Set<String>>> topRankChoices, + Set<String> idsToExclude, + Set<String> idsToInclude, + SortedMap<String, ChoiceScore> resultByChoice) { + + if (CollectionUtils.isNotEmpty(idsToExclude)) { + + // on supprime des classements les ids données + + for (List<Set<String>> choicesByLevel : topRankChoices.values()) { + Iterator<Set<String>> itr = choicesByLevel.iterator(); + while (itr.hasNext()) { + Set<String> choiceIds = itr.next(); + choiceIds.removeAll(idsToExclude); + if (choiceIds.isEmpty()) { + + // remove this level + itr.remove(); + } + } + } + } + + // on remet à zero les scores pour les ids a conserver + for (String id : idsToInclude) { + resultByChoice.get(id).setScoreValue(null); + } + + // on calcule les scores à partir des classements + + for (Map.Entry<Voter, List<Set<String>>> entry : topRankChoices.entrySet()) { + List<Set<String>> idsByLevel = entry.getValue(); + if (!idsByLevel.isEmpty()) { + + Set<String> winnerIds = idsByLevel.get(0); + Voter voter = entry.getKey(); + double voterWeight = voter.getWeight(); + for (String id : winnerIds) { + if (idsToInclude.contains(id)) { + ChoiceScore choiceScore = resultByChoice.get(id); + choiceScore.addScoreValue(voterWeight); + } + } + } + } + + // recopy choices to run rounds on it and eliminates choices until + // there is a choice > 50 + List<ChoiceScore> results = Lists.newArrayList(); + + for (String id : idsToInclude) { + results.add(resultByChoice.get(id)); + } + + Collections.sort(results); + + // on supprime tout score à 0 + Iterator<ChoiceScore> itr = results.iterator(); + while (itr.hasNext()) { + ChoiceScore choiceScore = itr.next(); + if (choiceScore.getScoreValue() == null || + ZERO_D.equals(choiceScore.getScoreValue())) { + itr.remove(); + } else { + // score > 0 on peut s'arreter + break; + } + } + return results; + } + + public void guessChoiceIdsToRemove(Set<String> idsToExclude, + List<ChoiceScore> results) { + + double min = results.get(0).getScoreValue().doubleValue(); + + idsToExclude.clear(); + + for (ChoiceScore choiceScore : results) { + + if (min == choiceScore.getScoreValue().doubleValue()) { + + idsToExclude.add(choiceScore.getChoiceId()); + } else { + // value > min, on peut s'arreter là + break; + } + } + } + +} Property changes on: trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategy.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/strategy/InstantRunoffStrategy.java =================================================================== --- trunk/pollen-votecounting-strategy-instant-runoff/src/main/java/org/chorem/pollen/votecounting/strategy/InstantRunoffStrategy.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-instant-runoff/src/main/java/org/chorem/pollen/votecounting/strategy/InstantRunoffStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,278 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Instant Runoff - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import org.apache.commons.collections.CollectionUtils; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; - -import static org.nuiton.i18n.I18n.l_; -import static org.nuiton.i18n.I18n.n_; - -/** - * InstantRunoff. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class InstantRunoffStrategy extends AbstractVoteCountingStrategy { - - public static final int ID = 5; - - @Override - public int getId() { - return ID; - } - - @Override - public String getI18nName() { - return n_("pollen.voteCountingType.instantRunoff"); - } - - @Override - public String getI18nHelp() { - return n_("pollen.voteCountingType.instantRunoff.help"); - } - - @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { - // no validation on total value, so no message - return null; - } - - @Override - public String getVoteValueNotValidMessage(Locale locale) { - return l_(locale, "pollen.error.vote.invalidInstantRunoffVoteValue"); - } - - @Override - public String getDisplayVoteValue(Integer voteValue) { - return voteValue == null ? "" : String.valueOf(voteValue); - } - - @Override - public ChoiceToVoteRenderType getVoteValueEditorType() { - return ChoiceToVoteRenderType.TEXTFIELD; - } - - @Override - public boolean isChoiceInVote(Integer voteValue) { - return voteValue != null && voteValue > 0 && voteValue < 100; - } - - @Override - public boolean isVoteValueNull(Integer voteValue) { - return voteValue == null; - } - - @Override - public boolean isDisplayResultsByChoice() { - return false; - } - - @Override - public boolean isVoteValueValid(Integer voteValue) { - return voteValue != null && voteValue > 0; - } - - @Override - public boolean isTotalVoteValueValid(int totalValues) { - // no validation on total value - return true; - } - - @Override - public VoteCountingResult votecount(Set<Voter> voters) { - - // get empty result by choice - SortedMap<String, ChoiceScore> resultByChoice = votersToResult(voters); - - // calcul du score minimum pour atteindre la majorité absolue - double totalWeight = 0.; - for (Voter voter : voters) { - totalWeight += voter.getWeight(); - } - totalWeight /= 2; - - // calcul pour chaque votant de ses choix préférés - Map<Voter, List<Set<String>>> topRankChoices = - buildVoterSortedChoices(voters); - - Set<String> choiceIdsToExclude = Sets.newHashSet(); - Set<String> choiceIdsToKeep = Sets.newHashSet(resultByChoice.keySet()); - - round(topRankChoices, - choiceIdsToExclude, - choiceIdsToKeep, - resultByChoice, - totalWeight); - - // transform map of result to list of them (and sort them) - VoteCountingResult result = resultToList(resultByChoice); - return result; - } - - public void round(Map<Voter, List<Set<String>>> topRankChoices, - Set<String> idsToExclude, - Set<String> idsToInclude, - SortedMap<String, ChoiceScore> resultByChoice, - double totalWeight) { - - List<ChoiceScore> results = applyScores(topRankChoices, - idsToExclude, - idsToInclude, - resultByChoice); - - if (!results.isEmpty()) { - - // get best score - double max = - results.get(results.size() - 1).getScoreValue().doubleValue(); - - if (max < totalWeight) { - - // pas de majorité absolue, il faut éliminer le(s) choix les plus mauvais - - guessChoiceIdsToRemove(idsToExclude, results); - - - // on ne veux plus utiliser ces choix dans le tour suivant - idsToInclude.removeAll(idsToExclude); - - // nouveau tour - round(topRankChoices, - idsToExclude, - idsToInclude, - resultByChoice, - totalWeight); - - } else { - - // majorité absolue trouvée plus rien à faire en fait :) - } - } - } - - public List<ChoiceScore> applyScores(Map<Voter, List<Set<String>>> topRankChoices, - Set<String> idsToExclude, - Set<String> idsToInclude, - SortedMap<String, ChoiceScore> resultByChoice) { - - if (CollectionUtils.isNotEmpty(idsToExclude)) { - - // on supprime des classements les ids données - - for (List<Set<String>> choicesByLevel : topRankChoices.values()) { - Iterator<Set<String>> itr = choicesByLevel.iterator(); - while (itr.hasNext()) { - Set<String> choiceIds = itr.next(); - choiceIds.removeAll(idsToExclude); - if (choiceIds.isEmpty()) { - - // remove this level - itr.remove(); - } - } - } - } - - // on remet à zero les scores pour les ids a conserver - for (String id : idsToInclude) { - resultByChoice.get(id).setScoreValue(null); - } - - // on calcule les scores à partir des classements - - for (Map.Entry<Voter, List<Set<String>>> entry : topRankChoices.entrySet()) { - List<Set<String>> idsByLevel = entry.getValue(); - if (!idsByLevel.isEmpty()) { - - Set<String> winnerIds = idsByLevel.get(0); - Voter voter = entry.getKey(); - double voterWeight = voter.getWeight(); - for (String id : winnerIds) { - if (idsToInclude.contains(id)) { - ChoiceScore choiceScore = resultByChoice.get(id); - choiceScore.addScoreValue(voterWeight); - } - } - } - } - - // recopy choices to run rounds on it and eliminates choices until - // there is a choice > 50 - List<ChoiceScore> results = Lists.newArrayList(); - - for (String id : idsToInclude) { - results.add(resultByChoice.get(id)); - } - - Collections.sort(results); - - // on supprime tout score à 0 - Iterator<ChoiceScore> itr = results.iterator(); - while (itr.hasNext()) { - ChoiceScore choiceScore = itr.next(); - if (choiceScore.getScoreValue() == null || - ZERO_D.equals(choiceScore.getScoreValue())) { - itr.remove(); - } else { - // score > 0 on peut s'arreter - break; - } - } - return results; - } - - public void guessChoiceIdsToRemove(Set<String> idsToExclude, - List<ChoiceScore> results) { - - double min = results.get(0).getScoreValue().doubleValue(); - - idsToExclude.clear(); - - for (ChoiceScore choiceScore : results) { - - if (min == choiceScore.getScoreValue().doubleValue()) { - - idsToExclude.add(choiceScore.getChoiceId()); - } else { - // value > min, on peut s'arreter là - break; - } - } - } - -} Copied: trunk/pollen-votecounting-instant-runoff/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (from rev 3707, trunk/pollen-votecounting-strategy-instant-runoff/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy) =================================================================== --- trunk/pollen-votecounting-instant-runoff/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (rev 0) +++ trunk/pollen-votecounting-instant-runoff/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1 @@ +org.chorem.pollen.votecounting.InstantRunoffVoteCounting Property changes on: trunk/pollen-votecounting-instant-runoff/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-instant-runoff/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy =================================================================== --- trunk/pollen-votecounting-strategy-instant-runoff/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-instant-runoff/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-29 12:36:25 UTC (rev 3708) @@ -1 +0,0 @@ -org.chorem.pollen.votecounting.strategy.InstantRunoffStrategy Copied: trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java (from rev 3707, trunk/pollen-votecounting-strategy-instant-runoff/src/test/java/org/chorem/pollen/votecounting/strategy/InstantRunoffStrategyTest.java) =================================================================== --- trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java (rev 0) +++ trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,327 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Instant Runoff + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.chorem.pollen.votecounting.model.ChoiceIdAble; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Tests the {@link InstantRunoffVoteCountingStrategy}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +@Ignore +public class InstantRunoffVoteCountingStrategyTest { + + public static final String CHOICE_A = "Ville A"; + + public static final String CHOICE_B = "Ville B"; + + public static final String CHOICE_C = "Ville C"; + + public static final String CHOICE_D = "Ville D"; + + protected static VoteCounting voteCounting; + + protected VoteCountingStrategy strategy; + + @BeforeClass + public static void beforeClass() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + voteCounting = factory.getVoteCounting(InstantRunoffVoteCounting.ID); + } + + @Before + public void setUp() throws Exception { + strategy = voteCounting.newVoteCountingStrategy(); + } + + @Test + public void simpleVotecount() throws Exception { + + // see http://fr.wikipedia.org/wiki/Vote_alternatif + + // Ville 1re 2e 3e 4e R1 R2 R3 + // A 42 0 0 58 42 42 42 + // B 26 42 32 0 26 26 - + // C 15 43 42 0 15 - - + // D 17 15 26 42 17 32 58 + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("Ville A", 42.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 3.). + addVoteForChoice(CHOICE_D, 4.). + newVoter("Ville B", 26.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 2.). + addVoteForChoice(CHOICE_D, 3.). + addVoteForChoice(CHOICE_A, 4.). + newVoter("Ville C", 15.). + addVoteForChoice(CHOICE_C, 1.). + addVoteForChoice(CHOICE_D, 2.). + addVoteForChoice(CHOICE_B, 3.). + addVoteForChoice(CHOICE_A, 4.). + newVoter("Ville D", 17.). + addVoteForChoice(CHOICE_D, 1.). + addVoteForChoice(CHOICE_C, 2.). + addVoteForChoice(CHOICE_B, 3.). + addVoteForChoice(CHOICE_A, 4.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(4, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_D, BigDecimal.valueOf(58.)); + assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(42.)); + assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(26.)); + assertChoiceScore(scores.get(3), CHOICE_C, BigDecimal.valueOf(15.)); + } + + @Test + public void simpleVotecount0() throws Exception { + + // Simple poll (all weight to 1) R1 + // 1 (a=1 b=2 c=null) a 2 + // 2 (a=3 b=2 c=1) b 1 + // 3 (a=1 b=null c=2) c - + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 3.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(2.)); + assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(1.)); + assertChoiceScore(scores.get(2), CHOICE_B, null); + } + + @Test + public void simpleVotecount2() throws Exception { + + // Simple poll (all weight to 1) R1 + // 1 (a=1 b=2 c=null) a 2 + // 2 (a=1 b=2 c=1) b - + // 3 (a=null b=null c=2) c 2 + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(2.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_C); + assertChoiceScore(scores.get(2), CHOICE_B, null); + } + + @Test + public void simpleVotecount3() throws Exception { + + // Simple poll (all weight to 1) R1 + // 1 (a=1 b=null c=null) a 1 + // 2 (a=null b=1 c=null) b 1 + // 3 (a=null b=null c=1) c 1 + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(1.), + Sets.newHashSet(scores.get(0), + scores.get(1), + scores.get(2) + ), + CHOICE_A, CHOICE_B, CHOICE_C); + } + + @Test + public void weightedVotecount1() throws Exception { + + // poll with weighted vote R1 + // 1 (x2) (a=1 b=null c=null) a 2 + // 2 (x1) (a=null b=1 c=null) b 2 + // 3 (x1) (a=null b=1 c=2) c - + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 2.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(2.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_B); + assertChoiceScore(scores.get(2), CHOICE_C, null); + } + + @Test + public void weightedVotecount2() throws Exception { + + // poll with weighted vote R1 + // 1 (x2) (a=1 b=null c=null) a 2 + // 2 (x1) (a=null b=1 c=null) b 1 + // 3 (x3) (a=null b=2 c=1) c 3 + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 3.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(3.)); + assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(2.)); + assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(1.)); + } + + public static void assertChoiceScore(ChoiceScore choiceScore, + String choiceId, + BigDecimal choiceResult) { + Assert.assertNotNull(choiceScore); + Assert.assertEquals(choiceId, choiceScore.getChoiceId()); + Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); + } + + public static void assertChoiceScoreEquals(BigDecimal choiceResult, + Set<ChoiceScore> choiceScores, + String... choiceIds) { + + Assert.assertNotNull(choiceScores); + Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( + choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); + for (String choiceId : choiceIds) { + + ChoiceScore choiceScore = choicesById.get(choiceId); + Assert.assertNotNull(choiceScore); + assertChoiceScore(choiceScore, choiceId, choiceResult); + } + } + +} Property changes on: trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/InstantRunoffVoteCountingStrategyTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (from rev 3707, trunk/pollen-votecounting-strategy-instant-runoff/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java) =================================================================== --- trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (rev 0) +++ trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,43 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Instant Runoff + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests the {@link VoteCountingFactory}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class VoteCountingFactoryTest { + + @Test + public void getVoteCounting() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + VoteCounting voteCounting = + factory.getVoteCounting(InstantRunoffVoteCounting.ID); + Assert.assertNotNull(voteCounting); + } +} Property changes on: trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/strategy/InstantRunoffStrategyTest.java =================================================================== --- trunk/pollen-votecounting-strategy-instant-runoff/src/test/java/org/chorem/pollen/votecounting/strategy/InstantRunoffStrategyTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/strategy/InstantRunoffStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,326 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Instant Runoff - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.chorem.pollen.votecounting.model.ChoiceIdAble; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Tests the {@link InstantRunoffStrategy}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -@Ignore -public class InstantRunoffStrategyTest { - - public static final String CHOICE_A = "Ville A"; - - public static final String CHOICE_B = "Ville B"; - - public static final String CHOICE_C = "Ville C"; - - public static final String CHOICE_D = "Ville D"; - - protected static VoteCountingStrategyProvider provider; - - protected VoteCountingStrategy strategy; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Before - public void setUp() throws Exception { - strategy = provider.getStrategy(InstantRunoffStrategy.ID); - } - - @Test - public void simpleVotecount() throws Exception { - - // see http://fr.wikipedia.org/wiki/Vote_alternatif - - // Ville 1re 2e 3e 4e R1 R2 R3 - // A 42 0 0 58 42 42 42 - // B 26 42 32 0 26 26 - - // C 15 43 42 0 15 - - - // D 17 15 26 42 17 32 58 - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("Ville A", 42.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 3.). - addVoteForChoice(CHOICE_D, 4.). - newVoter("Ville B", 26.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_D, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville C", 15.). - addVoteForChoice(CHOICE_C, 1.). - addVoteForChoice(CHOICE_D, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - newVoter("Ville D", 17.). - addVoteForChoice(CHOICE_D, 1.). - addVoteForChoice(CHOICE_C, 2.). - addVoteForChoice(CHOICE_B, 3.). - addVoteForChoice(CHOICE_A, 4.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(4, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_D, BigDecimal.valueOf(58.)); - assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(42.)); - assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(26.)); - assertChoiceScore(scores.get(3), CHOICE_C, BigDecimal.valueOf(15.)); - } - - @Test - public void simpleVotecount0() throws Exception { - - // Simple poll (all weight to 1) R1 - // 1 (a=1 b=2 c=null) a 2 - // 2 (a=3 b=2 c=1) b 1 - // 3 (a=1 b=null c=2) c - - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 3.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(2.)); - assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(1.)); - assertChoiceScore(scores.get(2), CHOICE_B, null); - } - - @Test - public void simpleVotecount2() throws Exception { - - // Simple poll (all weight to 1) R1 - // 1 (a=1 b=2 c=null) a 2 - // 2 (a=1 b=2 c=1) b - - // 3 (a=null b=null c=2) c 2 - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(2.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_C); - assertChoiceScore(scores.get(2), CHOICE_B, null); - } - - @Test - public void simpleVotecount3() throws Exception { - - // Simple poll (all weight to 1) R1 - // 1 (a=1 b=null c=null) a 1 - // 2 (a=null b=1 c=null) b 1 - // 3 (a=null b=null c=1) c 1 - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(1.), - Sets.newHashSet(scores.get(0), - scores.get(1), - scores.get(2) - ), - CHOICE_A, CHOICE_B, CHOICE_C); - } - - @Test - public void weightedVotecount1() throws Exception { - - // poll with weighted vote R1 - // 1 (x2) (a=1 b=null c=null) a 2 - // 2 (x1) (a=null b=1 c=null) b 2 - // 3 (x1) (a=null b=1 c=2) c - - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 2.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(2.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_B); - assertChoiceScore(scores.get(2), CHOICE_C, null); - } - - @Test - public void weightedVotecount2() throws Exception { - - // poll with weighted vote R1 - // 1 (x2) (a=1 b=null c=null) a 2 - // 2 (x1) (a=null b=1 c=null) b 1 - // 3 (x3) (a=null b=2 c=1) c 3 - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(3.)); - assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(2.)); - assertChoiceScore(scores.get(2), CHOICE_B, BigDecimal.valueOf(1.)); - } - - public static void assertChoiceScore(ChoiceScore choiceScore, - String choiceId, - BigDecimal choiceResult) { - Assert.assertNotNull(choiceScore); - Assert.assertEquals(choiceId, choiceScore.getChoiceId()); - Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); - } - - public static void assertChoiceScoreEquals(BigDecimal choiceResult, - Set<ChoiceScore> choiceScores, - String... choiceIds) { - - Assert.assertNotNull(choiceScores); - Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( - choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); - for (String choiceId : choiceIds) { - - ChoiceScore choiceScore = choicesById.get(choiceId); - Assert.assertNotNull(choiceScore); - assertChoiceScore(choiceScore, choiceId, choiceResult); - } - } - -} Deleted: trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java =================================================================== --- trunk/pollen-votecounting-strategy-instant-runoff/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-instant-runoff/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,49 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Instant Runoff - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Tests the {@link VoteCountingStrategyProvider}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class VoteCountingStrategyProviderTest { - - protected static VoteCountingStrategyProvider provider; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Test - public void getStrategy() throws Exception { - - Assert.assertNotNull(provider.getStrategy(InstantRunoffStrategy.ID)); - } -} Modified: trunk/pollen-votecounting-normal/pom.xml =================================================================== --- trunk/pollen-votecounting-strategy-normal/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-normal/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -10,11 +12,10 @@ </parent> <groupId>org.chorem.pollen</groupId> - <artifactId>pollen-votecounting-strategy-normal</artifactId> + <artifactId>pollen-votecounting-normal</artifactId> + <name>Pollen :: VoteCounting :: Normal</name> + <description>Implements the normal vote counting</description> - <name>Pollen :: VoteCounting strategy :: Normal</name> - <description>Implements the normal vote counting strategy</description> - <dependencies> <dependency> @@ -27,12 +28,19 @@ <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> + <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> </dependency> <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> Added: trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java =================================================================== --- trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java (rev 0) +++ trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,71 @@ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.n_; + +/** + * Coombs vote counting entry point. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6 + */ +public class NormalVoteCounting extends AbstractVoteCounting<NormalVoteCountingStrategy> { + + public static final int ID = 0; + + public NormalVoteCounting() { + super(ID, + NormalVoteCountingStrategy.class, + n_("pollen.voteCountingType.normal"), + n_("pollen.voteCountingType.normal.help") + ); + } + + @Override + public String getDisplayVoteValue(Integer voteValue) { + return voteValue != null ? "OK" : ""; + } + + @Override + public boolean isChoiceInVote(Integer voteValue) { + return voteValue != null && voteValue > 0; + } + + @Override + public boolean isVoteValueNull(Integer voteValue) { + return voteValue == null || voteValue == 0; + } + + @Override + public ChoiceToVoteRenderType getVoteValueEditorType() { + return ChoiceToVoteRenderType.CHECKBOX; + } + + @Override + public boolean isVoteValueValid(Integer voteValue) { + // no validation on not null vote value + return true; + } + + @Override + public boolean isTotalVoteValueValid(int totalValues) { + // no validation on total value + return true; + } + + @Override + public String getVoteValueNotValidMessage(Locale locale) { + // no validation on not null vote value, so no message + return null; + } + + @Override + public String getTotalVoteValueNotValidMessage(Locale locale) { + // no validation on total values, so no message + return null; + } + +} Property changes on: trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCounting.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java (from rev 3707, trunk/pollen-votecounting-strategy-normal/src/main/java/org/chorem/pollen/votecounting/strategy/NormalStrategy.java) =================================================================== --- trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java (rev 0) +++ trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,78 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Normal + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.VoteForChoice; +import org.chorem.pollen.votecounting.model.Voter; + +import java.util.Map; +import java.util.Set; + +/** + * Condorcet. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class NormalVoteCountingStrategy extends AbstractVoteCountingStrategy { + + @Override + public VoteCountingResult votecount(Set<Voter> voters) { + + // get empty result by choice + Map<String, ChoiceScore> resultByChoice = votersToResult(voters); + + for (Voter voter : voters) { + // add this voter votes to result + addVoterChoices(voter, resultByChoice); + } + // transform map of result to list of them (and sort them) + VoteCountingResult result = resultToList(resultByChoice); + return result; + } + + public void addVoterChoices(Voter voter, + Map<String, ChoiceScore> resultByChoice) { + + double voterWeight = voter.getWeight(); + + for (VoteForChoice voteForChoice : voter.getVoteForChoices()) { + Double voteValue = voteForChoice.getVoteValue(); + if (voteValue != null) { + + // get score for choice + String choiceId = voteForChoice.getChoiceId(); + ChoiceScore choiceScore = resultByChoice.get(choiceId); + + // compute score to add + double scoreToAdd = voteValue * voterWeight; + + // add to score this weighted vote + choiceScore.addScoreValue(scoreToAdd); + } + } + } + +} Property changes on: trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategy.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/strategy/NormalStrategy.java =================================================================== --- trunk/pollen-votecounting-strategy-normal/src/main/java/org/chorem/pollen/votecounting/strategy/NormalStrategy.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-normal/src/main/java/org/chorem/pollen/votecounting/strategy/NormalStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,148 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Normal - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.VoteForChoice; -import org.chorem.pollen.votecounting.model.Voter; - -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import static org.nuiton.i18n.I18n.n_; - -/** - * Condorcet. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class NormalStrategy extends AbstractVoteCountingStrategy { - - public static final int ID = 0; - - @Override - public int getId() { - return ID; - } - - @Override - public String getI18nName() { - return n_("pollen.voteCountingType.normal"); - } - - @Override - public String getI18nHelp() { - return n_("pollen.voteCountingType.normal.help"); - } - - @Override - public VoteCountingResult votecount(Set<Voter> voters) { - - // get empty result by choice - Map<String, ChoiceScore> resultByChoice = votersToResult(voters); - - for (Voter voter : voters) { - // add this voter votes to result - addVoterChoices(voter, resultByChoice); - } - // transform map of result to list of them (and sort them) - VoteCountingResult result = resultToList(resultByChoice); - return result; - } - - @Override - public String getDisplayVoteValue(Integer voteValue) { - return voteValue != null ? "OK" : ""; - } - - @Override - public boolean isChoiceInVote(Integer voteValue) { - return voteValue != null && voteValue > 0; - } - - @Override - public boolean isVoteValueNull(Integer voteValue) { - return voteValue == null || voteValue == 0; - } - - @Override - public ChoiceToVoteRenderType getVoteValueEditorType() { - return ChoiceToVoteRenderType.CHECKBOX; - } - - @Override - public boolean isDisplayResultsByChoice() { - return false; - } - - @Override - public boolean isVoteValueValid(Integer voteValue) { - // no validation on not null vote value - return true; - } - - @Override - public boolean isTotalVoteValueValid(int totalValues) { - // no validation on total value - return true; - } - - @Override - public String getVoteValueNotValidMessage(Locale locale) { - // no validation on not null vote value, so no message - return null; - } - - @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { - // no validation on total values, so no message - return null; - } - - public void addVoterChoices(Voter voter, - Map<String, ChoiceScore> resultByChoice) { - - double voterWeight = voter.getWeight(); - - for (VoteForChoice voteForChoice : voter.getVoteForChoices()) { - Double voteValue = voteForChoice.getVoteValue(); - if (voteValue != null) { - - // get score for choice - String choiceId = voteForChoice.getChoiceId(); - ChoiceScore choiceScore = resultByChoice.get(choiceId); - - // compute score to add - double scoreToAdd = voteValue * voterWeight; - - // add to score this weighted vote - choiceScore.addScoreValue(scoreToAdd); - } - } - } - -} Copied: trunk/pollen-votecounting-normal/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (from rev 3707, trunk/pollen-votecounting-strategy-normal/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy) =================================================================== --- trunk/pollen-votecounting-normal/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (rev 0) +++ trunk/pollen-votecounting-normal/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1 @@ +org.chorem.pollen.votecounting.NormalVoteCounting Property changes on: trunk/pollen-votecounting-normal/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-normal/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy =================================================================== --- trunk/pollen-votecounting-strategy-normal/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-normal/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-29 12:36:25 UTC (rev 3708) @@ -1 +0,0 @@ -org.chorem.pollen.votecounting.strategy.NormalStrategy Copied: trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java (from rev 3707, trunk/pollen-votecounting-strategy-normal/src/test/java/org/chorem/pollen/votecounting/strategy/NormalStrategyTest.java) =================================================================== --- trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java (rev 0) +++ trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,344 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Normal + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.chorem.pollen.votecounting.model.ChoiceIdAble; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.GroupOfVoter; +import org.chorem.pollen.votecounting.model.GroupOfVoterBuilder; +import org.chorem.pollen.votecounting.model.GroupVoteCountingResult; +import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Tests the {@link NormalVoteCountingStrategy}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class NormalVoteCountingStrategyTest { + + public static final String CHOICE_A = "a"; + + public static final String CHOICE_B = "b"; + + public static final String CHOICE_C = "c"; + + protected static VoteCounting voteCounting; + + protected VoteCountingStrategy strategy; + + @BeforeClass + public static void beforeClass() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + voteCounting = factory.getVoteCounting(NormalVoteCounting.ID); + } + + @Before + public void setUp() throws Exception { + strategy = voteCounting.newVoteCountingStrategy(); + } + + @Test + public void simpleVotecount() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=null c=null) + // 2 (a=null b=1 c=null) + // 3 (a=null b=1 c=1) + // Result (a=1 b=2 c=1) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(2.)); + + assertChoiceScoreEquals(BigDecimal.valueOf(1.), + Sets.newHashSet(scores.get(1), + scores.get(2)), + CHOICE_A, CHOICE_C); + } + + //TODO Finish me + @Ignore + @Test + public void groupVotecount() throws Exception { + + // Group poll (all weight to 1) + // G1U1 (a=1 b=null c=null) + // G1U2 (a=null b=1 c=null) + // G1U3 (a=null b=1 c=1) + // Result G1 (a=1 b=2 c=1) + // G2U1 (a=null b=1 c=null) + // G2U2 (a=1 b=null c=null) + // G2U3 (a=null b=1 c=1) + // Result G2 (a=1 b=2 c=1) + // Result (a=1 b=2 c=1) + + GroupOfVoter voters = new GroupOfVoterBuilder(). + newGroupVoter("G1", 1.). + newVoter("G1U1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("G1U2", 2.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("G1U3", 3.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 1.). + newGroupVoter("G2", 1.). + newVoter("G2U1", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.0). + addVoteForChoice(CHOICE_C, null). + newVoter("G2U2", 1.). + addVoteForChoice(CHOICE_A, 1.0). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("G2U3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 1.). + getRoot(); + + GroupVoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + VoteCountingResult mainResult = result.getMainResult(); + Assert.assertNotNull(mainResult); + + List<ChoiceScore> scores = mainResult.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(2.)); + + assertChoiceScoreEquals(BigDecimal.valueOf(1.), + Sets.newHashSet(scores.get(1), + scores.get(2)), + CHOICE_A, CHOICE_C); + } + + @Test + public void simpleVotecount2() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=null c=null) + // 2 (a=1 b=1 c=null) + // 3 (a=1 b=1 c=null) + // Result (a=3 b=2 c=null) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(3.)); + assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(2.)); + assertChoiceScore(scores.get(2), CHOICE_C, null); + } + + @Test + public void simpleVotecount3() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=1 c=null) + // 2 (a=1 b=1 c=null) + // 3 (a=1 b=1 c=null) + // Result (a=3 b=3 c=null) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(3.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_B); + assertChoiceScore(scores.get(2), CHOICE_C, null); + } + + @Test + public void weightedVotecount1() throws Exception { + + // poll with weighted vote + // 1 (x2) (a=1 b=null c=null) + // 2 (x1) (a=null b=1 c=null) + // 3 (x1) (a=null b=1 c=1) + // Result (a=2 b=2 c=1) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(2.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_B); + assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(1.)); + } + + @Test + public void weightedVotecount2() throws Exception { + + // poll with weighted vote + // 1 (x2) (a=1 b=null c=null) + // 2 (x1) (a=null b=1 c=null) + // 3 (x3) (a=null b=1 c=1) + // Result (a=2 b=4 c=3) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 3.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(4.)); + assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(3.)); + assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(2.)); + } + + public static void assertChoiceScore(ChoiceScore choiceScore, + String choiceId, + BigDecimal choiceResult) { + Assert.assertNotNull(choiceScore); + Assert.assertEquals(choiceId, choiceScore.getChoiceId()); + Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); + } + + public static void assertChoiceScoreEquals(BigDecimal choiceResult, + Set<ChoiceScore> choiceScores, + String... choiceIds) { + + Assert.assertNotNull(choiceScores); + Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( + choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); + for (String choiceId : choiceIds) { + + ChoiceScore choiceScore = choicesById.get(choiceId); + Assert.assertNotNull(choiceScore); + assertChoiceScore(choiceScore, choiceId, choiceResult); + } + } + +} Property changes on: trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/NormalVoteCountingStrategyTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (from rev 3707, trunk/pollen-votecounting-strategy-normal/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java) =================================================================== --- trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (rev 0) +++ trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,43 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Normal + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests the {@link VoteCountingFactory}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class VoteCountingFactoryTest { + + @Test + public void getVoteCounting() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + VoteCounting voteCounting = + factory.getVoteCounting(NormalVoteCounting.ID); + Assert.assertNotNull(voteCounting); + } +} Property changes on: trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/strategy/NormalStrategyTest.java =================================================================== --- trunk/pollen-votecounting-strategy-normal/src/test/java/org/chorem/pollen/votecounting/strategy/NormalStrategyTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/strategy/NormalStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,338 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Normal - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.chorem.pollen.votecounting.model.ChoiceIdAble; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.GroupOfVoter; -import org.chorem.pollen.votecounting.model.GroupOfVoterBuilder; -import org.chorem.pollen.votecounting.model.GroupVoteCountingResult; -import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Tests the {@link NormalStrategy}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class NormalStrategyTest { - - public static final String CHOICE_A = "a"; - - public static final String CHOICE_B = "b"; - - public static final String CHOICE_C = "c"; - - protected static VoteCountingStrategyProvider provider; - - protected VoteCountingStrategy strategy; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Before - public void setUp() throws Exception { - strategy = provider.getStrategy(NormalStrategy.ID); - } - - @Test - public void simpleVotecount() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=null c=null) - // 2 (a=null b=1 c=null) - // 3 (a=null b=1 c=1) - // Result (a=1 b=2 c=1) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(2.)); - - assertChoiceScoreEquals(BigDecimal.valueOf(1.), - Sets.newHashSet(scores.get(1), - scores.get(2)), - CHOICE_A, CHOICE_C); - } - - //TODO Finish me - @Ignore - @Test - public void groupVotecount() throws Exception { - - // Group poll (all weight to 1) - // 1 (a=1 b=null c=null) - // 2 (a=null b=1 c=null) - // 3 (a=null b=1 c=1) - // Result (a=1 b=2 c=1) - - GroupOfVoter voters = new GroupOfVoterBuilder(). - newGroupVoter("G1", 1.). - newVoter("G1U1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("G1U2", 2.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("G1U3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - newGroupVoter("G2", 1.). - newVoter("G2U1", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 2.0). - addVoteForChoice(CHOICE_C, null). - newVoter("G2U2", 1.). - addVoteForChoice(CHOICE_A, 1.0). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("G2U3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getRoot(); - - GroupVoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - VoteCountingResult mainResult = result.getMainResult(); - Assert.assertNotNull(mainResult); - - List<ChoiceScore> scores = mainResult.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(2.)); - - assertChoiceScoreEquals(BigDecimal.valueOf(1.), - Sets.newHashSet(scores.get(1), - scores.get(2)), - CHOICE_A, CHOICE_C); - } - - @Test - public void simpleVotecount2() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=null c=null) - // 2 (a=1 b=1 c=null) - // 3 (a=1 b=1 c=null) - // Result (a=3 b=2 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(3.)); - assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(2.)); - assertChoiceScore(scores.get(2), CHOICE_C, null); - } - - @Test - public void simpleVotecount3() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=1 c=null) - // 2 (a=1 b=1 c=null) - // 3 (a=1 b=1 c=null) - // Result (a=3 b=3 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(3.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_B); - assertChoiceScore(scores.get(2), CHOICE_C, null); - } - - @Test - public void weightedVotecount1() throws Exception { - - // poll with weighted vote - // 1 (x2) (a=1 b=null c=null) - // 2 (x1) (a=null b=1 c=null) - // 3 (x1) (a=null b=1 c=1) - // Result (a=2 b=2 c=1) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(2.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_B); - assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(1.)); - } - - @Test - public void weightedVotecount2() throws Exception { - - // poll with weighted vote - // 1 (x2) (a=1 b=null c=null) - // 2 (x1) (a=null b=1 c=null) - // 3 (x3) (a=null b=1 c=1) - // Result (a=2 b=4 c=3) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(4.)); - assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(3.)); - assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(2.)); - } - - public static void assertChoiceScore(ChoiceScore choiceScore, - String choiceId, - BigDecimal choiceResult) { - Assert.assertNotNull(choiceScore); - Assert.assertEquals(choiceId, choiceScore.getChoiceId()); - Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); - } - - public static void assertChoiceScoreEquals(BigDecimal choiceResult, - Set<ChoiceScore> choiceScores, - String... choiceIds) { - - Assert.assertNotNull(choiceScores); - Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( - choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); - for (String choiceId : choiceIds) { - - ChoiceScore choiceScore = choicesById.get(choiceId); - Assert.assertNotNull(choiceScore); - assertChoiceScore(choiceScore, choiceId, choiceResult); - } - } - -} Deleted: trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java =================================================================== --- trunk/pollen-votecounting-strategy-normal/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-normal/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,49 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Normal - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Tests the {@link VoteCountingStrategyProvider}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class VoteCountingStrategyProviderTest { - - protected static VoteCountingStrategyProvider provider; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Test - public void getStrategy() throws Exception { - - Assert.assertNotNull(provider.getStrategy(NormalStrategy.ID)); - } -} Modified: trunk/pollen-votecounting-number/pom.xml =================================================================== --- trunk/pollen-votecounting-strategy-number/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-number/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -10,11 +12,10 @@ </parent> <groupId>org.chorem.pollen</groupId> - <artifactId>pollen-votecounting-strategy-number</artifactId> + <artifactId>pollen-votecounting-number</artifactId> + <name>Pollen :: VoteCounting :: Number</name> + <description>Implements the number vote counting</description> - <name>Pollen :: VoteCounting strategy :: Number</name> - <description>Implements the number vote counting strategy</description> - <dependencies> <dependency> @@ -27,12 +28,19 @@ <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> + <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> </dependency> <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>test</scope> + </dependency> + + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> Added: trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCounting.java =================================================================== --- trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCounting.java (rev 0) +++ trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCounting.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,71 @@ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.n_; + +/** + * Coombs vote counting entry point. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6 + */ +public class NumberVoteCounting extends AbstractVoteCounting<NumberVoteCountingStrategy> { + + public static final int ID = 3; + + public NumberVoteCounting() { + super(ID, + NumberVoteCountingStrategy.class, + n_("pollen.voteCountingType.number"), + n_("pollen.voteCountingType.number.help") + ); + } + + @Override + public String getDisplayVoteValue(Integer voteValue) { + return voteValue == null ? "" : String.valueOf(voteValue); + } + + @Override + public boolean isChoiceInVote(Integer voteValue) { + return voteValue != null && voteValue >= 0; + } + + @Override + public boolean isVoteValueNull(Integer voteValue) { + return voteValue == null || voteValue == 0; + } + + @Override + public ChoiceToVoteRenderType getVoteValueEditorType() { + return ChoiceToVoteRenderType.TEXTFIELD; + } + + @Override + public boolean isVoteValueValid(Integer voteValue) { + // no validation on not null vote value + return true; + } + + @Override + public boolean isTotalVoteValueValid(int totalValues) { + // no validation on total value + return true; + } + + @Override + public String getTotalVoteValueNotValidMessage(Locale locale) { + // no validation on total values, so no message + return null; + } + + @Override + public String getVoteValueNotValidMessage(Locale locale) { + // no validation on not null vote value, so no message + return null; + } + +} Property changes on: trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCounting.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java (from rev 3707, trunk/pollen-votecounting-strategy-number/src/main/java/org/chorem/pollen/votecounting/strategy/NumberStrategy.java) =================================================================== --- trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java (rev 0) +++ trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,77 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Number + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.VoteForChoice; +import org.chorem.pollen.votecounting.model.Voter; + +import java.util.Map; +import java.util.Set; + +/** + * Number strategy. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class NumberVoteCountingStrategy extends AbstractVoteCountingStrategy { + + @Override + public VoteCountingResult votecount(Set<Voter> voters) { + + // get empty result by choice + Map<String, ChoiceScore> resultByChoice = votersToResult(voters); + + for (Voter voter : voters) { + // add this voter votes to result + addVoterChoices(voter, resultByChoice); + } + // transform map of result to list of them (and sort them) + VoteCountingResult result = resultToList(resultByChoice); + return result; + } + + public void addVoterChoices(Voter voter, + Map<String, ChoiceScore> resultByChoice) { + + double voterWeight = voter.getWeight(); + + for (VoteForChoice voteForChoice : voter.getVoteForChoices()) { + Double voteValue = voteForChoice.getVoteValue(); + if (voteValue != null) { + + // get score for choice + String choiceId = voteForChoice.getChoiceId(); + ChoiceScore choiceScore = resultByChoice.get(choiceId); + + // compute score to add + double scoreToAdd = voteValue * voterWeight; + + // add to score this weighted vote + choiceScore.addScoreValue(scoreToAdd); + } + } + } +} Property changes on: trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategy.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/strategy/NumberStrategy.java =================================================================== --- trunk/pollen-votecounting-strategy-number/src/main/java/org/chorem/pollen/votecounting/strategy/NumberStrategy.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-number/src/main/java/org/chorem/pollen/votecounting/strategy/NumberStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,147 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Number - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.VoteForChoice; -import org.chorem.pollen.votecounting.model.Voter; - -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import static org.nuiton.i18n.I18n.n_; - -/** - * Number strategy. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class NumberStrategy extends AbstractVoteCountingStrategy { - - public static final int ID = 3; - - @Override - public int getId() { - return ID; - } - - @Override - public String getI18nName() { - return n_("pollen.voteCountingType.number"); - } - - @Override - public String getI18nHelp() { - return n_("pollen.voteCountingType.number.help"); - } - - @Override - public VoteCountingResult votecount(Set<Voter> voters) { - - // get empty result by choice - Map<String, ChoiceScore> resultByChoice = votersToResult(voters); - - for (Voter voter : voters) { - // add this voter votes to result - addVoterChoices(voter, resultByChoice); - } - // transform map of result to list of them (and sort them) - VoteCountingResult result = resultToList(resultByChoice); - return result; - } - - @Override - public String getDisplayVoteValue(Integer voteValue) { - return voteValue == null ? "" : String.valueOf(voteValue); - } - - @Override - public boolean isChoiceInVote(Integer voteValue) { - return voteValue != null && voteValue >= 0; - } - - @Override - public boolean isVoteValueNull(Integer voteValue) { - return voteValue == null || voteValue == 0; - } - - @Override - public ChoiceToVoteRenderType getVoteValueEditorType() { - return ChoiceToVoteRenderType.TEXTFIELD; - } - - @Override - public boolean isDisplayResultsByChoice() { - return true; - } - - @Override - public boolean isVoteValueValid(Integer voteValue) { - // no validation on not null vote value - return true; - } - - @Override - public boolean isTotalVoteValueValid(int totalValues) { - // no validation on total value - return true; - } - - @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { - // no validation on total values, so no message - return null; - } - - @Override - public String getVoteValueNotValidMessage(Locale locale) { - // no validation on not null vote value, so no message - return null; - } - - public void addVoterChoices(Voter voter, - Map<String, ChoiceScore> resultByChoice) { - - double voterWeight = voter.getWeight(); - - for (VoteForChoice voteForChoice : voter.getVoteForChoices()) { - Double voteValue = voteForChoice.getVoteValue(); - if (voteValue != null) { - - // get score for choice - String choiceId = voteForChoice.getChoiceId(); - ChoiceScore choiceScore = resultByChoice.get(choiceId); - - // compute score to add - double scoreToAdd = voteValue * voterWeight; - - // add to score this weighted vote - choiceScore.addScoreValue(scoreToAdd); - } - } - } -} Copied: trunk/pollen-votecounting-number/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (from rev 3707, trunk/pollen-votecounting-strategy-number/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy) =================================================================== --- trunk/pollen-votecounting-number/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (rev 0) +++ trunk/pollen-votecounting-number/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1 @@ +org.chorem.pollen.votecounting.NumberVoteCounting Property changes on: trunk/pollen-votecounting-number/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-number/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy =================================================================== --- trunk/pollen-votecounting-strategy-number/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-number/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-29 12:36:25 UTC (rev 3708) @@ -1 +0,0 @@ -org.chorem.pollen.votecounting.strategy.NumberStrategy Copied: trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java (from rev 3707, trunk/pollen-votecounting-strategy-number/src/test/java/org/chorem/pollen/votecounting/strategy/NumberStrategyTest.java) =================================================================== --- trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java (rev 0) +++ trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,274 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Number + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.chorem.pollen.votecounting.model.ChoiceIdAble; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Tests the {@link NumberVoteCountingStrategy}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class NumberVoteCountingStrategyTest { + + public static final String CHOICE_A = "a"; + + public static final String CHOICE_B = "b"; + + public static final String CHOICE_C = "c"; + + protected static VoteCounting voteCounting; + + protected VoteCountingStrategy strategy; + + @BeforeClass + public static void beforeClass() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + voteCounting = factory.getVoteCounting(NumberVoteCounting.ID); + } + + @Before + public void setUp() throws Exception { + strategy = voteCounting.newVoteCountingStrategy(); + } + + @Test + public void simpleVotecount() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=2 c=null) + // 2 (a=2 b=null c=3) + // 3 (a=7 b=12 c=20) + // Result (a=10 b=14 c=23) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 2.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 2.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, 3.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 7.). + addVoteForChoice(CHOICE_B, 12.). + addVoteForChoice(CHOICE_C, 20.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(23.)); + assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(14.)); + assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(10.)); + } + + @Test + public void simpleVotecount2() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=null c=null) + // 2 (a=1 b=1 c=null) + // 3 (a=1 b=1 c=null) + // Result (a=3 b=2 c=null) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(3.)); + assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(2.)); + assertChoiceScore(scores.get(2), CHOICE_C, null); + } + + @Test + public void simpleVotecount3() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=1 b=1 c=null) + // 2 (a=1 b=1 c=null) + // 3 (a=1 b=1 c=null) + // Result (a=3 b=3 c=null) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(3.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_B); + assertChoiceScore(scores.get(2), CHOICE_C, null); + } + + @Test + public void weightedVotecount1() throws Exception { + + // poll with weighted vote + // 1 (x2) (a=1 b=null c=null) + // 2 (x1) (a=null b=1 c=null) + // 3 (x1) (a=null b=1 c=1) + // Result (a=2 b=2 c=1) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(2.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_B); + assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(1.)); + } + + @Test + public void weightedVotecount2() throws Exception { + + // poll with weighted vote + // 1 (x2) (a=1 b=null c=null) + // 2 (x1) (a=null b=1 c=null) + // 3 (x3) (a=null b=1 c=1) + // Result (a=2 b=4 c=3) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 1.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 3.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 1.). + addVoteForChoice(CHOICE_C, 1.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(4.)); + assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(3.)); + assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(2.)); + } + + public static void assertChoiceScore(ChoiceScore choiceScore, + String choiceId, + BigDecimal choiceResult) { + Assert.assertNotNull(choiceScore); + Assert.assertEquals(choiceId, choiceScore.getChoiceId()); + Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); + } + + public static void assertChoiceScoreEquals(BigDecimal choiceResult, + Set<ChoiceScore> choiceScores, + String... choiceIds) { + + Assert.assertNotNull(choiceScores); + Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( + choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); + for (String choiceId : choiceIds) { + + ChoiceScore choiceScore = choicesById.get(choiceId); + Assert.assertNotNull(choiceScore); + assertChoiceScore(choiceScore, choiceId, choiceResult); + } + } + +} Property changes on: trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/NumberVoteCountingStrategyTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (from rev 3707, trunk/pollen-votecounting-strategy-number/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java) =================================================================== --- trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (rev 0) +++ trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,43 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Number + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests the {@link VoteCountingFactory}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class VoteCountingFactoryTest { + + @Test + public void getVoteCounting() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + VoteCounting voteCounting = + factory.getVoteCounting(NumberVoteCounting.ID); + Assert.assertNotNull(voteCounting); + } +} Property changes on: trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/strategy/NumberStrategyTest.java =================================================================== --- trunk/pollen-votecounting-strategy-number/src/test/java/org/chorem/pollen/votecounting/strategy/NumberStrategyTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/strategy/NumberStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,273 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Number - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.chorem.pollen.votecounting.model.ChoiceIdAble; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Tests the {@link NumberStrategy}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class NumberStrategyTest { - - public static final String CHOICE_A = "a"; - - public static final String CHOICE_B = "b"; - - public static final String CHOICE_C = "c"; - - protected static VoteCountingStrategyProvider provider; - - protected VoteCountingStrategy strategy; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Before - public void setUp() throws Exception { - strategy = provider.getStrategy(NumberStrategy.ID); - } - - @Test - public void simpleVotecount() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=2 c=null) - // 2 (a=2 b=null c=3) - // 3 (a=7 b=12 c=20) - // Result (a=10 b=14 c=23) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 2.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 2.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, 3.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 7.). - addVoteForChoice(CHOICE_B, 12.). - addVoteForChoice(CHOICE_C, 20.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(23.)); - assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(14.)); - assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(10.)); - } - - @Test - public void simpleVotecount2() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=null c=null) - // 2 (a=1 b=1 c=null) - // 3 (a=1 b=1 c=null) - // Result (a=3 b=2 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(3.)); - assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(2.)); - assertChoiceScore(scores.get(2), CHOICE_C, null); - } - - @Test - public void simpleVotecount3() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=1 b=1 c=null) - // 2 (a=1 b=1 c=null) - // 3 (a=1 b=1 c=null) - // Result (a=3 b=3 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(3.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_B); - assertChoiceScore(scores.get(2), CHOICE_C, null); - } - - @Test - public void weightedVotecount1() throws Exception { - - // poll with weighted vote - // 1 (x2) (a=1 b=null c=null) - // 2 (x1) (a=null b=1 c=null) - // 3 (x1) (a=null b=1 c=1) - // Result (a=2 b=2 c=1) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(2.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_B); - assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(1.)); - } - - @Test - public void weightedVotecount2() throws Exception { - - // poll with weighted vote - // 1 (x2) (a=1 b=null c=null) - // 2 (x1) (a=null b=1 c=null) - // 3 (x3) (a=null b=1 c=1) - // Result (a=2 b=4 c=3) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 1.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 1.). - addVoteForChoice(CHOICE_C, 1.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(4.)); - assertChoiceScore(scores.get(1), CHOICE_C, BigDecimal.valueOf(3.)); - assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(2.)); - } - - public static void assertChoiceScore(ChoiceScore choiceScore, - String choiceId, - BigDecimal choiceResult) { - Assert.assertNotNull(choiceScore); - Assert.assertEquals(choiceId, choiceScore.getChoiceId()); - Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); - } - - public static void assertChoiceScoreEquals(BigDecimal choiceResult, - Set<ChoiceScore> choiceScores, - String... choiceIds) { - - Assert.assertNotNull(choiceScores); - Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( - choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); - for (String choiceId : choiceIds) { - - ChoiceScore choiceScore = choicesById.get(choiceId); - Assert.assertNotNull(choiceScore); - assertChoiceScore(choiceScore, choiceId, choiceResult); - } - } - -} Deleted: trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java =================================================================== --- trunk/pollen-votecounting-strategy-number/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-number/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,49 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Number - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Tests the {@link VoteCountingStrategyProvider}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class VoteCountingStrategyProviderTest { - - protected static VoteCountingStrategyProvider provider; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Test - public void getStrategy() throws Exception { - - Assert.assertNotNull(provider.getStrategy(NumberStrategy.ID)); - } -} Modified: trunk/pollen-votecounting-percentage/pom.xml =================================================================== --- trunk/pollen-votecounting-strategy-percentage/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-percentage/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -10,11 +12,10 @@ </parent> <groupId>org.chorem.pollen</groupId> - <artifactId>pollen-votecounting-strategy-percentage</artifactId> + <artifactId>pollen-votecounting-percentage</artifactId> + <name>Pollen :: VoteCounting :: Percentage</name> + <description>Implements the percentage vote counting</description> - <name>Pollen :: VoteCounting strategy :: Percentage</name> - <description>Implements the percentage vote counting strategy</description> - <dependencies> <dependency> @@ -23,23 +24,22 @@ <version>${project.version}</version> </dependency> - <!--dependency> - <groupId>commons-logging</groupId> - <artifactId>commons-logging</artifactId> - </dependency--> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> + <dependency> <groupId>org.nuiton.i18n</groupId> <artifactId>nuiton-i18n</artifactId> </dependency> + <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> <scope>test</scope> </dependency> + <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> Added: trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java =================================================================== --- trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java (rev 0) +++ trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,71 @@ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; + +import java.util.Locale; + +import static org.nuiton.i18n.I18n.l_; +import static org.nuiton.i18n.I18n.n_; + +/** + * Coombs vote counting entry point. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.6 + */ +public class PercentageVoteCounting extends AbstractVoteCounting<PercentageVoteCountingStrategy> { + + public static final int ID = 1; + + public PercentageVoteCounting() { + super(ID, + PercentageVoteCountingStrategy.class, + n_("pollen.voteCountingType.percentage"), + n_("pollen.voteCountingType.percentage.help") + ); + } + + @Override + public String getDisplayVoteValue(Integer voteValue) { + return voteValue == null ? "" : String.valueOf(voteValue); + } + + @Override + public boolean isChoiceInVote(Integer voteValue) { + return voteValue != null && voteValue >= 0 && voteValue <= 100; + } + + + @Override + public boolean isVoteValueNull(Integer value) { + return value == null || value == 0; + } + + @Override + public ChoiceToVoteRenderType getVoteValueEditorType() { + return ChoiceToVoteRenderType.TEXTFIELD; + } + + @Override + public boolean isVoteValueValid(Integer voteValue) { + // no validation on not null vote value + return true; + } + + @Override + public boolean isTotalVoteValueValid(int totalValues) { + return totalValues == 100; + } + + @Override + public String getVoteValueNotValidMessage(Locale locale) { + // no validation on not null vote value, so no message + return null; + } + + @Override + public String getTotalVoteValueNotValidMessage(Locale locale) { + return l_(locale, "pollen.error.vote.percentage"); + } + +} Property changes on: trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCounting.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Copied: trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java (from rev 3707, trunk/pollen-votecounting-strategy-percentage/src/main/java/org/chorem/pollen/votecounting/strategy/PercentageStrategy.java) =================================================================== --- trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java (rev 0) +++ trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,76 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Percentage + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.VoteForChoice; +import org.chorem.pollen.votecounting.model.Voter; + +import java.util.Map; +import java.util.Set; + +/** + * Percentage strategy. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class PercentageVoteCountingStrategy extends AbstractVoteCountingStrategy { + + @Override + public VoteCountingResult votecount(Set<Voter> voters) { + // get empty result by choice + Map<String, ChoiceScore> resultByChoice = votersToResult(voters); + + for (Voter voter : voters) { + // add this voter votes to result + addVoterChoices(voter, resultByChoice); + } + // transform map of result to list of them (and sort them) + VoteCountingResult result = resultToList(resultByChoice); + return result; + } + + public void addVoterChoices(Voter voter, + Map<String, ChoiceScore> resultByChoice) { + + double voterWeight = voter.getWeight(); + + for (VoteForChoice voteForChoice : voter.getVoteForChoices()) { + Double voteValue = voteForChoice.getVoteValue(); + if (voteValue != null) { + + // get score for choice + String choiceId = voteForChoice.getChoiceId(); + ChoiceScore choiceScore = resultByChoice.get(choiceId); + + // compute score to add + double scoreToAdd = voteValue * voterWeight; + + // add to score this weighted vote + choiceScore.addScoreValue(scoreToAdd); + } + } + } +} Property changes on: trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategy.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/strategy/PercentageStrategy.java =================================================================== --- trunk/pollen-votecounting-strategy-percentage/src/main/java/org/chorem/pollen/votecounting/strategy/PercentageStrategy.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-percentage/src/main/java/org/chorem/pollen/votecounting/strategy/PercentageStrategy.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,146 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Percentage - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.ChoiceToVoteRenderType; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.VoteForChoice; -import org.chorem.pollen.votecounting.model.Voter; - -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import static org.nuiton.i18n.I18n.l_; -import static org.nuiton.i18n.I18n.n_; - -/** - * Percentage strategy. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class PercentageStrategy extends AbstractVoteCountingStrategy { - - public static final int ID = 1; - - @Override - public int getId() { - return ID; - } - - @Override - public String getI18nName() { - return n_("pollen.voteCountingType.percentage"); - } - - @Override - public String getI18nHelp() { - return n_("pollen.voteCountingType.percentage.help"); - } - - @Override - public VoteCountingResult votecount(Set<Voter> voters) { - // get empty result by choice - Map<String, ChoiceScore> resultByChoice = votersToResult(voters); - - for (Voter voter : voters) { - // add this voter votes to result - addVoterChoices(voter, resultByChoice); - } - // transform map of result to list of them (and sort them) - VoteCountingResult result = resultToList(resultByChoice); - return result; - } - - @Override - public String getDisplayVoteValue(Integer voteValue) { - return voteValue == null ? "" : String.valueOf(voteValue); - } - - @Override - public boolean isChoiceInVote(Integer voteValue) { - return voteValue != null && voteValue >= 0 && voteValue <= 100; - } - - - @Override - public boolean isVoteValueNull(Integer value) { - return value == null || value == 0; - } - - @Override - public ChoiceToVoteRenderType getVoteValueEditorType() { - return ChoiceToVoteRenderType.TEXTFIELD; - } - - @Override - public boolean isDisplayResultsByChoice() { - return false; - } - - @Override - public boolean isVoteValueValid(Integer voteValue) { - // no validation on not null vote value - return true; - } - - @Override - public boolean isTotalVoteValueValid(int totalValues) { - return totalValues == 100; - } - - @Override - public String getVoteValueNotValidMessage(Locale locale) { - // no validation on not null vote value, so no message - return null; - } - - @Override - public String getTotalVoteValueNotValidMessage(Locale locale) { - return l_(locale, "pollen.error.vote.percentage"); - } - - public void addVoterChoices(Voter voter, - Map<String, ChoiceScore> resultByChoice) { - - double voterWeight = voter.getWeight(); - - for (VoteForChoice voteForChoice : voter.getVoteForChoices()) { - Double voteValue = voteForChoice.getVoteValue(); - if (voteValue != null) { - - // get score for choice - String choiceId = voteForChoice.getChoiceId(); - ChoiceScore choiceScore = resultByChoice.get(choiceId); - - // compute score to add - double scoreToAdd = voteValue * voterWeight; - - // add to score this weighted vote - choiceScore.addScoreValue(scoreToAdd); - } - } - } -} Copied: trunk/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (from rev 3707, trunk/pollen-votecounting-strategy-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy) =================================================================== --- trunk/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting (rev 0) +++ trunk/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1 @@ +org.chorem.pollen.votecounting.PercentageVoteCounting Property changes on: trunk/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.VoteCounting ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy =================================================================== --- trunk/pollen-votecounting-strategy-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-percentage/src/main/resources/META-INF/services/org.chorem.pollen.votecounting.strategy.VoteCountingStrategy 2012-09-29 12:36:25 UTC (rev 3708) @@ -1 +0,0 @@ -org.chorem.pollen.votecounting.strategy.PercentageStrategy Copied: trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategyTest.java (from rev 3707, trunk/pollen-votecounting-strategy-percentage/src/test/java/org/chorem/pollen/votecounting/strategy/PercentageStrategyTest.java) =================================================================== --- trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategyTest.java (rev 0) +++ trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,275 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Percentage + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.chorem.pollen.votecounting.model.ChoiceIdAble; +import org.chorem.pollen.votecounting.model.ChoiceScore; +import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; +import org.chorem.pollen.votecounting.model.VoteCountingResult; +import org.chorem.pollen.votecounting.model.Voter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Tests the {@link PercentageVoteCountingStrategy}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class PercentageVoteCountingStrategyTest { + + public static final String CHOICE_A = "a"; + + public static final String CHOICE_B = "b"; + + public static final String CHOICE_C = "c"; + + protected static VoteCounting voteCounting; + + protected VoteCountingStrategy strategy; + + @BeforeClass + public static void beforeClass() throws Exception { + VoteCountingFactory factory = new VoteCountingFactory(); + voteCounting = factory.getVoteCounting(PercentageVoteCounting.ID); + } + + @Before + public void setUp() throws Exception { + + strategy = voteCounting.newVoteCountingStrategy(); + } + + @Test + public void simpleVotecount() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=100 b=null c=null) + // 2 (a=null b=100 c=null) + // 3 (a=50 b=50 c=null) + // Result (a=100 b=150 c=null) + + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 100.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 100.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 50.). + addVoteForChoice(CHOICE_B, 50.). + addVoteForChoice(CHOICE_C, null). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(150.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_B); + + assertChoiceScore(scores.get(2), CHOICE_C, null); + } + + @Test + public void simpleVotecount2() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=20 b=30 c=50) + // 2 (a=50 b=20 c=30) + // 3 (a=10 b=50 c=40) + // Result (a=80 b=100 c=120) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 20.). + addVoteForChoice(CHOICE_B, 30.). + addVoteForChoice(CHOICE_C, 50.). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 50.). + addVoteForChoice(CHOICE_B, 20.). + addVoteForChoice(CHOICE_C, 30.). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 10.). + addVoteForChoice(CHOICE_B, 50.). + addVoteForChoice(CHOICE_C, 40.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(120.)); + assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(100.)); + assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(80.)); + } + + @Test + public void simpleVotecount3() throws Exception { + + // Simple poll (all weight to 1) + // 1 (a=50 b=50 c=null) + // 2 (a=50 b=50 c=null) + // 3 (a=50 b=50 c=null) + // Result (a=150 b=150 c=null) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 1.). + addVoteForChoice(CHOICE_A, 50.). + addVoteForChoice(CHOICE_B, 50.). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, 50.). + addVoteForChoice(CHOICE_B, 50.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, 50.). + addVoteForChoice(CHOICE_B, 50.). + addVoteForChoice(CHOICE_C, null). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScoreEquals(BigDecimal.valueOf(150.), + Sets.newHashSet(scores.get(0), + scores.get(1)), + CHOICE_A, CHOICE_B); + assertChoiceScore(scores.get(2), CHOICE_C, null); + } + + @Test + public void weightedVotecount1() throws Exception { + + // poll with weighted vote + // 1 (x2) (a=100 b=null c=null) + // 2 (x1) (a=null b=100 c=null) + // 3 (x1) (a=null b=50 c=50) + // Result (a=200 b=150 c=50) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 100.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 100.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 50.). + addVoteForChoice(CHOICE_C, 50.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(200.)); + assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(150.)); + assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(50.)); + } + + @Test + public void weightedVotecount2() throws Exception { + + // poll with weighted vote + // 1 (x2) (a=100 b=null c=null) + // 2 (x1) (a=null b=100 c=null) + // 3 (x3) (a=null b=50 c=50) + // Result (a=200 b=250 c=150) + Set<Voter> voters = new SimpleVoterBuilder(). + newVoter("1", 2.). + addVoteForChoice(CHOICE_A, 100.). + addVoteForChoice(CHOICE_B, null). + addVoteForChoice(CHOICE_C, null). + newVoter("2", 1.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 100.). + addVoteForChoice(CHOICE_C, null). + newVoter("3", 3.). + addVoteForChoice(CHOICE_A, null). + addVoteForChoice(CHOICE_B, 50.). + addVoteForChoice(CHOICE_C, 50.). + getVoters(); + + VoteCountingResult result = strategy.votecount(voters); + + Assert.assertNotNull(result); + List<ChoiceScore> scores = result.getScores(); + Assert.assertNotNull(scores); + Assert.assertEquals(3, scores.size()); + + assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(250.)); + assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(200.)); + assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(150.)); + } + + public static void assertChoiceScore(ChoiceScore choiceScore, + String choiceId, + BigDecimal choiceResult) { + Assert.assertNotNull(choiceScore); + Assert.assertEquals(choiceId, choiceScore.getChoiceId()); + Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); + } + + public static void assertChoiceScoreEquals(BigDecimal choiceResult, + Set<ChoiceScore> choiceScores, + String... choiceIds) { + + Assert.assertNotNull(choiceScores); + Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( + choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); + for (String choiceId : choiceIds) { + + ChoiceScore choiceScore = choicesById.get(choiceId); + Assert.assertNotNull(choiceScore); + assertChoiceScore(choiceScore, choiceId, choiceResult); + } + } + +} Property changes on: trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/PercentageVoteCountingStrategyTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (from rev 3707, trunk/pollen-votecounting-strategy-percentage/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java) =================================================================== --- trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java (rev 0) +++ trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -0,0 +1,44 @@ +/* + * #%L + * Pollen :: VoteCounting strategy :: Percentage + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.votecounting; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Tests the {@link VoteCountingFactory}. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.4.5 + */ +public class VoteCountingFactoryTest { + + @Test + public void getVoteCounting() throws Exception { + + VoteCountingFactory factory = new VoteCountingFactory(); + VoteCounting voteCounting = + factory.getVoteCounting(PercentageVoteCounting.ID); + Assert.assertNotNull(voteCounting); + } +} Property changes on: trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/VoteCountingFactoryTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Deleted: trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/strategy/PercentageStrategyTest.java =================================================================== --- trunk/pollen-votecounting-strategy-percentage/src/test/java/org/chorem/pollen/votecounting/strategy/PercentageStrategyTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/strategy/PercentageStrategyTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,273 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Percentage - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.chorem.pollen.votecounting.model.ChoiceIdAble; -import org.chorem.pollen.votecounting.model.ChoiceScore; -import org.chorem.pollen.votecounting.model.SimpleVoterBuilder; -import org.chorem.pollen.votecounting.model.VoteCountingResult; -import org.chorem.pollen.votecounting.model.Voter; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.math.BigDecimal; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Tests the {@link PercentageStrategy}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class PercentageStrategyTest { - - public static final String CHOICE_A = "a"; - - public static final String CHOICE_B = "b"; - - public static final String CHOICE_C = "c"; - - protected static VoteCountingStrategyProvider provider; - - protected VoteCountingStrategy strategy; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Before - public void setUp() throws Exception { - strategy = provider.getStrategy(PercentageStrategy.ID); - } - - @Test - public void simpleVotecount() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=100 b=null c=null) - // 2 (a=null b=100 c=null) - // 3 (a=50 b=50 c=null) - // Result (a=100 b=150 c=null) - - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 100.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 100.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 50.). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, null). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(150.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_B); - - assertChoiceScore(scores.get(2), CHOICE_C, null); - } - - @Test - public void simpleVotecount2() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=20 b=30 c=50) - // 2 (a=50 b=20 c=30) - // 3 (a=10 b=50 c=40) - // Result (a=80 b=100 c=120) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 20.). - addVoteForChoice(CHOICE_B, 30.). - addVoteForChoice(CHOICE_C, 50.). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 50.). - addVoteForChoice(CHOICE_B, 20.). - addVoteForChoice(CHOICE_C, 30.). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 10.). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, 40.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_C, BigDecimal.valueOf(120.)); - assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(100.)); - assertChoiceScore(scores.get(2), CHOICE_A, BigDecimal.valueOf(80.)); - } - - @Test - public void simpleVotecount3() throws Exception { - - // Simple poll (all weight to 1) - // 1 (a=50 b=50 c=null) - // 2 (a=50 b=50 c=null) - // 3 (a=50 b=50 c=null) - // Result (a=150 b=150 c=null) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 1.). - addVoteForChoice(CHOICE_A, 50.). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, 50.). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, 50.). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, null). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScoreEquals(BigDecimal.valueOf(150.), - Sets.newHashSet(scores.get(0), - scores.get(1)), - CHOICE_A, CHOICE_B); - assertChoiceScore(scores.get(2), CHOICE_C, null); - } - - @Test - public void weightedVotecount1() throws Exception { - - // poll with weighted vote - // 1 (x2) (a=100 b=null c=null) - // 2 (x1) (a=null b=100 c=null) - // 3 (x1) (a=null b=50 c=50) - // Result (a=200 b=150 c=50) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 100.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 100.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, 50.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - assertChoiceScore(scores.get(0), CHOICE_A, BigDecimal.valueOf(200.)); - assertChoiceScore(scores.get(1), CHOICE_B, BigDecimal.valueOf(150.)); - assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(50.)); - } - - @Test - public void weightedVotecount2() throws Exception { - - // poll with weighted vote - // 1 (x2) (a=100 b=null c=null) - // 2 (x1) (a=null b=100 c=null) - // 3 (x3) (a=null b=50 c=50) - // Result (a=200 b=250 c=150) - Set<Voter> voters = new SimpleVoterBuilder(). - newVoter("1", 2.). - addVoteForChoice(CHOICE_A, 100.). - addVoteForChoice(CHOICE_B, null). - addVoteForChoice(CHOICE_C, null). - newVoter("2", 1.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 100.). - addVoteForChoice(CHOICE_C, null). - newVoter("3", 3.). - addVoteForChoice(CHOICE_A, null). - addVoteForChoice(CHOICE_B, 50.). - addVoteForChoice(CHOICE_C, 50.). - getVoters(); - - VoteCountingResult result = strategy.votecount(voters); - - Assert.assertNotNull(result); - List<ChoiceScore> scores = result.getScores(); - Assert.assertNotNull(scores); - Assert.assertEquals(3, scores.size()); - - assertChoiceScore(scores.get(0), CHOICE_B, BigDecimal.valueOf(250.)); - assertChoiceScore(scores.get(1), CHOICE_A, BigDecimal.valueOf(200.)); - assertChoiceScore(scores.get(2), CHOICE_C, BigDecimal.valueOf(150.)); - } - - public static void assertChoiceScore(ChoiceScore choiceScore, - String choiceId, - BigDecimal choiceResult) { - Assert.assertNotNull(choiceScore); - Assert.assertEquals(choiceId, choiceScore.getChoiceId()); - Assert.assertEquals(choiceResult, choiceScore.getScoreValue()); - } - - public static void assertChoiceScoreEquals(BigDecimal choiceResult, - Set<ChoiceScore> choiceScores, - String... choiceIds) { - - Assert.assertNotNull(choiceScores); - Map<String, ChoiceScore> choicesById = Maps.uniqueIndex( - choiceScores, new ChoiceIdAble.ChoiceIdAbleById()); - for (String choiceId : choiceIds) { - - ChoiceScore choiceScore = choicesById.get(choiceId); - Assert.assertNotNull(choiceScore); - assertChoiceScore(choiceScore, choiceId, choiceResult); - } - } - -} Deleted: trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java =================================================================== --- trunk/pollen-votecounting-strategy-percentage/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pollen-votecounting-percentage/src/test/java/org/chorem/pollen/votecounting/strategy/VoteCountingStrategyProviderTest.java 2012-09-29 12:36:25 UTC (rev 3708) @@ -1,49 +0,0 @@ -/* - * #%L - * Pollen :: VoteCounting strategy :: Percentage - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2009 - 2012 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ -package org.chorem.pollen.votecounting.strategy; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Tests the {@link VoteCountingStrategyProvider}. - * - * @author tchemit <chemit@codelutin.com> - * @since 1.4.5 - */ -public class VoteCountingStrategyProviderTest { - - protected static VoteCountingStrategyProvider provider; - - @BeforeClass - public static void beforeClass() throws Exception { - provider = new VoteCountingStrategyProvider(); - } - - @Test - public void getStrategy() throws Exception { - - Assert.assertNotNull(provider.getStrategy(PercentageStrategy.ID)); - } -} Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2012-09-25 15:32:42 UTC (rev 3707) +++ trunk/pom.xml 2012-09-29 12:36:25 UTC (rev 3708) @@ -3,10 +3,6 @@ <modelVersion>4.0.0</modelVersion> - <!-- ************************************************************* --> - <!-- *** POM Relationships *************************************** --> - <!-- ************************************************************* --> - <parent> <groupId>org.nuiton</groupId> <artifactId>mavenpom4redmine</artifactId> @@ -19,7 +15,7 @@ <modules> <module>pollen-votecounting-api</module> - <module>pollen-votecounting-strategy</module> + <module>pollen-votecounting-aggregator</module> <module>pollen-persistence</module> <module>pollen-services</module> <module>pollen-ui-struts2</module> @@ -163,7 +159,7 @@ <struts2Version>2.3.4</struts2Version> <jqueryPluginVersion>3.3.1</jqueryPluginVersion> <shiroVersion>1.2.0</shiroVersion> - <slf4jVersion>1.6.5</slf4jVersion> + <slf4jVersion>1.6.6</slf4jVersion> <jettyVersion>${jettyPluginVersion}</jettyVersion> <hibernateVersion>3.6.10.Final</hibernateVersion> <seleniumVersion>2.25.0</seleniumVersion> @@ -353,12 +349,6 @@ <version>${slf4jVersion}</version> <scope>compile</scope> </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - <version>${slf4jVersion}</version> - <scope>runtime</scope> - </dependency> <!-- Others --> @@ -533,10 +523,6 @@ </resources> </build> - <!-- ************************************************************* --> - <!-- *** Build Environment ************************************** --> - <!-- ************************************************************* --> - <scm> <connection>scm:svn:http://svn.chorem.org/svn/pollen/trunk</connection> <developerConnection>
participants (1)
-
tchemit@users.chorem.org