-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Description
GitHub Issue: Timezone-related test failures in JsonNormalizerTest
Problem Description:
The JsonNormalizerTest in the JToon project contains 4 test cases related to time types that fail in my UTC+8 timezones because they use hardcoded expected values, while JsonNormalizer uses the system default timezone when processing SQL time types.
Affected 4 Test Cases:
dev.toonformat.jtoon.normalizer.JsonNormalizerTest$TemporalTypes.testSQLTimeStamp(JsonNormalizerTest.java:357)
dev.toonformat.jtoon.normalizer.JsonNormalizerTest$TemporalTypes.testSQLTime(JsonNormalizerTest.java:348)
dev.toonformat.jtoon.normalizer.JsonNormalizerTest$TryNormalizeTemporal.givenGregorianCalendar_whenTryNormalizeTemporal_thenIsoStringNode(JsonNormalizerTest.java:1208)
dev.toonformat.jtoon.normalizer.JsonNormalizerTest$TryNormalizeTemporal.givenCalendar_whenTryNormalizeTemporal_thenIsoStringNode(JsonNormalizerTest.java:1194)Problem Details:
Original failing test result:
#My timezone: UTC+8
#e.g. Result of run:JsonNormalizerTest$TemporalTypes.testSQLTimeStamp
Expected:1970-01-21T11:40:19.274
Actual:1970-01-21T18:40:19.274
org.opentest4j.AssertionFailedError: expected: <1970-01-21T11:40:19.274> but was: <1970-01-21T18:40:19.274>
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:158)
at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:139)
at org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:201)
at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:184)
at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:179)
at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1188)
at dev.toonformat.jtoon.normalizer.JsonNormalizerTest$TemporalTypes.testSQLTimeStamp(JsonNormalizerTest.java:357)Original failing test code:
@Test
@DisplayName("should convert java.sql.Timestamp to ISO formatted StringNode")
void testSQLTimeStamp() {
java.sql.Timestamp dateTime = new java.sql.Timestamp(1766419274);
JsonNode result = JsonNormalizer.normalize(dateTime);
assertTrue(result.isString());
assertEquals("1970-01-21T11:40:19.274", result.asString());
}
@Test
@DisplayName("should convert java.sql.Time to ISO formatted StringNode")
void testSQLTime() {
java.sql.Time time = new java.sql.Time(1766419274);
JsonNode result = JsonNormalizer.normalize(time);
assertTrue(result.isString());
assertEquals("11:40:19", result.asString());
}
@Test
@DisplayName("Given GregorianCalendar, When tryNormalizeTemporal is called, Then an ISO date StringNode is returned")
void givenGregorianCalendar_whenTryNormalizeTemporal_thenIsoStringNode() throws Exception {
// Given
GregorianCalendar input = new GregorianCalendar(2017, Calendar.FEBRUARY, 16, 20, 22, 28);
// When
Object result = invokePrivateStatic("tryNormalizeTemporal", new Class[]{Object.class}, input);
// Then
assertInstanceOf(StringNode.class, result);
assertEquals("2017-02-16T19:22:28Z", ((JsonNode) result).asString());
}
@Test
@DisplayName("Given Calendar, When tryNormalizeTemporal is called, Then an ISO date StringNode is returned")
void givenCalendar_whenTryNormalizeTemporal_thenIsoStringNode() throws Exception {
// Given
Calendar input = Calendar.getInstance();
input.set(2017, Calendar.FEBRUARY, 16, 20, 22, 28);
input.set(Calendar.MILLISECOND, 0);
// When
Object result = invokePrivateStatic("tryNormalizeTemporal", new Class[]{Object.class}, input);
// Then
assertInstanceOf(StringNode.class, result);
assertEquals("2017-02-16T19:22:28Z", ((JsonNode) result).asString());
}Root Cause:
The JsonNormalizer's [tryNormalizeTemporal] method uses system default timezone for SQL time types:
} else if (value instanceof java.sql.Timestamp timestamp) {
return formatTemporal(timestamp.toLocalDateTime(), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
} else if (value instanceof java.sql.Date date) {
return formatTemporal(date.toLocalDate(), DateTimeFormatter.ISO_LOCAL_DATE);
} else if (value instanceof java.sql.Time time) {
return formatTemporal(time.toLocalTime(), DateTimeFormatter.ISO_LOCAL_TIME);
} else if (value instanceof Date date) {
return StringNode.valueOf(LocalDate.ofInstant(date.toInstant(), ZoneId.systemDefault()).toString());
}Solution:
Modify the test cases to calculate expected values using the same timezone logic as the implementation, instead of using hardcoded UTC values.
Fix Applied:
All 4 test cases now calculate expected values using the same timezone-aware logic as the implementation, ensuring tests pass in any timezone.
Code Changes:
The tests use dynamic expected values:
@Test
@DisplayName("should convert java.sql.Timestamp to ISO formatted StringNode")
void testSQLTimeStamp() {
java.sql.Timestamp dateTime = new java.sql.Timestamp(1766419274);
JsonNode result = JsonNormalizer.normalize(dateTime);
assertTrue(result.isString());
//assertEquals("1970-01-21T11:40:19.274", result.asString());
// Instead of hardcoded "1970-01-21T11:40:19.274"
String expected = dateTime.toLocalDateTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
assertEquals(expected, result.asString());
}
I have already fixed this issue in my forked repository and can submit a pull request if desired. The fix ensures test portability across different timezone environments.
Files Modified:
src/test/java/dev/toonformat/jtoon/normalizer/JsonNormalizerTest.java
This fix ensures the tests are timezone-agnostic and will pass regardless of the system's timezone configuration.
Reproduction Steps
Run test in UTC+8 environment,error follow
Expected Behavior
no error
Actual Behavior
#My timezone: UTC+8
#e.g. Result of run:JsonNormalizerTest$TemporalTypes.testSQLTimeStamp
Expected:1970-01-21T11:40:19.274
Actual:1970-01-21T18:40:19.274
org.opentest4j.AssertionFailedError: expected: <1970-01-21T11:40:19.274> but was: <1970-01-21T18:40:19.274>
at org.junit.jupiter.api.AssertionFailureBuilder.build(AssertionFailureBuilder.java:158)
at org.junit.jupiter.api.AssertionFailureBuilder.buildAndThrow(AssertionFailureBuilder.java:139)
at org.junit.jupiter.api.AssertEquals.failNotEqual(AssertEquals.java:201)
at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:184)
at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:179)
at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1188)
at dev.toonformat.jtoon.normalizer.JsonNormalizerTest$TemporalTypes.testSQLTimeStamp(JsonNormalizerTest.java:357)
Environment
timezone: UTC+8
os: macOS 13.15.7
jdk: build 21.0.8+12-LTS-250
Additional Context
No response