diff --git a/ganttzk/src/test/java/org/zkoss/ganttz/data/criticalpath/CriticalPathCalculatorTest.java b/ganttzk/src/test/java/org/zkoss/ganttz/data/criticalpath/CriticalPathCalculatorTest.java
index 6008bde08..bb9365ba4 100644
--- a/ganttzk/src/test/java/org/zkoss/ganttz/data/criticalpath/CriticalPathCalculatorTest.java
+++ b/ganttzk/src/test/java/org/zkoss/ganttz/data/criticalpath/CriticalPathCalculatorTest.java
@@ -1536,6 +1536,333 @@ public class CriticalPathCalculatorTest {
replay(diagramGraphExample);
}
+ /**
+ *
+ * _- #### T1 #### -_
+ * | |
+ * |- #### 10 #### -|
+ * | |
+ * |- #### 5 #### -|----|
+ * |
+ * |---- #### 8 ####
+ *
+ */
+ private void givenExampleWithContainers() {
+ diagramGraphExample = createNiceMock(ICriticalPathCalculable.class);
+
+ ITaskFundamentalProperties taskContainer1 = createTask(START, 10);
+ ITaskFundamentalProperties task10 = createTask(START, 10);
+ ITaskFundamentalProperties task5 = createTask(START, 5);
+
+ ITaskFundamentalProperties task8 = createTask(START, 8);
+
+ List listOfTasks = Arrays.asList(
+ taskContainer1, task10, task5, task8);
+
+ expect(diagramGraphExample.getTasks()).andReturn(listOfTasks)
+ .anyTimes();
+ expect(diagramGraphExample.getInitialTasks()).andReturn(
+ Arrays.asList(taskContainer1)).anyTimes();
+ expect(diagramGraphExample.getLatestTasks()).andReturn(
+ Arrays.asList(taskContainer1, task8)).anyTimes();
+
+ IDependency dependencyStartStart1 = createDependency(
+ taskContainer1, task10, DependencyType.START_START);
+ expect(diagramGraphExample.getDependencyFrom(taskContainer1, task10))
+ .andReturn(dependencyStartStart1).anyTimes();
+ IDependency dependencyEndEnd1 = createDependency(
+ task10, taskContainer1, DependencyType.END_END);
+ expect(diagramGraphExample.getDependencyFrom(task10, taskContainer1))
+ .andReturn(dependencyEndEnd1).anyTimes();
+
+ IDependency dependencyStartStart2 = createDependency(
+ taskContainer1, task5, DependencyType.START_START);
+ expect(diagramGraphExample.getDependencyFrom(taskContainer1, task5))
+ .andReturn(dependencyStartStart2).anyTimes();
+ IDependency dependencyEndEnd2 = createDependency(
+ task5, taskContainer1, DependencyType.END_END);
+ expect(diagramGraphExample.getDependencyFrom(task5, taskContainer1))
+ .andReturn(dependencyEndEnd2).anyTimes();
+
+ expect(diagramGraphExample.isContainer(taskContainer1)).andReturn(true)
+ .anyTimes();
+ expect(diagramGraphExample.contains(taskContainer1, task10)).andReturn(
+ true).anyTimes();
+ expect(diagramGraphExample.contains(taskContainer1, task5)).andReturn(
+ true).anyTimes();
+ expect(diagramGraphExample.getChildren(taskContainer1)).andReturn(
+ Arrays.asList(task10, task5)).anyTimes();
+
+ expect(diagramGraphExample.getIncomingTasksFor(taskContainer1))
+ .andReturn(
+ new HashSet(Arrays.asList(
+ task10, task5))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(task10)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer1))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(task5)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer1))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(task8)).andReturn(
+ new HashSet(Arrays.asList(task5)))
+ .anyTimes();
+
+ expect(diagramGraphExample.getOutgoingTasksFor(taskContainer1))
+ .andReturn(
+ new HashSet(Arrays.asList(
+ task10, task5))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task10)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer1))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task5)).andReturn(
+ new HashSet(Arrays.asList(
+ taskContainer1, task8))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task8)).andReturn(
+ new HashSet()).anyTimes();
+
+ addTaskMethods(listOfTasks);
+
+ replay(diagramGraphExample);
+ }
+
+ /**
+ *
+ * #### 8 ####----|
+ * |
+ * |_- ############ T1 ############ -_|
+ * | | |
+ * | |---- #### 5 #### -|
+ * | |
+ * |- #### 10 #### -|
+ *
+ *
+ */
+ private void givenAnotherWithContainers() {
+ diagramGraphExample = createNiceMock(ICriticalPathCalculable.class);
+
+ ITaskFundamentalProperties task8 = createTask(START, 8);
+
+ ITaskFundamentalProperties taskContainer1 = createTask(START, 10);
+ ITaskFundamentalProperties task5 = createTask(START, 5);
+ ITaskFundamentalProperties task10 = createTask(START, 10);
+
+ List listOfTasks = Arrays.asList(task8,
+ taskContainer1, task5, task10);
+
+ expect(diagramGraphExample.getTasks()).andReturn(listOfTasks)
+ .anyTimes();
+ expect(diagramGraphExample.getInitialTasks()).andReturn(
+ Arrays.asList(task8, taskContainer1)).anyTimes();
+ expect(diagramGraphExample.getLatestTasks()).andReturn(
+ Arrays.asList(taskContainer1)).anyTimes();
+
+ IDependency dependencyStartStart2 = createDependency(
+ taskContainer1, task5, DependencyType.START_START);
+ expect(diagramGraphExample.getDependencyFrom(taskContainer1, task5))
+ .andReturn(dependencyStartStart2).anyTimes();
+ IDependency dependencyEndEnd2 = createDependency(
+ task5, taskContainer1, DependencyType.END_END);
+ expect(diagramGraphExample.getDependencyFrom(task5, taskContainer1))
+ .andReturn(dependencyEndEnd2).anyTimes();
+
+ IDependency dependencyStartStart1 = createDependency(
+ taskContainer1, task10, DependencyType.START_START);
+ expect(diagramGraphExample.getDependencyFrom(taskContainer1, task10))
+ .andReturn(dependencyStartStart1).anyTimes();
+ IDependency dependencyEndEnd1 = createDependency(
+ task10, taskContainer1, DependencyType.END_END);
+ expect(diagramGraphExample.getDependencyFrom(task10, taskContainer1))
+ .andReturn(dependencyEndEnd1).anyTimes();
+
+ expect(diagramGraphExample.isContainer(taskContainer1)).andReturn(true)
+ .anyTimes();
+ expect(diagramGraphExample.contains(taskContainer1, task5)).andReturn(
+ true).anyTimes();
+ expect(diagramGraphExample.contains(taskContainer1, task10)).andReturn(
+ true).anyTimes();
+ expect(diagramGraphExample.getChildren(taskContainer1)).andReturn(
+ Arrays.asList(task5, task10)).anyTimes();
+
+ expect(diagramGraphExample.getIncomingTasksFor(taskContainer1))
+ .andReturn(
+ new HashSet(Arrays.asList(
+ task5, task10))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(task5)).andReturn(
+ new HashSet(Arrays.asList(
+ taskContainer1, task8))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(task10)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer1))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(task8)).andReturn(
+ new HashSet()).anyTimes();
+
+ expect(diagramGraphExample.getOutgoingTasksFor(taskContainer1))
+ .andReturn(
+ new HashSet(Arrays.asList(
+ task5, task10))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task5)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer1))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task10)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer1))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task8)).andReturn(
+ new HashSet(Arrays.asList(task5)))
+ .anyTimes();
+
+ addTaskMethods(listOfTasks);
+
+ replay(diagramGraphExample);
+ }
+
+ /**
+ *
+ * _- #### T1 #### -_----|
+ * | | |
+ * |- #### 10 #### -| |
+ * | | |
+ * |- #### 5 #### -| |
+ * |
+ * |----_- #### T2 #### -_
+ * | |
+ * |- #### 8 #### -|
+ * | |
+ * |- #### 4 #### -|----|
+ * |
+ * |- #### 9 #### -|
+ *
+ */
+ private void givenComplexExample() {
+ diagramGraphExample = createNiceMock(ICriticalPathCalculable.class);
+
+ ITaskFundamentalProperties taskContainer1 = createTask(START, 10);
+ ITaskFundamentalProperties task10 = createTask(START, 10);
+ ITaskFundamentalProperties task5 = createTask(START, 5);
+
+ ITaskFundamentalProperties taskContainer2 = createTask(START, 8);
+ ITaskFundamentalProperties task8 = createTask(START, 8);
+ ITaskFundamentalProperties task4 = createTask(START, 4);
+
+ ITaskFundamentalProperties task9 = createTask(START, 9);
+
+ List listOfTasks = Arrays.asList(
+ taskContainer1, task10, task5, taskContainer2, task8, task4,
+ task9);
+
+ expect(diagramGraphExample.getTasks()).andReturn(listOfTasks)
+ .anyTimes();
+ expect(diagramGraphExample.getInitialTasks()).andReturn(
+ Arrays.asList(taskContainer1)).anyTimes();
+ expect(diagramGraphExample.getLatestTasks()).andReturn(
+ Arrays.asList(taskContainer2, task9)).anyTimes();
+
+ IDependency dependencyStartStart1 = createDependency(
+ taskContainer1, task10, DependencyType.START_START);
+ expect(diagramGraphExample.getDependencyFrom(taskContainer1, task10))
+ .andReturn(dependencyStartStart1).anyTimes();
+ IDependency dependencyEndEnd1 = createDependency(
+ task10, taskContainer1, DependencyType.END_END);
+ expect(diagramGraphExample.getDependencyFrom(task10, taskContainer1))
+ .andReturn(dependencyEndEnd1).anyTimes();
+
+ IDependency dependencyStartStart2 = createDependency(
+ taskContainer1, task5, DependencyType.START_START);
+ expect(diagramGraphExample.getDependencyFrom(taskContainer1, task5))
+ .andReturn(dependencyStartStart2).anyTimes();
+ IDependency dependencyEndEnd2 = createDependency(
+ task5, taskContainer1, DependencyType.END_END);
+ expect(diagramGraphExample.getDependencyFrom(task5, taskContainer1))
+ .andReturn(dependencyEndEnd2).anyTimes();
+
+ IDependency dependencyStartStart3 = createDependency(
+ taskContainer2, task8, DependencyType.START_START);
+ expect(diagramGraphExample.getDependencyFrom(taskContainer2, task8))
+ .andReturn(dependencyStartStart3).anyTimes();
+ IDependency dependencyEndEnd3 = createDependency(
+ task8, taskContainer2, DependencyType.END_END);
+ expect(diagramGraphExample.getDependencyFrom(task8, taskContainer2))
+ .andReturn(dependencyEndEnd3).anyTimes();
+
+ IDependency dependencyStartStart4 = createDependency(
+ taskContainer2, task4, DependencyType.START_START);
+ expect(diagramGraphExample.getDependencyFrom(taskContainer2, task4))
+ .andReturn(dependencyStartStart4).anyTimes();
+ IDependency dependencyEndEnd4 = createDependency(
+ task4, taskContainer2, DependencyType.END_END);
+ expect(diagramGraphExample.getDependencyFrom(task4, taskContainer2))
+ .andReturn(dependencyEndEnd4).anyTimes();
+
+ expect(diagramGraphExample.isContainer(taskContainer1)).andReturn(true)
+ .anyTimes();
+ expect(diagramGraphExample.contains(taskContainer1, task10))
+ .andReturn(true).anyTimes();
+ expect(diagramGraphExample.contains(taskContainer1, task5)).andReturn(
+ true).anyTimes();
+ expect(diagramGraphExample.getChildren(taskContainer1)).andReturn(
+ Arrays.asList(task10, task5)).anyTimes();
+
+ expect(diagramGraphExample.isContainer(taskContainer2)).andReturn(true)
+ .anyTimes();
+ expect(diagramGraphExample.contains(taskContainer2, task8)).andReturn(
+ true).anyTimes();
+ expect(diagramGraphExample.contains(taskContainer2, task4)).andReturn(
+ true).anyTimes();
+ expect(diagramGraphExample.getChildren(taskContainer2)).andReturn(
+ Arrays.asList(task8, task4)).anyTimes();
+
+ expect(diagramGraphExample.getIncomingTasksFor(taskContainer1))
+ .andReturn(
+ new HashSet(Arrays.asList(
+ task10, task5))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(task10)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer1))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(task5)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer1))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(taskContainer2))
+ .andReturn(
+ new HashSet(Arrays.asList(
+ taskContainer1, task8, task4))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(task8)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer2))).anyTimes();
+ expect(diagramGraphExample.getIncomingTasksFor(task4)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer2))).anyTimes();
+
+ expect(diagramGraphExample.getIncomingTasksFor(task9)).andReturn(
+ new HashSet(Arrays.asList(task4)))
+ .anyTimes();
+
+ expect(diagramGraphExample.getOutgoingTasksFor(taskContainer1))
+ .andReturn(
+ new HashSet(Arrays.asList(
+ task10, task5, taskContainer2))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task10)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer1))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task5)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer1))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(taskContainer2))
+ .andReturn(
+ new HashSet(Arrays.asList(
+ task8, task4))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task8)).andReturn(
+ new HashSet(Arrays
+ .asList(taskContainer2))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task4)).andReturn(
+ new HashSet(Arrays.asList(
+ taskContainer2, task9))).anyTimes();
+ expect(diagramGraphExample.getOutgoingTasksFor(task9)).andReturn(
+ new HashSet()).anyTimes();
+
+ addTaskMethods(listOfTasks);
+
+ replay(diagramGraphExample);
+ }
+
@Test
public void trivialBaseCaseWithTwoTasksNotConnected() {
givenTwoTasksNotConnected(5, 10);
@@ -2112,4 +2439,46 @@ public class CriticalPathCalculatorTest {
}
}
+ @Test
+ public void exampleWithContainers() {
+ givenExampleWithContainers();
+ List criticalPath = buildCalculator()
+ .calculateCriticalPath(diagramGraphExample);
+
+ assertThat(criticalPath.size(), equalTo(2));
+ for (ITaskFundamentalProperties task : criticalPath) {
+ assertThat(daysBetweenStartAndEnd(task), anyOf(equalTo(5),
+ equalTo(8)));
+ assertFalse(diagramGraphExample.isContainer(task));
+ }
+ }
+
+ @Test
+ public void anotherExampleWithContiners() {
+ givenAnotherWithContainers();
+ List criticalPath = buildCalculator()
+ .calculateCriticalPath(diagramGraphExample);
+
+ assertThat(criticalPath.size(), equalTo(2));
+ for (ITaskFundamentalProperties task : criticalPath) {
+ assertThat(daysBetweenStartAndEnd(task), anyOf(equalTo(8),
+ equalTo(5)));
+ assertFalse(diagramGraphExample.isContainer(task));
+ }
+ }
+
+ @Test
+ public void complexExample() {
+ givenComplexExample();
+ List criticalPath = buildCalculator()
+ .calculateCriticalPath(diagramGraphExample);
+
+ assertThat(criticalPath.size(), equalTo(3));
+ for (ITaskFundamentalProperties task : criticalPath) {
+ assertThat(daysBetweenStartAndEnd(task), anyOf(equalTo(10),
+ equalTo(4), equalTo(9)));
+ assertFalse(diagramGraphExample.isContainer(task));
+ }
+ }
+
}