Skip to content

Commit

Permalink
fix tests and checkstyle
Browse files Browse the repository at this point in the history
  • Loading branch information
nkramer44 committed Oct 18, 2024
1 parent 9f96789 commit 1ec7628
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public JsonNode toJson() {
if (field.name().equals(OBJECT_END_MARKER)) {
break;
}
JsonNode value = parser.readFieldValue(field).toJson();
JsonNode value = parser.readFieldValue(field).toJson(field);
JsonNode mapped = definitionsService.mapFieldRawValueToSpecialization(field.name(), value.asText())
.map(TextNode::new)
.map(JsonNode.class::cast)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,23 @@ public T fromParser(BinaryParser parser, int lengthHint) {
* @param node A {@link JsonNode} to use.
*
* @return A {@link T} based upon the information found in {@code node}.
*
* @throws JsonProcessingException if {@code node} is not well-formed JSON.
*/
public abstract T fromJson(JsonNode node) throws JsonProcessingException;

/**
* Obtain a {@link T} using the supplied {@link JsonNode} as well as a {@link FieldInstance}. Prefer using this method
* where possible over {@link #fromJson(JsonNode)}, as some {@link SerializedType}s require a {@link FieldInstance} to
* accurately serialize and deserialize.
*
* @param node A {@link JsonNode} to serialize to binary.
* @param fieldInstance The {@link FieldInstance} describing the field being serialized.
*
* @return A {@link T}.
*
* @throws JsonProcessingException If {@code node} is not well-formed JSON.
*/
public T fromJson(JsonNode node, FieldInstance fieldInstance) throws JsonProcessingException {
return fromJson(node);
}
Expand Down Expand Up @@ -207,6 +220,15 @@ public JsonNode toJson() {
return new TextNode(toHex());
}

/**
* Convert this {@link SerializedType} to a {@link JsonNode} based on the supplied {@link FieldInstance}. Prefer using
* this method where possible over {@link #fromJson(JsonNode)}, as some {@link SerializedType}s require a
* {@link FieldInstance} to accurately serialize and deserialize.
*
* @param fieldInstance A {@link FieldInstance} describing the field being deserialized.
*
* @return A {@link JsonNode}.
*/
public JsonNode toJson(FieldInstance fieldInstance) {
return toJson();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@
*/
public class UInt64Type extends UIntType<UInt64Type> {

private static final Set<String> BASE_10_UINT64_FIELD_NAMES = Sets.newHashSet(
/**
* These fields are represented as base 10 Strings in JSON, whereas all other STUInt64s are represented
* in base16.
*/
protected static final Set<String> BASE_10_UINT64_FIELD_NAMES = Sets.newHashSet(
"MaximumAmount", "OutstandingAmount", "MPTAmount"
);

Expand All @@ -57,19 +61,19 @@ public UInt64Type fromJson(JsonNode value) {
"the overload of this method that accepts a FieldInstance instead.");
}

@Override
public JsonNode toJson() {
throw new UnsupportedOperationException("Cannot convert UInt64Type to JSON without a FieldInstance. Call " +
"the overload of this method that accepts a FieldInstance instead.");
}

@Override
public UInt64Type fromJson(JsonNode value, FieldInstance fieldInstance) {
int radix = getRadix(fieldInstance);
// STUInt64s are represented as hex-encoded Strings in JSON.
return new UInt64Type(UnsignedLong.valueOf(value.asText(), radix));
}

@Override
public JsonNode toJson() {
throw new UnsupportedOperationException("Cannot convert UInt64Type to JSON without a FieldInstance. Call " +
"the overload of this method that accepts a FieldInstance instead.");
}

@Override
public JsonNode toJson(FieldInstance fieldInstance) {
int radix = getRadix(fieldInstance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,43 +21,97 @@
*/

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.fasterxml.jackson.databind.node.TextNode;
import com.google.common.base.Strings;
import com.google.common.io.BaseEncoding;
import com.google.common.primitives.UnsignedInteger;
import com.google.common.primitives.UnsignedLong;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.xrpl.xrpl4j.codec.binary.definitions.FieldInstance;

import java.util.stream.Stream;

public class UInt64TypeUnitTest {
private final UInt64Type base16Type = new UInt64Type();
private final UInt64Type type = new UInt64Type();
private static UnsignedLong maxUint64 = UnsignedLong.valueOf("FFFFFFFFFFFFFFFF", 16);

@Test
void decodeBase16() {
assertThat(base16Type.fromHex("0000000000000000").valueOf()).isEqualTo(UnsignedLong.valueOf(0));
assertThat(base16Type.fromHex("000000000000000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15));
assertThat(base16Type.fromHex("00000000FFFFFFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(4294967295L));
assertThat(base16Type.fromHex("FFFFFFFFFFFFFFFF").valueOf()).isEqualTo(maxUint64);
void testFromHex() {
assertThat(type.fromHex("0000000000000000").valueOf()).isEqualTo(UnsignedLong.valueOf(0));
assertThat(type.fromHex("000000000000000F").valueOf()).isEqualTo(UnsignedLong.valueOf(15));
assertThat(type.fromHex("00000000FFFFFFFF").valueOf()).isEqualTo(UnsignedLong.valueOf(4294967295L));
assertThat(type.fromHex("FFFFFFFFFFFFFFFF").valueOf()).isEqualTo(maxUint64);
}

@ParameterizedTest
@MethodSource(value = "base16JsonArguments")
void testFromJsonBase16(TextNode json) {
FieldInstance base16FieldInstance = mock(FieldInstance.class);
when(base16FieldInstance.name()).thenReturn("Base16Field");
assertThat(type.fromJson(json, base16FieldInstance).toHex())
.isEqualTo(Strings.padStart(json.asText(), 16, '0'));
assertThat(type.fromJson(json, base16FieldInstance).toJson(base16FieldInstance)).isEqualTo(json);
}

@ParameterizedTest
@MethodSource(value = "base10JsonArguments")
void testFromJsonBase10(TextNode json) {
UInt64Type.BASE_10_UINT64_FIELD_NAMES.forEach(
b10FieldName -> {
FieldInstance base10FieldInstance = mock(FieldInstance.class);
when(base10FieldInstance.name()).thenReturn(b10FieldName);
String expectedHex = Strings.padStart(UnsignedLong.valueOf(json.asText()).toString(16).toUpperCase(), 16, '0');
assertThat(type.fromJson(json, base10FieldInstance).toHex())
.isEqualTo(expectedHex);
assertThat(type.fromJson(json, base10FieldInstance).toJson(base10FieldInstance)).isEqualTo(json);
}
);
}

@Test
void fromJsonThrowsWithoutFieldInstance() {
assertThatThrownBy(() -> type.fromJson(new TextNode("0")))
.isInstanceOf(UnsupportedOperationException.class);
}

@Test
void encodeBase16() {
assertThat(base16Type.fromJson("\"0\"").toHex()).isEqualTo("0000000000000000");
assertThat(base16Type.fromJson("\"F\"").toHex()).isEqualTo("000000000000000F");
assertThat(base16Type.fromJson("\"FFFF\"").toHex()).isEqualTo("000000000000FFFF");
assertThat(base16Type.fromJson("\"FFFFFFFF\"").toHex()).isEqualTo("00000000FFFFFFFF");
assertThat(base16Type.fromJson("\"FFFFFFFFFFFFFFFF\"").toHex()).isEqualTo("FFFFFFFFFFFFFFFF");
void toJsonThrowsWithoutFieldInstance() {
assertThatThrownBy(type::toJson)
.isInstanceOf(UnsupportedOperationException.class);
}

private static Stream<TextNode> base16JsonArguments() {
return Stream.of(
new TextNode("0"),
new TextNode("F"),
new TextNode("FFFF"),
new TextNode("FFFFFFFF"),
new TextNode("FFFFFFFFFFFFFFFF")
);
}

@ParameterizedTest
@ValueSource(strings = {"\"0\"", "\"F\"", "\"FFFF\"", "\"FFFFFFFF\"", "\"FFFFFFFFFFFFFFFF\""})
void toFromJsonBase16(String json) {
assertThat(base16Type.fromJson(json).toJson().toString()).isEqualTo(json);
private static Stream<TextNode> base10JsonArguments() {
return Stream.of(
new TextNode("0"),
new TextNode("15"),
new TextNode("65535"),
new TextNode("4294967295"),
new TextNode("18446744073709551615")
);
}

@Test
void encodeOutOfBounds() {
assertThrows(IllegalArgumentException.class, () -> base16Type.fromJson("18446744073709551616"));
FieldInstance field = mock(FieldInstance.class);
when(field.name()).thenReturn("Field");
assertThrows(IllegalArgumentException.class, () -> type.fromJson(new TextNode("18446744073709551616"), field));
}
}

0 comments on commit 1ec7628

Please sign in to comment.