/* * Copyright 2012 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.optaplanner.core.impl.heuristic.selector; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Objects; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ListMultimap; import org.apache.commons.lang3.ArrayUtils; import org.optaplanner.core.config.heuristic.selector.common.SelectionCacheType; import org.optaplanner.core.impl.domain.entity.descriptor.EntityDescriptor; import org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor; import org.optaplanner.core.impl.domain.variable.descriptor.GenuineVariableDescriptor; import org.optaplanner.core.impl.domain.variable.inverserelation.SingletonInverseVariableSupply; import org.optaplanner.core.impl.heuristic.move.Move; import org.optaplanner.core.impl.heuristic.selector.entity.EntitySelector; import org.optaplanner.core.impl.heuristic.selector.move.MoveSelector; import org.optaplanner.core.impl.heuristic.selector.value.EntityIndependentValueSelector; import org.optaplanner.core.impl.heuristic.selector.value.ValueSelector; import org.optaplanner.core.impl.testdata.domain.chained.TestdataChainedEntity; import org.optaplanner.core.impl.testdata.domain.chained.TestdataChainedObject; import static org.junit.Assert.*; import static org.mockito.Mockito.*; public class SelectorTestUtils { public static SolutionDescriptor mockSolutionDescriptor() { SolutionDescriptor solutionDescriptor = mock(SolutionDescriptor.class); return solutionDescriptor; } public static EntityDescriptor mockEntityDescriptor(Class<?> entityClass) { EntityDescriptor entityDescriptor = mock(EntityDescriptor.class); when(entityDescriptor.getEntityClass()).thenReturn(entityClass); return entityDescriptor; } public static GenuineVariableDescriptor mockVariableDescriptor(Class<?> entityClass, String variableName) { EntityDescriptor entityDescriptor = mockEntityDescriptor(entityClass); return mockVariableDescriptor(entityDescriptor, variableName); } public static GenuineVariableDescriptor mockVariableDescriptor(EntityDescriptor entityDescriptor, String variableName) { GenuineVariableDescriptor variableDescriptor = mock(GenuineVariableDescriptor.class); when(variableDescriptor.getEntityDescriptor()).thenReturn(entityDescriptor); when(variableDescriptor.getVariableName()).thenReturn(variableName); return variableDescriptor; } public static EntitySelector mockEntitySelector(Class<?> entityClass, Object... entities) { EntityDescriptor entityDescriptor = mockEntityDescriptor(entityClass); return mockEntitySelector(entityDescriptor, entities); } public static EntitySelector mockEntitySelector(EntityDescriptor entityDescriptor, Object... entities) { EntitySelector entitySelector = mock(EntitySelector.class); when(entitySelector.getEntityDescriptor()).thenReturn(entityDescriptor); final List<Object> entityList = Arrays.<Object>asList(entities); when(entitySelector.iterator()).thenAnswer(invocation -> entityList.iterator()); when(entitySelector.listIterator()).thenAnswer(invocation -> entityList.listIterator()); for (int i = 0; i < entityList.size(); i++) { final int index = i; when(entitySelector.listIterator(index)).thenAnswer(invocation -> entityList.listIterator(index)); } when(entitySelector.endingIterator()).thenAnswer(invocation -> entityList.iterator()); when(entitySelector.isCountable()).thenReturn(true); when(entitySelector.isNeverEnding()).thenReturn(false); when(entitySelector.getSize()).thenReturn((long) entityList.size()); return entitySelector; } public static ValueSelector mockValueSelector(Class<?> entityClass, String variableName, Object... values) { GenuineVariableDescriptor variableDescriptor = mockVariableDescriptor(entityClass, variableName); return mockValueSelector(variableDescriptor, values); } public static ValueSelector mockValueSelector(EntityDescriptor entityDescriptor, String variableName, Object... values) { GenuineVariableDescriptor variableDescriptor = mockVariableDescriptor(entityDescriptor, variableName); return mockValueSelector(variableDescriptor, values); } public static ValueSelector mockValueSelector(GenuineVariableDescriptor variableDescriptor, Object... values) { ValueSelector valueSelector = mock(ValueSelector.class); when(valueSelector.getVariableDescriptor()).thenReturn(variableDescriptor); final List<Object> valueList = Arrays.<Object>asList(values); when(valueSelector.iterator(any())).thenAnswer(invocation -> valueList.iterator()); when(valueSelector.isCountable()).thenReturn(true); when(valueSelector.isNeverEnding()).thenReturn(false); when(valueSelector.getSize(any())).thenReturn((long) valueList.size()); return valueSelector; } public static ValueSelector mockValueSelectorForEntity(Class<?> entityClass, Object entity, String variableName, Object... values) { return mockValueSelectorForEntity(entityClass, variableName, ImmutableListMultimap.builder().putAll(entity, values).build()); } public static ValueSelector mockValueSelectorForEntity(Class<?> entityClass, String variableName, ListMultimap<Object, Object> entityToValues) { GenuineVariableDescriptor variableDescriptor = mockVariableDescriptor(entityClass, variableName); return mockValueSelectorForEntity(variableDescriptor, entityToValues); } public static ValueSelector mockValueSelectorForEntity(GenuineVariableDescriptor variableDescriptor, ListMultimap<Object, Object> entityToValues) { ValueSelector valueSelector = mock(ValueSelector.class); when(valueSelector.getVariableDescriptor()).thenReturn(variableDescriptor); for (Map.Entry<Object, Collection<Object>> entry : entityToValues.asMap().entrySet()) { Object entity = entry.getKey(); final List<Object> valueList = (List<Object>) entry.getValue(); when(valueSelector.getSize(entity)).thenAnswer(invocation -> (long) valueList.size()); when(valueSelector.iterator(entity)).thenAnswer(invocation -> valueList.iterator()); when(valueSelector.getSize(entity)).thenReturn((long) valueList.size()); } when(valueSelector.isCountable()).thenReturn(true); when(valueSelector.isNeverEnding()).thenReturn(false); return valueSelector; } public static EntityIndependentValueSelector mockEntityIndependentValueSelector(Class<?> entityClass, String variableName, Object... values) { GenuineVariableDescriptor variableDescriptor = mockVariableDescriptor(entityClass, variableName); when(variableDescriptor.isValueRangeEntityIndependent()).thenReturn(true); return mockEntityIndependentValueSelector(variableDescriptor, values); } public static EntityIndependentValueSelector mockEntityIndependentValueSelector( GenuineVariableDescriptor variableDescriptor, Object... values) { EntityIndependentValueSelector valueSelector = mock(EntityIndependentValueSelector.class); when(valueSelector.getVariableDescriptor()).thenReturn(variableDescriptor); final List<Object> valueList = Arrays.<Object>asList(values); when(valueSelector.iterator(any())).thenAnswer(invocation -> valueList.iterator()); when(valueSelector.endingIterator(any())).thenAnswer(invocation -> valueList.iterator()); when(valueSelector.iterator()).thenAnswer(invocation -> valueList.iterator()); when(valueSelector.isCountable()).thenReturn(true); when(valueSelector.isNeverEnding()).thenReturn(false); when(valueSelector.getSize(any())).thenReturn((long) valueList.size()); when(valueSelector.getSize()).thenReturn((long) valueList.size()); return valueSelector; } public static MoveSelector mockMoveSelector(Class<?> moveClass, Move... moves) { MoveSelector moveSelector = mock(MoveSelector.class); final List<Move> moveList = Arrays.<Move>asList(moves); when(moveSelector.iterator()).thenAnswer(invocation -> moveList.iterator()); when(moveSelector.isCountable()).thenReturn(true); when(moveSelector.isNeverEnding()).thenReturn(false); when(moveSelector.getCacheType()).thenReturn(SelectionCacheType.JUST_IN_TIME); when(moveSelector.getSize()).thenReturn((long) moveList.size()); return moveSelector; } public static SingletonInverseVariableSupply mockSingletonInverseVariableSupply( final TestdataChainedEntity[] allEntities) { return planningValue -> { for (TestdataChainedEntity entity : allEntities) { if (entity.getChainedObject().equals(planningValue)) { return entity; } } return null; }; } public static void assertChain(TestdataChainedObject... chainedObjects) { TestdataChainedObject chainedObject = chainedObjects[0]; for (int i = 1; i < chainedObjects.length; i++) { TestdataChainedEntity chainedEntity = (TestdataChainedEntity) chainedObjects[i]; if (!Objects.equals(chainedObject, chainedEntity.getChainedObject())) { fail("Chain assertion failed for chainedEntity (" + chainedEntity + ").\n" + "Expected: " + chainedObject + "\n" + "Actual: " + chainedEntity.getChainedObject() + "\n" + "Expected chain: " + Arrays.toString(chainedObjects) + "\n" + "Actual chain: " + Arrays.toString(ArrayUtils.subarray(chainedObjects, 0, i)) + " ... [" + chainedEntity.getChainedObject() + ", " + chainedEntity + "] ..."); } chainedObject = chainedEntity; } } private SelectorTestUtils() { } }