Package org.jhighfun.util

Source Code of org.jhighfun.util.CollectionFunctionChainSpec

package org.jhighfun.util;


import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
import support.Language;
import support.Person;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.*;

import static org.jhighfun.util.CollectionUtil.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class CollectionFunctionChainSpec {

    @Spy
    ExecutorService spyHighPriorityTaskThreadPool = new ThreadPoolExecutor(1, Integer.MAX_VALUE, 1, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());

    @Spy
    ExecutorService spyLowPriorityAsyncTaskThreadPool = new ThreadPoolExecutor(0, 5, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());


    @Before
    public void before() {
        try {
            Field globalPool = FunctionUtil.class.getDeclaredField("highPriorityTaskThreadPool");
            globalPool.setAccessible(true);
            globalPool.set(null, spyHighPriorityTaskThreadPool);

            globalPool = FunctionUtil.class.getDeclaredField("lowPriorityAsyncTaskThreadPool");
            globalPool.setAccessible(true);
            globalPool.set(null, spyLowPriorityAsyncTaskThreadPool);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testUnchain() {

        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 100; i++) {
            list.add("India");
            list.add("ndia");
            list.add("dia");
            list.add("ia");
            list.add("a");
        }
        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        assertEquals(chain.extract(), list);
    }


    @Test
    public void testToObject() {
        Object object = new Object();
        CollectionFunctionChain<Object> chain = new CollectionFunctionChain<Object>(List(object));

        Function<List<Object>, Object> mockConverter = spy(new Function<List<Object>, Object>() {
            public Object apply(List<Object> input) {
                return input.get(0);
            }
        });
        assertEquals(chain.toObject(mockConverter).extract(), object);
        verify(mockConverter, times(1)).apply(List(object));

    }

    @Test
    public void testMap() {

        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 100; i++) {
            list.add("India");
            list.add("ndia");
            list.add("dia");
            list.add("ia");
            list.add("a");
        }
        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        Collection<Character> mapList = chain.map(new Function<String, Character>() {
            public Character apply(String input) {
                return input.charAt(0);
            }
        }).extract();

        List<Character> expectedList = new LinkedList<Character>();
        for (int i = 1; i <= 100; i++) {
            expectedList.add('I');
            expectedList.add('n');
            expectedList.add('d');
            expectedList.add('i');
            expectedList.add('a');
        }

        assertEquals(mapList, expectedList);
    }

    @Test
    public void testMapWithThreads() {

        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 100; i++) {
            list.add("India");
            list.add("ndia");
            list.add("dia");
            list.add("ia");
            list.add("a");
        }
        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        Collection<Character> mapList = chain.map(new Function<String, Character>() {
            public Character apply(String input) {
                return input.charAt(0);
            }
        }, FunctionUtil.parallel(3)).extract();

        List<Character> expectedList = new LinkedList<Character>();
        for (int i = 1; i <= 100; i++) {
            expectedList.add('I');
            expectedList.add('n');
            expectedList.add('d');
            expectedList.add('i');
            expectedList.add('a');
        }

        assertEquals(mapList, expectedList);
        verify(spyHighPriorityTaskThreadPool, times(2)).submit(any(Runnable.class));
    }

    @Test
    public void testFilter() {

        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 1000; i++) {
            list.add("Scala");
            list.add("Ruby");
        }


        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        Collection<String> filterList = chain.filter(new Function<String, Boolean>() {

            public Boolean apply(String t) {
                return t.contains("y");
            }

        }).extract();

        assertTrue(filterList.size() == (list.size() / 2));

        for (String string : filterList) {
            assertTrue(string.equals("Ruby"));
        }

    }

    @Test
    public void testFilterWithThreads() {

        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 1000; i++) {
            list.add("Scala");
            list.add("Ruby");
        }

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        Collection<String> filterList = chain.filter(new Function<String, Boolean>() {

            public Boolean apply(String t) {
                return t.contains("y");
            }

        }, FunctionUtil.parallel(3)).extract();

        assertEquals(filterList.size(), (list.size() / 2));

        for (String string : filterList) {
            assertTrue(string.equals("Ruby"));
        }

        verify(spyHighPriorityTaskThreadPool, times(2)).submit(any(Runnable.class));
    }

    @Test
    public void testBatch() {
        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 1000; i++) {
            list.add("Scala");
            list.add("Ruby");
        }

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        List<List<String>> batchedOutput = chain.batch(100).extract();

        assertEquals(batchedOutput.size(), 20);

        for (List<String> batchedList : batchedOutput) {
            assertEquals(batchedList.size(), 100);
        }

    }


    @Test
    public void testExpand() {
        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Ruby");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        List<String> expandedOutput = chain.flatMap(new Function<String, Iterable<String>>() {
            public Iterable<String> apply(String arg) {
                return List(arg, arg);
            }
        }).extract();

        assertEquals(expandedOutput.size(), 4);
        assertEquals(expandedOutput.get(0), "Scala");
        assertEquals(expandedOutput.get(1), "Scala");
        assertEquals(expandedOutput.get(2), "Ruby");
        assertEquals(expandedOutput.get(3), "Ruby");

    }

    @Test
    public void testSortWith() {
        List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(4);
        list.add(2);
        list.add(3);

        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(list);

        Collection<Integer> filterList = chain.sortWith(new Comparator<Integer>() {

            public int compare(Integer t1, Integer t2) {
                return t1 - t2;
            }
        }).extract();

        assertTrue(filterList.toString().equals("[1, 2, 3, 4]"));

    }

    @Test
    public void testForSort() {
        Set<Integer> set = new HashSet<Integer>();
        set.add(1);
        set.add(4);
        set.add(2);
        set.add(3);

        assertTrue(new CollectionFunctionChain<Integer>(CollectionUtil.FlattenList(set)).sort().extract().toString().equals("[1, 2, 3, 4]"));

    }

    @Test
    public void testForSortBy() {
        Person joe = new Person("Joe", 10000, 34);
        Person amanda = new Person("Amanda", 70000, 24);
        Person chloe = new Person("Chloe", 10000, 30);

        List<Person> inputList = new LinkedList<Person>();
        inputList.add(joe);
        inputList.add(amanda);
        inputList.add(chloe);

        //---sort by age

        List<Person> expectedList = new LinkedList<Person>();
        expectedList.add(amanda);
        expectedList.add(chloe);
        expectedList.add(joe);

        assertEquals(new CollectionFunctionChain<Person>(inputList).sortBy("age").extract(), expectedList);

        //---sort by salary, name

        expectedList = new LinkedList<Person>();
        expectedList.add(chloe);
        expectedList.add(joe);
        expectedList.add(amanda);

        assertEquals(new CollectionFunctionChain<Person>(inputList).sortBy("salary", "firstName").extract(), expectedList);

    }


    @Test
    public void testForSortByWithSetterGetter() {
        Language java = new Language(false, "Java");
        Language javascript = new Language(true, "Javascript");
        Language ruby = new Language(true, "Ruby");
        Language scala = new Language(true, "Scala");

        List<Language> inputList = new LinkedList<Language>();
        inputList.add(java);
        inputList.add(ruby);
        inputList.add(javascript);
        inputList.add(scala);

        //---sort by age

        List<Language> expectedList = new LinkedList<Language>();
        expectedList.add(java);
        expectedList.add(ruby);
        expectedList.add(javascript);
        expectedList.add(scala);


        assertEquals(new CollectionFunctionChain<Language>(inputList).sortBy("functional").extract(), expectedList);

        //---sort by salary, name

        expectedList = new LinkedList<Language>();
        expectedList.add(java);
        expectedList.add(javascript);
        expectedList.add(ruby);
        expectedList.add(scala);

        assertEquals(new CollectionFunctionChain<Language>(inputList).sortBy("name").extract(), expectedList);

    }

    @Test
    public void testEach() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");

        final List<String> temp = new LinkedList<String>();

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        chain.each(new RecordProcessor<String>() {
            public void process(String item) {
                temp.add(item);
            }
        }).extract();

        assertEquals(temp, list);

    }

    @Test
    public void testEachWithIndexFunction() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");

        final Map<Integer, String> temp = new HashMap<Integer, String>();

        new CollectionFunctionChain<String>(list).eachWithIndex(new RecordWithIndexProcessor<String>() {
            public void process(String item, int index) {
                temp.put(index, item);
            }
        });

        final Map<Integer, String> expected = new HashMap<Integer, String>();
        expected.put(0, "Scala");
        expected.put(1, "Java");

        assertEquals(expected, temp);
    }

    @Test
    public void testEachFunctionWithThreads() {

        List<Integer> list = new LinkedList<Integer>();
        for (int i = 0; i < 1000; i++) {
            list.add(i);
        }

        final List<Integer> temp = new CopyOnWriteArrayList<Integer>();

        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(list);

        chain.each(new RecordProcessor<Integer>() {
            public void process(Integer item) {
                temp.add(item);
            }
        }, FunctionUtil.parallel(5)).extract();

        for (int i = 0; i < 1000; i++) {
            assertTrue(temp.contains(i));
        }

        verify(spyHighPriorityTaskThreadPool, times(4)).submit(any(Runnable.class));
    }

    @Test
    public void testFoldLeft() {

        List<String> list = new LinkedList<String>();
        list.add("Java");
        list.add(" ");
        list.add("Rocks");
        list.add("!");

        StringBuilder stringBuilder = new StringBuilder();

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        StringBuilder foldLeft = chain.foldLeft(stringBuilder, new Accumulator<StringBuilder, String>() {

            public StringBuilder accumulate(StringBuilder accumulator,
                                            String element) {
                return accumulator.append(element);
            }

        }).extract();

        assertTrue(foldLeft.toString().equals("Java Rocks!"));

    }

    @Test
    public void testFoldRight() {

        List<String> list = new LinkedList<String>();
        list.add("Java");
        list.add(" ");
        list.add("Rocks");
        list.add("!");

        StringBuilder stringBuilder = new StringBuilder();

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        StringBuilder foldRight = chain.foldRight(stringBuilder, new Accumulator<StringBuilder, String>() {

            public StringBuilder accumulate(StringBuilder accumulator,
                                            String element) {
                return accumulator.append(element);
            }

        }).extract();

        assertTrue(foldRight.toString().equals("!Rocks Java"));

    }

    @Test
    public void testTransform() {

        List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(list);

        List<String> stringList = chain.transform(new Function<List<Integer>, List<String>>() {
            public List<String> apply(List<Integer> arg) {
                return List("One", "Two", "Three");
            }
        }).extract();

        assertEquals(stringList, List("One", "Two", "Three"));
    }


    @Test
    public void testAsObject() {

        List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(list);

        List<Integer> integerList = chain.asObject().extract();

        assertEquals(integerList, List(1, 2, 3, 4));
    }


    @Test
    public void testExtract() {

        List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(list);

        Integer extract = chain.extract(new Function<List<Integer>, Integer>() {
            public Integer apply(List<Integer> arg) {
                return arg.get(0) + arg.get(1);
            }
        });

        assertTrue(extract == 3);
    }

    @Test
    public void testAsStream() {

        List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(list);

        TaskStream<Integer> integers = chain.asTaskStream();

        assertEquals(list, integers.extract());
    }

    @Test
    public void testReduce() {

        List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(list);

        Integer foldLeft = chain.reduce(new Accumulator<Integer, Integer>() {

            public Integer accumulate(Integer accumulator,
                                      Integer element) {
                return accumulator + element;
            }

        }).extract();

        assertTrue(foldLeft == 10);

    }


    @Test
    public void testReduceWithNoOfThreads() {

        List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(list);

        Integer foldLeft = chain.reduce(new Accumulator<Integer, Integer>() {

            public Integer accumulate(Integer accumulator,
                                      Integer element) {
                return accumulator + element;
            }

        }, FunctionUtil.parallel(2)).extract();

        assertTrue(foldLeft == 10);

        verify(spyHighPriorityTaskThreadPool, times(1)).submit(any(Callable.class));

    }

    @Test
    public void testEvery() {

        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 10; i++) {
            list.add("Scala");
            list.add("Java");
        }

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        boolean bool = chain.every(new Function<String, Boolean>() {

            public Boolean apply(String string) {
                return string.contains("v");
            }
        }).extract();

        assertTrue(!bool);

        bool = chain.every(new Function<String, Boolean>() {

            public Boolean apply(String string) {
                return string.contains("a");
            }
        }).extract();

        assertTrue(bool);
    }

    @Test
    public void testEveryFunctionWithThreads() {

        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 10000; i++) {
            list.add("Scala");
            list.add("Java");
        }

        boolean bool = new CollectionFunctionChain<String>(list).every(new Function<String, Boolean>() {

            public Boolean apply(String string) {
                return string.contains("v");
            }
        }, FunctionUtil.parallel(3)).extract();

        assertTrue(!bool);

        verify(spyHighPriorityTaskThreadPool, times(2)).submit(any(Runnable.class));

        bool = new CollectionFunctionChain<String>(list).every(new Function<String, Boolean>() {

            public Boolean apply(String string) {
                return string.contains("a");
            }
        }, FunctionUtil.parallel(5)).extract();

        assertTrue(bool);
        verify(spyHighPriorityTaskThreadPool, times(2 + 4)).submit(any(Runnable.class));
    }

    @Test
    public void testAnyFunctionWithThreads() {

        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 10000; i++) {
            list.add("Scala");
            list.add("Java");
        }

        boolean bool = new CollectionFunctionChain<String>(list).any(new Function<String, Boolean>() {

            public Boolean apply(String string) {
                return string.contains("v");
            }
        }, FunctionUtil.parallel(3)).extract();

        assertTrue(bool);

        verify(spyHighPriorityTaskThreadPool, times(2)).submit(any(Runnable.class));

        bool = new CollectionFunctionChain<String>(list).any(new Function<String, Boolean>() {

            public Boolean apply(String string) {
                return string.contains("a");
            }
        }, FunctionUtil.parallel(5)).extract();

        assertTrue(bool);
        verify(spyHighPriorityTaskThreadPool, times(2 + 4)).submit(any(Runnable.class));
    }


    @Test
    public void testCountFunctionWithThreads() {

        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 10000; i++) {
            list.add("Scala");
            list.add("Java");
        }

        int count = new CollectionFunctionChain<String>(list).count(new Function<String, Boolean>() {

            public Boolean apply(String string) {
                return string.contains("v");
            }
        }, FunctionUtil.parallel(3)).extract();

        assertEquals(count, 10000);
        verify(spyHighPriorityTaskThreadPool, times(2)).submit(any(Callable.class));
    }

    @Test
    public void testWithIndex() {

        List<String> list = List("hello", "Mr.", "FirstName", "LastName");

        List<String> outList = new CollectionFunctionChain(list).filterWithIndex(new Function<Integer, Boolean>() {
            public Boolean apply(Integer index) {
                return index % 2 == 0;
            }
        }).extract();

        assertEquals(outList, List("hello", "FirstName"));

    }

    @Test
    public void testSomeFunction() {

        List<String> list = new LinkedList<String>();
        for (int i = 1; i <= 10; i++) {
            list.add("Scala");
            list.add("Java");
        }

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        boolean bool = chain.any(new Function<String, Boolean>() {

            public Boolean apply(String string) {
                return string.contains("R");
            }
        }).extract();

        assertTrue(!bool);

        bool = chain.any(new Function<String, Boolean>() {

            public Boolean apply(String string) {
                return string.contains("a");
            }
        }).extract();

        assertTrue(bool);
    }

    @Test
    public void testCount() {

        Set<String> set = new HashSet<String>();
        set.add("Scala");
        set.add("Java");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(CollectionUtil.FlattenList(set));

        int count = chain.count(new Function<String, Boolean>() {
            public Boolean apply(String s) {
                return s.contains("Scala");
            }
        }).extract();

        assertEquals(count, 1);
    }


    @Test
    public void testPlus() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");

        List<String> list1 = new LinkedList<String>();
        list1.add("Groovy");
        list1.add("Ruby");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        Collection<String> combinedList = chain.plus(list1).extract();

        List<String> expectedList = new LinkedList<String>();
        expectedList.add("Scala");
        expectedList.add("Java");
        expectedList.add("Groovy");
        expectedList.add("Ruby");

        assertEquals(expectedList, combinedList);
    }

    @Test
    public void testMinus() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");

        List<String> list1 = new LinkedList<String>();
        list1.add("Java");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        Collection<String> combinedList = chain.minus(list1).extract();

        List<String> expectedList = new LinkedList<String>();
        expectedList.add("Scala");

        assertEquals(expectedList, combinedList);
    }


    @Test
    public void testUnion() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");

        List<String> list1 = new LinkedList<String>();
        list1.add("Java");
        list1.add("Groovy");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        Collection<String> combinedList = chain.union(FlattenSet(list1)).extract();

        List<String> expectedList = new LinkedList<String>();
        expectedList.add("Scala");
        expectedList.add("Java");
        expectedList.add("Groovy");

        assertEquals(expectedList, combinedList);
    }

    @Test
    public void testIntersect() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");

        List<String> list1 = new LinkedList<String>();
        list1.add("Java");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        Collection<String> combinedList = chain.intersect(FlattenSet(list1)).extract();

        List<String> expectedList = new LinkedList<String>();
        expectedList.add("Java");

        assertEquals(expectedList, combinedList);
    }


    @Test
    public void testCrossProduct() {

        Iterable<Integer> integers = LazyIntRange(1, 100);

        Iterable<Long> longs = LazyLongRange(101, 200);

        Iterable<String> product = new CollectionFunctionChain<Integer>(integers).crossProduct(longs, new Function<Tuple2<Integer, Long>, String>() {

            public String apply(Tuple2<Integer, Long> tuple) {
                return tuple.toString();
            }
        }).extract();

        Iterator<String> iterator = product.iterator();

        for (Integer integer : integers) {
            for (Long lon : longs) {
                assertEquals(iterator.next(), new Tuple2<Integer, Long>(integer, lon).toString());
            }
        }

    }

    @Test
    public void testSelfProduct() {

        Iterable<Integer> integers = LazyIntRange(1, 100);

        Iterable<Integer> integers1 = LazyIntRange(1, 100);

        Iterable<String> product = new CollectionFunctionChain<Integer>(integers).selfProduct(new Function<Tuple2<Integer, Integer>, String>() {

            public String apply(Tuple2<Integer, Integer> tuple) {
                return tuple.toString();
            }
        }).extract();

        Iterator<String> iterator = product.iterator();

        for (Integer integer : integers) {
            for (Integer integer1 : integers1) {
                assertEquals(iterator.next(), new Tuple2<Integer, Integer>(integer, integer1).toString());
            }
        }

    }


    @Test
    public void testSlice() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");
        list.add("Groovy");
        list.add("Ruby");

        Collection<String> combinedList = new CollectionFunctionChain<String>(list).slice(1, 2).extract();

        List<String> expectedList = new LinkedList<String>();
        expectedList.add("Java");
        expectedList.add("Groovy");

        assertEquals(expectedList, combinedList);

        //--------------------------------

        combinedList = new CollectionFunctionChain<String>(list).slice(1, 3).extract();

        expectedList = new LinkedList<String>();
        expectedList.add("Java");
        expectedList.add("Groovy");
        expectedList.add("Ruby");

        assertEquals(expectedList, combinedList);

        //--------------------------------

        combinedList = new CollectionFunctionChain<String>(list).slice(0, 0).extract();

        expectedList = new LinkedList<String>();
        expectedList.add("Scala");

        assertEquals(expectedList, combinedList);

        //--------------------------------

        combinedList = new CollectionFunctionChain<String>(list).slice(5, 6).extract();

        expectedList = new LinkedList<String>();

        assertEquals(expectedList, combinedList);

    }

    @Test
    public void testFork() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");
        list.add("Groovy");
        list.add("Ruby");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);
        assertTrue(chain.fork().getClass() == CollectionForkAndJoin.class);

    }

    @Test
    public void testLimit() {
        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");
        list.add("Groovy");
        list.add("Ruby");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        assertEquals(chain.limit(10).extract(), List("Scala", "Java", "Groovy", "Ruby"));
        assertEquals(chain.limit(3).extract(), List("Scala", "Java", "Groovy"));
        assertEquals(chain.limit(1).extract(), List("Scala"));
    }


    @Test(expected = IllegalArgumentException.class)
    public void testLimitWithNegativeValue() {
        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");
        list.add("Groovy");
        list.add("Ruby");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        assertEquals(chain.limit(-1).extract(), List());
    }

    @Test
    public void testReverse() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");
        list.add("Groovy");
        list.add("Ruby");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        assertEquals(chain.reverse().extract(), List("Ruby", "Groovy", "Java", "Scala"));
    }

    @Test
    public void testRemoveAlikes() {

        List<String> list = new LinkedList<String>();
        list.add("Scala - JVM");
        list.add("Java  - JVM");
        list.add("Groovy  - JVM");
        list.add("Ruby - Custom");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);

        assertEquals(chain.removeDuplicates(new Function<Tuple2<String, String>, Boolean>() {
            public Boolean apply(Tuple2<String, String> tuple) {
                return tuple._1.endsWith("JVM") && tuple._2.endsWith("JVM");
            }
        }).extract(), List("Scala - JVM", "Ruby - Custom"));
    }

    @Test
    public void testDivideAndConquerWithChunks() {
        List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        Task<List<Integer>> mockTask = mock(Task.class);

        new CollectionFunctionChain<Integer>(list).divideAndConquer(mockTask, FunctionUtil.batch(2));

        List<Integer> chunk1 = new LinkedList<Integer>();
        chunk1.add(1);
        chunk1.add(2);

        verify(mockTask, times(1)).execute(chunk1);

        List<Integer> chunk2 = new LinkedList<Integer>();
        chunk2.add(3);
        chunk2.add(4);

        verify(mockTask, times(1)).execute(chunk2);
        verify(spyHighPriorityTaskThreadPool, times(1)).submit(any(Runnable.class));

    }

    @Test
    public void testDivideAndConquerWithPartitions() {
        List<Integer> list = new LinkedList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);

        Task<List<Integer>> mockTask = mock(Task.class);

        new CollectionFunctionChain<Integer>(list).divideAndConquer(mockTask, FunctionUtil.parallel(3));

        List<Integer> partition1 = new LinkedList<Integer>();
        partition1.add(1);
        partition1.add(4);

        verify(mockTask, times(1)).execute(partition1);

        List<Integer> partition2 = new LinkedList<Integer>();
        partition2.add(2);
        partition2.add(5);

        verify(mockTask, times(1)).execute(partition2);

        List<Integer> partitions3 = new LinkedList<Integer>();
        partitions3.add(3);

        verify(mockTask, times(1)).execute(partitions3);

        verify(spyHighPriorityTaskThreadPool, times(2)).submit(any(Runnable.class));

    }


    @Test
    public void testExecute() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");
        list.add("Groovy");
        list.add("Ruby");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);
        Task<List<String>> mockTask = mock(Task.class);

        chain.execute(mockTask);

        verify(mockTask, times(1)).execute(list);
    }

    @Test
    public void testExecuteAsync() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");
        list.add("Groovy");
        list.add("Ruby");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);
        Task<List<String>> mockTask = mock(Task.class);

        chain.executeAsync(mockTask);

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        verify(mockTask, times(1)).execute(list);
        verify(spyHighPriorityTaskThreadPool, times(1)).submit(any((Runnable.class)));
    }

    @Test
    public void testGroupBy() {

        List<String> list = List("a", "b", "a", "c", "c", "d");

        Map<Character, List<String>> results = new CollectionFunctionChain<String>(list).groupBy(new Function<String, Character>() {

            @Override
            public Character apply(String arg) {
                return arg.charAt(0);
            }
        }).extract();


        assertEquals(results, Map(Entry('a', List("a", "a")), Entry('b', List("b")), Entry('c', List("c", "c")), Entry('d', List("d"))));
    }

    @Test
    public void testPartition() {

        List<String> set = new LinkedList<String>();
        set.add("Scala");
        set.add("Java");


        Tuple2<List<String>, List<String>> tuple2 = new CollectionFunctionChain<String>(set).partition(new Function<String, Boolean>() {
            public Boolean apply(String s) {
                return s.contains("Scala");
            }
        }).extract();

        assertEquals(tuple2._1.toString(), "[Scala]");
        assertEquals(tuple2._2.toString(), "[Java]");
    }

    @Test
    public void testExecuteLater() {

        List<String> list = new LinkedList<String>();
        list.add("Scala");
        list.add("Java");
        list.add("Groovy");
        list.add("Ruby");

        CollectionFunctionChain<String> chain = new CollectionFunctionChain<String>(list);
        Task<List<String>> mockTask = mock(Task.class);

        chain.executeLater(mockTask);

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        verify(mockTask, times(1)).execute(list);
        verify(spyLowPriorityAsyncTaskThreadPool, times(1)).submit(any((Runnable.class)));
    }

    @Test
    public void testExecuteWithGlobalLockWithMultipleThread() {

        final List<Integer> list = IntRange(1, 10000);

        final Block spyBlock = spy(new Block() {
            public void execute() {
                list.add(1);
                for (Integer i : list) ;
                list.add(2);
            }
        });

        FunctionUtil.each(IntRange(1, 100), new RecordProcessor<Integer>() {
            public void process(Integer item) {
                new CollectionFunctionChain<Integer>(IntRange(1, 10)).executeWithGlobalLock(new Task<List<Integer>>() {
                    public void execute(List<Integer> input) {
                        spyBlock.execute();
                    }
                });
            }
        }, FunctionUtil.parallel(100));

        verify(spyBlock, times(100)).execute();
    }


    private static ConcurrentHashMap<ExecutionThrottler, ExecutorService> mapSpy;
    private static ExecutionThrottler throttler;

    public static void init() throws Exception {

        Field throttlerPoolMap = FunctionUtil.class.getDeclaredField("throttlerPoolMap");
        throttlerPoolMap.setAccessible(true);
        mapSpy = spy(new ConcurrentHashMap<ExecutionThrottler, ExecutorService>(15, 0.9f, 32));
        throttlerPoolMap.set(null, mapSpy);

        String identity = "some operation";
        throttler = FunctionUtil.throttler(identity);
        FunctionUtil.registerPool(throttler, 10);

    }

    @Test
    public void testExecuteWithThrottle() throws Exception {
        init();
        Task<List<Integer>> taskMock = mock(Task.class);

        List<Integer> integerList = IntRange(1, 100);
        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(integerList);

        chain.executeWithThrottle(throttler, taskMock);

        verify(mapSpy, times(1)).get(throttler);

        verify(taskMock, times(1)).execute(integerList);

    }

    @Test
    public void testExecuteAsyncWithThrottle() throws Exception {
        init();
        Task<List<Integer>> taskMock = mock(Task.class);

        List<Integer> integerList = IntRange(1, 100);
        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(integerList);

        chain.executeAsyncWithThrottle(throttler, taskMock);

        verify(mapSpy, times(1)).get(throttler);
        Thread.sleep(200);

        verify(taskMock, times(1)).execute(integerList);

    }

    @Test
    public void testExecuteAsyncWithThrottle_callback() throws Exception {
        init();
        Function<List<Integer>, Object> function = mock(Function.class);
        CallbackTask<Object> callbackTask = mock(CallbackTask.class);
        Object asyncTaskResult = new Object();
        List<Integer> integerList = IntRange(1, 100);
        CollectionFunctionChain<Integer> chain = new CollectionFunctionChain<Integer>(integerList);


        when(function.apply(integerList)).thenReturn(asyncTaskResult);

        chain.executeAsyncWithThrottle(throttler, function, callbackTask);

        verify(mapSpy, times(1)).get(throttler);
        Thread.sleep(200);
        ArgumentCaptor<AsyncTaskHandle> argument = ArgumentCaptor.forClass(AsyncTaskHandle.class);
        verify(callbackTask, times(1)).execute(argument.capture());

        assertEquals(argument.getValue().getOutput(), asyncTaskResult);
        assertEquals(argument.getValue().getException(), null);
    }

}
TOP

Related Classes of org.jhighfun.util.CollectionFunctionChainSpec

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.