/*******************************************************************************
* Copyright (c) 2011-2014 Fernando Petrola
*
* This file is part of Dragome SDK.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
******************************************************************************/
// Copyright © 2013-2014 Esko Luontola <www.orfjackal.net>
// This software is released under the Apache License 2.0.
// The license text is at http://www.apache.org/licenses/LICENSE-2.0
package com.dragome.tests;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
import org.junit.runner.RunWith;
import junit.framework.TestCase;
@RunWith(DragomeTestRunner.class)
public class LambdaTests extends TestCase {
public void test_empty_lambda() {
Runnable lambda = () -> {
};
lambda.run();
}
public void test_lambda_returning_a_value() throws Exception {
Callable<String> lambda = () -> "some value";
assertEquals("some value", lambda.call());
}
private interface Function1<IN, OUT> {
OUT apply(IN value);
}
public void test_lambda_taking_parameters() {
Function1<String, Integer> lambda = (String s) -> s.getBytes().length;
assertEquals((Integer) 3, lambda.apply("foo"));
}
private int instanceVar = 0;
public void test_lambda_using_instance_variables() {
Runnable lambda = () -> {
instanceVar = 42;
};
lambda.run();
assertEquals(instanceVar, 42);
}
public void test_lambda_using_local_variables() {
int[] localVar = new int[1];
Runnable lambda = () -> {
localVar[0] = 42;
};
lambda.run();
assertEquals(localVar[0], 42);
}
public void test_lambda_using_local_variables_of_primitive_types() throws Exception {
boolean bool = true;
byte b = 2;
short s = 3;
int i = 4;
long l = 5;
float f = 6;
double d = 7;
char c = 8;
Callable<Integer> lambda = () -> (int) ((bool ? 1 : 0) + b + s + i + l + f + d + c);
Integer call = lambda.call();
assertEquals(call, (Integer) 36);
}
public void test_method_references_to_virtual_methods() throws Exception {
String foo = "foo";
Callable<String> ref = foo::toUpperCase;
assertEquals(ref.call(), "FOO");
}
public void test_method_references_to_interface_methods() throws Exception {
List<String> foos = Arrays.asList("foo");
Callable<Integer> ref = foos::size;
Integer result = ref.call();
assertEquals(result, (Integer) 1);
}
public void test_method_references_to_static_methods() throws Exception {
long expected = System.currentTimeMillis();
Callable<Long> ref = System::currentTimeMillis;
assertTrue(ref.call() >= expected);
}
public void test_method_references_to_constructors() throws Exception {
Callable<List<String>> ref = ArrayList<String>::new;
assertTrue(ref.call() instanceof ArrayList);
}
class SuperClass {
String inheritedMethod() {
return "superclass version";
}
}
public class SubClass extends SuperClass {
private String t1() throws Exception {
Callable<String> ref = super::inheritedMethod;
return ref.call();
}
}
public void test_method_references_to_overridden_inherited_methods_with_super() throws Exception {
SubClass subClass = new SubClass();
assertEquals(subClass.t1(), "superclass version");
}
String inheritedMethod() {
return "overridden version";
}
public void test_method_references_to_private_methods() throws Exception {
Callable<String> ref1 = LambdaTests::privateClassMethod;
assertEquals(ref1.call(), "foo");
Callable<String> ref2 = this::privateInstanceMethod;
assertEquals(ref2.call(), "foo");
// Normal method calls should still work after our magic
// of making them them accessible from the lambda classes.
assertEquals(privateClassMethod(), "foo");
assertEquals(privateInstanceMethod(), "foo");
}
public class SomeEntity {
protected String name;
public SomeEntity(String name) {
this.name = name;
}
public int compareTo(SomeEntity entity1) {
return name.compareTo(entity1.name);
}
}
public void test_method_reference_to_instance_comparator() throws Exception {
SomeEntity[] a = new SomeEntity[] { new SomeEntity("c"), new SomeEntity("a"), new SomeEntity("b") };
Arrays.sort(a, SomeEntity::compareTo);
assertEquals(a[0].name, "a");
assertEquals(a[1].name, "b");
assertEquals(a[2].name, "c");
}
private String privateInstanceMethod() {
return "foo";
}
private static String privateClassMethod() {
return "foo";
}
public void testLambda_using_instance_variables() {
Runnable lambda = () -> {
instanceVar = 42;
};
lambda.run();
assertEquals(instanceVar, 42);
}
public void testLambda_using_local_variables() {
int[] localVar = new int[1];
Runnable lambda = () -> {
localVar[0] = 43;
};
lambda.run();
assertEquals(localVar[0], 43);
}
public void testCreatingBinaryOperatorWithLambda() {
BinaryOperator<Integer> sum = (v1, v2) -> v1 + v2;
Integer result = sum.apply(1, 2);
assertEquals(new Integer(3), result);
}
public void testLambaFromLambda() {
FileFilter[] filters = new FileFilter[] { f -> f.exists(), f -> f.canRead(), f -> f.getName().startsWith("q") };
Supplier<Runnable> c = () -> () -> {
instanceVar = 80;
};
Runnable runnable = c.get();
runnable.run();
assertEquals(80, instanceVar);
}
public void testNoParametersMethodReferenceAsLambda() {
String[] list = new String[] { "One", "Two", "Three", "Four", "Five", "Six" };
Comparator<String> upperComparator = Comparator.comparing(String::toUpperCase);
Arrays.sort(list, upperComparator);
assertEquals(list[0], "Five");
assertEquals(list[1], "Four");
assertEquals(list[2], "One");
assertEquals(list[3], "Six");
assertEquals(list[4], "Three");
assertEquals(list[5], "Two");
}
public void testUseTwoParametersMethodReferenceAsComparator() {
String[] list = new String[] { "One", "Two", "Three", "Four", "Five", "Six" };
Arrays.sort(list, (a, b) -> a.substring(1).compareTo(b.substring(1)));
assertEquals(list[0], "Three");
assertEquals(list[1], "Five");
assertEquals(list[2], "Six");
assertEquals(list[3], "One");
assertEquals(list[4], "Four");
assertEquals(list[5], "Two");
}
public static int compareFrom2(String a, String b) {
return a.substring(1).compareTo(b.substring(1));
}
}