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)); + } + } + }