Skip to content

Commit 2f04ccb

Browse files
authored
Migrate JsonMapperTest to Java (#10716)
Migrate JsonMapperTest to Java Update claude skill Simplify casting Improve readability Rename var Improve readability and address review comments Merge branch 'master' into sarahchen6/g2j-components Co-authored-by: sarah.chen <sarah.chen@datadoghq.com>
1 parent e27f234 commit 2f04ccb

3 files changed

Lines changed: 206 additions & 180 deletions

File tree

.claude/skills/migrate-groovy-to-java/SKILL.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ description: migrate test groovy files to java
55

66
Migrate test Groovy files to Java using JUnit 5
77

8-
1. List all groovy files of the current gradle module
9-
2. convert groovy files to Java using Junit 5
10-
3. make sure the tests are still passing after migration
11-
4. remove groovy files
8+
1. List all Groovy files of the current Gradle module
9+
2. Convert Groovy files to Java using JUnit 5
10+
3. Make sure the tests are still passing after migration and that the test count has not changed
11+
4. Remove Groovy files
1212

13-
When converting groovy code to java code make sure that:
14-
- the Java code generated is compatible with JDK 8
15-
- when translating Spock test, favor using `@CsvSource` with `|` delimiters
16-
- when using a `@MethodSource`, use the test method name, and suffix it with `_arguments`
17-
- when converting tuples, create light dedicated structure instead to keep the typing system
13+
When converting Groovy code to Java code, make sure that:
14+
- The Java code generated is compatible with JDK 8
15+
- When translating Spock tests, favor using `@CsvSource` with `|` delimiters
16+
- When using `@MethodSource`, name the arguments method by appending `Arguments` using camelCase to the test method name (e.g. `testMethodArguments`)
17+
- Ensure parameterized test names are human-readable (i.e. no hashcodes); instead add a description string as the first `Arguments.of(...)` value or index the test case
18+
- When converting tuples, create a light dedicated structure instead to keep the typing system
1819
- Instead of checking a state and throwing an exception, use JUnit asserts
19-
- Do not wrap checked exception and throwing a Runtime exception, prefer adding a throws clause at method declaration
20+
- Do not wrap checked exceptions and throw a Runtime exception; prefer adding a throws clause at method declaration
2021
- Do not mark local variables `final`
22+
- Ensure variables are human-readable; avoid single-letter names and pre-define variables that are referenced multiple times

components/json/src/test/groovy/datadog/json/JsonMapperTest.groovy

Lines changed: 0 additions & 170 deletions
This file was deleted.
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
package datadog.json;
2+
3+
import static java.util.Collections.emptyList;
4+
import static java.util.Collections.emptyMap;
5+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
6+
import static org.junit.jupiter.api.Assertions.assertEquals;
7+
import static org.junit.jupiter.api.Assertions.assertThrows;
8+
import static org.junit.jupiter.api.Assertions.assertTrue;
9+
10+
import java.io.IOException;
11+
import java.util.ArrayList;
12+
import java.util.Arrays;
13+
import java.util.HashMap;
14+
import java.util.LinkedHashMap;
15+
import java.util.List;
16+
import java.util.Map;
17+
import java.util.stream.Stream;
18+
import org.junit.jupiter.params.ParameterizedTest;
19+
import org.junit.jupiter.params.provider.Arguments;
20+
import org.junit.jupiter.params.provider.MethodSource;
21+
import org.junit.jupiter.params.provider.ValueSource;
22+
23+
class JsonMapperTest {
24+
25+
@ParameterizedTest(name = "test mapping to JSON object: {0}")
26+
@MethodSource("testMappingToJsonObjectArguments")
27+
void testMappingToJsonObject(String testCase, Map<String, Object> input, String expected)
28+
throws IOException {
29+
String json = JsonMapper.toJson(input);
30+
assertEquals(expected, json);
31+
32+
Map<String, Object> parsed = JsonMapper.fromJsonToMap(json);
33+
if (input == null) {
34+
assertEquals(emptyMap(), parsed);
35+
} else {
36+
assertEquals(input.size(), parsed.size());
37+
for (Map.Entry<String, Object> entry : input.entrySet()) {
38+
String expectedKey = entry.getKey();
39+
Object expectedValue = entry.getValue();
40+
assertTrue(parsed.containsKey(expectedKey));
41+
Object parsedValue = parsed.get(expectedKey);
42+
if (expectedValue instanceof UnsupportedType) {
43+
assertEquals(expectedValue.toString(), parsedValue);
44+
} else if (expectedValue instanceof Float) {
45+
assertTrue(parsedValue instanceof Double);
46+
assertEquals((Float) expectedValue, (Double) parsedValue, 0.001);
47+
} else {
48+
assertEquals(expectedValue, parsedValue);
49+
}
50+
}
51+
}
52+
}
53+
54+
static Stream<Arguments> testMappingToJsonObjectArguments() {
55+
Map<String, Object> singleEntry = new LinkedHashMap<>();
56+
singleEntry.put("key1", "value1");
57+
58+
Map<String, Object> twoEntries = new LinkedHashMap<>();
59+
twoEntries.put("key1", "value1");
60+
twoEntries.put("key2", "value2");
61+
62+
Map<String, Object> quotedEntries = new LinkedHashMap<>();
63+
quotedEntries.put("key1", "va\"lu\"e1");
64+
quotedEntries.put("ke\"y2", "value2");
65+
66+
Map<String, Object> complexMap = new LinkedHashMap<>();
67+
complexMap.put("key1", null);
68+
complexMap.put("key2", "bar");
69+
complexMap.put("key3", 3);
70+
complexMap.put("key4", 3456789123L);
71+
complexMap.put("key5", 3.142f);
72+
complexMap.put("key6", Math.PI);
73+
complexMap.put("key7", true);
74+
complexMap.put("key8", new UnsupportedType());
75+
76+
return Stream.of(
77+
Arguments.of("null input", null, "{}"),
78+
Arguments.of("empty map", new HashMap<>(), "{}"),
79+
Arguments.of("single entry", singleEntry, "{\"key1\":\"value1\"}"),
80+
Arguments.of("two entries", twoEntries, "{\"key1\":\"value1\",\"key2\":\"value2\"}"),
81+
Arguments.of(
82+
"quoted entries",
83+
quotedEntries,
84+
"{\"key1\":\"va\\\"lu\\\"e1\",\"ke\\\"y2\":\"value2\"}"),
85+
Arguments.of(
86+
"complex map",
87+
complexMap,
88+
"{\"key1\":null,\"key2\":\"bar\",\"key3\":3,\"key4\":3456789123,\"key5\":3.142,\"key6\":3.141592653589793,\"key7\":true,\"key8\":\"toString\"}"));
89+
}
90+
91+
@ParameterizedTest(name = "test mapping to Map from empty JSON object: {0}")
92+
@MethodSource("testMappingToMapFromEmptyJsonObjectArguments")
93+
void testMappingToMapFromEmptyJsonObject(String json) throws IOException {
94+
Map<String, Object> parsed = JsonMapper.fromJsonToMap(json);
95+
assertEquals(emptyMap(), parsed);
96+
}
97+
98+
static Stream<Arguments> testMappingToMapFromEmptyJsonObjectArguments() {
99+
return Stream.of(
100+
Arguments.of((Object) null), Arguments.of("null"), Arguments.of(""), Arguments.of("{}"));
101+
}
102+
103+
@ParameterizedTest(name = "test mapping to Map from non-object JSON: {0}")
104+
@ValueSource(strings = {"1", "[1, 2]"})
105+
void testMappingToMapFromNonObjectJson(String json) {
106+
assertThrows(IOException.class, () -> JsonMapper.fromJsonToMap(json));
107+
}
108+
109+
@ParameterizedTest(name = "test mapping iterable to JSON array: {0}")
110+
@MethodSource("testMappingIterableToJsonArrayArguments")
111+
void testMappingIterableToJsonArray(List<String> input, String expected) throws IOException {
112+
String json = JsonMapper.toJson(input);
113+
assertEquals(expected, json);
114+
115+
List<String> parsed = JsonMapper.fromJsonToList(json);
116+
assertEquals(input != null ? input : emptyList(), parsed);
117+
}
118+
119+
static Stream<Arguments> testMappingIterableToJsonArrayArguments() {
120+
return Stream.of(
121+
Arguments.of(null, "[]"),
122+
Arguments.of(new ArrayList<>(), "[]"),
123+
Arguments.of(Arrays.asList("value1"), "[\"value1\"]"),
124+
Arguments.of(Arrays.asList("value1", "value2"), "[\"value1\",\"value2\"]"),
125+
Arguments.of(Arrays.asList("va\"lu\"e1", "value2"), "[\"va\\\"lu\\\"e1\",\"value2\"]"));
126+
}
127+
128+
@ParameterizedTest(name = "test mapping array to JSON array: {0}")
129+
@MethodSource("testMappingArrayToJsonArrayArguments")
130+
void testMappingArrayToJsonArray(String testCase, String[] input, String expected)
131+
throws IOException {
132+
String json = JsonMapper.toJson(input);
133+
assertEquals(expected, json);
134+
135+
String[] parsed = JsonMapper.fromJsonToList(json).toArray(new String[] {});
136+
assertArrayEquals(input != null ? input : new String[] {}, parsed);
137+
}
138+
139+
static Stream<Arguments> testMappingArrayToJsonArrayArguments() {
140+
return Stream.of(
141+
Arguments.of("null input", (Object) null, "[]"),
142+
Arguments.of("empty array", new String[] {}, "[]"),
143+
Arguments.of("single element", new String[] {"value1"}, "[\"value1\"]"),
144+
Arguments.of("two elements", new String[] {"value1", "value2"}, "[\"value1\",\"value2\"]"),
145+
Arguments.of(
146+
"escaped quotes",
147+
new String[] {"va\"lu\"e1", "value2"},
148+
"[\"va\\\"lu\\\"e1\",\"value2\"]"));
149+
}
150+
151+
@ParameterizedTest(name = "test mapping to List from empty JSON object: {0}")
152+
@MethodSource("testMappingToListFromEmptyJsonObjectArguments")
153+
void testMappingToListFromEmptyJsonObject(String json) throws IOException {
154+
List<String> parsed = JsonMapper.fromJsonToList(json);
155+
assertEquals(emptyList(), parsed);
156+
}
157+
158+
static Stream<Arguments> testMappingToListFromEmptyJsonObjectArguments() {
159+
return Stream.of(
160+
Arguments.of((Object) null), Arguments.of("null"), Arguments.of(""), Arguments.of("[]"));
161+
}
162+
163+
@ParameterizedTest(name = "test mapping to JSON string: {0}")
164+
@MethodSource("testMappingToJsonStringArguments")
165+
void testMappingToJsonString(String input, String expected) {
166+
String json = JsonMapper.toJson(input);
167+
assertEquals(expected, json);
168+
}
169+
170+
static Stream<Arguments> testMappingToJsonStringArguments() {
171+
return Stream.of(
172+
Arguments.of((Object) null, ""),
173+
Arguments.of("", ""),
174+
Arguments.of(String.valueOf((char) 4096), "\"\\u1000\""),
175+
Arguments.of(String.valueOf((char) 256), "\"\\u0100\""),
176+
Arguments.of(String.valueOf((char) 128), "\"\\u0080\""),
177+
Arguments.of("\b", "\"\\b\""),
178+
Arguments.of("\t", "\"\\t\""),
179+
Arguments.of("\n", "\"\\n\""),
180+
Arguments.of("\f", "\"\\f\""),
181+
Arguments.of("\r", "\"\\r\""),
182+
Arguments.of("\"", "\"\\\"\""),
183+
Arguments.of("/", "\"\\/\""),
184+
Arguments.of("\\", "\"\\\\\""),
185+
Arguments.of("a", "\"a\""));
186+
}
187+
188+
private static class UnsupportedType {
189+
@Override
190+
public String toString() {
191+
return "toString";
192+
}
193+
}
194+
}

0 commit comments

Comments
 (0)