Browse Source

fix for NumberFormatException exception during Criteria evaluation

Its incorrect to break entire path evaluation - other nodes should have their chance to be found by Criteria.
pull/148/head
Alexey Makeyev 9 years ago
parent
commit
fcc81d16d6
  1. 15
      json-path/src/main/java/com/jayway/jsonpath/Criteria.java
  2. 33
      json-path/src/test/java/com/jayway/jsonpath/InlineFilterTest.java
  3. 32
      json-path/src/test/java/com/jayway/jsonpath/TestUtils.java

15
json-path/src/main/java/com/jayway/jsonpath/Criteria.java

@ -955,6 +955,7 @@ public class Criteria implements Predicate {
boolean leftNullish = isNullish(left); boolean leftNullish = isNullish(left);
boolean rightNullish = isNullish(right); boolean rightNullish = isNullish(right);
BigDecimal bigDecimal;
if (leftNullish && !rightNullish) { if (leftNullish && !rightNullish) {
return -1; return -1;
@ -965,12 +966,12 @@ public class Criteria implements Predicate {
} else if (left instanceof String && right instanceof String) { } else if (left instanceof String && right instanceof String) {
String expected = unescape((String) left); String expected = unescape((String) left);
return expected.compareTo((String) right); return expected.compareTo((String) right);
} else if (left instanceof Number && right instanceof Number) {
return new BigDecimal(left.toString()).compareTo(new BigDecimal(right.toString()));
} else if (left instanceof Number && right instanceof BigDecimal) { } else if (left instanceof Number && right instanceof BigDecimal) {
return new BigDecimal(left.toString()).compareTo((BigDecimal)right); return new BigDecimal(left.toString()).compareTo((BigDecimal)right);
} else if (left instanceof String && right instanceof Number) { } else if (left instanceof Number && right instanceof Number) {
return new BigDecimal(left.toString()).compareTo(new BigDecimal(right.toString())); return new BigDecimal(left.toString()).compareTo(new BigDecimal(right.toString()));
} else if (left instanceof String && right instanceof Number && (bigDecimal = safeBigDecimal((String)left)) != null) {
return bigDecimal.compareTo(new BigDecimal(right.toString()));
} else if (left instanceof String && right instanceof Boolean) { } else if (left instanceof String && right instanceof Boolean) {
Boolean e = Boolean.valueOf((String) left); Boolean e = Boolean.valueOf((String) left);
Boolean a = (Boolean) right; Boolean a = (Boolean) right;
@ -988,6 +989,14 @@ public class Criteria implements Predicate {
} }
} }
private static BigDecimal safeBigDecimal(final String value) {
try {
return new BigDecimal(value);
} catch (NumberFormatException exc) {
return null;
}
}
private static boolean isNullish(Object o) { private static boolean isNullish(Object o) {
return (o == null || ((o instanceof String) && ("null".equals(o)))); return (o == null || ((o instanceof String) && ("null".equals(o))));
} }

33
json-path/src/test/java/com/jayway/jsonpath/InlineFilterTest.java

@ -1,5 +1,8 @@
package com.jayway.jsonpath; package com.jayway.jsonpath;
import static com.jayway.jsonpath.TestUtils.assertHasNoResults;
import static com.jayway.jsonpath.TestUtils.assertHasOneResult;
import org.junit.Test; import org.junit.Test;
import java.util.ArrayList; import java.util.ArrayList;
@ -163,4 +166,34 @@ public class InlineFilterTest extends BaseTest {
assertThat(isNull).containsExactly(new Integer[]{}); assertThat(isNull).containsExactly(new Integer[]{});
} }
@Test
public void equality_check_does_not_break_evaluation() {
assertHasOneResult("[{\"value\":\"5\"}]", "$[?(@.value=='5')]");
assertHasOneResult("[{\"value\":5}]", "$[?(@.value==5)]");
assertHasOneResult("[{\"value\":\"5.1.26\"}]", "$[?(@.value=='5.1.26')]");
assertHasNoResults("[{\"value\":\"5\"}]", "$[?(@.value=='5.1.26')]");
assertHasNoResults("[{\"value\":5}]", "$[?(@.value=='5.1.26')]");
assertHasNoResults("[{\"value\":5.1}]", "$[?(@.value=='5.1.26')]");
assertHasNoResults("[{\"value\":\"5.1.26\"}]", "$[?(@.value=='5')]");
assertHasNoResults("[{\"value\":\"5.1.26\"}]", "$[?(@.value==5)]");
assertHasNoResults("[{\"value\":\"5.1.26\"}]", "$[?(@.value==5.1)]");
}
@Test
public void lt_check_does_not_break_evaluation() {
assertHasOneResult("[{\"value\":\"5\"}]", "$[?(@.value<'7')]");
assertHasNoResults("[{\"value\":\"7\"}]", "$[?(@.value<'5')]");
assertHasOneResult("[{\"value\":5}]", "$[?(@.value<7)]");
assertHasNoResults("[{\"value\":7}]", "$[?(@.value<5)]");
assertHasOneResult("[{\"value\":5}]", "$[?(@.value<7.1)]");
assertHasNoResults("[{\"value\":7}]", "$[?(@.value<5.1)]");
assertHasOneResult("[{\"value\":5.1}]", "$[?(@.value<7)]");
assertHasNoResults("[{\"value\":7.1}]", "$[?(@.value<5)]");
}
} }

32
json-path/src/test/java/com/jayway/jsonpath/TestUtils.java

@ -1,6 +1,9 @@
package com.jayway.jsonpath; package com.jayway.jsonpath;
import java.util.List;
import static com.jayway.jsonpath.JsonPath.using; import static com.jayway.jsonpath.JsonPath.using;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail; import static org.assertj.core.api.Assertions.fail;
public final class TestUtils { public final class TestUtils {
@ -29,4 +32,33 @@ public final class TestUtils {
throw exc; throw exc;
} }
} }
/**
* Assertion which requires empty list as a result of indefinite path search.
* @param json json to be parsed
* @param path path to be evaluated
*/
public static void assertHasNoResults(final String json, final String path) {
assertHasResults(json, path, 0);
}
/**
* Assertion which requires list of one element as a result of indefinite path search.
* @param json json to be parsed
* @param path path to be evaluated
*/
public static void assertHasOneResult(final String json, final String path) {
assertHasResults(json, path, 1);
}
/**
* Shortcut for counting found nodes.
* @param json json to be parsed
* @param path path to be evaluated
* @param expectedResultCount expected number of nodes to be found
*/
public static void assertHasResults(final String json, final String path, final int expectedResultCount) {
final List<Object> result = JsonPath.parse(json).read(path);
assertThat(result).hasSize(expectedResultCount);
}
} }

Loading…
Cancel
Save