Skip to content

Commit 07900b1

Browse files
Adding some test between the years (#80)
* Adding some test between the years * adding test for ObjectEncoder * use Delimiter and not string of it * adding Test for PrimitiveDecoder * adding Test * given/when/then pattern for all test part 1/n * given/when/then pattern for all test part 2/n * given/when/then pattern for all test part 3/n * given/when/then pattern for all test part 4/n * given/when/then pattern for all test part 5/n * given/when/then pattern for all test part 6/n * given/when/then pattern for all test part 7/n * given/when/then pattern for all test part 8/n * given/when/then pattern for all test part 9/n * given/when/then pattern for all test part 10/n * given/when/then pattern for all test part 11/11 * remove warnings from spotbugs analyze
1 parent 0edc592 commit 07900b1

39 files changed

+2644
-391
lines changed

src/main/java/dev/toonformat/jtoon/decoder/ArrayDecoder.java

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package dev.toonformat.jtoon.decoder;
22

3+
import dev.toonformat.jtoon.Delimiter;
4+
35
import java.util.ArrayList;
46
import java.util.Collections;
57
import java.util.List;
@@ -11,7 +13,7 @@
1113
/**
1214
* Handles decoding of TOON arrays to JSON format.
1315
*/
14-
public class ArrayDecoder {
16+
public final class ArrayDecoder {
1517

1618
private ArrayDecoder() {
1719
throw new UnsupportedOperationException("Utility class cannot be instantiated");
@@ -26,8 +28,8 @@ private ArrayDecoder() {
2628
* @param context decode an object to deal with lines, delimiter and options
2729
* @return parsed array with delimiter
2830
*/
29-
protected static List<Object> parseArray(String header, int depth, DecodeContext context) {
30-
String arrayDelimiter = extractDelimiterFromHeader(header, context);
31+
static List<Object> parseArray(String header, int depth, DecodeContext context) {
32+
Delimiter arrayDelimiter = extractDelimiterFromHeader(header, context);
3133

3234
return parseArrayWithDelimiter(header, depth, arrayDelimiter, context);
3335
}
@@ -40,15 +42,16 @@ protected static List<Object> parseArray(String header, int depth, DecodeContext
4042
* @param context decode an object to deal with lines, delimiter and options
4143
* @return extracted delimiter from header
4244
*/
43-
protected static String extractDelimiterFromHeader(String header, DecodeContext context) {
45+
static Delimiter extractDelimiterFromHeader(String header, DecodeContext context) {
4446
Matcher matcher = ARRAY_HEADER_PATTERN.matcher(header);
45-
if (matcher.find() && matcher.groupCount() == 3) {
47+
if (matcher.find()) {
4648
String delimiter = matcher.group(3);
4749
if (delimiter != null) {
4850
if ("\t".equals(delimiter)) {
49-
return "\t";
50-
} else if ("|".equals(delimiter)) {
51-
return "|";
51+
return Delimiter.TAB;
52+
}
53+
if ("|".equals(delimiter)) {
54+
return Delimiter.PIPE;
5255
}
5356
}
5457
}
@@ -67,7 +70,7 @@ protected static String extractDelimiterFromHeader(String header, DecodeContext
6770
* @param context decode an object to deal with lines, delimiter and options
6871
* @return parsed array
6972
*/
70-
protected static List<Object> parseArrayWithDelimiter(String header, int depth, String arrayDelimiter, DecodeContext context) {
73+
static List<Object> parseArrayWithDelimiter(String header, int depth, Delimiter arrayDelimiter, DecodeContext context) {
7174
Matcher tabularMatcher = TABULAR_HEADER_PATTERN.matcher(header);
7275
Matcher arrayMatcher = ARRAY_HEADER_PATTERN.matcher(header);
7376

@@ -130,7 +133,7 @@ protected static List<Object> parseArrayWithDelimiter(String header, int depth,
130133
* @param header header
131134
* @param actualLength actual length
132135
*/
133-
protected static void validateArrayLength(String header, int actualLength) {
136+
static void validateArrayLength(String header, int actualLength) {
134137
Integer declaredLength = extractLengthFromHeader(header);
135138
if (declaredLength != null && declaredLength != actualLength) {
136139
throw new IllegalArgumentException(
@@ -147,12 +150,8 @@ protected static void validateArrayLength(String header, int actualLength) {
147150
*/
148151
private static Integer extractLengthFromHeader(String header) {
149152
Matcher matcher = ARRAY_HEADER_PATTERN.matcher(header);
150-
if (matcher.find() && matcher.groupCount() > 2) {
151-
try {
152-
return Integer.parseInt(matcher.group(2));
153-
} catch (NumberFormatException e) {
154-
return null;
155-
}
153+
if (matcher.find()) {
154+
return Integer.parseInt(matcher.group(2));
156155
}
157156
return null;
158157
}
@@ -164,7 +163,7 @@ private static Integer extractLengthFromHeader(String header) {
164163
* @param arrayDelimiter array delimiter
165164
* @return parsed array values
166165
*/
167-
protected static List<Object> parseArrayValues(String values, String arrayDelimiter) {
166+
static List<Object> parseArrayValues(String values, Delimiter arrayDelimiter) {
168167
List<Object> result = new ArrayList<>();
169168
List<String> rawValues = parseDelimitedValues(values, arrayDelimiter);
170169
for (String value : rawValues) {
@@ -181,12 +180,12 @@ protected static List<Object> parseArrayValues(String values, String arrayDelimi
181180
* @param arrayDelimiter array delimiter
182181
* @return parsed delimited values
183182
*/
184-
protected static List<String> parseDelimitedValues(String input, String arrayDelimiter) {
183+
static List<String> parseDelimitedValues(String input, Delimiter arrayDelimiter) {
185184
List<String> result = new ArrayList<>();
186185
StringBuilder stringBuilder = new StringBuilder();
187186
boolean inQuotes = false;
188187
boolean escaped = false;
189-
char delimiterChar = arrayDelimiter.charAt(0);
188+
char delimiterChar = arrayDelimiter.toString().charAt(0);
190189

191190
int i = 0;
192191
while (i < input.length()) {
@@ -220,7 +219,7 @@ protected static List<String> parseDelimitedValues(String input, String arrayDel
220219
}
221220

222221
// Add final value
223-
if (!stringBuilder.isEmpty() || input.endsWith(arrayDelimiter)) {
222+
if (!stringBuilder.isEmpty() || input.endsWith(arrayDelimiter.toString())) {
224223
result.add(stringBuilder.toString().trim());
225224
}
226225

src/main/java/dev/toonformat/jtoon/decoder/DecodeContext.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dev.toonformat.jtoon.decoder;
22

33
import dev.toonformat.jtoon.DecodeOptions;
4+
import dev.toonformat.jtoon.Delimiter;
45

56
/**
67
* Deals with the main attributes used to decode TOON to JSON format
@@ -18,7 +19,7 @@ public class DecodeContext {
1819
/**
1920
* Delimiter used to split array elements.
2021
*/
21-
protected String delimiter;
22+
protected Delimiter delimiter;
2223
/**
2324
* Current line being decoded.
2425
*/

src/main/java/dev/toonformat/jtoon/decoder/DecodeHelper.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/**
77
* Handles indentation, depth, conflicts, and validation for other decode classes.
88
*/
9-
public class DecodeHelper {
9+
public final class DecodeHelper {
1010

1111
private DecodeHelper() {
1212
throw new UnsupportedOperationException("Utility class cannot be instantiated");
@@ -76,7 +76,7 @@ private static int computeLeadingSpaces(String line, DecodeContext context) {
7676
* @param line the line string to parse
7777
* @return true or false depending on if the line is blank or not
7878
*/
79-
protected static boolean isBlankLine(String line) {
79+
static boolean isBlankLine(String line) {
8080
return line.trim().isEmpty();
8181
}
8282

@@ -87,7 +87,7 @@ protected static boolean isBlankLine(String line) {
8787
* @param content the content string to parse
8888
* @return the unquoted colon
8989
*/
90-
protected static int findUnquotedColon(String content) {
90+
static int findUnquotedColon(String content) {
9191
boolean inQuotes = false;
9292
boolean escaped = false;
9393

@@ -115,7 +115,7 @@ protected static int findUnquotedColon(String content) {
115115
* @param context decode an object to deal with lines, delimiter, and options
116116
* @return index aiming for the next non-blank line
117117
*/
118-
protected static int findNextNonBlankLine(int startIndex, DecodeContext context) {
118+
static int findNextNonBlankLine(int startIndex, DecodeContext context) {
119119
int index = startIndex;
120120
while (index < context.lines.length && isBlankLine(context.lines[index])) {
121121
index++;
@@ -132,7 +132,7 @@ protected static int findNextNonBlankLine(int startIndex, DecodeContext context)
132132
* @param context decode an object to deal with lines, delimiter, and options
133133
* @throws IllegalArgumentException in case there's a expansion conflict
134134
*/
135-
protected static void checkFinalValueConflict(String finalSegment, Object existing, Object value, DecodeContext context) {
135+
static void checkFinalValueConflict(String finalSegment, Object existing, Object value, DecodeContext context) {
136136
if (existing != null && context.options.strict()) {
137137
// Check for conflicts in strict mode
138138
if (existing instanceof Map && !(value instanceof Map)) {
@@ -157,7 +157,7 @@ protected static void checkFinalValueConflict(String finalSegment, Object existi
157157
* @param value present value in a map
158158
* @param context decode an object to deal with lines, delimiter, and options
159159
*/
160-
protected static void checkPathExpansionConflict(Map<String, Object> map, String key, Object value, DecodeContext context) {
160+
static void checkPathExpansionConflict(Map<String, Object> map, String key, Object value, DecodeContext context) {
161161
if (!context.options.strict()) {
162162
return;
163163
}
@@ -172,7 +172,7 @@ protected static void checkPathExpansionConflict(Map<String, Object> map, String
172172
* @param context decode an object to deal with lines, delimiter, and options
173173
* @return the depth of the next non-blank line, or null if none exists
174174
*/
175-
protected static Integer findNextNonBlankLineDepth(DecodeContext context) {
175+
static Integer findNextNonBlankLineDepth(DecodeContext context) {
176176
int nextLineIdx = context.currentLine;
177177
while (nextLineIdx < context.lines.length && isBlankLine(context.lines[nextLineIdx])) {
178178
nextLineIdx++;
@@ -191,7 +191,7 @@ protected static Integer findNextNonBlankLineDepth(DecodeContext context) {
191191
* @param context decode an object to deal with lines, delimiter, and options
192192
* @throws IllegalArgumentException in case the next depth is equal to 0
193193
*/
194-
protected static void validateNoMultiplePrimitivesAtRoot(DecodeContext context) {
194+
static void validateNoMultiplePrimitivesAtRoot(DecodeContext context) {
195195
int lineIndex = context.currentLine;
196196
while (lineIndex < context.lines.length && isBlankLine(context.lines[lineIndex])) {
197197
lineIndex++;

src/main/java/dev/toonformat/jtoon/decoder/KeyDecoder.java

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.toonformat.jtoon.decoder;
22

3+
import dev.toonformat.jtoon.Delimiter;
34
import dev.toonformat.jtoon.PathExpansion;
45
import dev.toonformat.jtoon.util.StringEscaper;
56

@@ -13,9 +14,11 @@
1314
/**
1415
* Handles decoding of key values/arrays to JSON format.
1516
*/
16-
public class KeyDecoder {
17+
public final class KeyDecoder {
1718

18-
private KeyDecoder() {throw new UnsupportedOperationException("Utility class cannot be instantiated");}
19+
private KeyDecoder() {
20+
throw new UnsupportedOperationException("Utility class cannot be instantiated");
21+
}
1922

2023
/**
2124
* Processes a keyed array line (e.g., "key[3]: value").
@@ -26,8 +29,8 @@ public class KeyDecoder {
2629
* @param parentDepth parent depth of keyed array line
2730
* @param context decode an object to deal with lines, delimiter and options
2831
*/
29-
protected static void processKeyedArrayLine(Map<String, Object> result, String content, String originalKey,
30-
int parentDepth, DecodeContext context) {
32+
static void processKeyedArrayLine(Map<String, Object> result, String content, String originalKey,
33+
int parentDepth, DecodeContext context) {
3134
String key = StringEscaper.unescape(originalKey);
3235
String arrayHeader = content.substring(originalKey.length());
3336
List<Object> arrayValue = ArrayDecoder.parseArray(arrayHeader, parentDepth + 1, context);
@@ -50,7 +53,7 @@ protected static void processKeyedArrayLine(Map<String, Object> result, String c
5053
* @param value value
5154
* @param context decode an object to deal with lines, delimiter and options
5255
*/
53-
protected static void expandPathIntoMap(Map<String, Object> current, String dottedKey, Object value, DecodeContext context) {
56+
static void expandPathIntoMap(Map<String, Object> current, String dottedKey, Object value, DecodeContext context) {
5457
String[] segments = dottedKey.split("\\.");
5558

5659
// Navigate/create nested structure
@@ -73,7 +76,7 @@ protected static void expandPathIntoMap(Map<String, Object> current, String dott
7376
if (context.options.strict()) {
7477
throw new IllegalArgumentException(
7578
String.format("Path expansion conflict: %s is %s, cannot expand to object",
76-
segment, existing.getClass().getSimpleName()));
79+
segment, existing.getClass().getSimpleName()));
7780
}
7881
// LWW: overwrite with new nested object
7982
Map<String, Object> nested = new LinkedHashMap<>();
@@ -101,7 +104,7 @@ protected static void expandPathIntoMap(Map<String, Object> current, String dott
101104
* @param depth the depth of the value line
102105
* @param context decode an object to deal with lines, delimiter and options
103106
*/
104-
protected static void processKeyValueLine(Map<String, Object> result, String content, int depth, DecodeContext context) {
107+
static void processKeyValueLine(Map<String, Object> result, String content, int depth, DecodeContext context) {
105108
int colonIdx = DecodeHelper.findUnquotedColon(content);
106109

107110
if (colonIdx > 0) {
@@ -127,8 +130,8 @@ protected static void processKeyValueLine(Map<String, Object> result, String con
127130
* @param depth the depth of the value pair
128131
* @param context decode an object to deal with lines, delimiter and options
129132
*/
130-
protected static void parseKeyValuePairIntoMap(Map<String, Object> map, String key, String value,
131-
int depth, DecodeContext context) {
133+
static void parseKeyValuePairIntoMap(Map<String, Object> map, String key, String value,
134+
int depth, DecodeContext context) {
132135
String unescapedKey = StringEscaper.unescape(key);
133136

134137
Object parsedValue = parseKeyValue(value, depth, context);
@@ -144,7 +147,7 @@ protected static void parseKeyValuePairIntoMap(Map<String, Object> map, String k
144147
* @param context decode an object to deal with lines, delimiter and options
145148
* @return true if a key should be expanded or false if not
146149
*/
147-
protected static boolean shouldExpandKey(String key, DecodeContext context) {
150+
static boolean shouldExpandKey(String key, DecodeContext context) {
148151
if (context.options.expandPaths() != PathExpansion.SAFE) {
149152
return false;
150153
}
@@ -238,8 +241,8 @@ private static void putKeyValueIntoMap(Map<String, Object> map, String originalK
238241
* @param context decode an object to deal with lines, delimiter, and options
239242
* @return parsed a key-value pair
240243
*/
241-
protected static Object parseKeyValuePair(String key, String value, int depth, boolean parseRootFields,
242-
DecodeContext context) {
244+
static Object parseKeyValuePair(String key, String value, int depth, boolean parseRootFields,
245+
DecodeContext context) {
243246
Map<String, Object> obj = new LinkedHashMap<>();
244247
parseKeyValuePairIntoMap(obj, key, value, depth, context);
245248

@@ -258,7 +261,7 @@ protected static Object parseKeyValuePair(String key, String value, int depth, b
258261
* @param context decode an object to deal with lines, delimiter, and options
259262
* @return parsed keyed array value
260263
*/
261-
protected static Object parseKeyedArrayValue(Matcher keyedArray, String content, int depth, DecodeContext context) {
264+
static Object parseKeyedArrayValue(Matcher keyedArray, String content, int depth, DecodeContext context) {
262265
String originalKey = keyedArray.group(1).trim();
263266
String key = StringEscaper.unescape(originalKey);
264267
String arrayHeader = content.substring(keyedArray.group(1).length());
@@ -292,7 +295,7 @@ protected static Object parseKeyedArrayValue(Matcher keyedArray, String content,
292295
* @param context decode an object to deal with lines, delimiter and options
293296
* @return true if the field was processed as a keyed array, false otherwise
294297
*/
295-
protected static boolean parseKeyedArrayField(String fieldContent, Map<String, Object> item, int depth, DecodeContext context) {
298+
static boolean parseKeyedArrayField(String fieldContent, Map<String, Object> item, int depth, DecodeContext context) {
296299
Matcher keyedArray = KEYED_ARRAY_PATTERN.matcher(fieldContent);
297300
if (!keyedArray.matches()) {
298301
return false;
@@ -303,7 +306,7 @@ protected static boolean parseKeyedArrayField(String fieldContent, Map<String, O
303306
String arrayHeader = fieldContent.substring(keyedArray.group(1).length());
304307

305308
// For nested arrays in list items, default to comma delimiter if not specified
306-
String nestedArrayDelimiter = ArrayDecoder.extractDelimiterFromHeader(arrayHeader, context);
309+
Delimiter nestedArrayDelimiter = ArrayDecoder.extractDelimiterFromHeader(arrayHeader, context);
307310
var arrayValue = ArrayDecoder.parseArrayWithDelimiter(arrayHeader, depth + 2, nestedArrayDelimiter, context);
308311

309312
// Handle path expansion for array keys
@@ -326,7 +329,7 @@ protected static boolean parseKeyedArrayField(String fieldContent, Map<String, O
326329
* @param context decode an object to deal with lines, delimiter and options
327330
* @return true if the field was processed as a key-value pair, false otherwise
328331
*/
329-
protected static boolean parseKeyValueField(String fieldContent, Map<String, Object> item, int depth, DecodeContext context) {
332+
static boolean parseKeyValueField(String fieldContent, Map<String, Object> item, int depth, DecodeContext context) {
330333
int colonIdx = DecodeHelper.findUnquotedColon(fieldContent);
331334
if (colonIdx <= 0) {
332335
return false;

src/main/java/dev/toonformat/jtoon/decoder/ListItemDecoder.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.toonformat.jtoon.decoder;
22

3+
import dev.toonformat.jtoon.Delimiter;
34
import dev.toonformat.jtoon.util.StringEscaper;
45

56
import java.util.LinkedHashMap;
@@ -12,7 +13,7 @@
1213
/**
1314
* Handles decoding of TOON list item to JSON format.
1415
*/
15-
public class ListItemDecoder {
16+
public final class ListItemDecoder {
1617

1718
private ListItemDecoder() {throw new UnsupportedOperationException("Utility class cannot be instantiated");}
1819

@@ -67,7 +68,7 @@ public static Object parseListItem(String content, int depth, DecodeContext cont
6768
// Check for standalone array (e.g., "[2]: 1,2")
6869
if (itemContent.startsWith("[")) {
6970
// For nested arrays in list items, default to comma delimiter if not specified
70-
String nestedArrayDelimiter = ArrayDecoder.extractDelimiterFromHeader(itemContent, context);
71+
Delimiter nestedArrayDelimiter = ArrayDecoder.extractDelimiterFromHeader(itemContent, context);
7172
// parseArrayWithDelimiter handles currentLine increment internally
7273
// For inline arrays, it increments. For multi-line arrays, parseListArray
7374
// handles it.
@@ -85,7 +86,7 @@ public static Object parseListItem(String content, int depth, DecodeContext cont
8586
String arrayHeader = itemContent.substring(keyedArray.group(1).length());
8687

8788
// For nested arrays in list items, default to comma delimiter if not specified
88-
String nestedArrayDelimiter = ArrayDecoder.extractDelimiterFromHeader(arrayHeader, context);
89+
Delimiter nestedArrayDelimiter = ArrayDecoder.extractDelimiterFromHeader(arrayHeader, context);
8990
List<Object> arrayValue = ArrayDecoder.parseArrayWithDelimiter(arrayHeader, depth + 2, nestedArrayDelimiter, context);
9091

9192
Map<String, Object> item = new LinkedHashMap<>();

0 commit comments

Comments
 (0)