/* * This file is part of LibrePlan * * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e * Desenvolvemento Tecnolóxico de Galicia * Copyright (C) 2010-2011 Igalia, S.L. * * 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 Affero 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/>. */ package org.libreplan.business.common; import static org.hamcrest.CoreMatchers.equalTo; import static org.junit.Assert.assertThat; import java.util.Arrays; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.junit.Test; /** * @author Óscar González Fernández <ogonzalez@igalia.com> * */ public class ProportionalDistributorTest { @Test public void mustGiveTheSameDistributionForSameTotal() { ProportionalDistributor distributor = ProportionalDistributor.create(100, 200); assertThat(distributor.distribute(300), equalToDistribution(100, 200)); } @Test public void exactDivisionsWorkOk() { ProportionalDistributor distributor = ProportionalDistributor.create(100, 100, 100); assertThat(distributor.distribute(600), equalToDistribution(200, 200, 200)); } @Test public void distributingZeroGivesZeroShares() { ProportionalDistributor distributor = ProportionalDistributor.create(100, 100, 100); assertThat(distributor.distribute(0), equalToDistribution(0, 0, 0)); } @Test public void ifOneOfTheProportionsIsZeroAlwaysGivesZeros() { ProportionalDistributor distributor = ProportionalDistributor.create(100, 100, 0); assertThat(distributor.distribute(100), equalToDistribution(50, 50, 0)); } @Test public void ifEmptySharesProvidedItDistributesEqually() { ProportionalDistributor distributor = ProportionalDistributor.create(0, 0, 0, 0); assertThat(distributor.distribute(4), equalToDistribution(1, 1, 1, 1)); assertThat(distributor.distribute(5), equalToDistribution(2, 1, 1, 1)); assertThat(distributor.distribute(6), equalToDistribution(2, 2, 1, 1)); } @Test public void noSharesProvidedImpliesItReturnsEmptyDistribution() { ProportionalDistributor distributor = ProportionalDistributor.create(); assertThat(distributor.distribute(0).length, equalTo(0)); assertThat(distributor.distribute(1).length, equalTo(0)); } @Test public void disputedPartGoesToFirstIfEqualWeight() { ProportionalDistributor distributor = ProportionalDistributor.create(10, 10, 10); assertThat(distributor.distribute(10), equalToDistribution(4, 3, 3)); } @Test public void distributionIsKept() { ProportionalDistributor distributor = ProportionalDistributor.create(2, 3, 5); assertThat(distributor.distribute(1), equalToDistribution(0, 0, 1)); assertThat(distributor.distribute(2), equalToDistribution(0, 1, 1)); assertThat(distributor.distribute(3), equalToDistribution(1, 1, 1)); assertThat(distributor.distribute(4), equalToDistribution(1, 1, 2)); assertThat(distributor.distribute(5), equalToDistribution(1, 2, 2)); assertThat(distributor.distribute(6), equalToDistribution(1, 2, 3)); assertThat(distributor.distribute(10), equalToDistribution(2, 3, 5)); assertThat(distributor.distribute(7), equalToDistribution(1, 2, 4)); } @Test public void addingOneEachTime() { ProportionalDistributor distributor = ProportionalDistributor.create(99, 101, 800); assertThat(distributor.distribute(1), equalToDistribution(0, 0, 1)); assertThat(distributor.distribute(3), equalToDistribution(0, 0, 3)); assertThat(distributor.distribute(6), equalToDistribution(0, 1, 5)); assertThat(distributor.distribute(7), equalToDistribution(1, 1, 5)); assertThat(distributor.distribute(8), equalToDistribution(1, 1, 6)); assertThat(distributor.distribute(9), equalToDistribution(1, 1, 7)); assertThat(distributor.distribute(10), equalToDistribution(1, 1, 8)); assertThat(distributor.distribute(11), equalToDistribution(1, 1, 9)); assertThat(distributor.distribute(12), equalToDistribution(1, 1, 10)); assertThat(distributor.distribute(13), equalToDistribution(1, 1, 11)); assertThat(distributor.distribute(14), equalToDistribution(1, 2, 11)); assertThat(distributor.distribute(15), equalToDistribution(1, 2, 12)); assertThat(distributor.distribute(16), equalToDistribution(1, 2, 13)); assertThat(distributor.distribute(17), equalToDistribution(2, 2, 13)); assertThat(distributor.distribute(20), equalToDistribution(2, 2, 16)); } private static Matcher<int[]> equalToDistribution(final int... distribution) { return new BaseMatcher<int[]>() { @Override public boolean matches(Object object) { if ( object instanceof int[] ) { int[] arg = (int[]) object; return Arrays.equals(arg, distribution); } return false; } @Override public void describeTo(Description description) { description.appendText("must equal " + Arrays.toString(distribution)); } }; } @Test public void notThrowDivisionByZeroException() { ProportionalDistributor.create(0); } @Test public void notThrowDivisionByZeroExceptionAtDistributeMehtod() { ProportionalDistributor distributor = ProportionalDistributor.create(100); distributor.distribute(0); } }