RemoveVisit implements ProblemFactChange<VehicleRoutingSolution> { @Override public void doChange(ScoreDirector<VehicleRoutingSolution> scoreDirector) { VehicleRoutingSolution workingSolution = scoreDirector.getWorkingSolution(); PlanningVisit workingVisit = scoreDirector.lookUpWorkingObject(planningVisit); if (workingVisit == null) { throw new IllegalStateException("Can't look up a working copy of " + planningVisit); } PlanningVisit nextVisit = workingVisit.getNextVisit(); if (nextVisit != null) { scoreDirector.beforeVariableChanged(nextVisit, "previousStandstill"); nextVisit.setPreviousStandstill(workingVisit.getPreviousStandstill()); scoreDirector.afterVariableChanged(nextVisit, "previousStandstill"); } scoreDirector.beforeEntityRemoved(workingVisit); if (!workingSolution.getVisitList().remove(workingVisit)) { throw new IllegalStateException( "Working solution's visitList " + workingSolution.getVisitList() + " doesn't contain the workingVisit (" + workingVisit + "). This is a bug!"); } scoreDirector.afterEntityRemoved(workingVisit); scoreDirector.triggerVariableListeners(); } RemoveVisit(PlanningVisit planningVisit); @Override void doChange(ScoreDirector<VehicleRoutingSolution> scoreDirector);  }
@Test void remove_last_visit() { VehicleRoutingSolution solution = SolutionFactory.emptySolution(); when(scoreDirector.getWorkingSolution()).thenReturn(solution); PlanningVisit removedVisit = testVisit(1); PlanningVisit otherVisit = testVisit(2); solution.getVisitList().add(otherVisit); solution.getVisitList().add(removedVisit); otherVisit.setPreviousStandstill(testVehicle(10)); otherVisit.setNextVisit(removedVisit); removedVisit.setPreviousStandstill(otherVisit); when(scoreDirector.lookUpWorkingObject(removedVisit)).thenReturn(removedVisit); RemoveVisit removeVisit = new RemoveVisit(removedVisit); removeVisit.doChange(scoreDirector); verify(scoreDirector).beforeEntityRemoved(removedVisit); verify(scoreDirector).afterEntityRemoved(removedVisit); assertThat(solution.getVisitList()).containsExactly(otherVisit); verify(scoreDirector).triggerVariableListeners(); }
@Test void remove_middle_visit() { VehicleRoutingSolution solution = SolutionFactory.emptySolution(); when(scoreDirector.getWorkingSolution()).thenReturn(solution); PlanningVisit firstVisit = testVisit(1); PlanningVisit middleVisit = testVisit(2); PlanningVisit lastVisit = testVisit(3); solution.getVisitList().add(firstVisit); solution.getVisitList().add(lastVisit); solution.getVisitList().add(middleVisit); firstVisit.setPreviousStandstill(testVehicle(1)); firstVisit.setNextVisit(middleVisit); middleVisit.setPreviousStandstill(firstVisit); middleVisit.setNextVisit(lastVisit); lastVisit.setPreviousStandstill(middleVisit); PlanningVisit removedVisit = testVisit(2); when(scoreDirector.lookUpWorkingObject(removedVisit)).thenReturn(middleVisit); RemoveVisit removeVisit = new RemoveVisit(removedVisit); removeVisit.doChange(scoreDirector); verify(scoreDirector).beforeVariableChanged(lastVisit, "previousStandstill"); verify(scoreDirector).afterVariableChanged(lastVisit, "previousStandstill"); verify(scoreDirector).beforeEntityRemoved(middleVisit); verify(scoreDirector).afterEntityRemoved(middleVisit); assertThat(solution.getVisitList()) .hasSize(2) .containsOnly(firstVisit, lastVisit); assertThat(lastVisit.getPreviousStandstill()).isEqualTo(firstVisit); verify(scoreDirector).triggerVariableListeners(); }
@Test void fail_fast_if_working_solution_visit_list_does_not_contain_working_visit() { VehicleRoutingSolution solution = SolutionFactory.emptySolution(); long removedId = 111L; PlanningVisit removedVisit = testVisit(removedId); long wrongId = 222L; PlanningVisit wrongVisit = testVisit(wrongId); wrongVisit.setPreviousStandstill(testVisit(10)); removedVisit.setNextVisit(wrongVisit); solution.getVisitList().add(wrongVisit); when(scoreDirector.getWorkingSolution()).thenReturn(solution); when(scoreDirector.lookUpWorkingObject(removedVisit)).thenReturn(removedVisit); RemoveVisit removeVisit = new RemoveVisit(removedVisit); assertThatIllegalStateException() .isThrownBy(() -> removeVisit.doChange(scoreDirector)) .withMessageMatching(".*List .*" + wrongId + ".* doesn't contain the working.*" + removedId + ".*"); }
@Test void fail_fast_if_working_object_is_null() { when(scoreDirector.getWorkingSolution()).thenReturn(SolutionFactory.emptySolution()); assertThatIllegalStateException() .isThrownBy(() -> new RemoveVisit(testVisit(0)).doChange(scoreDirector)) .withMessageContaining("working copy of"); }