Skip to content

Commit 49d54da

Browse files
Add more complex examples
1 parent dcc7e8c commit 49d54da

13 files changed

Lines changed: 407 additions & 3 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package testSuite.classes.bytebuf_correct;
2+
3+
// SO 48582520 — UnsupportedOperationException at ByteBuffer.array()
4+
// https://stackoverflow.com/questions/48582520
5+
// SO class is already self-contained pure java.nio; only added the package.
6+
import java.nio.ByteBuffer;
7+
8+
public class ByteBufTest {
9+
10+
public static final int TEST_BUFFER_SIZE = 128;
11+
12+
// private ByteBuffer mDirectBuffer;
13+
14+
public ByteBufTest() {
15+
// FIX (from accepted answer): mDirectBuffer = ByteBuffer.wrap(new byte[TEST_BUFFER_SIZE]);
16+
// or guard with: if (mDirectBuffer.hasArray()) { ... }
17+
ByteBuffer mDirectBuffer = ByteBuffer.wrap(new byte[TEST_BUFFER_SIZE]);
18+
// VIOLATION: a direct buffer is not array-backed -> array() throws
19+
// UnsupportedOperationException.
20+
byte[] buf = mDirectBuffer.array();
21+
buf[1] = 100;
22+
}
23+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package testSuite.classes.bytebuf_correct;
2+
3+
import liquidjava.specification.ExternalRefinementsFor;
4+
import liquidjava.specification.Ghost;
5+
import liquidjava.specification.Refinement;
6+
import liquidjava.specification.RefinementAlias;
7+
import liquidjava.specification.StateRefinement;
8+
import liquidjava.specification.StateSet;
9+
10+
import java.nio.ByteBuffer;
11+
import java.nio.ByteOrder;
12+
import java.nio.CharBuffer;
13+
import java.nio.ShortBuffer;
14+
import java.nio.IntBuffer;
15+
import java.nio.LongBuffer;
16+
import java.nio.FloatBuffer;
17+
import java.nio.DoubleBuffer;
18+
19+
20+
@Ghost("boolean arrayBacked")
21+
@ExternalRefinementsFor("java.nio.ByteBuffer")
22+
public interface ByteBufferRefinements {
23+
24+
// ---- Backing array access ----
25+
26+
@StateRefinement(to="_ ? arrayBacked() : !arrayBacked()")
27+
boolean hasArray();
28+
29+
@StateRefinement(from="arrayBacked()")
30+
byte[] array();
31+
32+
@StateRefinement(from="arrayBacked()")
33+
int arrayOffset();
34+
35+
@Refinement("arrayBacked(_)")
36+
ByteBuffer wrap(byte[] array, int offset, int length);
37+
38+
@Refinement("arrayBacked(_)")
39+
ByteBuffer wrap(byte[] array);
40+
41+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package testSuite.classes.bytebuf_error;
2+
3+
// SO 48582520 — UnsupportedOperationException at ByteBuffer.array()
4+
// https://stackoverflow.com/questions/48582520
5+
// SO class is already self-contained pure java.nio; only added the package.
6+
import java.nio.ByteBuffer;
7+
8+
public class ByteBufTest {
9+
10+
public static final int TEST_BUFFER_SIZE = 128;
11+
12+
// private ByteBuffer mDirectBuffer;
13+
14+
public ByteBufTest() {
15+
// FIX (from accepted answer): mDirectBuffer = ByteBuffer.wrap(new byte[TEST_BUFFER_SIZE]);
16+
// or guard with: if (mDirectBuffer.hasArray()) { ... }
17+
ByteBuffer mDirectBuffer = ByteBuffer.allocateDirect(TEST_BUFFER_SIZE);
18+
// VIOLATION: a direct buffer is not array-backed -> array() throws
19+
// UnsupportedOperationException.
20+
byte[] buf = mDirectBuffer.array(); // State Refinement Error
21+
buf[1] = 100;
22+
}
23+
24+
public void test(ByteBuffer mDirectBuffer) {
25+
printBuffer("nativeInitDirectBuffer", mDirectBuffer.array()); // State Refinement Error
26+
}
27+
28+
private void printBuffer(String tag, byte[] buffer) {
29+
StringBuffer sBuffer = new StringBuffer();
30+
for (int i = 0; i < buffer.length; i++) {
31+
sBuffer.append(buffer[i]);
32+
sBuffer.append(" ");
33+
}
34+
}
35+
36+
public static void main(String[] args) throws Exception {
37+
ByteBufTest item = new ByteBufTest();
38+
ByteBuffer mDirectBuffer = ByteBuffer.allocateDirect(128);
39+
item.test(mDirectBuffer);
40+
}
41+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package testSuite.classes.bytebuf_error;
2+
3+
import liquidjava.specification.ExternalRefinementsFor;
4+
import liquidjava.specification.Ghost;
5+
import liquidjava.specification.Refinement;
6+
import liquidjava.specification.RefinementAlias;
7+
import liquidjava.specification.StateRefinement;
8+
import liquidjava.specification.StateSet;
9+
10+
import java.nio.ByteBuffer;
11+
import java.nio.ByteOrder;
12+
import java.nio.CharBuffer;
13+
import java.nio.ShortBuffer;
14+
import java.nio.IntBuffer;
15+
import java.nio.LongBuffer;
16+
import java.nio.FloatBuffer;
17+
import java.nio.DoubleBuffer;
18+
19+
20+
@Ghost("boolean arrayBacked")
21+
@ExternalRefinementsFor("java.nio.ByteBuffer")
22+
public interface ByteBufferRefinements {
23+
24+
// ---- Backing array access ----
25+
26+
@StateRefinement(to="_ ? arrayBacked() : !arrayBacked()")
27+
boolean hasArray();
28+
29+
@StateRefinement(from="arrayBacked()")
30+
byte[] array();
31+
32+
@StateRefinement(from="arrayBacked()")
33+
int arrayOffset();
34+
35+
@Refinement("arrayBacked(_)")
36+
ByteBuffer wrap(byte[] array, int offset, int length);
37+
38+
@Refinement("arrayBacked(_)")
39+
ByteBuffer wrap(byte[] array);
40+
41+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package testSuite.classes.iterator_queue_error;
2+
3+
import liquidjava.specification.ExternalRefinementsFor;
4+
import liquidjava.specification.Refinement;
5+
import liquidjava.specification.StateRefinement;
6+
import liquidjava.specification.StateSet;
7+
8+
/**
9+
* Observer-style iteration over {@link java.util.Scanner} (an iterator-shaped JDK class):
10+
* {@code hasNext} is an informative check (no state change), and {@code next} consumes one
11+
* element, resetting state so a fresh check is required before the next consumption.
12+
*
13+
* <p>{@code java.util.Iterator} itself is an interface, and external refinements only attach to
14+
* classes — Scanner gives us the same API in a class form.
15+
*/
16+
@StateSet({"hasMore", "inNext", "notInNext"})
17+
@ExternalRefinementsFor("java.util.Iterator")
18+
public interface IteratorRefinements<N> {
19+
20+
@StateRefinement(to = "_ --> hasMore()")
21+
boolean hasNext();
22+
23+
@StateRefinement(from = "hasMore()", to = "inNext()")
24+
N next();
25+
26+
@StateRefinement(from="inNext()", to="notInNext()")
27+
void remove();
28+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package testSuite.classes.iterator_queue_error;
2+
3+
// SO 22361194 — "Iterator.remove() IllegalStateException"
4+
// https://stackoverflow.com/questions/22361194
5+
// Faithful to the question body. The asker's own (unshown) types are given
6+
// minimal stand-ins so the original structure compiles:
7+
// - the queues qev1/qev2/qcv1/qcv2 -> a small Queue exposing enqueue()/iterator()
8+
// - CInteger -> the nested class below
9+
// The asker catches UnsupportedOperationException, but iterator().remove()
10+
// before next() actually throws IllegalStateException — so the catch does NOT
11+
// fire. That mismatch is reproduced verbatim from the post.
12+
import java.util.ArrayList;
13+
import java.util.Date;
14+
import java.util.Iterator;
15+
16+
public class IteratorRemoveBeforeNext {
17+
18+
static class Queue<T> implements Iterable<T> {
19+
private final ArrayList<T> items = new ArrayList<>();
20+
void enqueue(T item) { items.add(item); }
21+
public Iterator<T> iterator() { return items.iterator(); }
22+
}
23+
24+
static class CInteger {
25+
final int value;
26+
CInteger(int value) { this.value = value; }
27+
}
28+
29+
public static void main(String[] args) {
30+
Queue<Object> qev1 = new Queue<>();
31+
Queue<Object> qev2 = new Queue<>();
32+
Queue<Object> qcv1 = new Queue<>();
33+
Queue<Object> qcv2 = new Queue<>();
34+
Object ci = new CInteger(0);
35+
36+
try {
37+
// VIOLATION: remove() before next() -> IllegalStateException
38+
// (NOT UnsupportedOperationException, so this catch does not fire).
39+
Iterator<Object> it = qev1.iterator();
40+
it.remove(); // State Refinement Error
41+
} catch (UnsupportedOperationException e) {
42+
System.out.println("Calling Iterator.remove() and throwing exception.");
43+
}
44+
45+
qev1.enqueue(ci);
46+
qev2.enqueue(ci);
47+
qcv1.enqueue(ci);
48+
qcv2.enqueue(ci);
49+
50+
for (int i = 1; i < 5; i++) {
51+
if (i % 2 == 0) {
52+
qev1.enqueue(new CInteger(i + 1));
53+
qev2.enqueue(new CInteger(i + 1));
54+
qcv1.enqueue(new CInteger(i + 1));
55+
qcv2.enqueue(new CInteger(i + 1));
56+
} else {
57+
qev1.enqueue(new Date(i * i));
58+
qev2.enqueue(new Date(i * i));
59+
qcv1.enqueue(new Date(i * i));
60+
qcv2.enqueue(new Date(i * i));
61+
}
62+
}
63+
}
64+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package testSuite.classes.resultset_forward_correct;
2+
import java.sql.PreparedStatement;
3+
import java.sql.ResultSet;
4+
5+
import liquidjava.specification.ExternalRefinementsFor;
6+
import liquidjava.specification.Refinement;
7+
8+
9+
@ExternalRefinementsFor("java.sql.Connection")
10+
public interface ConnectionRefinements {
11+
12+
// Default statements are forward-only: the produced ResultSet cannot scroll backwards.
13+
@Refinement("setBackwards(_) == false")
14+
PreparedStatement prepareStatement(String sql);
15+
16+
// Explicit type decides scrollability: only TYPE_FORWARD_ONLY forbids backward scrolling.
17+
@Refinement("resultSetType == ResultSet.TYPE_FORWARD_ONLY ? setBackwards(_) == false : setBackwards(_) == true")
18+
PreparedStatement prepareStatement(String sql, int resultSetType,
19+
int resultSetConcurrency);
20+
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package testSuite.classes.resultset_forward_correct;
2+
3+
import java.sql.ResultSet;
4+
import java.sql.SQLException;
5+
6+
import liquidjava.specification.ExternalRefinementsFor;
7+
import liquidjava.specification.Ghost;
8+
import liquidjava.specification.Refinement;
9+
import liquidjava.specification.StateRefinement;
10+
import liquidjava.specification.StateSet;
11+
12+
13+
@Ghost("boolean setBackwards")
14+
@ExternalRefinementsFor("java.sql.PreparedStatement")
15+
public interface PreparedStatementRefinements {
16+
17+
// The ResultSet inherits the statement's scrollability: backward-capable statements
18+
// yield an allowsBackward ResultSet, forward-only statements yield an onlyForward one.
19+
@Refinement("setBackwards(this) ? allowsBackward(_) : onlyForward(_)")
20+
ResultSet executeQuery();
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package testSuite.classes.resultset_forward_correct;
2+
3+
import liquidjava.specification.ExternalRefinementsFor;
4+
import liquidjava.specification.StateRefinement;
5+
import liquidjava.specification.StateSet;
6+
7+
@StateSet({"onlyForward", "allowsBackward"})
8+
@StateSet({"beforeRow", "onRow", "endRows"})
9+
10+
@ExternalRefinementsFor("java.sql.ResultSet")
11+
public interface ResultSetRefinements {
12+
13+
@StateRefinement(to = "_ ? onRow(this) : endRows(this)")
14+
boolean next();
15+
16+
@StateRefinement(from = "onRow(this)")
17+
float getFloat(String columnIndex);
18+
19+
@StateRefinement(from = "allowsBackward()")
20+
void beforeFirst();
21+
22+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package testSuite.classes.resultset_forward_correct;
2+
3+
4+
// SO 6367737 — "ResultSet: Exception: set type is TYPE_FORWARD_ONLY -- why?"
5+
// https://stackoverflow.com/questions/6367737
6+
// Counting rows by iterating, then calling rs.beforeFirst() to rewind and iterate
7+
// again. A default ResultSet is TYPE_FORWARD_ONLY, so the backward scroll throws:
8+
// java.sql.SQLException: Result set type is TYPE_FORWARD_ONLY
9+
// at ...JdbcOdbcResultSet.beforeFirst(...)
10+
// Kept as close to the question as possible; the SO lines are wrapped in a method
11+
// taking a Connection. Pure java.sql; compiles with no JDBC driver present.
12+
import java.sql.Connection;
13+
import java.sql.PreparedStatement;
14+
import java.sql.ResultSet;
15+
import java.sql.SQLException;
16+
import java.sql.Statement;
17+
18+
public class ResultSetTests {
19+
20+
int login(Connection con, String username, String password) throws SQLException {
21+
int typeID = 0;
22+
23+
PreparedStatement pstat =
24+
con.prepareStatement("select typeid from users where username=? and password=?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
25+
ResultSet rs = pstat.executeQuery();
26+
27+
rs.beforeFirst(); // State Refinement Error
28+
29+
return typeID;
30+
}
31+
32+
int login2(Connection con, String username, String password) throws SQLException {
33+
int typeID = 0;
34+
PreparedStatement pstat =
35+
con.prepareStatement("select typeid from users where username=? and password=?", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
36+
pstat.setString(1, username);
37+
pstat.setString(2, password);
38+
ResultSet rs = pstat.executeQuery();
39+
int rowCount = 0;
40+
while (rs.next()) {
41+
rowCount++;
42+
}
43+
rs.beforeFirst(); // State Refinement Error
44+
if (rowCount >= 1) {
45+
while (rs.next()) {
46+
typeID = rs.getInt(1);
47+
}
48+
}
49+
return typeID;
50+
}
51+
52+
float readAverage(Connection conn) throws SQLException {
53+
Statement parentstmt = conn.createStatement();
54+
ResultSet parentMessage =
55+
parentstmt.executeQuery("SELECT SUM(IMPORTANCE) AS IMPAVG FROM MAIL");
56+
// FIX (from accepted answer): parentMessage.next();
57+
// VIOLATION: cursor is before the first row; getFloat() with no next().
58+
if( parentMessage.next()) {
59+
float avgsum = parentMessage.getFloat("IMPAVG");
60+
return avgsum;
61+
} else {
62+
return 0.0f;
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)