diff --git a/README.md b/README.md index c146999c..5a7a6c85 100644 --- a/README.md +++ b/README.md @@ -256,6 +256,8 @@ List> books = JsonPath.parse(json) You can use `&&` and `||` to combine multiple predicates `[?(@.price < 10 && @.category == 'fiction')]` , `[?(@.category == 'reference' || @.price > 10)]`. +You can use `!` to negate a predicate `[?(!(@.price < 10 && @.category == 'fiction'))]`. + ###Filter Predicates Predicates can be built using the Filter API as shown below: diff --git a/build.gradle b/build.gradle index 623cba9f..fffe227a 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ ext { gson: 'com.google.code.gson:gson:2.3.1', jettison: 'org.codehaus.jettison:jettison:1.3.7', jsonOrg: 'org.json:json:20140107', - tapestryJson: 'org.apache.tapestry:tapestry-json:5.4.0', + tapestryJson: 'org.apache.tapestry:tapestry-json:5.4.1', hamcrestCore: 'org.hamcrest:hamcrest-core:1.3', hamcrestLibrary: 'org.hamcrest:hamcrest-library:1.3', @@ -73,7 +73,7 @@ subprojects { } task wrapper(type: Wrapper) { - gradleVersion = '2.11' + gradleVersion = '3.4.1' } //Task used by Heroku for staging diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5ccda13e..17279fa9 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ec299545..10eb72ab 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Feb 12 10:36:51 CET 2016 +#Fri Mar 17 10:32:10 CET 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-bin.zip diff --git a/gradlew b/gradlew index 9d82f789..4453ccea 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,12 +6,30 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,26 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -150,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save ( ) { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 72d362da..e95643d6 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -49,7 +49,6 @@ goto fail @rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/json-path-assert/build.gradle b/json-path-assert/build.gradle index 0a47bd0c..f63e70bb 100644 --- a/json-path-assert/build.gradle +++ b/json-path-assert/build.gradle @@ -1,7 +1,5 @@ apply from: "$rootDir/gradle/publishMaven.gradle" -displayName = "JsonPath Assert" - description = "Assertions on Json using JsonPath" jar { diff --git a/json-path-web-test/build.gradle b/json-path-web-test/build.gradle index 7c185eb4..83eb94fc 100644 --- a/json-path-web-test/build.gradle +++ b/json-path-web-test/build.gradle @@ -1,18 +1,18 @@ apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'application' -displayName = "JsonPath Test Bench" - description = "Web app that compares different JsonPath implementations." mainClassName = 'com.jayway.jsonpath.web.boot.Main' -task createBuildInfoFile << { - def buildInfoFile = new File("$buildDir/classes/main/build-info.properties") - Properties props = new Properties() - props.setProperty('version', project.version.toString()) - props.setProperty('timestamp', project.buildTimestamp) - props.store(buildInfoFile.newWriter(), null) +task createBuildInfoFile { + doLast { + def buildInfoFile = new File("$buildDir/classes/main/build-info.properties") + Properties props = new Properties() + props.setProperty('version', project.version.toString()) + props.setProperty('timestamp', project.buildTimestamp) + props.store(buildInfoFile.newWriter(), null) + } } jar { diff --git a/json-path/build.gradle b/json-path/build.gradle index 18f875ac..c86e35f0 100644 --- a/json-path/build.gradle +++ b/json-path/build.gradle @@ -1,20 +1,20 @@ apply from: "$rootDir/gradle/publishMaven.gradle" - -displayName = "Json Path" - description = "Java port of Stefan Goessner JsonPath." jar { baseName 'json-path' manifest { attributes 'Implementation-Title': 'json-path', 'Implementation-Version': version - instruction 'Import-Package', 'org.json.*;resolution:=optional', 'com.google.gson.*;resolution:=optional', 'com.fasterxml.jackson.*;resolution:=optional', 'org.apache.tapestry5.json.*;resolution:=optional', '*' + instruction 'Import-Package', 'org.json.*;resolution:=optional', 'com.google.gson.*;resolution:=optional', 'com.fasterxml.jackson.*;resolution:=optional', 'org.apache.tapestry5.json.*;resolution:=optional', 'org.codehaus.jettison.*;resolution:=optional', '*' } } dependencies { - compile libs.jsonSmart + compile (libs.jsonSmart){ + // see https://github.com/jayway/JsonPath/issues/228, https://github.com/netplex/json-smart-v2/issues/20 + exclude group: 'org.ow2.asm', module: 'asm' + } compile libs.slf4jApi compile libs.jacksonDatabind, optional compile libs.gson, optional @@ -39,7 +39,7 @@ task distZip(type: Zip, dependsOn: assemble) { } from(project.configurations.compile) { into 'lib' - exclude { it.file.name.contains('gson') || it.file.name.contains('jackson') || it.file.name.contains('json-2') || it.file.name.contains('jettison') } + exclude { it.file.name.contains('gson') || it.file.name.contains('jackson') || it.file.name.contains('json-2') || it.file.name.contains('jettison') || it.file.name.contains('tapestry') } } from(project.configurations.compile) { into 'lib-optional/jackson' @@ -58,7 +58,7 @@ task distZip(type: Zip, dependsOn: assemble) { include { it.file.name.contains('json-2') } } from(project.configurations.compile) { - into 'lib-optional/jsonOrg' + into 'lib-optional/tapestry' include { it.file.name.contains('tapestry') } } } @@ -79,7 +79,7 @@ task distTar(type: Tar, dependsOn: assemble) { } from(project.configurations.compile) { into 'lib' - exclude { it.file.name.contains('gson') || it.file.name.contains('jackson') || it.file.name.contains('json-2') || it.file.name.contains('jettison') } + exclude { it.file.name.contains('gson') || it.file.name.contains('jackson') || it.file.name.contains('json-2') || it.file.name.contains('jettison') || it.file.name.contains('tapestry') } } from(project.configurations.compile) { into 'lib-optional/jackson' @@ -98,7 +98,7 @@ task distTar(type: Tar, dependsOn: assemble) { include { it.file.name.contains('json-2') } } from(project.configurations.compile) { - into 'lib-optional/jsonOrg' + into 'lib-optional/tapestry' include { it.file.name.contains('tapestry') } } } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/JsonContext.java b/json-path/src/main/java/com/jayway/jsonpath/internal/JsonContext.java index 17ce9bce..50b84a08 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/JsonContext.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/JsonContext.java @@ -289,7 +289,7 @@ public class JsonContext implements ParseContext, DocumentContext { return this; } - private final class LimitingEvaluationListener implements EvaluationListener { + private final static class LimitingEvaluationListener implements EvaluationListener { final int limit; private LimitingEvaluationListener(int limit) { diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java index 7126b278..e5eb39a3 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/FilterCompiler.java @@ -120,7 +120,7 @@ public class FilterCompiler { /* * LogicalOR = LogicalAND { '||' LogicalAND } * LogicalAND = LogicalANDOperand { '&&' LogicalANDOperand } - * LogicalANDOperand = RelationalExpression | '(' LogicalOR ')' + * LogicalANDOperand = RelationalExpression | '(' LogicalOR ')' | '!' LogicalANDOperand * RelationalExpression = Value [ RelationalOperator Value ] */ @@ -164,6 +164,19 @@ public class FilterCompiler { } private ExpressionNode readLogicalANDOperand() { + int savepoint = filter.skipBlanks().position(); + if (filter.skipBlanks().currentCharIs(NOT)) { + filter.readSignificantChar(NOT); + switch (filter.skipBlanks().currentChar()) { + case DOC_CONTEXT: + case EVAL_CONTEXT: + filter.setPosition(savepoint); + break; + default: + final ExpressionNode op = readLogicalANDOperand(); + return LogicalExpressionNode.createLogicalNot(op); + } + } if (filter.skipBlanks().currentCharIs(OPEN_PARENTHESIS)) { filter.readSignificantChar(OPEN_PARENTHESIS); final ExpressionNode op = readLogicalOR(); diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/LogicalExpressionNode.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/LogicalExpressionNode.java index 3a5d9605..57cb3884 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/LogicalExpressionNode.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/LogicalExpressionNode.java @@ -10,6 +10,10 @@ public class LogicalExpressionNode extends ExpressionNode { protected List chain = new ArrayList(); private final LogicalOperator operator; + public static ExpressionNode createLogicalNot(ExpressionNode op) { + return new LogicalExpressionNode(op, LogicalOperator.NOT, null); + } + public static LogicalExpressionNode createLogicalOr(ExpressionNode left,ExpressionNode right){ return new LogicalExpressionNode(left, LogicalOperator.OR, right); } @@ -68,13 +72,17 @@ public class LogicalExpressionNode extends ExpressionNode { } } return false; - } else { + } else if (operator == LogicalOperator.AND) { for (ExpressionNode expression : chain) { if(!expression.apply(ctx)){ return false; } } return true; + } else { + ExpressionNode expression = chain.get(0); + return !expression.apply(ctx); } } + } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/LogicalOperator.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/LogicalOperator.java index 376e2ada..809a8560 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/LogicalOperator.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/LogicalOperator.java @@ -5,6 +5,7 @@ import com.jayway.jsonpath.InvalidPathException; public enum LogicalOperator { AND("&&"), + NOT("!"), OR("||"); private final String operatorString; @@ -24,6 +25,7 @@ public enum LogicalOperator { public static LogicalOperator fromString(String operatorString){ if(AND.operatorString.equals(operatorString)) return AND; + else if(NOT.operatorString.equals(operatorString)) return NOT; else if(OR.operatorString.equals(operatorString)) return OR; else throw new InvalidPathException("Failed to parse operator " + operatorString); } diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java index f1cda9eb..21c3fe24 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java @@ -810,9 +810,9 @@ public abstract class ValueNode { } public ValueNode evaluate(Predicate.PredicateContext ctx) { - Configuration c = Configuration.builder().jsonProvider(ctx.configuration().jsonProvider()).options(Option.REQUIRE_PROPERTIES).build(); if (isExistsCheck()) { try { + Configuration c = Configuration.builder().jsonProvider(ctx.configuration().jsonProvider()).options(Option.REQUIRE_PROPERTIES).build(); Object result = path.evaluate(ctx.item(), ctx.root(), c).getValue(false); return result == JsonProvider.UNDEFINED ? ValueNode.FALSE : ValueNode.TRUE; } catch (PathNotFoundException e) { diff --git a/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java b/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java index 3814419e..3fc7e487 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java +++ b/json-path/src/main/java/com/jayway/jsonpath/internal/path/EvaluationContextImpl.java @@ -163,7 +163,7 @@ public class EvaluationContextImpl implements EvaluationContext { return res; } - private class FoundResultImpl implements EvaluationListener.FoundResult { + private static class FoundResultImpl implements EvaluationListener.FoundResult { private final int index; private final String path; diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java index 7a2636a8..0828b295 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/GsonJsonProvider.java @@ -14,28 +14,25 @@ */ package com.jayway.jsonpath.spi.json; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; - -import java.math.BigDecimal; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; -import com.google.gson.internal.LazilyParsedNumber; - import com.jayway.jsonpath.InvalidJsonException; import com.jayway.jsonpath.JsonPathException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + public class GsonJsonProvider extends AbstractJsonProvider { private static final JsonParser PARSER = new JsonParser(); @@ -86,25 +83,38 @@ public class GsonJsonProvider extends AbstractJsonProvider { return o; } + private static boolean isPrimitiveNumber(final Number n) { + return n instanceof Integer || + n instanceof Double || + n instanceof Long || + n instanceof BigDecimal || + n instanceof BigInteger; + } + private static Number unwrapNumber(final Number n) { Number unwrapped; - if (n instanceof LazilyParsedNumber) { - LazilyParsedNumber lpn = (LazilyParsedNumber) n; - BigDecimal bigDecimal = new BigDecimal(lpn.toString()); + if (!isPrimitiveNumber(n)) { + BigDecimal bigDecimal = new BigDecimal(n.toString()); if (bigDecimal.scale() <= 0) { if (bigDecimal.compareTo(new BigDecimal(Integer.MAX_VALUE)) <= 0) { unwrapped = bigDecimal.intValue(); - } else { + } else if (bigDecimal.compareTo(new BigDecimal(Long.MAX_VALUE)) <= 0){ unwrapped = bigDecimal.longValue(); + } else { + unwrapped = bigDecimal; } } else { - unwrapped = bigDecimal.doubleValue(); + final double doubleValue = bigDecimal.doubleValue(); + if (BigDecimal.valueOf(doubleValue).compareTo(bigDecimal) != 0) { + unwrapped = bigDecimal; + } else { + unwrapped = doubleValue; + } } } else { unwrapped = n; } - return unwrapped; } diff --git a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonOrgJsonProvider.java b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonOrgJsonProvider.java index a5b77e88..6760f869 100644 --- a/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonOrgJsonProvider.java +++ b/json-path/src/main/java/com/jayway/jsonpath/spi/json/JsonOrgJsonProvider.java @@ -1,6 +1,6 @@ package com.jayway.jsonpath.spi.json; -import com.google.gson.JsonObject; +import org.json.JSONObject; import com.jayway.jsonpath.InvalidJsonException; import com.jayway.jsonpath.JsonPathException; import org.json.JSONArray; @@ -62,7 +62,7 @@ public class JsonOrgJsonProvider extends AbstractJsonProvider { @Override public Object createMap() { - return new JsonObject(); + return new JSONObject(); } @Override diff --git a/json-path/src/test/java/com/jayway/jsonpath/GsonJsonProviderTest.java b/json-path/src/test/java/com/jayway/jsonpath/GsonJsonProviderTest.java index 8f3ec333..1fc85bd9 100644 --- a/json-path/src/test/java/com/jayway/jsonpath/GsonJsonProviderTest.java +++ b/json-path/src/test/java/com/jayway/jsonpath/GsonJsonProviderTest.java @@ -7,6 +7,8 @@ import com.jayway.jsonpath.spi.mapper.MappingException; import org.junit.Test; import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; import java.util.List; import static com.jayway.jsonpath.JsonPath.using; @@ -69,6 +71,65 @@ public class GsonJsonProviderTest extends BaseTest { assertThat(val).isEqualTo(node.getAsLong()); } + @Test + public void doubles_are_unwrapped() { + final String json = "{double-property = 56.78}"; + + JsonElement node = using(GSON_CONFIGURATION).parse(json).read("$.double-property"); + Double val = using(GSON_CONFIGURATION).parse(json).read("$.double-property", Double.class); + + assertThat(val).isEqualTo(56.78); + assertThat(val).isEqualTo(node.getAsDouble()); + } + + @Test + public void bigdecimals_are_unwrapped() { + final BigDecimal bd = BigDecimal.valueOf(Long.MAX_VALUE).add(BigDecimal.valueOf(10.5)); + final String json = "{bd-property = " + bd.toString() + "}"; + + JsonElement node = using(GSON_CONFIGURATION).parse(json).read("$.bd-property"); + BigDecimal val = using(GSON_CONFIGURATION).parse(json).read("$.bd-property", BigDecimal.class); + + assertThat(val).isEqualTo(bd); + assertThat(val).isEqualTo(node.getAsBigDecimal()); + } + + @Test + public void small_bigdecimals_are_unwrapped() { + final BigDecimal bd = BigDecimal.valueOf(10.5); + final String json = "{bd-property = " + bd.toString() + "}"; + + JsonElement node = using(GSON_CONFIGURATION).parse(json).read("$.bd-property"); + BigDecimal val = using(GSON_CONFIGURATION).parse(json).read("$.bd-property", BigDecimal.class); + + assertThat(val).isEqualTo(bd); + assertThat(val).isEqualTo(node.getAsBigDecimal()); + } + + @Test + public void bigintegers_are_unwrapped() { + final BigInteger bi = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.TEN); + final String json = "{bi-property = " + bi.toString() + "}"; + + JsonElement node = using(GSON_CONFIGURATION).parse(json).read("$.bi-property"); + BigInteger val = using(GSON_CONFIGURATION).parse(json).read("$.bi-property", BigInteger.class); + + assertThat(val).isEqualTo(bi); + assertThat(val).isEqualTo(node.getAsBigInteger()); + } + + @Test + public void small_bigintegers_are_unwrapped() { + final BigInteger bi = BigInteger.valueOf(Long.MAX_VALUE); + final String json = "{bi-property = " + bi.toString() + "}"; + + JsonElement node = using(GSON_CONFIGURATION).parse(json).read("$.bi-property"); + BigInteger val = using(GSON_CONFIGURATION).parse(json).read("$.bi-property", BigInteger.class); + + assertThat(val).isEqualTo(bi); + assertThat(val).isEqualTo(node.getAsBigInteger()); + } + @Test public void int_to_long_mapping() { assertThat(using(GSON_CONFIGURATION).parse("{\"val\": 1}").read("val", Long.class)).isEqualTo(1L);