/* * 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.test.planner.entities; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.CoreMatchers; import org.junit.Test; import org.libreplan.business.planner.entities.Share; import org.libreplan.business.planner.entities.ShareDivision; public class ShareDivisionTest { private ShareDivision shareDivision; private void givenDivisionShare(Share... shares) { shareDivision = ShareDivision.create(Arrays.asList(shares)); } @Test public void aCompoundShareIsCreatedFromSeveralShares() { Share share1 = createExampleShare(); Share share2 = createExampleShare(); ShareDivision shareDivision = ShareDivision.create(Arrays.asList(share1, share2)); assertThat(shareDivision.getShares(), CoreMatchers.hasItems(share1, share2)); } private Share createExampleShare() { return new Share(10); } @Test(expected = NullPointerException.class) public void sharesCannotBeNull() { ShareDivision.create(null); } @Test(expected = IllegalArgumentException.class) public void allSharesMustBeNotNull(){ ShareDivision.create(Arrays.asList(createExampleShare(), null)); } @Test public void aSharesCompoundMustHaveADescriptiveToString() { givenDivisionShare(new Share(10), new Share(5)); assertTrue(shareDivision.toString().contains("[10, 5]")); } @Test public void remainderIsGivenToFirstShares() { givenDivisionShare(new Share(10), new Share(10), new Share(10)); ShareDivision s = shareDivision.plus(8); assertThat(s, haveValues(13, 13, 12)); } @Test public void theSharesWithLessAreGivenMore() { givenDivisionShare(new Share(10), new Share(5), new Share(10)); ShareDivision s = shareDivision.plus(4); assertThat(s, haveValues(10, 9, 10)); } @Test public void theIncrementIsEquallyDistributedToTheSharesWithLess() { givenDivisionShare(new Share(10), new Share(5), new Share(5), new Share(10)); ShareDivision s = shareDivision.plus(4); assertThat(s, haveValues(10, 7, 7, 10)); } @Test public void theIncrementIsEquallyDistributedToTheSharesWithLessUntilEqualTheOthers() { givenDivisionShare(new Share(10), new Share(5), new Share(5), new Share(10)); assertThat(shareDivision.plus(2), haveValues(10, 6, 6, 10)); assertThat(shareDivision.plus(10), haveValues(10, 10, 10, 10)); assertThat(shareDivision.plus(11), haveValues(11, 10, 10, 10)); assertThat(shareDivision.plus(12), haveValues(11, 11, 10, 10)); assertThat(shareDivision.plus(14), haveValues(11, 11, 11, 11)); } @Test public void areProgressivelyFilled() { givenDivisionShare(new Share(2), new Share(5), new Share(10)); assertThat(shareDivision.plus(1), haveValues(3, 5, 10)); assertThat(shareDivision.plus(3), haveValues(5, 5, 10)); assertThat(shareDivision.plus(4), haveValues(6, 5, 10)); assertThat(shareDivision.plus(5), haveValues(6, 6, 10)); assertThat(shareDivision.plus(6), haveValues(7, 6, 10)); assertThat(shareDivision.plus(13), haveValues(10, 10, 10)); } @Test public void canDistributeWhenSomeAreNegative() { givenDivisionShare(new Share(2), new Share(-5), new Share(-3)); assertThat(shareDivision.plus(2), haveValues(2, -3, -3)); assertThat(shareDivision.plus(3), haveValues(2, -2, -3)); assertThat(shareDivision.plus(8), haveValues(2, 0, 0)); assertThat(shareDivision.plus(11), haveValues(2, 2, 1)); assertThat(shareDivision.plus(12), haveValues(2, 2, 2)); } @Test(expected = IllegalArgumentException.class) public void cantKnowTheDifferenceBetweenTwoDivisionsOfDifferentNumberOfShares(){ givenDivisionShare(new Share(2), new Share(-5), new Share(-3)); shareDivision.to(ShareDivision.create(Arrays.asList(new Share(2), new Share(1)))); } @Test public void canKnowTheDifferenceBetweenTwoDivisions() { givenDivisionShare(new Share(2), new Share(-5), new Share(-3)); int[] difference = shareDivision.to( ShareDivision.create(Arrays.asList(new Share(1), new Share(1), new Share(-2)))); assertTrue(Arrays.equals(difference, new int[] { -1, 6, 1 })); } @Test public void canHandleMaximumValueIntegers() { givenDivisionShare( new Share(2), new Share(0), new Share(Integer.MAX_VALUE), new Share(Integer.MAX_VALUE), new Share(Integer.MAX_VALUE)); ShareDivision plus = shareDivision.plus(10); int[] difference = shareDivision.to(plus); assertArrayEquals(new int[] { 4, 6, 0, 0, 0 }, difference); } @Test public void canHandleAllMaximumValueIntegers() { givenDivisionShare(new Share(Integer.MAX_VALUE), new Share(Integer.MAX_VALUE), new Share(Integer.MAX_VALUE)); ShareDivision plus = shareDivision.plus(2); int[] difference = shareDivision.to(plus); assertArrayEquals(new int[] { 1, 1, 0 }, difference); } @Test public void canHandleMaximumValueIntegersAndMinimumValue() { givenDivisionShare( new Share(Integer.MIN_VALUE), new Share(Integer.MAX_VALUE), new Share(Integer.MAX_VALUE), new Share(Integer.MIN_VALUE), new Share(Integer.MIN_VALUE), new Share(Integer.MAX_VALUE)); ShareDivision plus = shareDivision.plus(9); int[] difference = shareDivision.to(plus); assertArrayEquals(new int[] { 3, 0, 0, 3, 3, 0 }, difference); } @Test public void canDistributeSubtraction() { /* * Subtraction is not handled! * Not to use something like: shareDivision.plus(-1). */ givenDivisionShare(new Share(2), new Share(5), new Share(10)); assertThat(shareDivision.plus(-1), haveValues(1, 5, 10)); } private Matcher<ShareDivision> haveValues(final int... shares) { final List<Integer> sharesList = asIntegersList(shares); return new BaseMatcher<ShareDivision>() { @Override public boolean matches(Object value) { if (value instanceof ShareDivision) { ShareDivision compound = (ShareDivision) value; return sharesList.equals(asIntegerList(compound.getShares())); } return false; } @Override public void describeTo(Description description) { description.appendText("must have this shares: " + Arrays.toString(shares)); } }; } private static List<Integer> asIntegerList(List<Share> shares) { List<Integer> result = new ArrayList<>(); for (Share share : shares) { result.add(share.getHours()); } return result; } private static List<Integer> asIntegersList(int[] shares) { List<Integer> result = new ArrayList<>(); for (int share : shares) { result.add(share); } return result; } }