diff --git a/src/main/java/dev/toonformat/jtoon/decoder/ArrayDecoder.java b/src/main/java/dev/toonformat/jtoon/decoder/ArrayDecoder.java index e68c1db..8d992df 100644 --- a/src/main/java/dev/toonformat/jtoon/decoder/ArrayDecoder.java +++ b/src/main/java/dev/toonformat/jtoon/decoder/ArrayDecoder.java @@ -7,6 +7,10 @@ import java.util.List; import java.util.regex.Matcher; +import static dev.toonformat.jtoon.util.Constants.BACKSLASH; +import static dev.toonformat.jtoon.util.Constants.COLON; +import static dev.toonformat.jtoon.util.Constants.DOUBLE_QUOTE; +import static dev.toonformat.jtoon.util.Constants.LIST_ITEM_PREFIX; import static dev.toonformat.jtoon.util.Headers.ARRAY_HEADER_PATTERN; import static dev.toonformat.jtoon.util.Headers.TABULAR_HEADER_PATTERN; @@ -47,10 +51,10 @@ static Delimiter extractDelimiterFromHeader(String header, DecodeContext context if (matcher.find()) { String delimiter = matcher.group(3); if (delimiter != null) { - if ("\t".equals(delimiter)) { + if (Delimiter.TAB.toString().equals(delimiter)) { return Delimiter.TAB; } - if ("|".equals(delimiter)) { + if (Delimiter.PIPE.toString().equals(delimiter)) { return Delimiter.PIPE; } } @@ -82,7 +86,7 @@ static List parseArrayWithDelimiter(String header, int depth, Delimiter int headerEndIdx = arrayMatcher.end(); String afterHeader = header.substring(headerEndIdx).trim(); - if (afterHeader.startsWith(":")) { + if (afterHeader.startsWith(COLON)) { String inlineContent = afterHeader.substring(1).trim(); if (!inlineContent.isEmpty()) { @@ -106,7 +110,7 @@ static List parseArrayWithDelimiter(String header, int depth, Delimiter return Collections.emptyList(); } - if (nextContent.startsWith("- ")) { + if (nextContent.startsWith(LIST_ITEM_PREFIX)) { context.currentLine--; return parseListArray(depth, header, context); } else { @@ -195,11 +199,11 @@ static List parseDelimitedValues(String input, Delimiter arrayDelimiter) stringBuilder.append(currentChar); escaped = false; i++; - } else if (currentChar == '\\') { + } else if (currentChar == BACKSLASH) { stringBuilder.append(currentChar); escaped = true; i++; - } else if (currentChar == '"') { + } else if (currentChar == DOUBLE_QUOTE) { stringBuilder.append(currentChar); inQuotes = !inQuotes; i++; diff --git a/src/main/java/dev/toonformat/jtoon/decoder/DecodeHelper.java b/src/main/java/dev/toonformat/jtoon/decoder/DecodeHelper.java index 2eaf392..f0db743 100644 --- a/src/main/java/dev/toonformat/jtoon/decoder/DecodeHelper.java +++ b/src/main/java/dev/toonformat/jtoon/decoder/DecodeHelper.java @@ -5,6 +5,11 @@ import java.util.List; import java.util.Map; +import static dev.toonformat.jtoon.util.Constants.BACKSLASH; +import static dev.toonformat.jtoon.util.Constants.DOUBLE_QUOTE; +import static dev.toonformat.jtoon.util.Constants.SPACE; +import static dev.toonformat.jtoon.util.Constants.COLON; + /** * Handles indentation, depth, conflicts, and validation for other decode classes. */ @@ -47,7 +52,7 @@ private static int computeLeadingSpaces(String line, DecodeContext context) { int lengthOfLine = line.length(); while (i < lengthOfLine) { char c = line.charAt(i); - if (c == ' ') { + if (c == SPACE.charAt(0)) { leadingSpaces++; } else if (c == Delimiter.TAB.getValue()) { if (context.options.strict()) { @@ -98,11 +103,11 @@ static int findUnquotedColon(String content) { if (escaped) { escaped = false; - } else if (c == '\\') { + } else if (c == BACKSLASH) { escaped = true; - } else if (c == '"') { + } else if (c == DOUBLE_QUOTE) { inQuotes = !inQuotes; - } else if (c == ':' && !inQuotes) { + } else if (c == COLON.charAt(0) && !inQuotes) { return i; } } diff --git a/src/main/java/dev/toonformat/jtoon/decoder/KeyDecoder.java b/src/main/java/dev/toonformat/jtoon/decoder/KeyDecoder.java index 5b80d4d..8d90be5 100644 --- a/src/main/java/dev/toonformat/jtoon/decoder/KeyDecoder.java +++ b/src/main/java/dev/toonformat/jtoon/decoder/KeyDecoder.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.regex.Matcher; +import static dev.toonformat.jtoon.util.Constants.DOT; import static dev.toonformat.jtoon.util.Headers.KEYED_ARRAY_PATTERN; /** @@ -156,7 +157,7 @@ static boolean shouldExpandKey(String key, DecodeContext context) { return false; } // Check if a key contains dots and is a valid identifier pattern - if (!key.contains(".")) { + if (!key.contains(DOT)) { return false; } // Valid identifier: starts with a letter or underscore, followed by letters, diff --git a/src/main/java/dev/toonformat/jtoon/decoder/ListItemDecoder.java b/src/main/java/dev/toonformat/jtoon/decoder/ListItemDecoder.java index 1b77479..2d5c118 100644 --- a/src/main/java/dev/toonformat/jtoon/decoder/ListItemDecoder.java +++ b/src/main/java/dev/toonformat/jtoon/decoder/ListItemDecoder.java @@ -8,6 +8,8 @@ import java.util.Map; import java.util.regex.Matcher; +import static dev.toonformat.jtoon.util.Constants.LIST_ITEM_MARKER; +import static dev.toonformat.jtoon.util.Constants.OPEN_BRACKET; import static dev.toonformat.jtoon.util.Headers.KEYED_ARRAY_PATTERN; /** @@ -31,7 +33,7 @@ public static void processListArrayItem(String line, int lineDepth, int depth, if (lineDepth == depth + 1) { String content = line.substring((depth + 1) * context.options.indent()); - if (content.startsWith("-")) { + if (content.startsWith(LIST_ITEM_MARKER)) { result.add(parseListItem(content, depth, context)); } else { context.currentLine++; @@ -66,7 +68,7 @@ public static Object parseListItem(String content, int depth, DecodeContext cont } // Check for standalone array (e.g., "[2]: 1,2") - if (itemContent.startsWith("[")) { + if (itemContent.startsWith(OPEN_BRACKET)) { // For nested arrays in list items, default to comma delimiter if not specified Delimiter nestedArrayDelimiter = ArrayDecoder.extractDelimiterFromHeader(itemContent, context); // parseArrayWithDelimiter handles currentLine increment internally diff --git a/src/main/java/dev/toonformat/jtoon/decoder/PrimitiveDecoder.java b/src/main/java/dev/toonformat/jtoon/decoder/PrimitiveDecoder.java index 4654326..e88aa55 100644 --- a/src/main/java/dev/toonformat/jtoon/decoder/PrimitiveDecoder.java +++ b/src/main/java/dev/toonformat/jtoon/decoder/PrimitiveDecoder.java @@ -2,6 +2,11 @@ import dev.toonformat.jtoon.util.StringEscaper; +import static dev.toonformat.jtoon.util.Constants.DOT; +import static dev.toonformat.jtoon.util.Constants.NULL_LITERAL; +import static dev.toonformat.jtoon.util.Constants.TRUE_LITERAL; +import static dev.toonformat.jtoon.util.Constants.FALSE_LITERAL; + /** * Handles parsing of primitive TOON values with type inference. * @@ -48,13 +53,13 @@ static Object parse(String value) { // Check for null literal switch (value) { - case "null" -> { + case NULL_LITERAL -> { return null; } - case "true" -> { + case TRUE_LITERAL -> { return true; } - case "false" -> { + case FALSE_LITERAL -> { return false; } default -> { @@ -78,7 +83,7 @@ static Object parse(String value) { // Try parsing as number try { // Check if it contains exponent notation or decimal point - if (value.contains(".") || value.contains("e") || value.contains("E")) { + if (value.contains(DOT) || value.contains("e") || value.contains("E")) { double parsed = Double.parseDouble(value); // Handle negative zero - Java doesn't distinguish, but spec says it should be 0 if (parsed == 0.0) { diff --git a/src/main/java/dev/toonformat/jtoon/decoder/TabularArrayDecoder.java b/src/main/java/dev/toonformat/jtoon/decoder/TabularArrayDecoder.java index 1feaeb6..60a3dc3 100644 --- a/src/main/java/dev/toonformat/jtoon/decoder/TabularArrayDecoder.java +++ b/src/main/java/dev/toonformat/jtoon/decoder/TabularArrayDecoder.java @@ -10,6 +10,8 @@ import java.util.Map; import java.util.regex.Matcher; +import static dev.toonformat.jtoon.util.Constants.BACKSLASH; +import static dev.toonformat.jtoon.util.Constants.DOUBLE_QUOTE; import static dev.toonformat.jtoon.util.Headers.TABULAR_HEADER_PATTERN; /** @@ -101,9 +103,9 @@ private static void validateKeysDelimiter(String keysStr, Delimiter expectedDeli char c = keysStr.charAt(i); if (escaped) { escaped = false; - } else if (c == '\\') { + } else if (c == BACKSLASH) { escaped = true; - } else if (c == '"') { + } else if (c == DOUBLE_QUOTE) { inQuotes = !inQuotes; } else if (!inQuotes) { checkDelimiterMismatch(expectedChar, c); diff --git a/src/main/java/dev/toonformat/jtoon/decoder/ValueDecoder.java b/src/main/java/dev/toonformat/jtoon/decoder/ValueDecoder.java index fe3158e..129b3c6 100644 --- a/src/main/java/dev/toonformat/jtoon/decoder/ValueDecoder.java +++ b/src/main/java/dev/toonformat/jtoon/decoder/ValueDecoder.java @@ -7,6 +7,8 @@ import java.util.LinkedHashMap; import java.util.regex.Matcher; +import static dev.toonformat.jtoon.util.Constants.NULL_LITERAL; +import static dev.toonformat.jtoon.util.Constants.OPEN_BRACKET; import static dev.toonformat.jtoon.util.Headers.KEYED_ARRAY_PATTERN; /** @@ -52,7 +54,7 @@ public static Object decode(String toon, DecodeOptions options) { // Special case: if input is exactly "null", return null String trimmed = toon.trim(); - if ("null".equals(trimmed)) { + if (NULL_LITERAL.equals(trimmed)) { return null; } @@ -78,7 +80,7 @@ public static Object decode(String toon, DecodeOptions options) { } // Handle standalone arrays: [2]: - if (!line.isEmpty() && line.charAt(0) == '[') { + if (!line.isEmpty() && line.charAt(0) == OPEN_BRACKET.charAt(0)) { return ArrayDecoder.parseArray(line, depth, context); } diff --git a/src/main/java/dev/toonformat/jtoon/encoder/ArrayEncoder.java b/src/main/java/dev/toonformat/jtoon/encoder/ArrayEncoder.java index b212019..1e3404f 100644 --- a/src/main/java/dev/toonformat/jtoon/encoder/ArrayEncoder.java +++ b/src/main/java/dev/toonformat/jtoon/encoder/ArrayEncoder.java @@ -1,6 +1,5 @@ package dev.toonformat.jtoon.encoder; - import dev.toonformat.jtoon.EncodeOptions; import tools.jackson.databind.JsonNode; import tools.jackson.databind.node.ArrayNode; diff --git a/src/main/java/dev/toonformat/jtoon/encoder/Flatten.java b/src/main/java/dev/toonformat/jtoon/encoder/Flatten.java index 9e16e4d..fc8bc7a 100644 --- a/src/main/java/dev/toonformat/jtoon/encoder/Flatten.java +++ b/src/main/java/dev/toonformat/jtoon/encoder/Flatten.java @@ -10,6 +10,8 @@ import java.util.Set; import java.util.regex.Pattern; +import static dev.toonformat.jtoon.util.Constants.DOT; + /** * Recursively flattens a JSON object or array into a single-level object. */ @@ -75,7 +77,7 @@ public static FoldResult tryFoldKeyChain(String key, } // start chain from absolute key - String absKey = (pathPrefix == null) ? key : String.join(".", pathPrefix, key); + String absKey = (pathPrefix == null) ? key : String.join(DOT, pathPrefix, key); // Collect segments of the single-key chain final ChainResult chain = collectSingleKeyChain(absKey, value, remainingDepth); @@ -97,7 +99,7 @@ public static FoldResult tryFoldKeyChain(String key, } // Build folded key - String foldedKey = String.join(".", chain.segments); + String foldedKey = String.join(DOT, chain.segments); // Detect collisions with sibling keys if (siblings.contains(foldedKey)) { @@ -107,7 +109,7 @@ public static FoldResult tryFoldKeyChain(String key, // Compute absolute dotted path String absolutePath = (pathPrefix != null && !pathPrefix.isEmpty()) - ? String.join(".", pathPrefix, foldedKey) + ? String.join(DOT, pathPrefix, foldedKey) : foldedKey; @@ -138,8 +140,8 @@ public static FoldResult tryFoldKeyChain(String key, */ private static ChainResult collectSingleKeyChain(String startKey, JsonNode startValue, int maxDepth) { // normalize absolute key to its local segment - String localStartKey = startKey.contains(".") - ? startKey.substring(startKey.lastIndexOf('.') + 1) + String localStartKey = startKey.contains(DOT) + ? startKey.substring(startKey.lastIndexOf(DOT.charAt(0)) + 1) : startKey; final List segments = new ArrayList<>(); diff --git a/src/main/java/dev/toonformat/jtoon/encoder/HeaderFormatter.java b/src/main/java/dev/toonformat/jtoon/encoder/HeaderFormatter.java index e22a772..164e3d6 100644 --- a/src/main/java/dev/toonformat/jtoon/encoder/HeaderFormatter.java +++ b/src/main/java/dev/toonformat/jtoon/encoder/HeaderFormatter.java @@ -2,7 +2,13 @@ import java.util.List; -import static dev.toonformat.jtoon.util.Constants.*; +import static dev.toonformat.jtoon.util.Constants.COLON; +import static dev.toonformat.jtoon.util.Constants.OPEN_BRACKET; +import static dev.toonformat.jtoon.util.Constants.COMMA; +import static dev.toonformat.jtoon.util.Constants.OPEN_BRACE; +import static dev.toonformat.jtoon.util.Constants.CLOSE_BRACE; +import static dev.toonformat.jtoon.util.Constants.CLOSE_BRACKET; +import static dev.toonformat.jtoon.util.Constants.HASHTAG; /** * Formats headers for arrays and tables in TOON format. @@ -81,7 +87,7 @@ private static void appendArrayLength( header.append(OPEN_BRACKET); if (lengthMarker) { - header.append("#"); + header.append(HASHTAG); } header.append(length); diff --git a/src/main/java/dev/toonformat/jtoon/encoder/LineWriter.java b/src/main/java/dev/toonformat/jtoon/encoder/LineWriter.java index 93aa842..59850b5 100644 --- a/src/main/java/dev/toonformat/jtoon/encoder/LineWriter.java +++ b/src/main/java/dev/toonformat/jtoon/encoder/LineWriter.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.List; +import static dev.toonformat.jtoon.util.Constants.SPACE; + /** * Line writer that accumulates indented lines for building the final output. */ @@ -16,7 +18,7 @@ public final class LineWriter { * @param indentSize Number of spaces per indentation level */ public LineWriter(int indentSize) { - this.indentationString = " ".repeat(indentSize); + this.indentationString = SPACE.repeat(indentSize); } /** diff --git a/src/main/java/dev/toonformat/jtoon/encoder/ListItemEncoder.java b/src/main/java/dev/toonformat/jtoon/encoder/ListItemEncoder.java index 879335a..2424f05 100644 --- a/src/main/java/dev/toonformat/jtoon/encoder/ListItemEncoder.java +++ b/src/main/java/dev/toonformat/jtoon/encoder/ListItemEncoder.java @@ -10,7 +10,12 @@ import java.util.List; import java.util.Set; -import static dev.toonformat.jtoon.util.Constants.*; +import static dev.toonformat.jtoon.util.Constants.LIST_ITEM_MARKER; +import static dev.toonformat.jtoon.util.Constants.COLON; +import static dev.toonformat.jtoon.util.Constants.SPACE; +import static dev.toonformat.jtoon.util.Constants.LIST_ITEM_PREFIX; +import static dev.toonformat.jtoon.util.Constants.OPEN_BRACKET; +import static dev.toonformat.jtoon.util.Constants.CLOSE_BRACKET; /** * Handles encoding of objects as list items in non-uniform arrays. diff --git a/src/main/java/dev/toonformat/jtoon/encoder/ObjectEncoder.java b/src/main/java/dev/toonformat/jtoon/encoder/ObjectEncoder.java index 59775be..fabf737 100644 --- a/src/main/java/dev/toonformat/jtoon/encoder/ObjectEncoder.java +++ b/src/main/java/dev/toonformat/jtoon/encoder/ObjectEncoder.java @@ -12,6 +12,7 @@ import java.util.Set; import java.util.stream.Collectors; +import static dev.toonformat.jtoon.util.Constants.DOT; import static dev.toonformat.jtoon.util.Constants.COLON; import static dev.toonformat.jtoon.util.Constants.SPACE; @@ -44,7 +45,7 @@ public static void encodeObject(ObjectNode value, LineWriter writer, int depth, if (depth == 0 && rootLiteralKeys != null) { rootLiteralKeys.clear(); fields.stream() - .filter(e -> e.getKey().contains(".")) + .filter(e -> e.getKey().contains(DOT)) .map(Map.Entry::getKey) .forEach(rootLiteralKeys::add); } @@ -89,7 +90,7 @@ public static void encodeKeyValuePair(String key, return; } String encodedKey = PrimitiveEncoder.encodeKey(key); - String currentPath = pathPrefix != null ? pathPrefix + "." + key : key; + String currentPath = pathPrefix != null ? pathPrefix + DOT + key : key; int effectiveFlattenDepth = flattenDepth != null && flattenDepth > 0 ? flattenDepth : options.flattenDepth(); int remainingDepth = effectiveFlattenDepth - depth; @@ -156,9 +157,9 @@ private static EncodeOptions flatten(String key, Flatten.FoldResult foldResult, // Case 2: Partially folded with a tail object if (remainder.isObject()) { - writer.push(depth, indentedLine(depth, encodedFoldedKey + ":", options.indent())); + writer.push(depth, indentedLine(depth, encodedFoldedKey + COLON, options.indent())); - String foldedPath = pathPrefix != null ? String.join(".", pathPrefix, foldedKey) : foldedKey; + String foldedPath = pathPrefix != null ? String.join(DOT, pathPrefix, foldedKey) : foldedKey; int newRemainingDepth = remainingDepth - foldResult.segmentCount(); if (newRemainingDepth <= 0) { @@ -182,7 +183,7 @@ private static void handleFullyFoldedLeaf(Flatten.FoldResult foldResult, LineWri if (leaf.isValueNode()) { writer.push(depth, indentedLine(depth, - encodedFoldedKey + ": " + + encodedFoldedKey + COLON + SPACE + PrimitiveEncoder.encodePrimitive(leaf, options.delimiter().toString()), options.indent())); return; @@ -196,7 +197,7 @@ private static void handleFullyFoldedLeaf(Flatten.FoldResult foldResult, LineWri // Object if (leaf.isObject()) { - writer.push(depth, indentedLine(depth, encodedFoldedKey + ":", options.indent())); + writer.push(depth, indentedLine(depth, encodedFoldedKey + COLON, options.indent())); if (!leaf.isEmpty()) { encodeObject((ObjectNode) leaf, writer, depth + 1, options, null, null, null, null); diff --git a/src/main/java/dev/toonformat/jtoon/encoder/PrimitiveEncoder.java b/src/main/java/dev/toonformat/jtoon/encoder/PrimitiveEncoder.java index 68f4543..8675bd2 100644 --- a/src/main/java/dev/toonformat/jtoon/encoder/PrimitiveEncoder.java +++ b/src/main/java/dev/toonformat/jtoon/encoder/PrimitiveEncoder.java @@ -8,7 +8,8 @@ import java.util.List; import java.util.Objects; -import static dev.toonformat.jtoon.util.Constants.*; +import static dev.toonformat.jtoon.util.Constants.NULL_LITERAL; +import static dev.toonformat.jtoon.util.Constants.DOUBLE_QUOTE; /** * Encodes primitive values and object keys for TOON format. diff --git a/src/main/java/dev/toonformat/jtoon/util/Constants.java b/src/main/java/dev/toonformat/jtoon/util/Constants.java index 2437bc1..5e092db 100644 --- a/src/main/java/dev/toonformat/jtoon/util/Constants.java +++ b/src/main/java/dev/toonformat/jtoon/util/Constants.java @@ -18,6 +18,10 @@ public final class Constants { public static final String COLON = ":"; /** Space character. */ public static final String SPACE = " "; + /** Dot character. */ + public static final String DOT = "."; + /** Hashtag character. */ + public static final String HASHTAG = "#"; // Brackets and braces /** Opening bracket character for arrays. */ diff --git a/src/test/java/dev/toonformat/jtoon/encoder/HeaderFormatterTest.java b/src/test/java/dev/toonformat/jtoon/encoder/HeaderFormatterTest.java index 988c688..6a50e13 100644 --- a/src/test/java/dev/toonformat/jtoon/encoder/HeaderFormatterTest.java +++ b/src/test/java/dev/toonformat/jtoon/encoder/HeaderFormatterTest.java @@ -1,5 +1,6 @@ package dev.toonformat.jtoon.encoder; +import dev.toonformat.jtoon.Delimiter; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Tag; @@ -30,7 +31,7 @@ class SimpleArrayHeaders { @DisplayName("should format simple array header without key") void testSimpleArrayWithoutKey() { // Given - String result = HeaderFormatter.format(3, null, null, ",", false); + String result = HeaderFormatter.format(3, null, null, Delimiter.COMMA.toString(), false); // Then assertEquals("[3]:", result); @@ -40,7 +41,7 @@ void testSimpleArrayWithoutKey() { @DisplayName("should format simple array header with key") void testSimpleArrayWithKey() { // Given - String result = HeaderFormatter.format(5, "items", null, ",", false); + String result = HeaderFormatter.format(5, "items", null, Delimiter.COMMA.toString(), false); // Then assertEquals("items[5]:", result); @@ -50,7 +51,7 @@ void testSimpleArrayWithKey() { @DisplayName("should format empty array") void testEmptyArray() { // Given - String result = HeaderFormatter.format(0, "items", null, ",", false); + String result = HeaderFormatter.format(0, "items", null, Delimiter.COMMA.toString(), false); // Then assertEquals("items[0]:", result); @@ -60,7 +61,7 @@ void testEmptyArray() { @DisplayName("should format array with length marker") void testArrayWithLengthMarker() { // Given - String result = HeaderFormatter.format(3, "items", null, ",", true); + String result = HeaderFormatter.format(3, "items", null, Delimiter.COMMA.toString(), true); // Then assertEquals("items[#3]:", result); @@ -78,7 +79,7 @@ void testTabularHeader() { List fields = List.of("id", "name", "age"); // When - String result = HeaderFormatter.format(2, "users", fields, ",", false); + String result = HeaderFormatter.format(2, "users", fields, Delimiter.COMMA.toString(), false); // Then assertEquals("users[2]{id,name,age}:", result); @@ -91,7 +92,7 @@ void testSingleField() { List fields = List.of("value"); // When - String result = HeaderFormatter.format(5, "data", fields, ",", false); + String result = HeaderFormatter.format(5, "data", fields, Delimiter.COMMA.toString(), false); // Then assertEquals("data[5]{value}:", result); @@ -104,7 +105,7 @@ void testTabularWithoutKey() { List fields = List.of("x", "y"); // When - String result = HeaderFormatter.format(10, null, fields, ",", false); + String result = HeaderFormatter.format(10, null, fields, Delimiter.COMMA.toString(), false); // Then assertEquals("[10]{x,y}:", result); @@ -117,7 +118,7 @@ void testEmptyFields() { List fields = List.of(); // When - String result = HeaderFormatter.format(3, "items", fields, ",", false); + String result = HeaderFormatter.format(3, "items", fields, Delimiter.COMMA.toString(), false); // Then assertEquals("items[3]:", result); @@ -130,7 +131,7 @@ void testTabularWithLengthMarker() { List fields = List.of("id", "name"); // When - String result = HeaderFormatter.format(2, "users", fields, ",", true); + String result = HeaderFormatter.format(2, "users", fields, Delimiter.COMMA.toString(), true); // Then assertEquals("users[#2]{id,name}:", result); @@ -166,7 +167,7 @@ static Stream delimiterTestData() { @DisplayName("should format array with pipe delimiter") void testArrayWithPipeDelimiter() { // Given - String result = HeaderFormatter.format(5, "items", null, "|", false); + String result = HeaderFormatter.format(5, "items", null, Delimiter.PIPE.toString(), false); // Then assertEquals("items[5|]:", result); @@ -176,7 +177,7 @@ void testArrayWithPipeDelimiter() { @DisplayName("should format array with tab delimiter") void testArrayWithTabDelimiter() { // Given - String result = HeaderFormatter.format(5, "items", null, "\t", false); + String result = HeaderFormatter.format(5, "items", null, Delimiter.TAB.toString(), false); // Then assertEquals("items[5\t]:", result); @@ -189,7 +190,7 @@ void testPipeWithLengthMarker() { List fields = List.of("x", "y"); // When - String result = HeaderFormatter.format(2, "points", fields, "|", true); + String result = HeaderFormatter.format(2, "points", fields, Delimiter.PIPE.toString(), true); // Then assertEquals("points[#2|]{x|y}:", result); @@ -204,7 +205,7 @@ class KeyQuoting { @DisplayName("should quote key with spaces") void testKeyWithSpaces() { // Given - String result = HeaderFormatter.format(3, "my items", null, ",", false); + String result = HeaderFormatter.format(3, "my items", null, Delimiter.COMMA.toString(), false); // Then assertEquals("\"my items\"[3]:", result); @@ -214,7 +215,7 @@ void testKeyWithSpaces() { @DisplayName("should quote numeric key") void testNumericKey() { // Given - String result = HeaderFormatter.format(2, "123", null, ",", false); + String result = HeaderFormatter.format(2, "123", null, Delimiter.COMMA.toString(), false); // Then assertEquals("\"123\"[2]:", result); @@ -224,7 +225,7 @@ void testNumericKey() { @DisplayName("should not quote simple alphanumeric key") void testSimpleKey() { // Given - String result = HeaderFormatter.format(3, "items", null, ",", false); + String result = HeaderFormatter.format(3, "items", null, Delimiter.COMMA.toString(), false); // Then assertEquals("items[3]:", result); @@ -237,7 +238,7 @@ void testFieldQuoting() { List fields = List.of("first name", "last name"); // When - String result = HeaderFormatter.format(2, "users", fields, ",", false); + String result = HeaderFormatter.format(2, "users", fields, Delimiter.COMMA.toString(), false); // Then assertEquals("users[2]{\"first name\",\"last name\"}:", result); @@ -250,7 +251,7 @@ void testMixedFieldQuoting() { List fields = List.of("id", "full name", "age"); // When - String result = HeaderFormatter.format(2, "users", fields, ",", false); + String result = HeaderFormatter.format(2, "users", fields, Delimiter.COMMA.toString(), false); // Then assertEquals("users[2]{id,\"full name\",age}:", result); @@ -266,7 +267,7 @@ class RecordBasedFormat { void testRecordFormat() { // Given HeaderFormatter.HeaderConfig config = new HeaderFormatter.HeaderConfig( - 3, "items", List.of("id", "name"), ",", false); + 3, "items", List.of("id", "name"), Delimiter.COMMA.toString(), false); // When String result = HeaderFormatter.format(config); @@ -280,7 +281,7 @@ void testRecordFormat() { void testRecordWithNullKey() { // Given HeaderFormatter.HeaderConfig config = new HeaderFormatter.HeaderConfig( - 5, null, null, ",", false); + 5, null, null, Delimiter.COMMA.toString(), false); // When String result = HeaderFormatter.format(config); @@ -294,7 +295,7 @@ void testRecordWithNullKey() { void testRecordWithPipeDelimiter() { // Given HeaderFormatter.HeaderConfig config = new HeaderFormatter.HeaderConfig( - 2, "data", List.of("x", "y"), "|", true); + 2, "data", List.of("x", "y"), Delimiter.PIPE.toString(), true); // When String result = HeaderFormatter.format(config); @@ -311,7 +312,7 @@ class EdgeCases { @DisplayName("should handle large array length") void testLargeLength() { // Given - String result = HeaderFormatter.format(999999, "data", null, ",", false); + String result = HeaderFormatter.format(999999, "data", null, Delimiter.COMMA.toString(), false); // Then assertEquals("data[999999]:", result); @@ -324,7 +325,7 @@ void testZeroLengthWithFields() { List fields = List.of("id", "name"); // When - String result = HeaderFormatter.format(0, "empty", fields, ",", false); + String result = HeaderFormatter.format(0, "empty", fields, Delimiter.COMMA.toString(), false); // Then assertEquals("empty[0]{id,name}:", result); @@ -337,7 +338,7 @@ void testManyFields() { List fields = List.of("f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10"); // When - String result = HeaderFormatter.format(1, "data", fields, ",", false); + String result = HeaderFormatter.format(1, "data", fields, Delimiter.COMMA.toString(), false); // Then assertEquals("data[1]{f1,f2,f3,f4,f5,f6,f7,f8,f9,f10}:", result); @@ -347,7 +348,7 @@ void testManyFields() { @DisplayName("should handle null fields list (treated as no fields)") void testNullFields() { // Given - String result = HeaderFormatter.format(3, "items", null, ",", false); + String result = HeaderFormatter.format(3, "items", null, Delimiter.COMMA.toString(), false); // Then assertEquals("items[3]:", result); @@ -365,7 +366,7 @@ void testGitHubRepos() { List fields = List.of("id", "name", "stars", "forks"); // When - String result = HeaderFormatter.format(100, "repositories", fields, ",", false); + String result = HeaderFormatter.format(100, "repositories", fields, Delimiter.COMMA.toString(), false); // Then assertEquals("repositories[100]{id,name,stars,forks}:", result); @@ -391,7 +392,7 @@ void testEmployeeRecords() { List fields = List.of("id", "name", "department", "salary"); // When - String result = HeaderFormatter.format(50, "employees", fields, "\t", false); + String result = HeaderFormatter.format(50, "employees", fields, Delimiter.TAB.toString(), false); // Then assertEquals("employees[50\t]{id\tname\tdepartment\tsalary}:", result); @@ -404,7 +405,7 @@ void testNestedArray() { List fields = List.of("sku", "qty", "price"); // When - String result = HeaderFormatter.format(3, "items", fields, ",", false); + String result = HeaderFormatter.format(3, "items", fields, Delimiter.COMMA.toString(), false); // Then assertEquals("items[3]{sku,qty,price}:", result); diff --git a/src/test/java/dev/toonformat/jtoon/encoder/PrimitiveEncoderTest.java b/src/test/java/dev/toonformat/jtoon/encoder/PrimitiveEncoderTest.java index ca905f2..0656d81 100644 --- a/src/test/java/dev/toonformat/jtoon/encoder/PrimitiveEncoderTest.java +++ b/src/test/java/dev/toonformat/jtoon/encoder/PrimitiveEncoderTest.java @@ -1,5 +1,6 @@ package dev.toonformat.jtoon.encoder; +import dev.toonformat.jtoon.Delimiter; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Tag; @@ -33,7 +34,7 @@ class EncodePrimitiveBoolean { @DisplayName("should encode true") void testTrue() { // Given - String result = PrimitiveEncoder.encodePrimitive(BooleanNode.TRUE, ","); + String result = PrimitiveEncoder.encodePrimitive(BooleanNode.TRUE, Delimiter.COMMA.toString()); // Then assertEquals("true", result); @@ -43,7 +44,7 @@ void testTrue() { @DisplayName("should encode false") void testFalse() { // Given - String result = PrimitiveEncoder.encodePrimitive(BooleanNode.FALSE, ","); + String result = PrimitiveEncoder.encodePrimitive(BooleanNode.FALSE, Delimiter.COMMA.toString()); // Then assertEquals("false", result); @@ -58,7 +59,7 @@ class EncodePrimitiveNumber { @DisplayName("should encode integer") void testInteger() { // Given - String result = PrimitiveEncoder.encodePrimitive(IntNode.valueOf(42), ","); + String result = PrimitiveEncoder.encodePrimitive(IntNode.valueOf(42), Delimiter.COMMA.toString()); // Then assertEquals("42", result); @@ -68,7 +69,7 @@ void testInteger() { @DisplayName("should encode negative integer") void testNegativeInteger() { // Given - String result = PrimitiveEncoder.encodePrimitive(IntNode.valueOf(-100), ","); + String result = PrimitiveEncoder.encodePrimitive(IntNode.valueOf(-100), Delimiter.COMMA.toString()); // Then assertEquals("-100", result); @@ -78,7 +79,7 @@ void testNegativeInteger() { @DisplayName("should encode zero") void testZero() { // Given - String result = PrimitiveEncoder.encodePrimitive(IntNode.valueOf(0), ","); + String result = PrimitiveEncoder.encodePrimitive(IntNode.valueOf(0), Delimiter.COMMA.toString()); // Then assertEquals("0", result); @@ -88,7 +89,7 @@ void testZero() { @DisplayName("should encode long") void testLong() { // Given - String result = PrimitiveEncoder.encodePrimitive(LongNode.valueOf(9999999999L), ","); + String result = PrimitiveEncoder.encodePrimitive(LongNode.valueOf(9999999999L), Delimiter.COMMA.toString()); // Then assertEquals("9999999999", result); @@ -98,7 +99,7 @@ void testLong() { @DisplayName("should encode double") void testDouble() { // Given - String result = PrimitiveEncoder.encodePrimitive(DoubleNode.valueOf(3.14), ","); + String result = PrimitiveEncoder.encodePrimitive(DoubleNode.valueOf(3.14), Delimiter.COMMA.toString()); // Then assertEquals("3.14", result); @@ -108,7 +109,7 @@ void testDouble() { @DisplayName("should encode float") void testFloat() { // Given - String result = PrimitiveEncoder.encodePrimitive(FloatNode.valueOf(2.5f), ","); + String result = PrimitiveEncoder.encodePrimitive(FloatNode.valueOf(2.5f), Delimiter.COMMA.toString()); // Then assertEquals("2.5", result); @@ -118,7 +119,7 @@ void testFloat() { @DisplayName("should encode decimal node") void testDecimal() { // Given - String result = PrimitiveEncoder.encodePrimitive(DecimalNode.valueOf(new java.math.BigDecimal("123.456")), ","); + String result = PrimitiveEncoder.encodePrimitive(DecimalNode.valueOf(new java.math.BigDecimal("123.456")), Delimiter.COMMA.toString()); // Then assertEquals("123.456", result); @@ -133,7 +134,7 @@ class EncodePrimitiveString { @DisplayName("should encode simple string unquoted") void testSimpleString() { // Given - String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("hello"), ","); + String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("hello"), Delimiter.COMMA.toString()); // Then assertEquals("hello", result); @@ -143,7 +144,7 @@ void testSimpleString() { @DisplayName("should quote string with comma when using comma delimiter") void testStringWithComma() { //give - String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("a,b"), ","); + String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("a,b"), Delimiter.COMMA.toString()); // Then assertEquals("\"a,b\"", result); @@ -153,7 +154,7 @@ void testStringWithComma() { @DisplayName("should not quote string with comma when using pipe delimiter") void testStringWithCommaUsingPipe() { // Given - String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("a,b"), "|"); + String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("a,b"), Delimiter.PIPE.toString()); // Then assertEquals("a,b", result); @@ -163,7 +164,7 @@ void testStringWithCommaUsingPipe() { @DisplayName("should quote empty string") void testEmptyString() { // Given - String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf(""), ","); + String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf(""), Delimiter.COMMA.toString()); // Then assertEquals("\"\"", result); @@ -173,7 +174,7 @@ void testEmptyString() { @DisplayName("should quote string that looks like boolean") void testBooleanLikeString() { // Given - String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("true"), ","); + String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("true"), Delimiter.COMMA.toString()); // Then assertEquals("\"true\"", result); @@ -183,7 +184,7 @@ void testBooleanLikeString() { @DisplayName("should quote string that looks like null") void testNullLikeString() { // Given - String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("null"), ","); + String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("null"), Delimiter.COMMA.toString()); // Then assertEquals("\"null\"", result); @@ -193,7 +194,7 @@ void testNullLikeString() { @DisplayName("should quote string that looks like number") void testNumberLikeString() { // Given - String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("123"), ","); + String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("123"), Delimiter.COMMA.toString()); // Then assertEquals("\"123\"", result); @@ -208,7 +209,7 @@ class EncodePrimitiveNull { @DisplayName("should encode null") void testNull() { // Given - String result = PrimitiveEncoder.encodePrimitive(NullNode.getInstance(), ","); + String result = PrimitiveEncoder.encodePrimitive(NullNode.getInstance(), Delimiter.COMMA.toString()); // Then assertEquals("null", result); @@ -223,7 +224,7 @@ class EncodeStringLiteral { @DisplayName("should encode simple string without quotes") void testSimpleString() { // Given - String result = PrimitiveEncoder.encodeStringLiteral("hello world", ","); + String result = PrimitiveEncoder.encodeStringLiteral("hello world", Delimiter.COMMA.toString()); // Then assertEquals("hello world", result); @@ -233,7 +234,7 @@ void testSimpleString() { @DisplayName("should quote and escape string with quotes") void testStringWithQuotes() { // Given - String result = PrimitiveEncoder.encodeStringLiteral("say \"hi\"", ","); + String result = PrimitiveEncoder.encodeStringLiteral("say \"hi\"", Delimiter.COMMA.toString()); // Then assertEquals("\"say \\\"hi\\\"\"", result); @@ -243,7 +244,7 @@ void testStringWithQuotes() { @DisplayName("should quote string with leading space") void testLeadingSpace() { // Given - String result = PrimitiveEncoder.encodeStringLiteral(" hello", ","); + String result = PrimitiveEncoder.encodeStringLiteral(" hello", Delimiter.COMMA.toString()); // Then assertEquals("\" hello\"", result); @@ -253,7 +254,7 @@ void testLeadingSpace() { @DisplayName("should quote string with trailing space") void testTrailingSpace() { // Given - String result = PrimitiveEncoder.encodeStringLiteral("hello ", ","); + String result = PrimitiveEncoder.encodeStringLiteral("hello ", Delimiter.COMMA.toString()); // Then assertEquals("\"hello \"", result); @@ -263,7 +264,7 @@ void testTrailingSpace() { @DisplayName("should quote string with colon") void testColon() { // Given - String result = PrimitiveEncoder.encodeStringLiteral("key:value", ","); + String result = PrimitiveEncoder.encodeStringLiteral("key:value", Delimiter.COMMA.toString()); // Then assertEquals("\"key:value\"", result); @@ -273,7 +274,7 @@ void testColon() { @DisplayName("should quote string with active delimiter") void testDelimiter() { // Given - String result = PrimitiveEncoder.encodeStringLiteral("a,b,c", ","); + String result = PrimitiveEncoder.encodeStringLiteral("a,b,c", Delimiter.COMMA.toString()); // Then assertEquals("\"a,b,c\"", result); @@ -283,7 +284,7 @@ void testDelimiter() { @DisplayName("should not quote string with inactive delimiter") void testInactiveDelimiter() { // Given - String result = PrimitiveEncoder.encodeStringLiteral("a|b|c", ","); + String result = PrimitiveEncoder.encodeStringLiteral("a|b|c", Delimiter.COMMA.toString()); // Then assertEquals("a|b|c", result); @@ -383,7 +384,7 @@ void testJoinWithComma() { BooleanNode.TRUE); // When - String result = PrimitiveEncoder.joinEncodedValues(values, ","); + String result = PrimitiveEncoder.joinEncodedValues(values, Delimiter.COMMA.toString()); // Then assertEquals("1,hello,true", result); @@ -399,7 +400,7 @@ void testJoinWithPipe() { IntNode.valueOf(2)); // When - String result = PrimitiveEncoder.joinEncodedValues(values, "|"); + String result = PrimitiveEncoder.joinEncodedValues(values, Delimiter.PIPE.toString()); // Then assertEquals("1|test|2", result); @@ -415,7 +416,7 @@ void testJoinWithTab() { StringNode.valueOf("c")); // When - String result = PrimitiveEncoder.joinEncodedValues(values, "\t"); + String result = PrimitiveEncoder.joinEncodedValues(values, Delimiter.TAB.toString()); // Then assertEquals("a\tb\tc", result); @@ -428,7 +429,7 @@ void testEmptyList() { List values = List.of(); // When - String result = PrimitiveEncoder.joinEncodedValues(values, ","); + String result = PrimitiveEncoder.joinEncodedValues(values, Delimiter.COMMA.toString()); // Then assertEquals("", result); @@ -441,7 +442,7 @@ void testSingleValue() { List values = List.of(IntNode.valueOf(42)); // When - String result = PrimitiveEncoder.joinEncodedValues(values, ","); + String result = PrimitiveEncoder.joinEncodedValues(values, Delimiter.COMMA.toString()); // Then assertEquals("42", result); @@ -456,7 +457,7 @@ void testQuoteDelimiter() { StringNode.valueOf("c,d")); // When - String result = PrimitiveEncoder.joinEncodedValues(values, ","); + String result = PrimitiveEncoder.joinEncodedValues(values, Delimiter.COMMA.toString()); // Then assertEquals("\"a,b\",\"c,d\"", result); @@ -472,7 +473,7 @@ void testNullValues() { IntNode.valueOf(2)); // When - String result = PrimitiveEncoder.joinEncodedValues(values, ","); + String result = PrimitiveEncoder.joinEncodedValues(values, Delimiter.COMMA.toString()); // Then assertEquals("1,null,2", result); @@ -487,7 +488,7 @@ class FormatHeader { @DisplayName("should format simple array header") void testSimpleHeader() { // Given - String result = PrimitiveEncoder.formatHeader(5, "items", null, ",", false); + String result = PrimitiveEncoder.formatHeader(5, "items", null, Delimiter.COMMA.toString(), false); // Then assertEquals("items[5]:", result); @@ -500,7 +501,7 @@ void testTabularHeader() { List fields = List.of("id", "name"); // When - String result = PrimitiveEncoder.formatHeader(3, "users", fields, ",", false); + String result = PrimitiveEncoder.formatHeader(3, "users", fields, Delimiter.COMMA.toString(), false); // Then assertEquals("users[3]{id,name}:", result); @@ -510,7 +511,7 @@ void testTabularHeader() { @DisplayName("should format header with length marker") void testWithLengthMarker() { // Given - String result = PrimitiveEncoder.formatHeader(5, "data", null, ",", true); + String result = PrimitiveEncoder.formatHeader(5, "data", null, Delimiter.COMMA.toString(), true); // Then assertEquals("data[#5]:", result); @@ -523,7 +524,7 @@ void testPipeDelimiter() { List fields = List.of("x", "y"); // When - String result = PrimitiveEncoder.formatHeader(2, "points", fields, "|", false); + String result = PrimitiveEncoder.formatHeader(2, "points", fields, Delimiter.PIPE.toString(), false); // Then assertEquals("points[2|]{x|y}:", result); @@ -533,7 +534,7 @@ void testPipeDelimiter() { @DisplayName("should format header without key") void testWithoutKey() { // Given - String result = PrimitiveEncoder.formatHeader(3, null, null, ",", false); + String result = PrimitiveEncoder.formatHeader(3, null, null, Delimiter.COMMA.toString(), false); // Then assertEquals("[3]:", result); @@ -543,12 +544,12 @@ void testWithoutKey() { @Nested @DisplayName("Edge Cases and Integration") class EdgeCasesIntegration { - +// @Test @DisplayName("should handle Unicode in string encoding") void testUnicode() { // Given - String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("Hello 世界"), ","); + String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("Hello 世界"), Delimiter.COMMA.toString()); // Then assertEquals("Hello 世界", result); @@ -558,7 +559,7 @@ void testUnicode() { @DisplayName("should handle emoji in string encoding") void testEmoji() { // Given - String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("Hello 🌍"), ","); + String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("Hello 🌍"), Delimiter.COMMA.toString()); // Then assertEquals("Hello 🌍", result); @@ -568,7 +569,7 @@ void testEmoji() { @DisplayName("should handle complex escaped string") void testComplexEscaping() { // Given - String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("line1\nline2\ttab"), ","); + String result = PrimitiveEncoder.encodePrimitive(StringNode.valueOf("line1\nline2\ttab"), Delimiter.COMMA.toString()); // Then assertEquals("\"line1\\nline2\\ttab\"", result); @@ -586,7 +587,7 @@ void testMixedTypes() { DoubleNode.valueOf(3.14)); // When - String result = PrimitiveEncoder.joinEncodedValues(values, ","); + String result = PrimitiveEncoder.joinEncodedValues(values, Delimiter.COMMA.toString()); // Then assertEquals("123,text,false,null,3.14", result); diff --git a/src/test/java/dev/toonformat/jtoon/util/ConstantsTest.java b/src/test/java/dev/toonformat/jtoon/util/ConstantsTest.java index 358cf18..bd5be9a 100644 --- a/src/test/java/dev/toonformat/jtoon/util/ConstantsTest.java +++ b/src/test/java/dev/toonformat/jtoon/util/ConstantsTest.java @@ -7,7 +7,26 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import static org.junit.jupiter.api.Assertions.*; +import static dev.toonformat.jtoon.util.Constants.LIST_ITEM_PREFIX; +import static dev.toonformat.jtoon.util.Constants.LIST_ITEM_MARKER; +import static dev.toonformat.jtoon.util.Constants.COMMA; +import static dev.toonformat.jtoon.util.Constants.COLON; +import static dev.toonformat.jtoon.util.Constants.SPACE; +import static dev.toonformat.jtoon.util.Constants.DOT; +import static dev.toonformat.jtoon.util.Constants.HASHTAG; +import static dev.toonformat.jtoon.util.Constants.OPEN_BRACKET; +import static dev.toonformat.jtoon.util.Constants.CLOSE_BRACKET; +import static dev.toonformat.jtoon.util.Constants.OPEN_BRACE; +import static dev.toonformat.jtoon.util.Constants.CLOSE_BRACE; +import static dev.toonformat.jtoon.util.Constants.NULL_LITERAL; +import static dev.toonformat.jtoon.util.Constants.TRUE_LITERAL; +import static dev.toonformat.jtoon.util.Constants.FALSE_LITERAL; +import static dev.toonformat.jtoon.util.Constants.BACKSLASH; +import static dev.toonformat.jtoon.util.Constants.DOUBLE_QUOTE; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; /** * Unit tests for Constants. @@ -31,4 +50,84 @@ void throwsOnConstructor() throws NoSuchMethodException { assertInstanceOf(UnsupportedOperationException.class, cause); assertEquals("Utility class cannot be instantiated", cause.getMessage()); } + + @Test + void expectsListItemMarker() { + assertEquals("-", LIST_ITEM_MARKER); + } + + @Test + void expectsListItemPrefix() { + assertEquals("- ", LIST_ITEM_PREFIX); + } + + @Test + void expectsComma() { + assertEquals(",", COMMA); + } + + @Test + void expectsColon() { + assertEquals(":", COLON); + } + + @Test + void expectsSpace() { + assertEquals(" ", SPACE); + } + + @Test + void expectsDot() { + assertEquals(".", DOT); + } + + @Test + void expectsHashtag() { + assertEquals("#", HASHTAG); + } + + @Test + void expectsOpenBracket() { + assertEquals("[", OPEN_BRACKET); + } + + @Test + void expectsCloseBracket() { + assertEquals("]", CLOSE_BRACKET); + } + + @Test + void expectsOpenBrace() { + assertEquals("{", OPEN_BRACE); + } + + @Test + void expectsCloseBrace() { + assertEquals("}", CLOSE_BRACE); + } + + @Test + void expectsNullLiteral() { + assertEquals("null", NULL_LITERAL); + } + + @Test + void expectsTrueLiteral() { + assertEquals("true", TRUE_LITERAL); + } + + @Test + void expectsFalseLiteral() { + assertEquals("false", FALSE_LITERAL); + } + + @Test + void expectsBackslash() { + assertEquals('\\', BACKSLASH); + } + + @Test + void expectsDoubleQuote() { + assertEquals('"', DOUBLE_QUOTE); + } } diff --git a/src/test/java/dev/toonformat/jtoon/util/StringValidatorTest.java b/src/test/java/dev/toonformat/jtoon/util/StringValidatorTest.java index 02df727..dee43f7 100644 --- a/src/test/java/dev/toonformat/jtoon/util/StringValidatorTest.java +++ b/src/test/java/dev/toonformat/jtoon/util/StringValidatorTest.java @@ -1,5 +1,6 @@ package dev.toonformat.jtoon.util; +import dev.toonformat.jtoon.Delimiter; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Tag; @@ -25,64 +26,64 @@ class IsSafeUnquotedBasic { @DisplayName("should return false for null") void testNullValue() { // Then - assertFalse(StringValidator.isSafeUnquoted(null, ",")); + assertFalse(StringValidator.isSafeUnquoted(null, Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for empty string") void testEmptyString() { // Then - assertFalse(StringValidator.isSafeUnquoted("", ",")); + assertFalse(StringValidator.isSafeUnquoted("", Delimiter.COMMA.toString())); } @Test @DisplayName("should return true for simple alphanumeric string") void testSimpleString() { // Then - assertTrue(StringValidator.isSafeUnquoted("hello123", ",")); + assertTrue(StringValidator.isSafeUnquoted("hello123", Delimiter.COMMA.toString())); } @Test @DisplayName("should return true for string with spaces") void testStringWithInnerSpaces() { // Then - assertTrue(StringValidator.isSafeUnquoted("hello world", ",")); + assertTrue(StringValidator.isSafeUnquoted("hello world", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for a number") void testNumber() { // Then - assertFalse(StringValidator.isSafeUnquoted("123456", ",")); + assertFalse(StringValidator.isSafeUnquoted("123456", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for a Scientific Notation number") void testScientificNumber() { // Then - assertFalse(StringValidator.isSafeUnquoted("-2.5E-8", ",")); - assertFalse(StringValidator.isSafeUnquoted("1e10", ",")); + assertFalse(StringValidator.isSafeUnquoted("-2.5E-8", Delimiter.COMMA.toString())); + assertFalse(StringValidator.isSafeUnquoted("1e10", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for a octal number") void testOctalNumber() { // Then - assertFalse(StringValidator.isSafeUnquoted("07", ",")); + assertFalse(StringValidator.isSafeUnquoted("07", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for a number with a leading zero") void testLeadingZeroNumber() { // Then - assertFalse(StringValidator.isSafeUnquoted("0.07", ",")); + assertFalse(StringValidator.isSafeUnquoted("0.07", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for a negative number with a leading zero") void testLeadingNegativeZeroNumber() { // Then - assertFalse(StringValidator.isSafeUnquoted("-0.07", ",")); + assertFalse(StringValidator.isSafeUnquoted("-0.07", Delimiter.COMMA.toString())); } } @@ -94,28 +95,28 @@ class WhitespacePadding { @DisplayName("should return false for leading space") void testLeadingSpace() { // Then - assertFalse(StringValidator.isSafeUnquoted(" hello", ",")); + assertFalse(StringValidator.isSafeUnquoted(" hello", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for trailing space") void testTrailingSpace() { // Then - assertFalse(StringValidator.isSafeUnquoted("hello ", ",")); + assertFalse(StringValidator.isSafeUnquoted("hello ", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for both leading and trailing spaces") void testBothSpaces() { // Then - assertFalse(StringValidator.isSafeUnquoted(" hello ", ",")); + assertFalse(StringValidator.isSafeUnquoted(" hello ", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for only spaces") void testOnlySpaces() { // Then - assertFalse(StringValidator.isSafeUnquoted(" ", ",")); + assertFalse(StringValidator.isSafeUnquoted(" ", Delimiter.COMMA.toString())); } } @@ -127,28 +128,28 @@ class Keywords { @DisplayName("should return false for 'true'") void testTrueKeyword() { // Then - assertFalse(StringValidator.isSafeUnquoted("true", ",")); + assertFalse(StringValidator.isSafeUnquoted("true", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for 'false'") void testFalseKeyword() { // Then - assertFalse(StringValidator.isSafeUnquoted("false", ",")); + assertFalse(StringValidator.isSafeUnquoted("false", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for 'null'") void testNullKeyword() { // Then - assertFalse(StringValidator.isSafeUnquoted("null", ",")); + assertFalse(StringValidator.isSafeUnquoted("null", Delimiter.COMMA.toString())); } @Test @DisplayName("should return true for 'True' (case sensitive)") void testTrueCaseSensitive() { // Then - assertTrue(StringValidator.isSafeUnquoted("True", ",")); + assertTrue(StringValidator.isSafeUnquoted("True", Delimiter.COMMA.toString())); } } @@ -160,44 +161,44 @@ class Numbers { @DisplayName("should return false for integer") void testInteger() { // Then - assertFalse(StringValidator.isSafeUnquoted("123", ",")); + assertFalse(StringValidator.isSafeUnquoted("123", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for negative integer") void testNegativeInteger() { // Then - assertFalse(StringValidator.isSafeUnquoted("-456", ",")); + assertFalse(StringValidator.isSafeUnquoted("-456", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for decimal") void testDecimal() { // Then - assertFalse(StringValidator.isSafeUnquoted("3.14", ",")); + assertFalse(StringValidator.isSafeUnquoted("3.14", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for scientific notation") void testScientificNotation() { // Then - assertFalse(StringValidator.isSafeUnquoted("1.5e10", ",")); - assertFalse(StringValidator.isSafeUnquoted("1.5E-10", ",")); + assertFalse(StringValidator.isSafeUnquoted("1.5e10", Delimiter.COMMA.toString())); + assertFalse(StringValidator.isSafeUnquoted("1.5E-10", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for octal-like numbers") void testOctalNumber() { // Then - assertFalse(StringValidator.isSafeUnquoted("0123", ",")); - assertFalse(StringValidator.isSafeUnquoted("0777", ",")); + assertFalse(StringValidator.isSafeUnquoted("0123", Delimiter.COMMA.toString())); + assertFalse(StringValidator.isSafeUnquoted("0777", Delimiter.COMMA.toString())); } @Test @DisplayName("should return true for text starting with number") void testTextStartingWithNumber() { // Then - assertTrue(StringValidator.isSafeUnquoted("123abc", ",")); + assertTrue(StringValidator.isSafeUnquoted("123abc", Delimiter.COMMA.toString())); } } @@ -209,35 +210,35 @@ class SpecialCharacters { @DisplayName("should return false for string with colon") void testColon() { // Then - assertFalse(StringValidator.isSafeUnquoted("key:value", ",")); + assertFalse(StringValidator.isSafeUnquoted("key:value", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for string with double quote") void testDoubleQuote() { // Then - assertFalse(StringValidator.isSafeUnquoted("say \"hi\"", ",")); + assertFalse(StringValidator.isSafeUnquoted("say \"hi\"", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for string with backslash") void testBackslash() { // Then - assertFalse(StringValidator.isSafeUnquoted("path\\file", ",")); + assertFalse(StringValidator.isSafeUnquoted("path\\file", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for string with brackets") void testBrackets() { // Then - assertFalse(StringValidator.isSafeUnquoted("array[0]", ",")); + assertFalse(StringValidator.isSafeUnquoted("array[0]", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for string with braces") void testBraces() { // Then - assertFalse(StringValidator.isSafeUnquoted("obj{key}", ",")); + assertFalse(StringValidator.isSafeUnquoted("obj{key}", Delimiter.COMMA.toString())); } } @@ -249,21 +250,21 @@ class ControlCharacters { @DisplayName("should return false for newline") void testNewline() { // Then - assertFalse(StringValidator.isSafeUnquoted("line1\nline2", ",")); + assertFalse(StringValidator.isSafeUnquoted("line1\nline2", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for carriage return") void testCarriageReturn() { // Then - assertFalse(StringValidator.isSafeUnquoted("line1\rline2", ",")); + assertFalse(StringValidator.isSafeUnquoted("line1\rline2", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for tab") void testTab() { // Then - assertFalse(StringValidator.isSafeUnquoted("col1\tcol2", ",")); + assertFalse(StringValidator.isSafeUnquoted("col1\tcol2", Delimiter.COMMA.toString())); } } @@ -275,42 +276,42 @@ class DelimiterAware { @DisplayName("should return false for comma with comma delimiter") void testCommaDelimiter() { // Then - assertFalse(StringValidator.isSafeUnquoted("a,b", ",")); + assertFalse(StringValidator.isSafeUnquoted("a,b", Delimiter.COMMA.toString())); } @Test @DisplayName("should return true for comma with pipe delimiter") void testCommaWithPipeDelimiter() { // Then - assertTrue(StringValidator.isSafeUnquoted("a,b", "|")); + assertTrue(StringValidator.isSafeUnquoted("a,b", Delimiter.PIPE.toString())); } @Test @DisplayName("should return false for pipe with pipe delimiter") void testPipeDelimiter() { // Then - assertFalse(StringValidator.isSafeUnquoted("a|b", "|")); + assertFalse(StringValidator.isSafeUnquoted("a|b", Delimiter.PIPE.toString())); } @Test @DisplayName("should return true for pipe with comma delimiter") void testPipeWithCommaDelimiter() { // Then - assertTrue(StringValidator.isSafeUnquoted("a|b", ",")); + assertTrue(StringValidator.isSafeUnquoted("a|b", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for tab with tab delimiter") void testTabDelimiter() { // Then - assertFalse(StringValidator.isSafeUnquoted("a\tb", "\t")); + assertFalse(StringValidator.isSafeUnquoted("a\tb", Delimiter.TAB.toString())); } @Test @DisplayName("should return true for tab with comma delimiter") void testTabWithCommaDelimiter() { // Then - assertFalse(StringValidator.isSafeUnquoted("a\tb", ",")); // Still false due to control char + assertFalse(StringValidator.isSafeUnquoted("a\tb", Delimiter.COMMA.toString())); // Still false due to control char } } @@ -322,21 +323,21 @@ class ListMarker { @DisplayName("should return false for string starting with list marker") void testListMarker() { // Then - assertFalse(StringValidator.isSafeUnquoted("- item", ",")); + assertFalse(StringValidator.isSafeUnquoted("- item", Delimiter.COMMA.toString())); } @Test @DisplayName("should return true for string containing but not starting with dash-space") void testDashSpaceInMiddle() { // Then - assertTrue(StringValidator.isSafeUnquoted("item - note", ",")); + assertTrue(StringValidator.isSafeUnquoted("item - note", Delimiter.COMMA.toString())); } @Test @DisplayName("should return false for string starting with dash") void testDashWithoutSpace() { // Then - assertFalse(StringValidator.isSafeUnquoted("-item", ",")); + assertFalse(StringValidator.isSafeUnquoted("-item", Delimiter.COMMA.toString())); } } @@ -348,34 +349,34 @@ class SafeStrings { @DisplayName("should return true for alphanumeric with underscores") void testAlphanumericUnderscore() { // Then - assertTrue(StringValidator.isSafeUnquoted("hello_world_123", ",")); + assertTrue(StringValidator.isSafeUnquoted("hello_world_123", Delimiter.COMMA.toString())); } @Test @DisplayName("should return true for string with hyphens") void testHyphens() { // Then - assertTrue(StringValidator.isSafeUnquoted("hello-world", ",")); + assertTrue(StringValidator.isSafeUnquoted("hello-world", Delimiter.COMMA.toString())); } @Test @DisplayName("should return true for string with dots") void testDots() { // Then - assertTrue(StringValidator.isSafeUnquoted("hello.world", ",")); + assertTrue(StringValidator.isSafeUnquoted("hello.world", Delimiter.COMMA.toString())); } @Test @DisplayName("should return true for Unicode characters") void testUnicode() { // Then - assertTrue(StringValidator.isSafeUnquoted("Hello 世界", ",")); + assertTrue(StringValidator.isSafeUnquoted("Hello 世界", Delimiter.COMMA.toString())); } @Test @DisplayName("should return true for emoji") void testEmoji() { - assertTrue(StringValidator.isSafeUnquoted("Hello 🌍", ",")); + assertTrue(StringValidator.isSafeUnquoted("Hello 🌍", Delimiter.COMMA.toString())); } }