package com.mattunderscore.trees.query;

import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

import java.util.Collection;
import java.util.List;
import java.util.function.BiFunction;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;

import com.mattunderscore.simple.collections.SimpleCollection;
import com.mattunderscore.trees.binary.BinaryTreeNode;
import com.mattunderscore.trees.binary.OpenBinaryTreeNode;
import com.mattunderscore.trees.tree.OpenNode;
import com.mattunderscore.trees.tree.Tree;

/**
 * Unit tests for {@link Querier}.
 *
 * @author Matt Champion on 29/08/2015
 */
public final class QuerierTest {
    @Mock
    private Tree<String, BinaryTreeNode<String>> tree;

    @Mock
    private BinaryTreeNode<String> node;

    @Before
    public void setUp() {
        initMocks(this);

        when(tree.getRoot()).thenReturn(node);
    }

    @Test
    public void treeHeight() {
        final Querier querier = spy(new TestQuerier());

        querier.height(tree);

        verify(querier).height(node);
    }

    @Test
    public void treePaths() {
        final Querier querier = spy(new TestQuerier());

        querier.pathsToLeaves(tree);

        verify(querier).pathsToLeaves(node);
    }

    @Test
    public void treeBalanced() {
        final Querier querier = spy(new TestQuerier());

        querier.pathsToLeaves(tree);

        verify(querier).pathsToLeaves(node);
    }

    private static class TestQuerier implements Querier {
        @Override
        public <E, N extends OpenNode<E, N>> int height(N node) {
            return 0;
        }

        @Override
        public <E, N extends OpenNode<E, N>> SimpleCollection<List<N>> pathsToLeaves(N node) {
            return null;
        }

        @Override
        public <E, N extends OpenBinaryTreeNode<E, N>> boolean isBalanced(N node) {
            return false;
        }

        @Override
        public <E, N extends OpenBinaryTreeNode<E, N>> boolean isPerfectlyBalanced(N node) {
            return false;
        }

        @Override
        public <E, N extends OpenNode<E, N>, R> R partialReduce(N node, BiFunction<N, Collection<R>, ReductionResult<R>> reducer) {
            return null;
        }
    }
}

@@ -34,16 +34,95 @@
 query;%0A%0A
+import static org.mockito.Matchers.eq;%0Aimport static org.mockito.Matchers.isA;%0A
 import s
@@ -956,24 +956,238 @@
 ing%3E node;%0A%0A
+    @Mock%0A    private BiFunction%3CBinaryTreeNode%3CString%3E, Collection%3CString%3E, ReductionResult%3CString%3E%3E partialReducer;%0A%0A    @Mock%0A    private BiFunction%3CBinaryTreeNode%3CString%3E, Collection%3CString%3E, String%3E reducer;%0A%0A
     @Before%0A
@@ -1773,72 +1773,782 @@
 ier.
-pathsToLeaves(tree);%0A%0A        verify(querier).pathsToLeaves(node
+isBalanced(tree);%0A%0A        verify(querier).isBalanced(node);%0A    %7D%0A%0A    @Test%0A    public void treePerfectlyBalanced() %7B%0A        final Querier querier = spy(new TestQuerier());%0A%0A        querier.isPerfectlyBalanced(tree);%0A%0A        verify(querier).isPerfectlyBalanced(node);%0A    %7D%0A%0A    @Test%0A    public void treePartialReduce() %7B%0A        final Querier querier = spy(new TestQuerier());%0A%0A        querier.partialReduce(tree, partialReducer);%0A%0A        verify(querier).partialReduce(node, partialReducer);%0A    %7D%0A%0A    @SuppressWarnings(%22unchecked%22)%0A    @Test%0A    public void treeReduce() %7B%0A        final Querier querier = spy(new TestQuerier());%0A%0A        querier.reduce(tree, reducer);%0A%0A        verify(querier).partialReduce(eq(node), isA(PartialToTotalReductionResultAdapter.class)
 );%0A 

Increase test coverage.