/* * Copyright 2015 S. Webber * * 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.oakgp.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.oakgp.TestUtils.singletonRankedCandidates; import java.util.Collection; import java.util.function.Function; import java.util.function.IntFunction; import java.util.function.Predicate; import org.junit.Test; import org.oakgp.Type; import org.oakgp.evolve.GenerationEvolver; import org.oakgp.node.Node; import org.oakgp.primitive.DummyPrimitiveSet; import org.oakgp.rank.GenerationRanker; import org.oakgp.rank.RankedCandidate; import org.oakgp.rank.RankedCandidates; import org.oakgp.util.RunBuilder.Config; import org.oakgp.util.RunBuilder.InitialPopulationSetter; import org.oakgp.util.RunBuilder.TreeDepthSetter; public class RunBuilderTest { private static final DummyPrimitiveSet DUMMY_PRIMITIVE_SET = new DummyPrimitiveSet(); private static final Random DUMMY_RANDOM = DummyRandom.EMPTY; private static final Type RETURN_TYPE = Type.type("runBuilderTest"); @SuppressWarnings("unchecked") @Test public void test() { // Create mock objects to pass as arguments to process method of Runner GenerationRanker ranker = mock(GenerationRanker.class); GenerationEvolver evolver = mock(GenerationEvolver.class); Predicate<RankedCandidates> terminator = mock(Predicate.class); Collection<Node> initialPopulation = mock(Collection.class); Function<Config, Collection<Node>> initialPopulationCreator = c -> { assertSame(c.getPrimitiveSet(), DUMMY_PRIMITIVE_SET); assertSame(c.getRandom(), DUMMY_RANDOM); assertSame(c.getReturnType(), RETURN_TYPE); return initialPopulation; }; Function<Config, GenerationEvolver> generationEvolverCreator = c -> { assertSame(c.getPrimitiveSet(), DUMMY_PRIMITIVE_SET); assertSame(c.getRandom(), DUMMY_RANDOM); assertSame(c.getReturnType(), RETURN_TYPE); return evolver; }; RankedCandidate expected = createRunExpectations(ranker, evolver, terminator, initialPopulation); RankedCandidates output = new RunBuilder().setReturnType(RETURN_TYPE).setRandom(DUMMY_RANDOM).setPrimitiveSet(DUMMY_PRIMITIVE_SET) .setGenerationRanker(ranker).setInitialPopulation(initialPopulationCreator).setGenerationEvolver(generationEvolverCreator) .setTerminator(terminator).process(); RankedCandidate actual = output.best(); // confirm output matches expected behaviour assertSame(expected, actual); } @Test public void testInvalidPopulationSize() { InitialPopulationSetter setter = createInitialPopulationSetter(); assertInvalidSizes(setter::setInitialPopulationSize); } @Test public void testInvalidTreeDepth() { TreeDepthSetter setter = createInitialPopulationSetter().setInitialPopulationSize(1000); assertInvalidSizes(setter::setTreeDepth); } private InitialPopulationSetter createInitialPopulationSetter() { GenerationRanker ranker = mock(GenerationRanker.class); return new RunBuilder().setReturnType(RETURN_TYPE).setRandom(DUMMY_RANDOM).setPrimitiveSet(DUMMY_PRIMITIVE_SET).setGenerationRanker(ranker); } private void assertInvalidSizes(IntFunction<?> setter) { // confirm negative values and zero are not valid for (int i : new int[] { Integer.MIN_VALUE, -2, -1, 0 }) { assertInvalidSize(setter, i); } } private void assertInvalidSize(IntFunction<?> setter, int size) { try { setter.apply(size); } catch (IllegalArgumentException e) { assertEquals("Expected a positive integer but got: " + size, e.getMessage()); } } @SuppressWarnings("unchecked") static RankedCandidate createRunExpectations(GenerationRanker ranker, GenerationEvolver evolver, Predicate<RankedCandidates> terminator, Collection<Node> initialPopulation) { // create mock objects used in processing RankedCandidates rankedInitialPopulation = singletonRankedCandidates(); Collection<Node> secondGeneration = mock(Collection.class); RankedCandidates rankedSecondGeneration = singletonRankedCandidates(); Collection<Node> thirdGeneration = mock(Collection.class); RankedCandidates rankedThirdGeneration = singletonRankedCandidates(); Collection<Node> fourthGeneration = mock(Collection.class); RankedCandidates rankedFourthGeneration = singletonRankedCandidates(); // expectations for initial population when(ranker.rank(initialPopulation)).thenReturn(rankedInitialPopulation); when(evolver.evolve(rankedInitialPopulation)).thenReturn(secondGeneration); // expectations for second generation when(ranker.rank(secondGeneration)).thenReturn(rankedSecondGeneration); when(evolver.evolve(rankedSecondGeneration)).thenReturn(thirdGeneration); // expectations for third generation when(ranker.rank(thirdGeneration)).thenReturn(rankedThirdGeneration); when(evolver.evolve(rankedThirdGeneration)).thenReturn(fourthGeneration); // expectations for fourth generation when(ranker.rank(fourthGeneration)).thenReturn(rankedFourthGeneration); when(terminator.test(rankedFourthGeneration)).thenReturn(true); return rankedFourthGeneration.best(); } }