Skip to content

Commit

Permalink
handle escape chars and add unit tests in java v2
Browse files Browse the repository at this point in the history
  • Loading branch information
yiyuan-he committed Dec 13, 2024
1 parent 1d1699d commit 64da476
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ private char currentChar() {
return json.charAt(position);
}

private static boolean isHexDigit(char c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}

private void expect(char c) {
skipWhitespace();
if (currentChar() != c) {
Expand All @@ -56,12 +60,55 @@ private String readString() {
expect('"'); // Ensure the string starts with a quote
StringBuilder result = new StringBuilder();
while (currentChar() != '"') {
// Handle escaped quotes within the string
if (currentChar() == '\\'
&& position + 1 < json.length()
&& json.charAt(position + 1) == '"') {
result.append('"');
position += 2; // Skip the backslash and the escaped quote
// Handle escape sequences
if (currentChar() == '\\') {
position++; // Move past the backslash
if (position >= json.length()) {
throw new IllegalArgumentException("Unexpected end of input in string escape sequence");
}
char escapeChar = currentChar();
switch (escapeChar) {
case '"':
case '\\':
case '/':
result.append(escapeChar);
break;
case 'b':
result.append('\b');
break;
case 'f':
result.append('\f');
break;
case 'n':
result.append('\n');
break;
case 'r':
result.append('\r');
break;
case 't':
result.append('\t');
break;
case 'u': // Unicode escape sequence
if (position + 4 >= json.length()) {
throw new IllegalArgumentException("Invalid unicode escape sequence in string");
}
char[] hexChars = new char[4];
for (int i = 0; i < 4; i++) {
position++; // Move to the next character
char hexChar = json.charAt(position);
if (!isHexDigit(hexChar)) {
throw new IllegalArgumentException(
"Invalid hexadecimal digit in unicode escape sequence");
}
hexChars[i] = hexChar;
}
int unicodeValue = Integer.parseInt(new String(hexChars), 16);
result.append((char) unicodeValue);
break;
default:
throw new IllegalArgumentException("Invalid escape character: \\" + escapeChar);
}
position++;
} else {
result.append(currentChar());
position++;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.awssdk.v2_2;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Map;
import org.junit.Test;

public class BedrockJsonParserTest {

@Test
public void shouldParseSimpleObject() {
// given
String json = "{\"key\":\"value\",\"number\":123,\"boolean\":true}";

// when
LlmJson parsedJson = BedrockJsonParser.parse(json);

// then
assertThat(parsedJson.getJsonBody()).containsEntry("key", "value");
assertThat(parsedJson.getJsonBody()).containsEntry("number", 123);
assertThat(parsedJson.getJsonBody()).containsEntry("boolean", true);
}

@Test
public void shouldParseNestedObject() {
// given
String json = "{\"parent\":{\"child\":\"value\"}}";

// when
LlmJson parsedJson = BedrockJsonParser.parse(json);

// then
Object parentObj = parsedJson.getJsonBody().get("parent");
assertThat(parentObj).isInstanceOf(Map.class); // Ensure it's a Map

@SuppressWarnings("unchecked")
Map<String, Object> parent = (Map<String, Object>) parentObj;
assertThat(parent).containsEntry("child", "value");
}

@Test
public void shouldParseEscapeSequences() {
// given
String json =
"{\"escaped\":\"Line1\\nLine2\\tTabbed\\\"Quoted\\\"\\bBackspace\\fFormfeed\\rCarriageReturn\\\\Backslash\\/Slash\\u0041\"}";

// when
LlmJson parsedJson = BedrockJsonParser.parse(json);

// then
assertThat(parsedJson.getJsonBody())
.containsEntry(
"escaped",
"Line1\nLine2\tTabbed\"Quoted\"\bBackspace\fFormfeed\rCarriageReturn\\Backslash/SlashA");
}

@Test
public void shouldParseUnicodeEscapeSequences() {
// given
String json = "{\"unicode\":\"\\u0041\\u0042\\u0043\"}";

// when
LlmJson parsedJson = BedrockJsonParser.parse(json);

// then
assertThat(parsedJson.getJsonBody()).containsEntry("unicode", "ABC");
}

@Test
public void shouldHandleEmptyObject() {
// given
String json = "{}";

// when
LlmJson parsedJson = BedrockJsonParser.parse(json);

// then
assertThat(parsedJson.getJsonBody()).isEmpty();
}

@Test
public void shouldHandleEmptyArray() {
// given
String json = "{\"array\":[]}";

// when
LlmJson parsedJson = BedrockJsonParser.parse(json);

// then
assertThat(parsedJson.getJsonBody()).containsKey("array");
assertThat((Iterable<?>) parsedJson.getJsonBody().get("array")).isEmpty();
}
}

0 comments on commit 64da476

Please sign in to comment.