package org.jmlspecs.openjmltest.testcases; import java.util.Collection; import org.jmlspecs.openjmltest.EscBase; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.ParameterizedWithNames; import org.junit.runners.Parameterized.Parameters; /** This class of JUnit tests checks various uses of generic types. * @author David R. Cok * */ @RunWith(ParameterizedWithNames.class) public class escgeneric extends EscBase { public escgeneric(String options, String solver) { super(options,solver); } @Parameters static public Collection<String[]> parameters() { return minQuantAndSolvers(solvers); } @Override public void setUp() throws Exception { //print = true; //noCollectDiagnostics = true; super.setUp(); main.addOptions("-nullableByDefault"); // Because the tests were written this way //JmlEsc.escdebug = false; main.addOptions("-timeout=30"); main.addOptions("-jmltesting"); } @Test public void testConstructor() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void mx(Integer i) {\n" +" Object oo = new TestG<Integer>(i);\n" +" }\n" +" public void ma(Object o) {\n" +" Object oo = new TestG<Object>(o);\n" +" }\n" +"}\n" +"class TestG<E> {\n" +" //@ requires \\type(E) != \\type(Integer) ;\n" +" public TestG(E i) {}\n" +"}" ,"/tt/TestJava.java:4: warning: The prover cannot establish an assertion (Precondition) in method mx",17 ,"/tt/TestJava.java:11: warning: Associated declaration",7 ); } /** Tests that we can reason about the result of \\typeof */ @Test public void testTypeOf() { main.addOptions("-checkFeasibility=all"); helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void m(Integer i) {\n" +" //@ assert \\typeof(this) <: \\type(TestJava);\n" +" }\n" +" public void ma(Object o) {\n" +" //@ assume \\typeof(this) == \\type(Object);\n" +" //@ assert false;\n" // should not trigger +" }\n" +" public void mb(Object o) {\n" +" //@ assert \\typeof(this) == \\type(Object);\n" +" }\n" +"}\n" ,"/tt/TestJava.java:7: warning: There is no feasible path to program point after explicit assume statement in method tt.TestJava.ma(java.lang.Object)",9 ,"/tt/TestJava.java:8: warning: There is no feasible path to program point before explicit assert statement in method tt.TestJava.ma(java.lang.Object)",9 ,"/tt/TestJava.java:6: warning: There is no feasible path to program point at program exit in method tt.TestJava.ma(java.lang.Object)",15 ,"/tt/TestJava.java:11: warning: The prover cannot establish an assertion (Assert) in method mb",9 ); } @Test public void testGenericType() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava<T> extends B<T> { \n" +" public void ma(T i) {\n" +" }\n" +"}\n" +"class A<T> extends TestJava<B<T>> { \n" +" public void mb(T i) {\n" +" }\n" +"}\n" +"class B<E> {}\n" +"class C<F> extends java.util.LinkedList<B<F>> {}\n" ); } @Test public void testGenericType2() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava<T extends B> { \n" +" public void m(T i) {\n" +" //@ assume i != null;\n" +" //@ assert i instanceof Object;\n" +" //@ assert \\typeof(i) <: \\type(Object);\n" // Line 6 +" //@ assert \\erasure(\\typeof(i)) <: \\erasure(\\type(Object));\n" +" //@ assert \\typeof(i) <: \\type(T);\n" +" //@ assert i instanceof B;\n" +" //@ assert \\erasure(\\typeof(i)) <: \\erasure(\\type(B));\n" +" //@ assert \\typeof(i) <: \\type(B);\n" // Line 11 +" //@ assert \\erasure(\\typeof(i)) <: \\erasure(\\type(C));\n" // false +" //@ assert \\typeof(i) <: \\type(C);\n" // false +" //@ assert \\type(T) <: \\type(B);\n" // true +" //@ assert \\type(T) <: \\type(C);\n" // false +" }\n" +" public TestJava() {}\n" +"}\n" +"class B {}\n" +"class C extends TestJava<B> {}\n" ,anyorder( seq("/tt/TestJava.java:12: warning: The prover cannot establish an assertion (Assert) in method m",9) ,seq("/tt/TestJava.java:13: warning: The prover cannot establish an assertion (Assert) in method m",9) ,seq("/tt/TestJava.java:15: warning: The prover cannot establish an assertion (Assert) in method m",9) ) ); } @Test public void testGenericType1() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava<T extends B> { \n" +" public void m(Integer i) {\n" +" //@ assert Object.class == java.lang.Object.class;\n" +" //@ assert \\type(TestJava<Integer>) != \\type(Object);\n" +" //@ assert \\type(TestJava<Integer>) != \\type(TestJava<Object>);\n" +" }\n" +" public void mz(Object o) {\n" +" //@ assert Object.class == \\erasure(\\type(T));\n" // NO +" }\n" +" public void ma(Object o) {\n" +" //@ assert \\type(TestJava<Integer>) == \\type(TestJava<T>);\n" // NO +" }\n" +" public void mb(Object o) {\n" +" //@ assert \\typeof(this) == \\type(Object);\n" // NO +" }\n" +" public void mc(Object o) {\n" +" //@ assert \\type(TestJava<Integer>) == \\type(TestJava<Object>);\n" // NO +" }\n" +" public void mz1(Object o) {\n" +" //@ assert Object.class != \\erasure(\\type(T));\n" // OK because T extends B so can't be Object +" }\n" +" public TestJava() {}\n" +"}\n" +"class B {}\n" +"class C {}\n" ,"/tt/TestJava.java:9: warning: The prover cannot establish an assertion (Assert) in method mz",9 ,"/tt/TestJava.java:12: warning: The prover cannot establish an assertion (Assert) in method ma",9 ,"/tt/TestJava.java:15: warning: The prover cannot establish an assertion (Assert) in method mb",9 ,"/tt/TestJava.java:18: warning: The prover cannot establish an assertion (Assert) in method mc",9 ); } @Test public void testStatic() { main.addOptions("-show"); helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void ma(Integer i) {\n" +" TestG.<Integer>mm(i);\n" +" }\n" +" public void mb(Object o) {\n" +" TestG.<Object>mm(o);\n" +" }\n" +"}\n" +"class TestG {\n" +" //@ requires \\type(E) != \\type(Integer) ;\n" +" public static <E> void mm(E t) {}\n" +"}" ,"/tt/TestJava.java:4: warning: The prover cannot establish an assertion (Precondition) in method ma",22 ,"/tt/TestJava.java:11: warning: Associated declaration",7 ); } @Test public void testStaticB() { //main.addOptions("-show","-method=mb"); helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void ma(Integer i) {\n" +" TestG.mm(i);\n" +" }\n" +" public void mb(Object o) {\n" +" TestG.mm(o);\n" +" }\n" +"}\n" +"class TestG {\n" +" //@ requires \\type(E) != \\type(Integer) ;\n" +" public static <E> void mm(E t) {}\n" +"}" ,"/tt/TestJava.java:4: warning: The prover cannot establish an assertion (Precondition) in method ma",13 ,"/tt/TestJava.java:11: warning: Associated declaration",7 ); } @Test public void testStatic2() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void ma(Integer i) {\n" +" TestG.<Integer>mm(i);\n" +" }\n" +" public void mb(Object o) {\n" +" TestG.<Object>mm(o);\n" +" }\n" +"}\n" +"class TestG {\n" +" //@ requires \\type(E) == \\type(Integer) ;\n" +" public static <E> void mm(E t) {}\n" +"}" ,"/tt/TestJava.java:7: warning: The prover cannot establish an assertion (Precondition) in method mb",21 ,"/tt/TestJava.java:11: warning: Associated declaration",7 ); } @Test public void testStatic2B() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void ma(Integer i) {\n" +" TestG.mm(i);\n" +" }\n" +" public void mb(Object o) {\n" +" TestG.mm(o);\n" +" }\n" +"}\n" +"class TestG {\n" +" //@ requires \\type(E) == \\type(Integer) ;\n" +" public static <E> void mm(E t) {}\n" +"}" ,"/tt/TestJava.java:7: warning: The prover cannot establish an assertion (Precondition) in method mb",13 ,"/tt/TestJava.java:11: warning: Associated declaration",7 ); } @Test public void testTypeParameter() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void ma(/*@ non_null*/ TestG<Integer> i, Integer j) {\n" +" i.mm(j);\n" +" }\n" +" public void mb(/*@ non_null*/ TestG<Object> i, Object j) {\n" +" i.mm(j);\n" +" }\n" +"}\n" +"class TestG<E> {\n" +" //@ requires \\type(E) != \\type(Integer);\n" +" public void mm(E t) {}\n" +"}\n" ,"/tt/TestJava.java:4: warning: The prover cannot establish an assertion (Precondition) in method ma",9 ,"/tt/TestJava.java:11: warning: Associated declaration",9 ); } @Test public void testTypeParameter2() { helpTCX("tt.TestJava","package tt; \n" +"public class TestJava { \n" +" public void ma(/*@ non_null*/TestG<Integer>.TestH i, Integer j) {\n" +" i.mm(j);\n" +" }\n" +" public void mb(/*@ non_null*/TestG<Object>.TestH i, Object j) {\n" +" i.mm(j);\n" +" }\n" +" public void mc(/*@ non_null*/TestG<String>.TestH i, String j) {\n" +" i.mm(j);\n" +" }\n" +"}\n" +"class TestG<E> {\n" +" class TestH {\n" +" //@ requires \\type(E) != \\type(Integer);\n" +" public void mm(E t) {}\n" +" }\n" +"}\n" ,"/tt/TestJava.java:4: warning: The prover cannot establish an assertion (Precondition) in method ma",9 ,"/tt/TestJava.java:15: warning: Associated declaration",9 ); } @Test public void testUnboxing() { main.addOptions("-method=m"); helpTCX("tt.TestJava"," class A { void m(/*@non_null*/ Integer ooo) { \n " +"int sum = 0; \n" +"{ /*@ assume ooo >= 0; */ sum += ooo; } \n" +"//@ assert sum >= 0; \n" +"}}" ); } @Test public void testForEach3() { helpTCX("tt.TestJava"," class A { void m(/*@non_null*/ java.util.List<Integer> list) { \n " +"int sum = 0; \n" +"//@ loop_invariant sum >= 0; \n" +"for (Integer o: list) { /*@ assume o != null && o >= 0; */ sum += o; } \n" +"//@ assert sum >= 0; \n" +"}}" ); } @Test public void testForEach3a() { helpTCX("tt.TestJava"," class A { void m(/*@non_null*/ java.util.List<Integer> list) { \n " +"int sum = 0; \n" +"//@ loop_invariant sum >= 0; \n" +"for (int o: list) { /*@ assume o >= 0; */ sum += o; } \n" +"//@ assert sum >= 0; \n" +"}}" ,"/tt/TestJava.java:4: warning: The prover cannot establish an assertion (PossiblyNullUnbox) in method m",13 ); } @Test public void testForEach3bad() { helpTCX("tt.TestJava"," class A { void m(/*@non_null*/ java.util.List<Integer> list) { \n " +"int sum = 0; \n" +"//@ loop_invariant sum >= 0; \n" +"for (int o: list) { /*@ assume o >= 0; */ sum += o; } \n" +"//@ assert sum > 0; \n" +"}}" ,anyorder( seq("/tt/TestJava.java:5: warning: The prover cannot establish an assertion (Assert) in method m",5) ,seq("/tt/TestJava.java:4: warning: The prover cannot establish an assertion (PossiblyNullUnbox) in method m",13) ) ); } @Test public void testElemType() { helpTCX("tt.TestJava"," class A { void m(/*@ non_null */ char[] a) { \n" +"//@ assert \\elemtype(\\typeof(a)) == \\type(char); \n" +"}}" ); } @Test public void testElemType2() { helpTCX("tt.TestJava"," class A { void m(/*@ non_null */ char[] a) { \n" +"//@ assert \\elemtype(\\typeof(a)) == \\type(int); \n" +"}}" ,"/tt/TestJava.java:2: warning: The prover cannot establish an assertion (Assert) in method m",5 ); } }