package org.jmlspecs.openjmltest.testcases;
import java.util.Arrays;
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;
@RunWith(ParameterizedWithNames.class)
public class escstrings extends EscBase {
public escstrings(String options, String solver) {
super(options,solver);
}
@Parameters
static public Collection<String[]> parameters() {
java.util.List<String> ss = new java.util.LinkedList<String>();
ss.addAll(solvers);
ss.remove("cvc4"); // FIXME - hangs up on CVC4 - fix the long proof times
ss.remove("yices2"); // FIXME - yices2 does not support quantifiers and so works poorly with strings
return optionsAndSolvers(minQuantOptions,ss);
}
@Override
public void setUp() throws Exception {
super.setUp();
}
/** This String declaration and assignment */
@Test
public void testSimpleString() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m1(String s) {\n"
+" String ss = s;\n"
+" //@ assert s != null;\n"
+" //@ assert s == ss;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }\n"
+"}"
);
}
/** Tests String equality */
@Test
public void testStringEquals() {
main.addOptions("-escMaxWarnings=1");
// main.addOptions("-prover=cvc4");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" String ss = s;\n"
+" /*@ nullable */ String sss = null;\n"
+" //@ assert s.equals(ss);\n"
+" //@ assert !s.equals(sss);\n"
+" //@ assert !sss.equals(ss);\n" // Null error
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:12: warning: The prover cannot establish an assertion (UndefinedNullDeReference) in method m",23
);
}
/** Tests String equality */
@Test
public void testStringEqualsNoSpecs1a() {
main.addOptions("-no-internalSpecs");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" String ss = s;\n"
+" /*@ nullable */ String sss = null;\n"
+" //@ assert s.equals(ss);\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:10: warning: The prover cannot establish an assertion (Assert) in method m",12
);
}
/** Tests String equality */
@Test
public void testStringEqualsNoSpecs1() {
main.addOptions("-no-internalSpecs");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" String ss = s;\n"
+" /*@ nullable */ String sss = null;\n"
+" boolean b = s.equals(ss); //@ assert b;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:10: warning: The prover cannot establish an assertion (Assert) in method m",38
);
}
/** Tests String equality */
@Test
public void testStringEqualsNoSpecs2() {
main.addOptions("-internalSpecs=false");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" String ss = s;\n"
+" /*@ nullable */ String sss = null;\n"
+" boolean b = !s.equals(sss); //@ assert b;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:10: warning: The prover cannot establish an assertion (Assert) in method m",40
);
}
/** Tests String equality */
@Test
public void testStringEqualsNoSpecs3() {
main.addOptions("-no-internalSpecs");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" String ss = s;\n"
+" /*@ nullable */ String sss = null;\n"
+" //@ assert !sss.equals(ss);\n" // Null error
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:10: warning: The prover cannot establish an assertion (UndefinedNullDeReference) in method m",24
);
}
/** Tests String concatenation */
@Test
public void testStringConcatNoSpecs1() {
main.addOptions("-no-internalSpecs");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" boolean b = (s + ss) != null; //@ assert b;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",42
);
}
/** Tests String concatenation */
@Test
public void testStringConcatNoSpecs1a() {
main.addOptions("-no-internalSpecs");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" //@ assert (s + ss) != null;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",12
);
}
/** Tests String concatenation */
@Test
public void testStringConcatNoSpecs2() {
main.addOptions("-no-internalSpecs");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" boolean b = (s+ss).equals(s+ss); //@ assert b;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",-45
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (PossiblyNullDeReference) in method m",26
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",-45
);
}
/** Tests String concatenation */
@Test
public void testStringConcatNoSpecs2a() {
main.addOptions("-no-internalSpecs");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" //@ assert (s+ss).equals(s+ss);\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (UndefinedNullDeReference) in method m",-25
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",12
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (UndefinedNullDeReference) in method m",-25
);
}
/** Tests String concatenation */
@Test
public void testStringConcatNoSpecs3() {
main.addOptions("-no-internalSpecs");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" boolean b = (s + ss) == (s + ss); //@ assert b;\n" // Should not hold necessarily
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",46
);
}
/** Tests String concatenation */
@Test
public void testStringConcatNoSpecs3a() {
main.addOptions("-no-internalSpecs");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" //@ assert (s + ss) == (s + ss); \n" // Should not hold necessarily
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",12
);
}
/** Tests String concatenation - whether the result in Java is non-null. */
@Test
public void testStringConcat1() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" String sss = (s + ss);\n"
+" //@ assert sss != null;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,!"yices2".equals(solver)?null: // FIXME because yices2 cannot do quantifiers
"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",12
);
}
/** Tests String concatenation - whether the result, computed in JML, is non-null*/
@Test
public void testStringConcat1a() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" //@ reachable true;\n"
+" //@ assert (s + ss) != null;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }\n"
+"}"
,!"yices2".equals(solver)?null: // because yices2 cannot do quantifiers
"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",12
);
}
/** Tests String concatenation */
@Test @Ignore // FIXME - need more semantics of concat and equals
public void testStringConcat2() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" String sss = s + ss;\n"
+" String s4 = s + ss;\n"
+" //@ assert sss.equals(s4);\n"
+" }\n"
+"}"
,!"yices2".equals(solver)?null:// FIXME because yices2 cannot do quantifiers
"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (UndefinedNullDeReference) in method m",12
);
}
/** Tests String concatenation */
@Test @Ignore // FIXME - need more semantics of concat and equals
public void testStringConcat2a() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" //@ assert (s+ss).equals(s+ss);\n"
+" }\n"
+"}"
,!"yices2".equals(solver)?null:// because yices2 cannot do quantifiers
"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (UndefinedNullDeReference) in method m",19
);
}
/** Tests String concatenation */
@Test
public void testStringConcat3() {
main.addOptions("-escMaxWarnings=1");
main.addOptions("-method=m");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" boolean b = (s + ss) == (s + ss); //@ assert b;\n" // Should not hold necessarily
+" }\n"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",46
);
}
/** Tests String concatenation */
@Test
public void testStringConcat3a() {
main.addOptions("-escMaxWarnings=1");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" //@ assert (s + ss) == (s + ss);\n" // Should not hold necessarily
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",12
);
}
/** Tests String charAt operation */
@Test @Ignore // FIXME - crashes Z3
public void testStringCharAt1q() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" //@ requires s.length() > 0; \n"
+" public void m(String s) {\n"
+" //@ assert s.charAt(0) == s.charAt(0);\n"
+" }\n"
+"}"
);
}
// FIXME - why do these two give different error messages
/** Tests String charAt operation */
@Test
public void testStringCharAt1() {
main.addOptions("-no-minQuant");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" //@ assert s.charAt(0) == s.charAt(0);\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (UndefinedCalledMethodPrecondition) in method m",27
,"$SPECS/java5/java/lang/String.jml:282: warning: Associated declaration",11
);
}
/** Tests String charAt operation */
@Test
public void testStringCharAt1mq() {
main.addOptions("-minQuant");
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" //@ assert s.charAt(0) == s.charAt(0);\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (UndefinedCalledMethodPrecondition) in method m",27
,"$SPECS/java5/java/lang/CharSequence.jml:63: warning: Associated declaration",14
);
}
/** Tests String charAt operation */
@Test
public void testStringCharAt2() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" //@ requires s.length() > 0; \n"
+" public void m(String s) {\n"
+" String ss = s;\n"
+" //@ assert s.charAt(0) == ss.charAt(0);\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
);
}
/** Tests String charAt operation */
@Test @Ignore // FIXME - crashes Z3
public void testStringCharAt3() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" //@ requires s.length() > 0;\n"
+" public void m(String s, String ss) {\n"
+" //@ assert s.charAt(0) == ss.charAt(0);\n" // should not hold since s != ss
+" }\n"
+"}"
,anyorder(
seq("/tt/TestJava.java:9: warning: The prover cannot establish an assertion (Assert) in method m",12)
,seq(seq("/tt/TestJava.java:9: warning: The prover cannot establish an assertion (UndefinedCalledMethodPrecondition) in method m",43)
,oneof(
seq("$SPECS\\java5\\java\\lang\\CharSequence.jml:63: warning: Associated declaration",14),
seq("$SPECS\\java5\\java\\lang\\String.jml:282: warning: Associated declaration",14)
)
)
)
);
}
/** Tests String charAt operation */
@Test
public void testStringCharAt3a() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" //@ requires s.length() > 0 && ss.length() > 0;\n"
+" public void m(String s, String ss) {\n"
+" //@ assert s.charAt(0) == ss.charAt(0);\n" // should not hold since s != ss
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:9: warning: The prover cannot establish an assertion (Assert) in method m",12
);
}
/** Tests String length operation */
@Test
public void testStringLength1() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" boolean b = s.length() >= 0; //@ assert b;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
);
}
/** Tests String length operation */
@Test
public void testStringLength1a() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" //@ assert s.length() >= 0;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
);
}
/** Tests String length operation */
@Test
public void testStringLength2() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" String ss = s;\n"
+" boolean b = s.length() == ss.length(); //@ assert b;\n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
);
}
/** Tests String length operation */
@Test
public void testStringLength2a() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s) {\n"
+" String ss = s;\n"
+" //@ assert s.length() == ss.length(); \n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
);
}
/** Tests String length operation */
@Test
public void testStringLength3() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" boolean b = s.length() == ss.length(); //@ assert b;\n" // should not hold
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",51
);
}
/** Tests String length operation */
@Test
public void testStringLength3a() {
helpTCX("tt.TestJava","package tt; \n"
+" import org.jmlspecs.annotation.*; \n"
+"@NonNullByDefault public class TestJava { \n"
+" public TestJava t;\n"
+" public int a;\n"
+" public static int b;\n"
+" public void m(String s, String ss) {\n"
+" //@ assert s.length() == ss.length(); \n"
+" }\n"
+" public TestJava() { t = new TestJava(); }"
+"}"
,"/tt/TestJava.java:8: warning: The prover cannot establish an assertion (Assert) in method m",12
);
}
// FIXME - also test interning
// FIXME - check charAt(i) if i 0 or >= length
}