import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Callable;

import static java.lang.Thread.*;

/**
 * Created by colin on 15. 8. 15..
 */
public class LambdaExpressionSyntaxesLearningTest {
	private List<String> strings;
	private List<Integer> integers;
	@Before
	public void prepare(){
		strings = Arrays.asList(new String[]{"1","21","321","4321","54321"});
		integers = Arrays.asList(new Integer[]{1,2,3,4,5});
	}

	@Test
	public void parameterTypesCanBeInferredByDefinition(){
		strings.sort((first, second) -> Integer.compare(first.length(), second.length()));
	}

	@Test
	public void parenthesisCanBeOmittedWhenRequireOnlyOneParameter(){
		strings.stream().map(anElement -> anElement.toUpperCase());
	}

	@Test
	public void isLambdaExpressionJustSyntacticSugarForAnonymousImplementation(){
		Comparator lambdaExpressionInstance = LambdaExpressionDiscloser.disclose(
			(Integer first, Integer second) -> Integer.compare(first, second));
		Comparator anonymousComparatorInstance= LambdaExpressionDiscloser.disclose(new Comparator<Integer>() {
			@Override public int compare(Integer o1, Integer o2) {
				return 0;
			}
		});
		Comparator namedComparatorInstance= LambdaExpressionDiscloser.disclose(new NamedComparator());
		Assert.assertTrue(Comparator.class.isAssignableFrom(lambdaExpressionInstance.getClass()));
		Assert.assertTrue(Comparator.class.isAssignableFrom(anonymousComparatorInstance.getClass()));
		Assert.assertTrue(Comparator.class.isAssignableFrom(namedComparatorInstance.getClass()));
	}

	@Test
	public void seemsYesSoNaturallyHaveToHaveConsistentMethodSignature(){
		Runnable runnableFromLambda = () -> {
			try {
				sleep(10);
			} catch (InterruptedException e) {
				//Can't throw Checked Exception as Runnable::run method doesn't have throws definition.
			}
		};

		Callable<?> callableFromLambda = () -> {Thread.sleep(10);return null;};
	}

	@Test
	public void butMethodReferenceProvideMoreSyntacticSugar() {
		Comparator<String> comparatorFromStringCompareToMethod = LambdaExpressionDiscloser.disclose(String::compareTo);
		/*
		The above is same as the below

		Comparator<String> comparator = new Comparator<String>(){
			public int compare(String s1, String s2){
				return s1.compareTo(s2);
			}
		}
		*/
	}



	public static class LambdaExpressionDiscloser{
		public static <E> Comparator<E> disclose(Comparator<E> comparator){
			return comparator;
		}

		public static <E> Comparator<E> createComplareFrom(Comparator<E> comparator){
			return comparator;
		}
	}
	public static class NamedComparator implements Comparator<Integer>{
		@Override public int compare(Integer o1, Integer o2) {
			return 0;
		}
	}

}

@@ -992,16 +992,30 @@
 disclose
+WithComparator
 (%0A%09%09%09(In
@@ -1151,24 +1151,38 @@
 ser.disclose
+WithComparator
 (new Compara
@@ -1353,16 +1353,30 @@
 disclose
+WithComparator
 (new Nam
@@ -1373,24 +1373,31 @@
 or(new Named
+Integer
 Comparator()
@@ -2041,24 +2041,93 @@
 null;%7D;%0A%09%7D%0A%0A
+%09@Test%0A%09public void yesNameDoesNotMatterOnlySignatureMatters()%7B%0A%0A%09%7D%0A%0A
 %09@Test%0A%09publ
@@ -2182,16 +2182,47 @@
 gar() %7B%0A
+%09%09//with Class::instanceMethod%0A
 %09%09Compar
@@ -2306,16 +2306,30 @@
 disclose
+WithComparator
 (String:
@@ -2373,17 +2373,14 @@
  as 
-the 
 below
+.
 %0A%0A%09%09
@@ -2524,16 +2524,342 @@
 %09%09%7D%0A%09%09*/
+%0A%0A%09%09//with instance::instanceMethod%0A%09%09NamedIntegerComparator comparator = new NamedIntegerComparator();%0A%09%09LambdaExpressionDiscloser.discloseWithComparator(comparator::compare);%0A%0A%09%09//with Class::staticMethod : (o1, o2) -%3E retrun 0%0A%09%09LambdaExpressionDiscloser.discloseWithComparator(StaticIntegerCompareMethodProvider::compare);
 %0A%09%7D%0A%0A%0A%0A%09
@@ -2947,16 +2947,30 @@
 disclose
+WithComparator
 (Compara
@@ -3060,17 +3060,16 @@
 eateComp
-l
 areFrom(
@@ -3124,16 +3124,17 @@
 %0A%09%09%7D%0A%09%7D%0A
+%0A
 %09public 
@@ -3147,24 +3147,31 @@
  class Named
+Integer
 Comparator i
@@ -3279,10 +3279,143 @@
 %09%09%7D%0A%09%7D%0A%0A
+%09public static class StaticIntegerCompareMethodProvider %7B%0A%09%09public static int compare(Integer o1, Integer o2) %7B%0A%09%09%09return 0;%0A%09%09%7D%0A%09%7D%0A%0A
 %7D%0A

add method reference explanation