RemoveVehicle implements ProblemFactChange<VehicleRoutingSolution> { @Override public void doChange(ScoreDirector<VehicleRoutingSolution> scoreDirector) { VehicleRoutingSolution workingSolution = scoreDirector.getWorkingSolution(); PlanningVehicle workingVehicle = scoreDirector.lookUpWorkingObject(removedVehicle); if (workingVehicle == null) { throw new IllegalStateException("Can't look up a working copy of " + removedVehicle); } for (PlanningVisit visit : workingVehicle.getFutureVisits()) { scoreDirector.beforeVariableChanged(visit, "previousStandstill"); visit.setPreviousStandstill(null); scoreDirector.afterVariableChanged(visit, "previousStandstill"); } scoreDirector.beforeProblemFactRemoved(workingVehicle); if (!workingSolution.getVehicleList().remove(workingVehicle)) { throw new IllegalStateException( "Working solution's vehicleList " + workingSolution.getVehicleList() + " doesn't contain the workingVehicle (" + workingVehicle + "). This is a bug!"); } scoreDirector.afterProblemFactRemoved(workingVehicle); scoreDirector.triggerVariableListeners(); } RemoveVehicle(PlanningVehicle removedVehicle); @Override void doChange(ScoreDirector<VehicleRoutingSolution> scoreDirector);  }
@Test void remove_vehicle() { PlanningVehicle removedVehicle = PlanningVehicleFactory.testVehicle(1); PlanningVehicle otherVehicle = PlanningVehicleFactory.testVehicle(2); PlanningDepot depot = new PlanningDepot(PlanningLocationFactory.testLocation(1)); PlanningVisit firstVisit = testVisit(1); PlanningVisit lastVisit = testVisit(2); VehicleRoutingSolution solution = SolutionFactory.solutionFromVisits( Arrays.asList(removedVehicle, otherVehicle), depot, Arrays.asList(firstVisit, lastVisit)); when(scoreDirector.getWorkingSolution()).thenReturn(solution); when(scoreDirector.lookUpWorkingObject(removedVehicle)).thenReturn(removedVehicle); removedVehicle.setNextVisit(firstVisit); firstVisit.setPreviousStandstill(removedVehicle); firstVisit.setVehicle(removedVehicle); firstVisit.setNextVisit(lastVisit); lastVisit.setPreviousStandstill(firstVisit); lastVisit.setVehicle(removedVehicle); RemoveVehicle removeVehicle = new RemoveVehicle(removedVehicle); removeVehicle.doChange(scoreDirector); assertThat(firstVisit.getPreviousStandstill()).isNull(); assertThat(lastVisit.getPreviousStandstill()).isNull(); assertThat(solution.getVehicleList()).containsExactly(otherVehicle); verify(scoreDirector).beforeVariableChanged(firstVisit, "previousStandstill"); verify(scoreDirector).afterVariableChanged(firstVisit, "previousStandstill"); verify(scoreDirector).beforeVariableChanged(lastVisit, "previousStandstill"); verify(scoreDirector).afterVariableChanged(lastVisit, "previousStandstill"); verify(scoreDirector).beforeProblemFactRemoved(removedVehicle); verify(scoreDirector).afterProblemFactRemoved(removedVehicle); verify(scoreDirector).triggerVariableListeners(); }
@Test void fail_fast_if_working_solution_vehicle_list_does_not_contain_working_vehicle() { long removedId = 111L; long wrongId = 222L; PlanningVehicle removedVehicle = PlanningVehicleFactory.testVehicle(removedId); PlanningVehicle wrongVehicle = PlanningVehicleFactory.testVehicle(wrongId); PlanningDepot depot = new PlanningDepot(PlanningLocationFactory.testLocation(1)); VehicleRoutingSolution solution = SolutionFactory.solutionFromVisits( Arrays.asList(wrongVehicle), depot, Collections.emptyList()); when(scoreDirector.getWorkingSolution()).thenReturn(solution); when(scoreDirector.lookUpWorkingObject(removedVehicle)).thenReturn(removedVehicle); RemoveVehicle removeVehicle = new RemoveVehicle(removedVehicle); assertThatIllegalStateException() .isThrownBy(() -> removeVehicle.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 RemoveVehicle(PlanningVehicleFactory.testVehicle(1)).doChange(scoreDirector)) .withMessageContaining("working copy of"); }