Skip to content

Commit fc3fbfe

Browse files
Refactored the old testing class for records (#519)
* Refactored the old testing class for records and implemented separate classes for each test scenario. Some tests are expected to fail for now as full support for records is not yet implemented. * Removed TODOs. we can add it later
1 parent 80c9660 commit fc3fbfe

File tree

6 files changed

+509
-53
lines changed

6 files changed

+509
-53
lines changed

src/tests/java17/RecordFeatureTest.java

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package java17.records;
2+
3+
import gov.nasa.jpf.util.test.TestJPF;
4+
import org.junit.Test;
5+
import java.lang.annotation.*;
6+
7+
8+
public class AnnotatedRecordTest extends TestJPF {
9+
10+
@Retention(RetentionPolicy.RUNTIME)
11+
@Target({ElementType.TYPE, ElementType.RECORD_COMPONENT, ElementType.METHOD})
12+
public @interface TestAnnotation {
13+
String value() default "";
14+
}
15+
16+
@Retention(RetentionPolicy.RUNTIME)
17+
@Target({ElementType.RECORD_COMPONENT})
18+
public @interface Field {
19+
String name() default "";
20+
boolean required() default false;
21+
}
22+
23+
@TestAnnotation("Record class annotation")
24+
record Person(
25+
@Field(name = "firstName", required = true)
26+
String firstName,
27+
28+
@Field(name = "lastName", required = true)
29+
String lastName,
30+
31+
@Field(name = "age")
32+
int age
33+
) {
34+
@TestAnnotation("Custom method annotation")
35+
public String fullName() {
36+
return firstName + " " + lastName;
37+
}
38+
}
39+
40+
@Test
41+
public void testRecordAnnotations() {
42+
if (verifyNoPropertyViolation()) {
43+
//class-level annotation
44+
TestAnnotation classAnnotation = Person.class.getAnnotation(TestAnnotation.class);
45+
assertNotNull(classAnnotation);
46+
assertEquals("Record class annotation", classAnnotation.value());
47+
}
48+
}
49+
50+
@Test
51+
public void testRecordMethodAnnotations() {
52+
if (verifyNoPropertyViolation()) {
53+
try {
54+
java.lang.reflect.Method fullNameMethod = Person.class.getMethod("fullName");
55+
TestAnnotation methodAnnotation = fullNameMethod.getAnnotation(TestAnnotation.class);
56+
assertNotNull(methodAnnotation);
57+
assertEquals("Custom method annotation", methodAnnotation.value());
58+
} catch (Exception e) {
59+
fail("Reflection on record method failed: " + e.getMessage());
60+
}
61+
}
62+
}
63+
64+
@Test
65+
public void testAnnotatedRecordBehavior() {
66+
if (verifyNoPropertyViolation()) {
67+
Person person = new Person("John", "Doe", 30);
68+
69+
// Basic functionality should still work
70+
assertEquals("John", person.firstName());
71+
assertEquals("Doe", person.lastName());
72+
assertEquals(30, person.age());
73+
assertEquals("John Doe", person.fullName());
74+
}
75+
}
76+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package java17.records;
2+
3+
import gov.nasa.jpf.util.test.TestJPF;
4+
import org.junit.Test;
5+
6+
public class BasicRecordTest extends TestJPF {
7+
8+
record Point(int x, int y) {}
9+
10+
record Temperature(double celsius) {
11+
public Temperature {
12+
if (celsius < -273.15) {
13+
throw new IllegalArgumentException("Temperature below absolute zero");
14+
}
15+
}
16+
}
17+
18+
record Rectangle(double width, double height) {
19+
public double area() {
20+
return width * height;
21+
}
22+
23+
public double perimeter() {
24+
return 2 * (width + height);
25+
}
26+
}
27+
28+
@Test
29+
public void testRecordCreation() {
30+
if (verifyNoPropertyViolation()) {
31+
Point p = new Point(10, 20);
32+
assertNotNull(p);
33+
}
34+
}
35+
36+
@Test
37+
public void testRecordAccessors() {
38+
if (verifyNoPropertyViolation()) {
39+
Point p = new Point(10, 20);
40+
// Test accessor methods
41+
assertEquals(10, p.x());
42+
assertEquals(20, p.y());
43+
}
44+
}
45+
46+
@Test
47+
public void testRecordDirectFieldAccess() {
48+
if (verifyNoPropertyViolation()) {
49+
// This should NOT work if JPF properly enforces record encapsulation
50+
// Field access should fail at compile time, but currently doesn't in JPF
51+
Point p = new Point(10, 20);
52+
try {
53+
// using reflection to test access, as direct access would fail compilation in correct Java
54+
java.lang.reflect.Field field = p.getClass().getDeclaredField("x");
55+
field.setAccessible(true);
56+
int value = (int) field.get(p);
57+
assertEquals(10, value);
58+
59+
try {
60+
field.set(p, 30);
61+
fail("Should not be able to modify final field");
62+
} catch (IllegalAccessException e) {
63+
// expected
64+
}
65+
} catch (Exception e) {
66+
// expected if JPF correctly implements record field access -> will do later
67+
assertTrue(e instanceof IllegalAccessException ||
68+
e instanceof NoSuchFieldException);
69+
}
70+
}
71+
}
72+
73+
@Test
74+
public void testRecordConstructorValidation() {
75+
if (verifyNoPropertyViolation()) {
76+
Temperature t1 = new Temperature(25.0);
77+
assertEquals(25.0, t1.celsius(), 0.001);
78+
79+
// Invalid temperature (should throw exception)
80+
try {
81+
Temperature t2 = new Temperature(-300.0);
82+
fail("Should have thrown IllegalArgumentException");
83+
} catch (IllegalArgumentException e) {
84+
// expected
85+
}
86+
}
87+
}
88+
89+
@Test
90+
public void testRecordCustomMethods() {
91+
if (verifyNoPropertyViolation()) {
92+
Rectangle r = new Rectangle(5.0, 10.0);
93+
assertEquals(50.0, r.area(), 0.001);
94+
assertEquals(30.0, r.perimeter(), 0.001);
95+
}
96+
}
97+
98+
@Test
99+
public void testRecordToString() {
100+
if (verifyNoPropertyViolation()) {
101+
Point p = new Point(10, 20);
102+
assertEquals("Point[x=10, y=20]", p.toString());
103+
}
104+
}
105+
}
106+
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package java17.records;
2+
3+
import gov.nasa.jpf.util.test.TestJPF;
4+
import org.junit.Test;
5+
import java.util.List;
6+
import java.util.ArrayList;
7+
import java.util.Arrays;
8+
9+
public class GenericRecordTest extends TestJPF {
10+
11+
record Pair<T, U>(T first, U second) {}
12+
13+
record Box<T extends Comparable<T>>(T value) {
14+
public boolean isGreaterThan(Box<T> other) {
15+
return this.value.compareTo(other.value) > 0;
16+
}
17+
}
18+
19+
// record with collection type
20+
record Collection<T>(List<T> items) {
21+
public Collection<T> add(T item) {
22+
List<T> newList = new ArrayList<>(items);
23+
newList.add(item);
24+
return new Collection<>(newList);
25+
}
26+
27+
public int size() {
28+
return items.size();
29+
}
30+
}
31+
32+
@Test
33+
public void testGenericRecordCreation() {
34+
if (verifyNoPropertyViolation()) {
35+
Pair<String, Integer> p1 = new Pair<>("Hello", 42);
36+
Pair<Double, Boolean> p2 = new Pair<>(3.14, true);
37+
38+
assertEquals("Hello", p1.first());
39+
assertEquals(Integer.valueOf(42), p1.second());
40+
assertEquals(Double.valueOf(3.14), p2.first());
41+
assertEquals(Boolean.TRUE, p2.second());
42+
}
43+
}
44+
45+
@Test
46+
public void testGenericRecordWithCollections() {
47+
if (verifyNoPropertyViolation()) {
48+
Collection<String> c1 = new Collection<>(new ArrayList<>());
49+
Collection<String> c2 = c1.add("one").add("two").add("three");
50+
51+
assertEquals(0, c1.size());
52+
assertEquals(3, c2.size());
53+
assertEquals("one", c2.items().get(0));
54+
assertEquals("two", c2.items().get(1));
55+
assertEquals("three", c2.items().get(2));
56+
}
57+
}
58+
59+
@Test
60+
public void testGenericRecordEquality() {
61+
if (verifyNoPropertyViolation()) {
62+
Pair<String, Integer> p1 = new Pair<>("Hello", 42);
63+
Pair<String, Integer> p2 = new Pair<>("Hello", 42);
64+
Pair<String, Integer> p3 = new Pair<>("Hello", 43);
65+
66+
assertEquals(p1, p2);
67+
assertNotEquals(p1, p3);
68+
assertEquals(p1.hashCode(), p2.hashCode());
69+
}
70+
}
71+
72+
@Test
73+
public void testGenericRecordWithArrays() {
74+
if (verifyNoPropertyViolation()) {
75+
Pair<int[], String[]> arrayPair = new Pair<>(
76+
new int[]{1, 2, 3},
77+
new String[]{"a", "b", "c"}
78+
);
79+
80+
assertTrue(Arrays.equals(new int[]{1, 2, 3}, arrayPair.first()));
81+
assertTrue(Arrays.equals(new String[]{"a", "b", "c"}, arrayPair.second()));
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)