///////////////////////////////////////////////////////////////////////////// // // Project ProjectForge Community Edition // www.projectforge.org // // Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de) // // ProjectForge is dual-licensed. // // This community edition is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation; version 3 of the License. // // This community edition 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 General Public License along // with this program; if not, see http://www.gnu.org/licenses/. // ///////////////////////////////////////////////////////////////////////////// package org.projectforge.gantt; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.math.BigDecimal; import java.util.Calendar; import java.util.Date; import org.junit.BeforeClass; import org.junit.Test; import org.projectforge.calendar.DayHolder; import org.projectforge.common.DateHelper; import org.projectforge.core.ConfigXmlTest; import org.projectforge.test.TestConfiguration; public class GanttUtilsTest { private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(GanttUtilsTest.class); private static int counter = 0; private static BigDecimal TWO = new BigDecimal("2"); @BeforeClass public static void setUp() { // Needed if this tests runs before the ConfigurationTest. ConfigXmlTest.createTestConfiguration(); TestConfiguration.initAsTestConfiguration(); } @Test public void calculateFromDate() { final GanttTaskImpl activity1 = createActivity(10).setTitle("activity1"); final DayHolder day = new DayHolder(); day.setDate(2010, Calendar.FEBRUARY, 5); activity1.setStartDate(day.getDate()); assertDates("2010-02-05", "2010-02-19", activity1); activity1.setStartDate(null); day.addWorkingDays(10); activity1.setEndDate(day.getDate()); assertDates("2010-02-05", "2010-02-19", activity1); final GanttTaskImpl activity2 = createActivity(5).setTitle("activity2"); activity2.setPredecessor(activity1); assertDate(2010, Calendar.FEBRUARY, 19, GanttUtils.getCalculatedStartDate(activity2)); activity2.setPredecessorOffset(2); assertDate(2010, Calendar.FEBRUARY, 19, GanttUtils.getCalculatedStartDate(activity2)); activity2.recalculate(); assertDate(2010, Calendar.FEBRUARY, 23, GanttUtils.getCalculatedStartDate(activity2)); final GanttTaskImpl a1 = createActivity(1).setTitle("a1"); day.setDate(2010, Calendar.FEBRUARY, 1); a1.setStartDate(day.getDate()); final GanttTaskImpl a2 = createActivity(10).setTitle("a2"); a2.setPredecessor(a1); final GanttTaskImpl a2_1 = createActivity(10).setTitle("a2_1"); a2_1.setPredecessor(a2).setRelationType(GanttRelationType.START_START); a2.addChild(a2_1); final GanttTaskImpl a2_2 = createActivity(2).setTitle("a2_2"); a2_2.setPredecessor(a2).setRelationType(GanttRelationType.START_START); a2.addChild(a2_2); assertDate(2010, Calendar.FEBRUARY, 1, GanttUtils.getCalculatedStartDate(a1)); assertDate(2010, Calendar.FEBRUARY, 2, GanttUtils.getCalculatedStartDate(a2)); assertDate(2010, Calendar.FEBRUARY, 2, GanttUtils.getCalculatedStartDate(a2_1)); assertDate(2010, Calendar.FEBRUARY, 2, GanttUtils.getCalculatedStartDate(a2_2)); } @Test public void subActivities() { final DayHolder day = new DayHolder(); final GanttTaskImpl a1 = createActivity(1).setTitle("a1"); day.setDate(2010, Calendar.SEPTEMBER, 1); a1.setStartDate(day.getDate()); final GanttTaskImpl a2 = createActivity(-1).setTitle("a2"); final GanttTaskImpl a2_1 = createActivity(2).setTitle("a2_1"); a2_1.setPredecessor(a1); a2.addChild(a2_1); final GanttTaskImpl a2_2 = createActivity(2).setTitle("a2_2"); a2_2.setPredecessor(a2_1); a2.addChild(a2_2); assertDates("2010-09-01", "2010-09-02", a1); assertDates("2010-09-02", "2010-09-06", a2_1); // 2010-09-04 to 2010-09-05 is a weekend. assertDates("2010-09-06", "2010-09-08", a2_2); assertDates("2010-09-02", "2010-09-08", a2); a2.setDuration(TWO); assertDates("Start date calculated from children and duration is fixed", "2010-09-02", "2010-09-06", a2); a2.setStartDate(day.getDate()); assertDates("Start date and duration are fixed", "2010-09-01", "2010-09-03", a2); a2.setStartDate(null).setDuration(null).setPredecessor(a1).setPredecessorOffset(1); assertDates("Start date is calculated from predecessor.", "2010-09-03", "2010-09-08", a2); a2.setDuration(TWO); assertDates("Start date is calculated from predecessor and duration is fixed.", "2010-09-03", "2010-09-07", a2); a2.setRelationType(GanttRelationType.FINISH_START).setDuration(null); // Default -> same results: assertDates("Start date is calculated from predecessor.", "2010-09-03", "2010-09-08", a2); a2.setDuration(TWO); assertDates("Start date is calculated from predecessor and duration is fixed.", "2010-09-03", "2010-09-07", a2); a2.setRelationType(GanttRelationType.START_START).setDuration(null); assertDates("Start date is calculated from predecessor.", "2010-09-02", "2010-09-08", a2); a2.setDuration(TWO); assertDates("Start date is calculated from predecessor and duration is fixed.", "2010-09-02", "2010-09-06", a2); a2.setRelationType(GanttRelationType.START_FINISH).setDuration(null).setPredecessorOffset(4); assertDates("End date is calculated from predecessor.", "2010-09-02", "2010-09-07", a2); a2.setDuration(TWO); // assertDates("End date is calculated from predecessor and duration is fixed.", "2010-09-03", "2010-09-07", a2); } @Test public void circularReferences() { final GanttTaskImpl a1 = createActivity(1).setTitle("a1"); final GanttTaskImpl a1_1 = createActivity(10).setTitle("a1_1"); a1_1.setPredecessor(a1); a1.addChild(a1_1); log.error("The two following error messages about circular reference detection are OK and part of this test."); assertNull(GanttUtils.getCalculatedStartDate(a1)); assertNull(GanttUtils.getCalculatedEndDate(a1)); assertNull(GanttUtils.getCalculatedStartDate(a1_1)); assertNull(GanttUtils.getCalculatedEndDate(a1_1)); } @Test public void compareTo() { final GanttTaskImpl a1 = new GanttTaskImpl(1).setTitle("B"); assertEquals(0, GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a1, a1)); GanttTaskImpl a2 = new GanttTaskImpl(1).setTitle("A"); assertEquals(0, GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a1, a1)); // Same id a2 = new GanttTaskImpl(2).setTitle("A"); assertTrue("Start date not given, use alphabetical order instead.", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a1, a2) > 0); assertTrue("Start date not given, use alphabetical order instead.", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a2, a1) < 0); final DayHolder day = new DayHolder(); day.setDate(2010, Calendar.JUNE, 1); a1.setStartDate(day.getDate()); assertTrue("a1.startDate before a2.startDate = null (now).", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a1, a2) < 0); assertTrue("a1.startDate before a2.startDate = null (now).", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a2, a1) > 0); day.addWorkingDays(2); a2.setStartDate(day.getDate()); assertTrue("a1.startDate before a2.startDate.", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a1, a2) < 0); assertTrue("a1.startDate before a2.startDate.", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a2, a1) > 0); a1.setStartDate(day.getDate()); assertTrue("Same start date -> alphabetical order", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a1, a2) > 0); assertTrue("Same start date -> alphabetical order", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a2, a1) < 0); day.addWorkingDays(2); a2.setEndDate(day.getDate()); final Date a1StartDate = a1.getStartDate(); a1.setStartDate(null); assertTrue("a1.endDate = null after a2.endDate", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a1, a2) > 0); assertTrue("a1.endDate = null before a2.endDate", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a2, a1) < 0); a1.setEndDate(day.getDate()); a1.setStartDate(a1StartDate); assertTrue("Same start and end date -> alphabetical order", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a1, a2) > 0); assertTrue("Same start and end date -> alphabetical order", GanttUtils.GANTT_OBJECT_COMPARATOR.compare(a2, a1) < 0); } private GanttTaskImpl createActivity(final int durationDays) { final GanttTaskImpl activity = new GanttTaskImpl(); if (durationDays >= 0) { activity.setDuration(new BigDecimal(durationDays)); } activity.setId(counter++); return activity; } private void assertDate(final int year, final int month, final int day, final Date date) { final DayHolder dh = new DayHolder(); dh.setDate(year, month, day); assertEquals(DateHelper.formatIsoDate(dh.getDate()), DateHelper.formatIsoDate(date)); } private void assertDates(final String expectedCalculatedStartDate, final String expectedCalculatedEndDate, final GanttTask task) { assertEquals(expectedCalculatedStartDate, DateHelper.formatIsoDate(task.recalculate().getCalculatedStartDate())); assertEquals(expectedCalculatedEndDate, DateHelper.formatIsoDate(task.getCalculatedEndDate())); } private void assertDates(final String msg, final String expectedCalculatedStartDate, final String expectedCalculatedEndDate, final GanttTask task) { assertEquals(msg, expectedCalculatedStartDate, DateHelper.formatIsoDate(task.recalculate().getCalculatedStartDate())); assertEquals(msg, expectedCalculatedEndDate, DateHelper.formatIsoDate(task.getCalculatedEndDate())); } }