package net.argius.java8.seq;

import static org.junit.Assert.fail;
import java.lang.reflect.*;
import java.util.*;
import org.junit.*;

public final class MetaTest {

    static final String[] methodList1 = { "of", "seq", "empty", "size", "at", "subSequence", "filter", "head", "tail",
            "map", "forEach", "fold", "reduce", "distinct", "reverse", "sort", "sortWith", "concat", "stream",
            "toArray", };

    static final String[] methodListForNumber = { "max", "min", "sum", "mapToObj", };
    static final String[] methodListExceptInt = { "mapToInt", };
    static final String[] methodListExceptLong = { "mapToLong", };
    static final String[] methodListExceptDouble = { "mapToDouble", };

    static void checkMethods(Class<?> c, String[]... lists) {
        for (String[] list : lists)
            for (final String methodName : list)
                if (!TestUtils.hasMethod(c, methodName))
                    fail(String.format("class %s does not have [%s] method", c.getSimpleName(), methodName));
    }

    @Test
    public void testSequenceImpl() {
        Class<?> c = Sequence.class;
        checkMethods(c, methodList1);
        checkMethods(c, methodListExceptInt);
        checkMethods(c, methodListExceptLong);
        checkMethods(c, methodListExceptDouble);
    }

    @Test
    public void testIntSequenceImpl() {
        Class<?> c = IntSequence.class;
        checkMethods(c, methodList1);
        checkMethods(c, methodListForNumber);
        checkMethods(c, methodListExceptLong);
        checkMethods(c, methodListExceptDouble);
    }

    @Test
    public void testLongSequenceImpl() {
        Class<?> c = LongSequence.class;
        checkMethods(c, methodList1);
        checkMethods(c, methodListForNumber);
        checkMethods(c, methodListExceptInt);
        checkMethods(c, methodListExceptDouble);
    }

    @Test
    public void testDoubleSequenceImpl() {
        Class<?> c = DoubleSequence.class;
        checkMethods(c, methodList1);
        checkMethods(c, methodListForNumber);
        checkMethods(c, methodListExceptInt);
        checkMethods(c, methodListExceptLong);
    }

    @Test
    public void testPrivateCtors() throws Exception {
        for (Class<?> c : Arrays.asList(SequenceFactory.class, IntSequenceFactory.class, LongSequenceFactory.class,
            DoubleSequenceFactory.class)) {
            Constructor<?> ctor = c.getDeclaredConstructor();
            ctor.setAccessible(true);
            ctor.newInstance();
        }
    }

}

@@ -208,55 +208,59 @@
  %7B %22
-of
+at
 %22, %22
-seq%22, %22empty%22, %22size%22, %22at%22, %22subSequence
+concat%22, %22distinct%22, %22drop%22, %22empty%22, %22exists
 %22, %22
@@ -273,20 +273,12 @@
 %22, %22
-head%22, %22tail
+find
 %22,%0A 
@@ -289,19 +289,20 @@
        %22
-map
+fold
 %22, %22forE
@@ -312,99 +312,150 @@
 %22, %22
-fol
+hea
 d%22, %22
-reduce%22, %22distinct%22, %22reverse%22, %22sort%22, %22sortWith%22, %22concat%22, %22stream%22,%0A           
+indexWhere%22, %22map%22, %22of%22, %22reduce%22, %22reverse%22, %22seq%22, %22size%22, %22sort%22,%0A            %22sortWith%22, %22stream%22, %22subSequence%22, %22tail%22, %22take%22,
  %22to
@@ -521,37 +521,48 @@
  %7B %22
-max
+average%22, %22mapToObj
 %22, %22m
-in
+ax
 %22, %22
-sum
+min
 %22, %22
-mapToObj
+sum
 %22, %7D
@@ -624,24 +624,94 @@
 pToInt%22, %7D;%0A
+    static final String%5B%5D methodListOnlyInt = %7B %22random%22, %22range%22, %7D;%0A
     static f
@@ -813,24 +813,47 @@
 ptDouble = %7B
+ %22contains%22, %22indexOf%22,
  %22mapToDoubl
@@ -957,16 +957,106 @@
 : lists)
+ %7B%0A            assert Sequence.of(list).toSet().size() == list.length : %22list not unique%22;
 %0A       
@@ -1264,16 +1264,26 @@
 Name));%0A
+        %7D%0A
     %7D%0A%0A 

Add method names to method lists in MetaTest