JsonNodeBigIntegerValueTest.java
package tools.jackson.databind.node;
import java.math.BigDecimal;
import java.math.BigInteger;
import org.junit.jupiter.api.Test;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.exc.JsonNodeException;
import tools.jackson.databind.util.RawValue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
/**
* Tests for [databind#5003], JsonNode.bigIntegerValue() (and related) parts
* over all types.
*/
public class JsonNodeBigIntegerValueTest
extends NodeTestBase
{
private final JsonNodeFactory NODES = newJsonMapper().getNodeFactory();
// // // bigIntegerValue() tests
@Test
public void bigIntegerValueFromNumberIntOk()
{
// Integer types, byte/short/int/long/BigInteger
_assertBigIntegerValue(BigInteger.ONE, NODES.numberNode((byte) 1));
_assertBigIntegerValue(BigInteger.ONE, NODES.numberNode((short) 1));
_assertBigIntegerValue(BigInteger.ONE, NODES.numberNode(1));
_assertBigIntegerValue(BigInteger.ONE, NODES.numberNode(1L));
_assertBigIntegerValue(BigInteger.ONE, NODES.numberNode(BigInteger.ONE));
}
@Test
public void bigIntegerValueFromNumberFPOk()
{
_assertBigIntegerValue(BigInteger.ONE, NODES.numberNode(1.0f));
_assertBigIntegerValue(bigInt(100_000), NODES.numberNode(100_000.0f));
_assertBigIntegerValue(bigInt(-100_000), NODES.numberNode(-100_000.0f));
_assertBigIntegerValue(BigInteger.ONE, NODES.numberNode(1.0d));
_assertBigIntegerValue(bigInt(100_000_000), NODES.numberNode(100_000_000.0d));
_assertBigIntegerValue(bigInt(-100_000_000), NODES.numberNode(-100_000_000.0d));
_assertBigIntegerValue(BigInteger.ONE,
NODES.numberNode(BigDecimal.valueOf(1.0d)));
_assertBigIntegerValue(bigInt(Long.MIN_VALUE),
NODES.numberNode(new BigDecimal(Long.MIN_VALUE+".0")));
_assertBigIntegerValue(bigInt(Long.MAX_VALUE),
NODES.numberNode(new BigDecimal(Long.MAX_VALUE+".0")));
}
// NOTE: BigInteger has unlimited range so cannot fail for Under-/Overflow (hence no tests)
// ... but there are NaNs:
@Test
public void bigIntegerValueFromNumberFPFailForNaN()
{
_assertFailBigIntegerForNaN(NODES.numberNode(Float.NaN));
_assertFailBigIntegerForNaN(NODES.numberNode(Float.NEGATIVE_INFINITY));
_assertFailBigIntegerForNaN(NODES.numberNode(Float.POSITIVE_INFINITY));
_assertFailBigIntegerForNaN(NODES.numberNode(Double.NaN));
_assertFailBigIntegerForNaN(NODES.numberNode(Double.NEGATIVE_INFINITY));
_assertFailBigIntegerForNaN(NODES.numberNode(Double.POSITIVE_INFINITY));
}
@Test
public void bigIntegerValueFromNumberFPFailFraction()
{
_assertFailBigIntegerValueForFraction(NODES.numberNode(100.5f));
_assertFailBigIntegerValueForFraction(NODES.numberNode(-0.25f));
_assertFailBigIntegerValueForFraction(NODES.numberNode(100.5d));
_assertFailBigIntegerValueForFraction(NODES.numberNode(-0.25d));
_assertFailBigIntegerValueForFraction(NODES.numberNode(BigDecimal.valueOf(100.5d)));
_assertFailBigIntegerValueForFraction(NODES.numberNode(BigDecimal.valueOf(-0.25d)));
}
@Test
public void bigIntegerValueFromNonNumberScalarFail()
{
_assertFailBigIntegerForNonNumber(NODES.booleanNode(true));
_assertFailBigIntegerForNonNumber(NODES.binaryNode(new byte[3]));
_assertFailBigIntegerForNonNumber(NODES.stringNode("123"));
_assertFailBigIntegerForNonNumber(NODES.rawValueNode(new RawValue("abc")));
_assertFailBigIntegerForNonNumber(NODES.pojoNode(Boolean.TRUE));
}
@Test
public void bigIntegerValueFromStructuralFail()
{
_assertFailBigIntegerForNonNumber(NODES.arrayNode(3));
_assertFailBigIntegerForNonNumber(NODES.objectNode());
}
@Test
public void bigIntegerValueFromMiscOtherFail()
{
_assertFailBigIntegerForNonNumber(NODES.nullNode());
_assertFailBigIntegerForNonNumber(NODES.missingNode());
}
// // // asBigInteger()
// // // BigInteger + bigIntegerValue()
@Test
public void asBigIntegerFromNumberIntOk()
{
// Integer types, byte/short/int/long/BigInteger
_assertAsBigInteger(BigInteger.ONE, NODES.numberNode((byte) 1));
_assertAsBigInteger(BigInteger.ONE, NODES.numberNode((short) 1));
_assertAsBigInteger(BigInteger.ONE, NODES.numberNode(1));
_assertAsBigInteger(BigInteger.ONE, NODES.numberNode(1L));
_assertAsBigInteger(BigInteger.ONE, NODES.numberNode(BigInteger.ONE));
}
// NOTE: BigInteger has unlimited range so cannot fail for Under-/Overflow (hence no tests)
@Test
public void asBigIntegerFromNumberFPOk()
{
_assertAsBigInteger(BigInteger.ONE, NODES.numberNode(1.0f));
_assertAsBigInteger(bigInt(100_000), NODES.numberNode(100_000.0f));
_assertAsBigInteger(bigInt(-100_000), NODES.numberNode(-100_000.0f));
_assertAsBigInteger(BigInteger.ONE, NODES.numberNode(1.0d));
_assertAsBigInteger(bigInt(100_000_000), NODES.numberNode(100_000_000.0d));
_assertAsBigInteger(bigInt(-100_000_000), NODES.numberNode(-100_000_000.0d));
_assertAsBigInteger(BigInteger.ONE,
NODES.numberNode(BigDecimal.valueOf(1.0d)));
_assertAsBigInteger(bigInt(Long.MIN_VALUE),
NODES.numberNode(new BigDecimal(Long.MIN_VALUE+".0")));
_assertAsBigInteger(bigInt(Long.MAX_VALUE),
NODES.numberNode(new BigDecimal(Long.MAX_VALUE+".0")));
}
// NOTE: unlike with "bigIntegerValue()", fractions ok: will be rounded
@Test
public void asBigIntegerFromNumberFPFraction()
{
final BigInteger B100 = bigInt(100);
final BigInteger B_MINUS_1 = bigInt(-1);
_assertAsBigInteger(B100, NODES.numberNode(100.75f));
_assertAsBigInteger(B_MINUS_1, NODES.numberNode(-1.25f));
_assertAsBigInteger(B100, NODES.numberNode(100.75d));
_assertAsBigInteger(B_MINUS_1, NODES.numberNode(-1.25d));
_assertAsBigInteger(B100, NODES.numberNode(BigDecimal.valueOf(100.75d)));
_assertAsBigInteger(B_MINUS_1, NODES.numberNode(BigDecimal.valueOf(-1.25d)));
}
@Test
public void asBigIntegerFromNonNumberScalar()
{
// First failing cases
_assertAsBigIntegerFailForNonNumber(NODES.binaryNode(new byte[3]));
_assertAsBigIntegerFailForNonNumber(NODES.booleanNode(true));
_assertAsBigIntegerFailForNonNumber(NODES.rawValueNode(new RawValue("abc")));
_assertAsBigIntegerFailForNonNumber(NODES.pojoNode(Boolean.TRUE));
_assertAsBigIntegerFailForNonNumber(NODES.stringNode("E000"),
"not valid String representation of `BigInteger`");
// Then passing
_assertAsBigInteger(BigInteger.TEN, NODES.pojoNode(BigInteger.TEN));
_assertAsBigInteger(BigInteger.TEN, NODES.pojoNode(Integer.valueOf(10)));
_assertAsBigInteger(BigInteger.TEN, NODES.pojoNode(Long.valueOf(10)));
_assertAsBigInteger(BigInteger.TEN, NODES.stringNode("10"));
_assertAsBigInteger(BigInteger.valueOf(-99), NODES.stringNode("-99"));
}
@Test
public void asBigIntegerFromStructuralFail()
{
_assertAsBigIntegerFailForNonNumber(NODES.arrayNode(3));
_assertAsBigIntegerFailForNonNumber(NODES.objectNode());
}
@Test
public void asBigIntegerFromMiscOther()
{
// NullNode becomes 0, not fail
_assertAsBigInteger(BigInteger.ZERO, NODES.nullNode());
// But MissingNode still fails
_assertAsBigIntegerFailForNonNumber(NODES.missingNode());
}
// // // Shared helper methods
private void _assertBigIntegerValue(BigInteger expected, JsonNode node) {
assertEquals(expected, node.bigIntegerValue());
// and then defaulting
assertEquals(expected, node.bigIntegerValue(BigInteger.valueOf(9999999L)));
assertEquals(expected, node.bigIntegerValueOpt().get());
}
private void _assertFailBigIntegerValueForFraction(JsonNode node) {
Exception e = assertThrows(JsonNodeException.class,
() -> node.bigIntegerValue(),
"For ("+node.getClass().getSimpleName()+") value: "+node);
assertThat(e.getMessage())
.contains("cannot convert value")
.contains("to `java.math.BigInteger`: value has fractional part");
// Verify default value handling
assertEquals(BigInteger.ONE, node.bigIntegerValue(BigInteger.ONE));
assertFalse(node.bigIntegerValueOpt().isPresent());
}
private void _assertFailBigIntegerForNonNumber(JsonNode node) {
Exception e = assertThrows(JsonNodeException.class,
() -> node.bigIntegerValue(),
"For ("+node.getClass().getSimpleName()+") value: "+node);
assertThat(e.getMessage())
.contains("cannot convert value")
.contains("value type not numeric");
// Verify default value handling
assertEquals(BigInteger.ONE, node.bigIntegerValue(BigInteger.ONE));
assertFalse(node.bigIntegerValueOpt().isPresent());
}
private void _assertFailBigIntegerForNaN(JsonNode node) {
Exception e = assertThrows(JsonNodeException.class,
() -> node.bigIntegerValue(),
"For ("+node.getClass().getSimpleName()+") value: "+node);
assertThat(e.getMessage())
.contains("cannot convert value")
.contains("value non-Finite ('NaN')");
// Verify default value handling
assertEquals(BigInteger.ONE, node.bigIntegerValue(BigInteger.ONE));
assertFalse(node.bigIntegerValueOpt().isPresent());
}
private void _assertAsBigInteger(BigInteger expected, JsonNode node) {
assertEquals(expected, node.asBigInteger());
// and then defaulting
assertEquals(expected, node.asBigInteger(BigInteger.valueOf(9999999L)));
assertEquals(expected, node.asBigIntegerOpt().get());
}
private void _assertAsBigIntegerFailForNonNumber(JsonNode node) {
_assertAsBigIntegerFailForNonNumber(node, "value type not numeric");
}
private void _assertAsBigIntegerFailForNonNumber(JsonNode node, String extraMsg) {
Exception e = assertThrows(JsonNodeException.class,
() -> node.asBigInteger(),
"For ("+node.getClass().getSimpleName()+") value: "+node);
assertThat(e.getMessage())
.contains("cannot convert value");
// Verify default value handling
assertEquals(BigInteger.ONE, node.asBigInteger(BigInteger.ONE));
assertFalse(node.asBigIntegerOpt().isPresent());
}
}