JsonPath仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

321 lines
10 KiB

package com.jayway.jsonpath;
import org.junit.jupiter.api.Test;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import static com.jayway.jsonpath.JsonPath.parse;
import static java.util.Collections.emptyMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class WriteTest extends BaseTest {
private static final Map<String, Object> EMPTY_MAP = emptyMap();
@Test
public void an_array_child_property_can_be_updated() {
Object o = parse(JSON_DOCUMENT).set("$.store.book[*].display-price", 1).json();
List<Integer> result = parse(o).read("$.store.book[*].display-price");
assertThat(result).containsExactly(1, 1, 1, 1);
}
@Test
public void an_root_property_can_be_updated() {
Object o = parse(JSON_DOCUMENT).set("$.int-max-property", 1).json();
Integer result = parse(o).read("$.int-max-property");
assertThat(result).isEqualTo(1);
}
@Test
public void an_deep_scan_can_update() {
Object o = parse(JSON_DOCUMENT).set("$..display-price", 1).json();
List<Integer> result = parse(o).read("$..display-price");
assertThat(result).containsExactly(1, 1, 1, 1, 1);
}
@Test
public void an_filter_can_update() {
Object o = parse(JSON_DOCUMENT).set("$.store.book[?(@.display-price)].display-price", 1).json();
List<Integer> result = parse(o).read("$.store.book[?(@.display-price)].display-price");
assertThat(result).containsExactly(1, 1, 1, 1);
}
@Test
public void a_path_can_be_deleted() {
Object o = parse(JSON_DOCUMENT).delete("$.store.book[*].display-price").json();
List<Integer> result = parse(o).read("$.store.book[*].display-price");
assertThat(result).isEmpty();
}
@Test
public void operations_can_chained() {
Object o = parse(JSON_DOCUMENT)
.delete("$.store.book[*].display-price")
.set("$.store.book[*].category", "A")
.json();
List<Integer> prices = parse(o).read("$.store.book[*].display-price");
List<String> categories = parse(o).read("$.store.book[*].category");
assertThat(prices).isEmpty();
assertThat(categories).containsExactly("A", "A", "A", "A");
}
@Test
public void an_array_can_be_updated() {
List<Integer> ints = parse("[0,1,2,3]").set("$[?(@ == 1)]", 9).json();
assertThat(ints).containsExactly(0, 9, 2, 3);
}
@Test
public void an_array_index_can_be_updated() {
String res = parse(JSON_DOCUMENT).set("$.store.book[0]", "a").read("$.store.book[0]");
assertThat(res).isEqualTo("a");
}
@Test
public void an_array_slice_can_be_updated() {
List<String> res = parse(JSON_DOCUMENT).set("$.store.book[0:2]", "a").read("$.store.book[0:2]");
assertThat(res).containsExactly("a", "a");
}
@Test
public void an_array_criteria_can_be_updated() {
List<String> res = parse(JSON_DOCUMENT)
.set("$.store.book[?(@.category == 'fiction')]", "a")
.read("$.store.book[?(@ == 'a')]");
assertThat(res).containsExactly("a", "a", "a");
}
@Test
public void an_array_criteria_can_be_deleted() {
List<String> res = parse(JSON_DOCUMENT)
.delete("$.store.book[?(@.category == 'fiction')]")
.read("$.store.book[*].category");
assertThat(res).containsExactly("reference");
}
@Test
public void an_array_criteria_with_multiple_results_can_be_deleted(){
InputStream stream = this.getClass().getResourceAsStream("/json_array_multiple_delete.json");
String deletePath = "$._embedded.mandates[?(@.count=~/0/)]";
DocumentContext documentContext = JsonPath.parse(stream);
documentContext.delete(deletePath);
List<Object> result = documentContext.read(deletePath);
assertThat(result.size()).isEqualTo(0);
}
@Test
public void multi_prop_delete() {
List<Map<String, Object>> res = parse(JSON_DOCUMENT).delete("$.store.book[*]['author', 'category']").read("$.store.book[*]['author', 'category']");
assertThat(res).containsExactly(EMPTY_MAP, EMPTY_MAP, EMPTY_MAP, EMPTY_MAP);
}
@Test
public void multi_prop_update() {
Map<String, Object> expected = new HashMap<String, Object>(){{
put("author", "a");
put("category", "a");
}};
List<Map<String, Object>> res = parse(JSON_DOCUMENT).set("$.store.book[*]['author', 'category']", "a").read("$.store.book[*]['author', 'category']");
assertThat(res).containsExactly(expected, expected, expected, expected);
}
@Test
public void multi_prop_update_not_all_defined() {
Map<String, Object> expected = new HashMap<String, Object>(){{
put("author", "a");
put("isbn", "a");
}};
List<Map<String, Object>> res = parse(JSON_DOCUMENT).set("$.store.book[*]['author', 'isbn']", "a").read("$.store.book[*]['author', 'isbn']");
assertThat(res).containsExactly(expected, expected, expected, expected);
}
@Test
public void add_to_array() {
Object res = parse(JSON_DOCUMENT).add("$.store.book", 1).read("$.store.book[4]");
assertThat(res).isEqualTo(1);
}
@Test
public void add_to_object() {
Object res = parse(JSON_DOCUMENT).put("$.store.book[0]", "new-key", "new-value").read("$.store.book[0].new-key");
assertThat(res).isEqualTo("new-value");
}
@Test
public void item_can_be_added_to_root_array() {
List<Integer> model = new LinkedList<>();
model.add(1);
model.add(2);
List<Integer> ints = parse(model).add("$", 3).read("$");
assertThat(ints).containsExactly(1,2,3);
}
@Test
public void key_val_can_be_added_to_root_object() {
Map model = new HashMap();
model.put("a", "a-val");
String newVal = parse(model).put("$", "new-key", "new-val").read("$.new-key");
assertThat(newVal).isEqualTo("new-val");
}
@Test
public void add_to_object_on_array() {
assertThrows(InvalidModificationException.class, () -> parse(JSON_DOCUMENT).put("$.store.book", "new-key", "new-value"));
}
@Test
public void add_to_array_on_object() {
assertThrows(InvalidModificationException.class, () -> parse(JSON_DOCUMENT).add("$.store.book[0]", "new-value"));
}
@Test
public void root_object_can_not_be_updated() {
Map model = new HashMap();
model.put("a", "a-val");
assertThrows(InvalidModificationException.class, () -> parse(model).set("$[?(@.a == 'a-val')]", 1));
}
@Test
public void a_path_can_be_renamed(){
Object o = parse(JSON_DOCUMENT).renameKey("$.store", "book", "updated-book").json();
List<Object> result = parse(o).read("$.store.updated-book");
assertThat(result).isNotEmpty();
}
@Test
public void keys_in_root_containing_map_can_be_renamed(){
Object o = parse(JSON_DOCUMENT).renameKey("$", "store", "new-store").json();
List<Object> result = parse(o).read("$.new-store[*]");
assertThat(result).isNotEmpty();
}
@Test
public void map_array_items_can_be_renamed(){
Object o = parse(JSON_DOCUMENT).renameKey("$.store.book[*]", "category", "renamed-category").json();
List<Object> result = parse(o).read("$.store.book[*].renamed-category");
assertThat(result).isNotEmpty();
}
@Test
public void non_map_array_items_cannot_be_renamed(){
List<Integer> model = new LinkedList<>();
model.add(1);
model.add(2);
assertThrows(InvalidModificationException.class, () -> parse(model).renameKey("$[*]", "oldKey", "newKey"));
}
@Test
public void multiple_properties_cannot_be_renamed(){
assertThrows(InvalidModificationException.class, () ->parse(JSON_DOCUMENT).renameKey("$.store.book[*]['author', 'category']", "old-key", "new-key"));
}
@Test
public void non_existent_key_rename_not_allowed(){
assertThrows(PathNotFoundException.class, () -> parse(JSON_DOCUMENT).renameKey("$", "fake", "new-fake").json());
}
@Test
public void rootCannotBeMapped(){
MapFunction mapFunction = new MapFunction() {
@Override
public Object map(Object currentValue, Configuration configuration) {
return currentValue.toString()+"converted";
}
};
assertThrows(InvalidModificationException.class, () -> parse(JSON_DOCUMENT).map("$", mapFunction).json());
}
@Test
public void single_match_value_can_be_mapped(){
MapFunction mapFunction = new ToStringMapFunction();
String stringResult = parse(JSON_DOCUMENT).map("$.string-property", mapFunction).read("$.string-property");
assertThat(stringResult.endsWith("converted")).isTrue();
}
@Test
public void object_can_be_mapped(){
TypeRef<List<String>> typeRef = new TypeRef<List<String>>() {};
MapFunction mapFunction = new ToStringMapFunction();
DocumentContext documentContext = JsonPath.using(JACKSON_CONFIGURATION).parse(JSON_DOCUMENT);
Object list = documentContext.read("$..book");
assertThat(list).isInstanceOf(List.class);
String result = documentContext.map("$..book", mapFunction).read("$..book", typeRef).get(0);
assertThat(result).isInstanceOf(String.class);
assertThat(result).endsWith("converted");
}
@Test
public void multi_match_path_can_be_mapped(){
MapFunction mapFunction = new ToStringMapFunction();
List<Double> doubleResult = parse(JSON_DOCUMENT).read("$..display-price");
for(Double dRes : doubleResult){
assertThat(dRes).isInstanceOf(Double.class);
}
List<String> stringResult = parse(JSON_DOCUMENT).map("$..display-price", mapFunction).read("$..display-price");
for(String sRes : stringResult){
assertThat(sRes).isInstanceOf(String.class);
assertThat(sRes.endsWith("converted")).isTrue();
}
}
// Helper converter implementation for test cases.
private class ToStringMapFunction implements MapFunction {
@Override
public Object map(Object currentValue, Configuration configuration) {
return currentValue.toString()+"converted";
}
}
}