package org.oakgp.mutate;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.oakgp.TestUtils.integerConstant;
import static org.oakgp.TestUtils.readNode;
import static org.oakgp.util.DummyRandom.GetIntExpectation.nextInt;

import org.junit.Test;
import org.oakgp.node.ConstantNode;
import org.oakgp.node.Node;
import org.oakgp.selector.DummyNodeSelector;
import org.oakgp.util.DummyRandom;
import org.oakgp.util.Random;

public class HoistMutationTest {
   @Test
   public void testTerminal() {
      ConstantNode constant = integerConstant(1);
      Node result = hoistMutate(DummyRandom.EMPTY, constant);
      assertSame(constant, result);
   }

   @Test
   public void testFunctionNodeNoAlternatives() {
      // tests when the return type of the root node (in this case a boolean)
      // is not same type of any of the other nodes in the tree (in this case they are all integers)
      Node input = readNode("(zero? (+ (+ v0 v1) (+ 9 v2)))");
      Node result = hoistMutate(DummyRandom.EMPTY, input);
      assertSame(input, result);
   }

   @Test
   public void testFunctionNode() {
      Node input = readNode("(+ (+ (if (zero? v0) 7 8) v1) (+ 9 v2))");
      DummyNodeSelector selector = DummyNodeSelector.repeat(9, input);
      DummyRandom random = nextInt(9).returns(3, 4, 5, 2, 1, 8, 6, 7, 0);
      HoistMutation mutator = new HoistMutation(random);

      // TODO better if first arg is String and second uses writeNode
      // TODO add assertNodeEquals(String, Node) to TestUtils and retro-fit to existing tests
      assertEquals(readNode("(if (zero? v0) 7 8)"), mutator.evolve(selector));
      assertEquals(readNode("v1"), mutator.evolve(selector));
      assertEquals(readNode("(+ (if (zero? v0) 7 8) v1)"), mutator.evolve(selector));
      assertEquals(readNode("8"), mutator.evolve(selector));
      assertEquals(readNode("7"), mutator.evolve(selector));
      assertEquals(readNode("(+ 9 v2)"), mutator.evolve(selector));
      assertEquals(readNode("9"), mutator.evolve(selector));
      assertEquals(readNode("v2"), mutator.evolve(selector));
      assertEquals(readNode("v0"), mutator.evolve(selector));

      selector.assertEmpty();
      random.assertEmpty();
   }

   private Node hoistMutate(Random random, Node input) {
      DummyNodeSelector selector = new DummyNodeSelector(input);
      Node result = new HoistMutation(random).evolve(selector);
      selector.assertEmpty();
      return result;
   }
}

@@ -57,22 +57,20 @@
 t.assert
-Equals
+Same
 ;%0Aimport
@@ -81,39 +81,48 @@
 tic org.
-junit.Assert.assertSame
+oakgp.TestUtils.assertNodeEquals
 ;%0Aimport
@@ -1434,193 +1434,24 @@
     
-// TODO better if first arg is String and second uses writeNode%0A      // TODO add assertNodeEquals(String, Node) to TestUtils and retro-fit to existing tests%0A      assertEquals(readNode
+assertNodeEquals
 (%22(i
@@ -1468,17 +1468,16 @@
 0) 7 8)%22
-)
 , mutato
@@ -1513,29 +1513,23 @@
 sert
+Node
 Equals(
-readNode(
 %22v1%22
-)
 , mu
@@ -1565,32 +1565,27 @@
   assert
+Node
 Equals(
-readNode(
 %22(+ (if 
@@ -1604,17 +1604,16 @@
  8) v1)%22
-)
 , mutato
@@ -1649,28 +1649,22 @@
 sert
+Node
 Equals(
-readNode(
 %228%22
-)
 , mu
@@ -1704,28 +1704,22 @@
 sert
+Node
 Equals(
-readNode(
 %227%22
-)
 , mu
@@ -1755,32 +1755,27 @@
   assert
+Node
 Equals(
-readNode(
 %22(+ 9 v2
@@ -1776,17 +1776,16 @@
 + 9 v2)%22
-)
 , mutato
@@ -1821,28 +1821,22 @@
 sert
+Node
 Equals(
-readNode(
 %229%22
-)
 , mu
@@ -1876,29 +1876,23 @@
 sert
+Node
 Equals(
-readNode(
 %22v2%22
-)
 , mu
@@ -1932,29 +1932,23 @@
 sert
+Node
 Equals(
-readNode(
 %22v0%22
-)
 , mu

use TestUtils.assertNodeEquals