Skip to content

Commit

Permalink
fix json serialization / deep copy issues #1231
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrthomas committed Jul 28, 2020
1 parent 1c3245c commit 6dbfa1e
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 9 deletions.
4 changes: 2 additions & 2 deletions karate-core/src/main/java/com/intuit/karate/JsonUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public <E extends Feature> void writeJSONString(E value, Appendable out, JSONSty

}

private static class ElementJsonWriter implements JsonWriterI<Element> {
private static class DriverElementJsonWriter implements JsonWriterI<Element> {

@Override
public <E extends Element> void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
Expand All @@ -109,7 +109,7 @@ public <E extends Element> void writeJSONString(E value, Appendable out, JSONSty
// prevent things like the karate script bridge getting serialized (especially in the javafx ui)
JSONValue.registerWriter(ScriptObjectMirror.class, new NashornObjectJsonWriter());
JSONValue.registerWriter(Feature.class, new FeatureJsonWriter());
JSONValue.registerWriter(DriverElement.class, new ElementJsonWriter());
JSONValue.registerWriter(DriverElement.class, new DriverElementJsonWriter());
// ensure that even if jackson (databind?) is on the classpath, don't switch provider
Configuration.setDefaults(new Configuration.Defaults() {

Expand Down
20 changes: 13 additions & 7 deletions karate-core/src/main/java/com/intuit/karate/ScriptValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,17 @@ public ScriptValue copy(boolean deep) {
String json = getValue(DocumentContext.class).jsonString();
return new ScriptValue(JsonPath.parse(json));
case MAP:
if (deep) {
if (deep) {
Map mapSource = getValue(Map.class);
String strSource = JsonPath.parse(mapSource).jsonString();
Map mapDest = JsonPath.parse(strSource).read("$");
// only care about JS functions for treating specially
retainRootKeyValuesWhichAreFunctions(mapSource, mapDest, false);
Map mapDest;
try {
String strSource = JsonPath.parse(mapSource).jsonString();
mapDest = JsonPath.parse(strSource).read("$");
// only care about JS functions for treating specially
retainRootKeyValuesWhichAreFunctions(mapSource, mapDest, false);
} catch (Throwable t) { // json serialization failed, fall-back
mapDest = new LinkedHashMap(mapSource);
}
return new ScriptValue(mapDest);
} else {
return new ScriptValue(new LinkedHashMap(getValue(Map.class)));
Expand Down Expand Up @@ -345,10 +350,11 @@ public String getAsStringRemovingCyclicReferences() {
case MAP:
Map map = JsonUtils.removeCyclicReferences(getAsMap());
return JsonUtils.toJsonDoc(map).jsonString();
default: return getAsString();
default:
return getAsString();
}
}

public String getAsString() {
switch (type) {
case NULL:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.intuit.karate.junit4.xml;

import com.intuit.karate.KarateOptions;
import com.intuit.karate.junit4.Karate;
import org.junit.runner.RunWith;

@RunWith(Karate.class)
@KarateOptions(features = "classpath:com/intuit/karate/junit4/xml/xml-call.feature")
public class XmlCallRunner {

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.intuit.karate.junit4.xml;

import com.intuit.karate.KarateOptions;
import com.intuit.karate.junit4.Karate;
import org.junit.runner.RunWith;

@RunWith(Karate.class)
@KarateOptions(features = "classpath:com/intuit/karate/junit4/xml/xml.feature")
public class XmlRunner {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Feature: Example

Background:
* def prepare_data = call read('xml-called.feature')
* def data = prepare_data.data

Scenario Outline: Executing for <name>
* print name
* print stats

Examples:
| data |
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
@ignore
Feature:

Scenario:
* def xml =
"""
<root>
<hello>
<there>everyone</there>
</hello>
<hello>
<there>anyone</there>
</hello>
</root>
"""
* def nodes = get xml //hello
* def data = [{name: "A", stats: {"vitality":2}}, {name: "B", stats: {"strength":3}}, {name: "C", stats: {"intelligence":5}}]

0 comments on commit 6dbfa1e

Please sign in to comment.