Skip to content

Commit

Permalink
Merge pull request #16 from fauna/feature/BT-4418-utf8faunareader_rea…
Browse files Browse the repository at this point in the history
…d_int

[BT-4418] FaunaParser Integer values
  • Loading branch information
pchitolina-fauna authored Jan 29, 2024
2 parents 7ec23fa + 8df98d8 commit c300f11
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 21 deletions.
82 changes: 78 additions & 4 deletions faunaJava/src/main/java/com/fauna/serialization/FaunaParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public class FaunaParser {
private FaunaTokenType bufferedFaunaTokenType;
private String taggedTokenValue;

private enum TokenTypeInternal {
START_ESCAPED_OBJECT
}

public FaunaParser(InputStream body) throws IOException {
JsonFactory factory = new JsonFactory();
this.jsonParser = factory.createParser(body);
Expand All @@ -52,8 +56,8 @@ public FaunaParser(JsonParser jsonParser) {
currentFaunaTokenType = NONE;
}

public JsonToken getCurrentTokenType() {
return jsonParser.currentToken();
public FaunaTokenType getCurrentTokenType() {
return currentFaunaTokenType;
}

private final Set<FaunaTokenType> closers = new HashSet<>(Arrays.asList(
Expand All @@ -64,7 +68,7 @@ public JsonToken getCurrentTokenType() {
END_ARRAY
));

public boolean read() {
public boolean read() throws IOException {
taggedTokenValue = null;

if (bufferedFaunaTokenType != null) {
Expand All @@ -86,6 +90,9 @@ public boolean read() {
case VALUE_STRING:
currentFaunaTokenType = FaunaTokenType.STRING;
break;
case START_OBJECT:
handleStartObject();
break;
default:
throw new SerializationException(
"Unhandled JSON token type " + currentToken + ".");
Expand All @@ -97,6 +104,55 @@ public boolean read() {
return true;
}

private void handleStartObject() throws IOException {
advanceTrue();

switch (jsonParser.currentToken()) {
case FIELD_NAME:
switch (jsonParser.getText()) {
case INT_TAG:
handleTaggedString(FaunaTokenType.INT);
break;
case DATE_TAG:
case DOC_TAG:
case DOUBLE_TAG:
case LONG_TAG:
case MOD_TAG:
case OBJECT_TAG:
case REF_TAG:
case SET_TAG:
case TIME_TAG:
throw new SerializationException(
"Token not implemented: " + jsonParser.currentToken());
default:
bufferedFaunaTokenType = FaunaTokenType.FIELD_NAME;
tokenStack.push(FaunaTokenType.START_OBJECT);
currentFaunaTokenType = FaunaTokenType.START_OBJECT;
break;
}
break;
case END_OBJECT:
throw new SerializationException(
"Token not implemented: " + jsonParser.currentToken());
default:
throw new SerializationException(
"Unexpected token following StartObject: " + jsonParser.currentToken());
}
}

private void handleTaggedString(FaunaTokenType token) throws IOException {
advanceTrue();
currentFaunaTokenType = token;
taggedTokenValue = jsonParser.getText();
advance();
}

private void advanceTrue() {
if (!advance()) {
throw new SerializationException("Unexpected end of underlying JSON reader.");
}
}

private boolean advance() {
try {
return Objects.nonNull(jsonParser.nextToken());
Expand All @@ -105,11 +161,29 @@ private boolean advance() {
}
}

private void validateTaggedType(FaunaTokenType type) {
if (currentFaunaTokenType != type || taggedTokenValue == null
|| !(taggedTokenValue instanceof String)) {
throw new IllegalStateException(
"CurrentTokenType is a " + currentFaunaTokenType.toString() +
", not a " + type.toString() + ".");
}
}

public String getValueAsString() {
try {
return jsonParser.getValueAsString();
} catch (IOException e) {
throw new RuntimeException("Error reading current token as String", e);
throw new RuntimeException("Error getting the current token as String", e);
}
}

public Integer getValueAsInt() {
validateTaggedType(FaunaTokenType.INT);
try {
return Integer.parseInt(taggedTokenValue);
} catch (NumberFormatException e) {
throw new RuntimeException("Error getting the current token as Integer", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.fauna.query.template;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class FaunaTemplateTest {

Expand Down Expand Up @@ -63,16 +62,4 @@ void testTemplates_WithEscapes() {
assertEquals(TemplatePartType.LITERAL, expanded.get(1).getType());
}

@Test
void testTemplates_WithUnsupportedIdentifiers() {
FaunaTemplate template = new FaunaTemplate("let x = ${かわいい}");
Exception exception = assertThrows(IllegalArgumentException.class, () -> {
List<FaunaTemplate.TemplatePart> expanded = new ArrayList<>();
template.forEach(expanded::add);
});
String expectedMessage = "Invalid placeholder in template: line 1, col 9";
String actualMessage = exception.getMessage();
assertTrue(actualMessage.contains(expectedMessage));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.fauna.common.enums.FaunaTokenType;
import com.fauna.exception.SerializationException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
Expand All @@ -28,19 +30,51 @@ public void testGetValueAsString() throws IOException {
assertReader(reader, expectedTokens);
}

@Test
public void testGetValueAsInt() throws IOException {
String s = "{\"@int\": \"123\"}";
InputStream inputStream = new ByteArrayInputStream(s.getBytes());
FaunaParser reader = new FaunaParser(inputStream);

List<Map.Entry<FaunaTokenType, Object>> expectedTokens = List.of(
Map.entry(FaunaTokenType.INT, 123)
);

assertReader(reader, expectedTokens);

String invalidJson = "{\"@int\": \"abc\"}";
InputStream invalidInputStream = new ByteArrayInputStream(invalidJson.getBytes());
FaunaParser invalidReader = new FaunaParser(invalidInputStream);

assertThrows(RuntimeException.class, invalidReader::getValueAsInt);
}

@Test
public void testUnexpectedEndDuringAdvance() throws IOException {

String json = "{\"@int\": \"123\"";
InputStream inputStream = new ByteArrayInputStream(json.getBytes());
FaunaParser reader = new FaunaParser(inputStream);

assertThrows(SerializationException.class, reader::read);
}

private static void assertReader(FaunaParser reader,
List<Map.Entry<FaunaTokenType, Object>> tokens) {
List<Map.Entry<FaunaTokenType, Object>> tokens) throws IOException {
for (Map.Entry<FaunaTokenType, Object> entry : tokens) {
reader.read();
assertNotNull(entry.getKey());
assertNotNull(reader.getCurrentTokenType());
assertEquals(entry.getKey(), FaunaTokenType.STRING);
assertEquals(entry.getKey(), reader.getCurrentTokenType());

switch (entry.getKey()) {
case FIELD_NAME:
case STRING:
assertEquals(entry.getValue(), reader.getValueAsString());
break;
case INT:
assertEquals(entry.getValue(), reader.getValueAsInt());
break;
default:
assertNull(entry.getValue() == null);
break;
Expand Down

0 comments on commit c300f11

Please sign in to comment.