From 516729bf57f7981bb5fb3af9736fdba7e2a1beb6 Mon Sep 17 00:00:00 2001 From: Thai Nguyen Date: Fri, 4 Mar 2016 10:32:39 +0700 Subject: [PATCH] jsonpath with new use cases --- json-path/pom.xml | 51 +++++++++++ json-path/src/main/resources/intro_api.json | 57 ++++++++++++ .../src/main/resources/intro_service.json | 61 +++++++++++++ .../jsonpath/introduction/OperationTest.java | 71 +++++++++++++++ .../jsonpath/introduction/ServiceTest.java | 91 +++++++++++++++++++ 5 files changed, 331 insertions(+) create mode 100644 json-path/pom.xml create mode 100644 json-path/src/main/resources/intro_api.json create mode 100644 json-path/src/main/resources/intro_service.json create mode 100644 json-path/src/test/java/org/baeldung/jsonpath/introduction/OperationTest.java create mode 100644 json-path/src/test/java/org/baeldung/jsonpath/introduction/ServiceTest.java diff --git a/json-path/pom.xml b/json-path/pom.xml new file mode 100644 index 0000000000..9a86431ffe --- /dev/null +++ b/json-path/pom.xml @@ -0,0 +1,51 @@ + + 4.0.0 + org.baeldung + json-path + 0.0.1-SNAPSHOT + json-path + + + + + com.jayway.jsonpath + json-path + ${json-path.version} + + + + + junit + junit + ${junit.version} + test + + + + + org.slf4j + slf4j-api + ${slf4j.version} + runtime + + + ch.qos.logback + logback-classic + ${logback.version} + runtime + + + + + + 2.1.0 + + + 4.12 + + + 1.7.14 + 1.1.3 + + \ No newline at end of file diff --git a/json-path/src/main/resources/intro_api.json b/json-path/src/main/resources/intro_api.json new file mode 100644 index 0000000000..8a252f2971 --- /dev/null +++ b/json-path/src/main/resources/intro_api.json @@ -0,0 +1,57 @@ +{ + "tool": + { + "jsonpath": + { + "creator": + { + "name": "Jayway Inc.", + "location": + [ + "Malmo", + "Stockholm", + "Copenhagen", + "San Francisco", + "Karlskrona", + "Halmstad", + "Helsingborg" + ] + }, + + "current release": "2.1" + } + }, + + "book": + [ + { + "title": "Beginning JSON", + "author": "Ben Smith", + "price": 49.99 + }, + + { + "title": "JSON at Work", + "author": "Tom Marrs", + "price": 29.99 + }, + + { + "title": "Learn JSON in a DAY", + "author": "Acodemy", + "price": 8.99 + }, + + { + "title": "JSON: Questions and Answers", + "author": "George Duckett", + "price": 6.00 + } + ], + + "price range": + { + "cheap": 10.00, + "medium": 20.00 + } +} \ No newline at end of file diff --git a/json-path/src/main/resources/intro_service.json b/json-path/src/main/resources/intro_service.json new file mode 100644 index 0000000000..448492463a --- /dev/null +++ b/json-path/src/main/resources/intro_service.json @@ -0,0 +1,61 @@ +[ + { + "id": 1, + "title": "Casino Royale", + "director": "Martin Campbell", + "starring": + [ + "Daniel Craig", + "Eva Green" + ], + + "desc": "Twenty-first James Bond movie", + "release date": 1163466000000, + "box office": 594275385 + }, + + { + "id": 2, + "title": "Quantum of Solace", + "director": "Marc Forster", + "starring": + [ + "Daniel Craig", + "Olga Kurylenko" + ], + + "desc": "Twenty-second James Bond movie", + "release date": 1225242000000, + "box office": 591692078 + }, + + { + "id": 3, + "title": "Skyfall", + "director": "Sam Mendes", + "starring": + [ + "Daniel Craig", + "Naomie Harris" + ], + + "desc": "Twenty-third James Bond movie", + "release date": 1350954000000, + "box office": 1110526981 + }, + + { + "id": 4, + "title": "Spectre", + "director": "Sam Mendes", + "starring": + [ + "Daniel Craig", + "Lea Seydoux" + ], + + "desc": "Twenty-fourth James Bond movie", + "release date": 1445821200000, + "box office": 879376275 + } +] \ No newline at end of file diff --git a/json-path/src/test/java/org/baeldung/jsonpath/introduction/OperationTest.java b/json-path/src/test/java/org/baeldung/jsonpath/introduction/OperationTest.java new file mode 100644 index 0000000000..9347a7f754 --- /dev/null +++ b/json-path/src/test/java/org/baeldung/jsonpath/introduction/OperationTest.java @@ -0,0 +1,71 @@ +package org.baeldung.jsonpath.introduction; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.not; + +import org.junit.Test; + +import java.io.InputStream; +import java.util.List; +import java.util.Map; +import java.util.Scanner; + +import com.jayway.jsonpath.Criteria; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.Filter; +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.Predicate; + +public class OperationTest { + InputStream jsonInputStream = this.getClass().getClassLoader().getResourceAsStream("intro_api.json"); + String jsonDataSourceString = new Scanner(jsonInputStream, "UTF-8").useDelimiter("\\Z").next(); + + @Test + public void givenJsonPathWithoutPredicates_whenReading_thenCorrect() { + String jsonpathCreatorNamePath = "$['tool']['jsonpath']['creator']['name']"; + String jsonpathCreatorLocationPath = "$['tool']['jsonpath']['creator']['location'][*]"; + + DocumentContext jsonContext = JsonPath.parse(jsonDataSourceString); + String jsonpathCreatorName = jsonContext.read(jsonpathCreatorNamePath); + List jsonpathCreatorLocation = jsonContext.read(jsonpathCreatorLocationPath); + + assertEquals("Jayway Inc.", jsonpathCreatorName); + assertThat(jsonpathCreatorLocation.toString(), containsString("Malmo")); + assertThat(jsonpathCreatorLocation.toString(), containsString("San Francisco")); + assertThat(jsonpathCreatorLocation.toString(), containsString("Helsingborg")); + } + + @Test + public void givenJsonPathWithFilterPredicate_whenReading_thenCorrect() { + Filter expensiveFilter = Filter.filter(Criteria.where("price").gt(20.00)); + List> expensive = JsonPath.parse(jsonDataSourceString).read("$['book'][?]", expensiveFilter); + predicateUsageAssertionHelper(expensive); + } + + @Test + public void givenJsonPathWithCustomizedPredicate_whenReading_thenCorrect() { + Predicate expensivePredicate = new Predicate() { + public boolean apply(PredicateContext context) { + String value = context.item(Map.class).get("price").toString(); + return Float.valueOf(value) > 20.00; + } + }; + List> expensive = JsonPath.parse(jsonDataSourceString).read("$['book'][?]", expensivePredicate); + predicateUsageAssertionHelper(expensive); + } + + @Test + public void givenJsonPathWithInlinePredicate_whenReading_thenCorrect() { + List> expensive = JsonPath.parse(jsonDataSourceString).read("$['book'][?(@['price'] > $['price range']['medium'])]"); + predicateUsageAssertionHelper(expensive); + } + + private void predicateUsageAssertionHelper(List predicate) { + assertThat(predicate.toString(), containsString("Beginning JSON")); + assertThat(predicate.toString(), containsString("JSON at Work")); + assertThat(predicate.toString(), not(containsString("Learn JSON in a DAY"))); + assertThat(predicate.toString(), not(containsString("JSON: Questions and Answers"))); + } +} diff --git a/json-path/src/test/java/org/baeldung/jsonpath/introduction/ServiceTest.java b/json-path/src/test/java/org/baeldung/jsonpath/introduction/ServiceTest.java new file mode 100644 index 0000000000..66cc73af52 --- /dev/null +++ b/json-path/src/test/java/org/baeldung/jsonpath/introduction/ServiceTest.java @@ -0,0 +1,91 @@ +package org.baeldung.jsonpath.introduction; + +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.hamcrest.CoreMatchers.containsString; + +import org.junit.Test; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Scanner; + +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.Option; + +public class ServiceTest { + InputStream jsonInputStream = this.getClass().getClassLoader().getResourceAsStream("intro_service.json"); + String jsonString = new Scanner(jsonInputStream, "UTF-8").useDelimiter("\\Z").next(); + + @Test + public void givenId_whenRequestingRecordData_thenSucceed() { + Object dataObject = JsonPath.parse(jsonString).read("$[?(@.id == 2)]"); + String dataString = dataObject.toString(); + + assertThat(dataString, containsString("2")); + assertThat(dataString, containsString("Quantum of Solace")); + assertThat(dataString, containsString("Twenty-second James Bond movie")); + } + + @Test + public void givenStarring_whenRequestingMovieTitle_thenSucceed() { + List> dataList = JsonPath.parse(jsonString).read("$[?('Eva Green' in @['starring'])]"); + String title = (String) dataList.get(0).get("title"); + + assertEquals("Casino Royale", title); + } + + @Test + public void givenCompleteStructure_whenCalculatingTotalRevenue_thenSucceed() { + DocumentContext context = JsonPath.parse(jsonString); + int length = context.read("$.length()"); + long revenue = 0; + for (int i = 0; i < length; i++) { + revenue += context.read("$[" + i + "]['box office']", Long.class); + } + + assertEquals(594275385L + 591692078L + 1110526981L + 879376275L, revenue); + } + + @Test + public void givenStructure_whenRequestingHighestRevenueMovieTitle_thenSucceed() { + DocumentContext context = JsonPath.parse(jsonString); + List revenueList = context.read("$[*]['box office']"); + Integer[] revenueArray = revenueList.toArray(new Integer[0]); + Arrays.sort(revenueArray); + + int highestRevenue = revenueArray[revenueArray.length - 1]; + Configuration pathConfiguration = Configuration.builder().options(Option.AS_PATH_LIST).build(); + List pathList = JsonPath.using(pathConfiguration).parse(jsonString).read("$[?(@['box office'] == " + highestRevenue + ")]"); + + Map dataRecord = context.read(pathList.get(0)); + String title = dataRecord.get("title"); + + assertEquals("Skyfall", title); + } + + @Test + public void givenDirector_whenRequestingLatestMovieTitle_thenSucceed() { + DocumentContext context = JsonPath.parse(jsonString); + List> dataList = context.read("$[?(@.director == 'Sam Mendes')]"); + + List dateList = new ArrayList<>(); + for (Map item : dataList) { + Object date = item.get("release date"); + dateList.add(date); + } + Long[] dateArray = dateList.toArray(new Long[0]); + Arrays.sort(dateArray); + + long latestTime = dateArray[dateArray.length - 1]; + List> finalDataList = context.read("$[?(@['director'] == 'Sam Mendes' && @['release date'] == " + latestTime + ")]"); + String title = (String) finalDataList.get(0).get("title"); + + assertEquals("Spectre", title); + } +} \ No newline at end of file