/******************************************************************************* * 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.lambda; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.Callable; import junit.framework.TestCase; public class LambdaTest 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= LambdaTest::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"; } }