Fixes default method resolution (#159)
[jpf-core.git] / src / tests / java8 / LambdaTest.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package java8;
19
20 import gov.nasa.jpf.util.test.TestJPF;
21
22 import java.util.function.Supplier;
23
24 import org.junit.Test;
25
26 /**
27  * @author Nastaran Shafiei <nastaran.shafiei@gmail.com>
28  */
29 public class LambdaTest extends TestJPF{
30   
31   static class EnforcedException extends RuntimeException {
32     // nothing in here
33   }
34   
35   @Test
36   public void testFuncObjAssignment() {
37     if(verifyUnhandledException(EnforcedException.class.getName())) {
38       
39       Runnable r = () -> {
40         throw new EnforcedException(); // make sure it gets here
41         };
42       
43       assertTrue(r != null);
44       
45       (new Thread(r)).start();
46     }
47   }
48   
49   public interface FI1 {
50     void sam();
51   }
52   
53   public interface FI2 extends FI1 {
54     @Override
55         public String toString();
56   }
57   
58   @Test
59   public void testSyntheticFuncObjClass() {
60     if (verifyNoPropertyViolation()) {
61       
62       FI2 fi = () -> {
63         return;
64         };
65       
66       assertTrue(fi != null);
67       
68       Class cls = fi.getClass();
69       
70       assertEquals(cls.getInterfaces().length, 1);
71       
72       assertEquals(cls.getDeclaredMethods().length, 1);
73             
74       assertSame(cls.getInterfaces()[0], FI2.class);
75       
76       assertSame(cls.getSuperclass(), Object.class);
77     }
78   }
79   
80   public interface FI3 {
81     public String ret();
82   }
83   
84   @Test
85   public void testSAMReturn() {
86     if (verifyNoPropertyViolation()) {
87       FI3 rt = () -> {
88         return "something"; 
89         };
90       
91       assertEquals(rt.ret(),"something"); 
92     }
93   }
94   
95   public class C {
96     int x = 1;
97   }
98   
99   public interface IncX {
100     public int incX(C o);
101   }
102   
103   @Test
104   public void testLambdaArgument() {
105     if (verifyNoPropertyViolation()) {
106       IncX fo = (arg) -> {
107         return ++arg.x;
108         };
109       
110       C o = new C();
111       
112       assertEquals(fo.incX(o),2);
113       assertEquals(fo.incX(o),3);
114     }
115   }
116   
117   static Integer io = new Integer(20);
118   
119   @Test
120   public void testClosure() {
121     if (verifyNoPropertyViolation()) {
122       int i = 10;
123       
124       FI1 fi = () -> {
125         assertSame(i,10);
126         assertSame(io.intValue(), 20);
127       };
128       
129       fi.sam();
130     }
131   }
132   
133   static void method(FI1 fi) {
134     fi.sam();
135   }
136   
137   @Test
138   public void testPassingToMethod() {
139     if (verifyUnhandledException(EnforcedException.class.getName())) {
140       int i = 10;
141       
142       method(() -> {
143         assertSame(i,10);
144         assertSame(io.intValue(), 20);
145         throw new EnforcedException();
146       });
147     }
148   }
149   
150   // When invokedynamic executes for the first time, it creates a new function object.
151   // Re-executing the same bytecode returns the existing function object.
152   @Test
153   public void testRepeatInvokedynamic() {
154     if (verifyNoPropertyViolation()) {
155       int i = 10;
156       FI1 f1, f2 = null; 
157       
158       for(int j=0; j<2; j++) {
159         f1 = () -> {
160           System.out.println("hello world!");
161         };
162         
163         if(j==1) {
164           assertTrue(f1!=null);
165           assertSame(f1,f2);
166         }
167         
168         f2 = f1;
169       }
170     }
171   }
172   
173   public static class C2 {
174     public static void throwException() {
175       throw new EnforcedException();
176     }
177   }
178   
179   @Test
180   public void testDoubleCloneOperator() {
181     if (verifyUnhandledException(EnforcedException.class.getName())) {
182       FI1 fi = C2::throwException;
183       fi.sam();
184     }
185   }
186   
187   static class A {
188     static {
189       if(true) {
190         throw new EnforcedException();
191       }
192     }
193   }
194
195   @Test
196   public void testInitDoubleCloneOperator() {
197     if (verifyUnhandledException(EnforcedException.class.getName())) {
198       new Thread(A::new).start();
199     }
200   }
201   
202   static class D {
203     static final B b = new B();
204   }
205   
206   static class B {
207     static final D a = new D();
208   }
209   
210   @Test
211   public void testClinitDeadlock() {
212     if(verifyDeadlock()) {
213       new Thread(D::new).start();
214       new B();
215     }
216   }
217   
218   @Test
219   public void testLambdaTypeName() {
220     if(verifyNoPropertyViolation()) {
221       Runnable r1 = (A::new);
222       Runnable r2 = (B::new);
223       
224       assertFalse(r1.getClass().getName().equals(r2.getClass().getName()));
225     }
226   }
227   
228   public interface FI {
229     default boolean returnTrue() {
230       return true;
231     }
232     @Override
233     public String toString();
234     public String toString(int i);
235   }
236   
237   @Test
238   public void testLambdaWithOverridenDefaultMethods() {
239     if(verifyNoPropertyViolation()) {
240       FI fi = (int i) -> {return "output:"+ i;};
241       assertEquals(fi.toString(10),"output:10");
242     }
243   }
244   
245   public interface FI4 {
246   }
247   
248   public interface FI5 extends FI {
249     @Override
250     public boolean equals(Object obj);
251   }
252   
253   @Test
254   public void testLambdaWithMultipleSuperInterfaces() {
255     if(verifyNoPropertyViolation()) {
256       FI5 fi = (int i) -> {return "output:"+ i;};
257       assertEquals(fi.toString(10),"output:10");
258     }
259   }
260   
261   public static class Foo {
262     
263     Integer i = 0;
264     static Integer j = 1;
265     
266     
267     public FI1 invokSam(FI1 fi) {
268       fi.sam();
269       return fi;
270     }
271     
272     
273     public FI1 withFreeVar() {
274       return invokSam(()->{Foo foo = this;});
275     }
276     
277     public static FI1 withStatic(Foo foo) {
278       return foo.invokSam(()->{Foo.j = 10;});
279     }
280   }
281   
282   @Test
283   public void testFreeVariables() {
284     if(verifyNoPropertyViolation()) {
285       
286       Foo foo = new Foo();
287       
288       FI1 fi1 = foo.withFreeVar();  
289       FI1 fi2 = foo.withFreeVar();
290       
291       assertFalse(fi1==fi2);
292      
293       fi1 = Foo.withStatic(foo);
294       fi2 = Foo.withStatic(foo);
295       
296       assertSame(fi1,fi2);
297     }
298   }
299   
300   @Test
301   public void testNullCaptureValues() {
302     if(verifyNoPropertyViolation()) {
303       Supplier<String> provider = getStringProvider(null);
304       assertEquals(provider.get(), "It was null");
305     }
306   }
307
308   private Supplier<String> getStringProvider(String object) {
309     return () -> object == null ? "It was null" : object;
310   }
311 }