Skip to content

Commit faae33e

Browse files
committed
add: full test coverage for MeosException base class
1 parent 3adcdf8 commit faae33e

2 files changed

Lines changed: 144 additions & 6 deletions

File tree

src/main/java/examples/N01_ErrorHandlingDemo.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public static void main(String[] args) {
4949
int total = 0;
5050

5151
System.out.println(BOLD + "\n╔══════════════════════════════════════════════╗");
52-
System.out.println( "║ JMEOS Error Handling Demo ║");
52+
System.out.println( "║ JMEOS - Error Handling Demo ║");
5353
System.out.println( "╚══════════════════════════════════════════════╝" + RESET);
5454

5555
//passed += test1_TextInputError() ? 1 : 0; total++;
@@ -145,7 +145,7 @@ private static boolean test3_InvalidArgValueError_divZero() {
145145
try {
146146
TFloatInst sog = new TFloatInst("12.5@2024-06-01 08:00:00+00");
147147
Pointer result = functions.div_tfloat_float(sog.getInner(), 0.0);
148-
System.out.println(RED + " ✗ No exception raised pointer: " + result + RESET);
148+
System.out.println(RED + " ✗ No exception raised - pointer: " + result + RESET);
149149
return false;
150150
} catch (MeosDivisionByZeroError e) {
151151
printCaught(e);
@@ -183,7 +183,7 @@ private static boolean test4_MfJsonInputError() {
183183
"{\"type\":\"MovingPoint\",\"coordinates\":[[1.0,2.0"; // cut off
184184
try {
185185
Pointer traj = functions.tgeompoint_from_mfjson(truncatedMfJson);
186-
System.out.println(RED + " ✗ No exception raised pointer: " + traj + RESET);
186+
System.out.println(RED + " ✗ No exception raised - pointer: " + traj + RESET);
187187
return false;
188188
} catch (MeosMfJsonInputError e) {
189189
printCaught(e);
@@ -206,7 +206,7 @@ private static boolean test5_WkbInputError() {
206206
String corruptHexWkb = "DEADBEEFCAFE0123456789ABCDEF";
207207
try {
208208
Pointer temp = functions.temporal_from_hexwkb(corruptHexWkb);
209-
System.out.println(RED + " ✗ No exception raised pointer: " + temp + RESET);
209+
System.out.println(RED + " ✗ No exception raised - pointer: " + temp + RESET);
210210
return false;
211211
} catch (MeosWkbInputError e) {
212212
printCaught(e);
@@ -231,7 +231,7 @@ private static boolean test6_InternalTypeError() {
231231
try {
232232
// Missing ')' before '@': MEOS cannot form a valid geometry object.
233233
TGeomPointInst inst = new TGeomPointInst("POINT(181.0 91.0@not-a-date");
234-
System.out.println(RED + " ✗ No exception raised got: " + inst + RESET);
234+
System.out.println(RED + " ✗ No exception raised - got: " + inst + RESET);
235235
return false;
236236
} catch (MeosInternalTypeError e) {
237237
printCaught(e);
@@ -279,7 +279,7 @@ private static boolean test7_TextInputError() {
279279
*/
280280
private static boolean test8_ValidCase() {
281281
printHeader(8, "Valid case",
282-
"Well-formed AIS TGeomPointInst no exception expected");
282+
"Well-formed AIS TGeomPointInst - no exception expected");
283283
try {
284284
TGeomPointInst inst = new TGeomPointInst(
285285
"SRID=4326;POINT(4.3517 50.8503)@2024-06-01 08:00:00+00");
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package functions;
2+
3+
import org.junit.jupiter.api.DisplayName;
4+
import org.junit.jupiter.api.Test;
5+
import org.junit.jupiter.api.extension.ExtendWith;
6+
import utils.TestLogger;
7+
8+
import static org.junit.jupiter.api.Assertions.*;
9+
10+
/**
11+
* Tests for {@link MeosException}, the base class of the JMEOS exception hierarchy.
12+
*
13+
* Covers:
14+
* - Constructor: code and message are stored correctly
15+
* - getCode() and getMessage() return the right values
16+
* - toString() follows the format: "ClassName (code): message"
17+
* - Is a RuntimeException
18+
* - Edge cases: empty message, zero code
19+
*/
20+
@DisplayName("MeosException - base class")
21+
@ExtendWith(TestLogger.class)
22+
class MeosExceptionTest {
23+
24+
// Construction
25+
26+
@Test
27+
@DisplayName("getCode() returns the code passed to constructor")
28+
void getCodeReturnsConstructorValue() {
29+
MeosException ex = new MeosException("msg", 42);
30+
assertEquals(42, ex.getCode());
31+
}
32+
33+
@Test
34+
@DisplayName("getMessage() returns the message passed to constructor")
35+
void getMessageReturnsConstructorValue() {
36+
MeosException ex = new MeosException("something failed", 1);
37+
assertEquals("something failed", ex.getMessage());
38+
}
39+
40+
@Test
41+
@DisplayName("code 0 is accepted")
42+
void codeZeroIsAccepted() {
43+
MeosException ex = new MeosException("no error", 0);
44+
assertEquals(0, ex.getCode());
45+
}
46+
47+
@Test
48+
@DisplayName("empty message is accepted")
49+
void emptyMessageIsAccepted() {
50+
MeosException ex = new MeosException("", 5);
51+
assertEquals("", ex.getMessage());
52+
}
53+
54+
@Test
55+
@DisplayName("negative code is accepted")
56+
void negativeCodeIsAccepted() {
57+
MeosException ex = new MeosException("msg", -1);
58+
assertEquals(-1, ex.getCode());
59+
}
60+
61+
@Test
62+
@DisplayName("Integer.MAX_VALUE is accepted")
63+
void integerMaxValueIsAccepted() {
64+
MeosException ex = new MeosException("msg", Integer.MAX_VALUE);
65+
assertEquals(Integer.MAX_VALUE, ex.getCode());
66+
}
67+
68+
@Test
69+
@DisplayName("Long.MAX_VALUE is not consistent")
70+
void longMaxValueIsNotConsistent() {
71+
MeosException ex = new MeosException("msg", (int) Long.MAX_VALUE);
72+
assertNotEquals(Long.MAX_VALUE, ex.getCode());
73+
}
74+
75+
// toString
76+
77+
@Test
78+
@DisplayName("toString() follows 'ClassName (code): message' format")
79+
void toStringFormat() {
80+
MeosException ex = new MeosException("something went wrong", 99);
81+
assertEquals("MeosException (99): something went wrong", ex.toString());
82+
}
83+
84+
@Test
85+
@DisplayName("toString() includes the code even when message is empty")
86+
void toStringWithEmptyMessage() {
87+
MeosException ex = new MeosException("", 7);
88+
assertEquals("MeosException (7): ", ex.toString());
89+
}
90+
91+
@Test
92+
@DisplayName("toString() reflects the concrete subclass name, not MeosException")
93+
void toStringUsesConcreteClassName() {
94+
MeosException sub = new MeosInternalError("internal failure", 1);
95+
assertTrue(sub.toString().startsWith("MeosInternalError"),
96+
"toString() must use the concrete class name: " + sub.toString());
97+
}
98+
99+
// Type hierarchy
100+
101+
@Test
102+
@DisplayName("is a RuntimeException (unchecked)")
103+
void isRuntimeException() {
104+
assertInstanceOf(RuntimeException.class, new MeosException("x", 0));
105+
}
106+
107+
@Test
108+
@DisplayName("is an Exception")
109+
void isException() {
110+
assertInstanceOf(Exception.class, new MeosException("x", 0));
111+
}
112+
113+
@Test
114+
@DisplayName("is a Throwable")
115+
void isThrowable() {
116+
assertInstanceOf(Throwable.class, new MeosException("x", 0));
117+
}
118+
119+
// Throw and catch
120+
121+
@Test
122+
@DisplayName("can be thrown and caught as MeosException")
123+
void canBeThrownAndCaught() {
124+
MeosException caught = assertThrows(MeosException.class, () -> {
125+
throw new MeosException("thrown", 10);
126+
});
127+
assertEquals(10, caught.getCode());
128+
assertEquals("thrown", caught.getMessage());
129+
}
130+
131+
@Test
132+
@DisplayName("can be thrown and caught as RuntimeException")
133+
void canBeCaughtAsRuntimeException() {
134+
assertThrows(RuntimeException.class, () -> {
135+
throw new MeosException("thrown", 10);
136+
});
137+
}
138+
}

0 commit comments

Comments
 (0)