package com.janosgyerik.utils.misc;

import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import static com.janosgyerik.utils.misc.IterTools.toList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;

public class IterToolsTest {

    private <T> Set<List<T>> permutations(List<T> nums) {
        return IterTools.toSet(IterTools.permutations(nums));
    }

    @Test
    public void test_permutate_empty() {
        assertEquals(Collections.singleton(Collections.emptyList()), permutations(Collections.emptyList()));
    }

    @Test
    public void test_permutate_1() {
        assertEquals(Collections.singleton(Collections.singletonList(1)), permutations(Collections.singletonList(1)));
    }

    private Set<List<Integer>> makeSet(List<List<Integer>> lists) {
        Set<List<Integer>> result = new HashSet<>();
        result.addAll(lists);
        return result;
    }

    @Test
    public void test_permutate_1_2() {
        assertEquals(
                makeSet(Arrays.asList(Arrays.asList(1, 2), Arrays.asList(2, 1))),
                permutations(Arrays.asList(1, 2)));
        assertEquals(
                makeSet(Arrays.asList(Arrays.asList(2, 1), Arrays.asList(1, 2))),
                permutations(Arrays.asList(1, 2)));
    }

    @Test
    public void test_permutate_1_2_3() {
        assertEquals(
                makeSet(Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(1, 3, 2), Arrays.asList(2, 1, 3),
                        Arrays.asList(2, 3, 1), Arrays.asList(3, 1, 2), Arrays.asList(3, 2, 1))),
                permutations(Arrays.asList(1, 2, 3)));
    }

    @Test
    public void should_get_equal_list_from_iterator() {
        List<Integer> list = Arrays.asList(3, 1, 4, 5, 2);
        assertEquals(list, toList(list.iterator()));
    }

    @Test
    public void should_get_empty_list_from_empty_iterator() {
        List<Integer> list = Collections.emptyList();
        assertEquals(list, toList(list.iterator()));
    }

    @Test
    public void should_get_1_empty_permutation_for_empty_list() {
        Iterable<List<Integer>> permutations = IterTools.permutations(0);
        assertThat(permutations).containsOnly(Collections.emptyList());
    }

    @Test
    public void should_get_1_permutation_for_singleton_list() {
        Set<List<Integer>> permutations = permutations(Collections.singletonList(7));
        assertThat(permutations).containsOnly(Collections.singletonList(7));
    }

    @Test
    public void should_get_2_permutations_for_x_y() {
        Set<List<Character>> permutations = permutations(Arrays.asList('x', 'y'));
        assertThat(permutations).containsOnly(
                Arrays.asList('x', 'y'),
                Arrays.asList('y', 'x')
        );
    }

    @Test
    public void should_get_6_permutations_for_1_2_3() {
        Set<List<Integer>> permutations = permutations(Arrays.asList(1, 2, 3));
        assertThat(permutations).containsOnly(
                Arrays.asList(1, 2, 3),
                Arrays.asList(1, 3, 2),
                Arrays.asList(2, 1, 3),
                Arrays.asList(2, 3, 1),
                Arrays.asList(3, 1, 2),
                Arrays.asList(3, 2, 1)
        );
    }

    @Test
    public void should_get_equal_permutations_from_recursion_and_iterator() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
        Set<List<Integer>> set = StreamSupport.stream(IterTools.permutations(6).spliterator(), false).collect(Collectors.toSet());
        assertEquals(set, permutations(list));
    }
}

@@ -1066,36 +1066,32 @@
 ls(%0A            
-    
 makeSet(Arrays.a
@@ -1132,36 +1132,32 @@
 asList(2, 1))),%0A
-    
             perm
@@ -1214,36 +1214,32 @@
 ls(%0A            
-    
 makeSet(Arrays.a
@@ -1284,28 +1284,24 @@
 st(1, 2))),%0A
-    
             
@@ -1420,36 +1420,32 @@
 ls(%0A            
-    
 makeSet(Arrays.a
@@ -1534,32 +1534,24 @@
             
-        
 Arrays.asLis
@@ -1604,36 +1604,32 @@
 ist(3, 2, 1))),%0A
-    
             perm
@@ -2228,32 +2228,64 @@
 ns).containsOnly
+ElementsOf(Collections.singleton
 (Collections.emp
@@ -2289,24 +2289,25 @@
 emptyList())
+)
 ;%0A    %7D%0A%0A   
@@ -2508,16 +2508,48 @@
 ainsOnly
+ElementsOf(Collections.singleton
 (Collect
@@ -2566,24 +2566,25 @@
 etonList(7))
+)
 ;%0A    %7D%0A%0A   
@@ -2764,38 +2764,58 @@
 ns).containsOnly
-(%0A    
+ElementsOf(Arrays.asList(%0A
             Arra
@@ -2839,36 +2839,32 @@
 '),%0A            
-    
 Arrays.asList('y
@@ -2871,32 +2871,33 @@
 ', 'x')%0A        
+)
 );%0A    %7D%0A%0A    @T
@@ -3081,22 +3081,42 @@
 ainsOnly
-(%0A    
+ElementsOf(Arrays.asList(%0A
         
@@ -3147,36 +3147,32 @@
 3),%0A            
- 
-   
 Arrays.asList(1,
@@ -3175,28 +3175,24 @@
 t(1, 3, 2),%0A
-    
             
@@ -3219,36 +3219,32 @@
 3),%0A            
-   
- 
 Arrays.asList(2,
@@ -3251,20 +3251,16 @@
  3, 1),%0A
-    
         
@@ -3291,36 +3291,32 @@
 2),%0A            
-    
 Arrays.asList(3,
@@ -3330,16 +3330,17 @@
         
+)
 );%0A    %7D
@@ -3491,16 +3491,90 @@
  5, 6);%0A
+        Iterable%3CList%3CInteger%3E%3E permutations = IterTools.permutations(6);%0A
         
@@ -3619,26 +3619,16 @@
 .stream(
-IterTools.
 permutat
@@ -3631,19 +3631,16 @@
 utations
-(6)
 .spliter

Fix warnings about generic vararg creation