Skip to content

Commit

Permalink
Merge pull request #649 from baulea/jsonPathJacksonProvider
Browse files Browse the repository at this point in the history
introduce JsonPathJacksonProvider
  • Loading branch information
a1shadows committed Mar 31, 2024
2 parents 6e1c2be + 881953b commit 569a8cd
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 121 deletions.
4 changes: 0 additions & 4 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,6 @@
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
<dependency>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
</dependency>

<dependency>
<groupId>com.google.classpath-explorer</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.jsmart.zerocode.core.di.provider;

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.spi.mapper.MappingProvider;
import jakarta.inject.Provider;
import java.util.EnumSet;
import java.util.Set;

public class JsonPathJacksonProvider implements Provider<Configuration.Defaults> {
@Override
public Configuration.Defaults get() {
return new Configuration.Defaults() {

private final JsonProvider jsonProvider = new JacksonJsonProvider();
private final MappingProvider mappingProvider = new JacksonMappingProvider();

@Override
public JsonProvider jsonProvider() {
return jsonProvider;
}

@Override
public MappingProvider mappingProvider() {
return mappingProvider;
}

@Override
public Set<Option> options() {
return EnumSet.noneOf(Option.class);
}
};
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

package org.jsmart.zerocode.core.engine.assertion.array;

import net.minidev.json.JSONArray;
import org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher;
import org.jsmart.zerocode.core.engine.assertion.JsonAsserter;

import java.util.List;

import static org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher.aMatchingMessage;
import static org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher.aNotMatchingMessage;

Expand All @@ -27,21 +28,14 @@ public Object getExpected() {

@Override
public FieldAssertionMatcher actualEqualsToExpected(Object result) {
if(result instanceof JSONArray){

final JSONArray actualArrayValue = (JSONArray) result;

if(actualArrayValue.isEmpty()){
if (result instanceof List<?>) {
List<?> list = (List<?>) result;

if (list.isEmpty()) {
return aMatchingMessage();
}

return aNotMatchingMessage(path, "[]", result);

} else {

return aNotMatchingMessage(path, "[]", result);

}
return aNotMatchingMessage(path, "[]", result);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

package org.jsmart.zerocode.core.engine.assertion.array;

import net.minidev.json.JSONArray;
import org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher;
import org.jsmart.zerocode.core.engine.assertion.JsonAsserter;

import java.util.List;

import static org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher.aMatchingMessage;
import static org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher.aNotMatchingMessage;
import static org.jsmart.zerocode.core.engine.tokens.ZeroCodeAssertionTokens.ASSERT_VALUE_EQUAL_TO_NUMBER;
Expand Down Expand Up @@ -41,25 +42,24 @@ public Object getExpected() {

@Override
public FieldAssertionMatcher actualEqualsToExpected(Object result) {
if (result instanceof JSONArray) {

final JSONArray actualArrayValue = (JSONArray) result;
if (result instanceof List<?>) {
List<?> list = (List<?>) result;

if (this.expectedSize == -1 && this.expectedSizeExpression != null) {

return processRelationalExpression(actualArrayValue);
return processRelationalExpression(list);

}

if (actualArrayValue.size() == this.expectedSize) {
if (list.size() == this.expectedSize) {

return aMatchingMessage();
}

return aNotMatchingMessage(
path,
String.format("Array of size %d", expectedSize),
actualArrayValue.size());
list.size());

} else {

Expand All @@ -68,33 +68,33 @@ public FieldAssertionMatcher actualEqualsToExpected(Object result) {
}
}

public FieldAssertionMatcher processRelationalExpression(JSONArray actualArrayValue) {
public FieldAssertionMatcher processRelationalExpression(List<?> list) {
if (expectedSizeExpression.startsWith(ASSERT_VALUE_GREATER_THAN)) {
String greaterThan = this.expectedSizeExpression.substring(ASSERT_VALUE_GREATER_THAN.length());
if (actualArrayValue.size() > Integer.parseInt(greaterThan)) {
if (list.size() > Integer.parseInt(greaterThan)) {
return aMatchingMessage();
}
} else if (expectedSizeExpression.startsWith(ASSERT_VALUE_LESSER_THAN)) {
String lesserThan = this.expectedSizeExpression.substring(ASSERT_VALUE_LESSER_THAN.length());
if (actualArrayValue.size() < Integer.parseInt(lesserThan)) {
if (list.size() < Integer.parseInt(lesserThan)) {
return aMatchingMessage();
}
} else if (expectedSizeExpression.startsWith(ASSERT_VALUE_EQUAL_TO_NUMBER)) {
String equalTo = this.expectedSizeExpression.substring(ASSERT_VALUE_EQUAL_TO_NUMBER.length());
if (actualArrayValue.size() == Integer.parseInt(equalTo)) {
if (list.size() == Integer.parseInt(equalTo)) {
return aMatchingMessage();
}
} else if (expectedSizeExpression.startsWith(ASSERT_VALUE_NOT_EQUAL_TO_NUMBER)) {
String notEqualTo = this.expectedSizeExpression.substring(ASSERT_VALUE_NOT_EQUAL_TO_NUMBER.length());
if (actualArrayValue.size() != Integer.parseInt(notEqualTo)) {
if (list.size() != Integer.parseInt(notEqualTo)) {
return aMatchingMessage();
}
}

return aNotMatchingMessage(
path,
String.format("Array of size %s", expectedSizeExpression),
actualArrayValue.size());
list.size());
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;
import org.apache.commons.text.StringSubstitutor;
import org.jsmart.zerocode.core.domain.Step;
import org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher;
Expand Down Expand Up @@ -442,7 +441,7 @@ private LocalDateTime parseLocalDateTime(String value) {
}

boolean isPathValueJson(Object jsonPathValue) {
return jsonPathValue instanceof LinkedHashMap || jsonPathValue instanceof JSONArray;
return jsonPathValue instanceof LinkedHashMap || jsonPathValue instanceof List<?>;
}

void resolveLeafOnlyNodeValue(String scenarioState, Map<String, String> paramMap, String thisPath) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
import org.jsmart.zerocode.core.domain.Step;
import org.jsmart.zerocode.core.engine.preprocessor.ZeroCodeAssertionsProcessor;
import org.slf4j.Logger;
Expand Down Expand Up @@ -52,43 +50,37 @@ public String sortArrayAndReplaceInResponse(Step thisStep, String results, Strin
//
String transformedPath = zeroCodeAssertionsProcessor.resolveStringJson(path,
resolvedScenarioState);
Object result = getArrayToSort(transformedPath, results);

List<?> listToSort = JsonPath.parse(results).read(transformedPath, List.class);
// sorting passed array
List<Map<?, ?>> sortedList = sortList(listToSort, key, order);
return replaceArrayWithSorted(results, transformedPath, sortedList);

if (result instanceof JSONArray) {
JSONArray arrayToSort = (JSONArray) result;

// sorting passed array
JSONArray sortedArray = sortArray(arrayToSort, key, order);
return replaceArrayWithSorted(results, transformedPath, sortedArray);
} else {
throw new RuntimeException("Can't sort not an array");
}
}

private JSONArray sortArray(JSONArray arrayToSort, String key, String order) {
JSONArray sortedJsonArray = new JSONArray();

List<Map<String, ?>> jsonValues = new ArrayList<>();
private List<Map<?, ?>> sortList(List<?> arrayToSort, String key, String order) {
List<Map<?, ?>> jsonValues = new ArrayList<>();
for (Object o : arrayToSort) {
jsonValues.add((Map<String, ?>) o);
if (o instanceof Map<?, ?>) {
Map<?, ?> map = (Map<?, ?>) o;
jsonValues.add(map);
} else {
LOGGER.error("list item is no map and ignored during sort: {}", o);
}
}

jsonValues.sort((a, b) -> {
Comparable valA;
Comparable valB;

try {
valA = (Comparable) a.get(key);
valB = (Comparable) b.get(key);
} catch (Exception e) {
LOGGER.error("Objects can't be compared" + e);
Comparable valA = (Comparable<?>) a.get(key);
Comparable valB = (Comparable<?>) b.get(key);
return order.equalsIgnoreCase(SortOrder.NATURAL.getValue()) ? valA.compareTo(valB)
: -valA.compareTo(valB);
} catch (ClassCastException e) {
LOGGER.error("Objects can't be compared", e);
throw new RuntimeException("Objects can't be compared", e.getCause());
}
return order.equalsIgnoreCase(SortOrder.NATURAL.getValue()) ? valA.compareTo(valB)
: -valA.compareTo(valB);
});
sortedJsonArray.addAll(jsonValues);
return sortedJsonArray;
return jsonValues;
}

private Map<String, String> convertToMap(String value) {
Expand All @@ -101,11 +93,7 @@ private Map<String, String> convertToMap(String value) {
}
}

public Object getArrayToSort(String path, String results) {
return JsonPath.read(results, path);
}

public String replaceArrayWithSorted(String results, String path, Object sortedArray) {
private String replaceArrayWithSorted(String results, String path, Object sortedArray) {
return JsonPath.parse(results).set(path, sortedArray).jsonString();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package org.jsmart.zerocode.core.engine.validators;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import java.util.ArrayList;
import java.util.List;
import org.jsmart.zerocode.core.di.provider.JsonPathJacksonProvider;
import org.jsmart.zerocode.core.di.provider.ObjectMapperProvider;
import org.jsmart.zerocode.core.domain.Step;
import org.jsmart.zerocode.core.domain.Validator;
import org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher;
import org.jsmart.zerocode.core.engine.assertion.JsonAsserter;
import org.jsmart.zerocode.core.engine.preprocessor.ZeroCodeAssertionsProcessor;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.List;

import static org.jsmart.zerocode.core.utils.HelperJsonUtils.strictComparePayload;
import static org.slf4j.LoggerFactory.getLogger;

Expand All @@ -20,9 +26,13 @@ public class ZeroCodeValidatorImpl implements ZeroCodeValidator {

private final ZeroCodeAssertionsProcessor zeroCodeAssertionsProcessor;

private final ObjectMapper mapper;

@Inject
public ZeroCodeValidatorImpl(ZeroCodeAssertionsProcessor zeroCodeAssertionsProcessor) {
this.zeroCodeAssertionsProcessor = zeroCodeAssertionsProcessor;
this.mapper = new ObjectMapperProvider().get();
Configuration.setDefaults(new JsonPathJacksonProvider().get());
}

@Override
Expand All @@ -40,10 +50,16 @@ public List<FieldAssertionMatcher> validateFlat(Step thisStep, String actualResu
JsonNode expectedValue = validator.getValue();

Object actualValue = JsonPath.read(actualResult, transformed);
String actualString;
try {
actualString = this.mapper.writeValueAsString(actualValue);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}

List<JsonAsserter> asserters = zeroCodeAssertionsProcessor.createJsonAsserters(expectedValue.toString());

failureResults.addAll(zeroCodeAssertionsProcessor.assertAllAndReturnFailed(asserters, actualValue.toString()));
failureResults.addAll(zeroCodeAssertionsProcessor.assertAllAndReturnFailed(asserters, actualString));
}

return failureResults;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package org.jsmart.zerocode.core.kafka.helper;

import static org.jsmart.zerocode.core.kafka.KafkaConstants.RAW;
import static org.jsmart.zerocode.core.kafka.common.CommonConfigs.BOOTSTRAP_SERVERS;
import static org.jsmart.zerocode.core.kafka.common.KafkaCommonUtils.resolveValuePlaceHolders;
import static org.jsmart.zerocode.core.kafka.error.KafkaMessageConstants.NO_RECORD_FOUND_TO_SEND;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Properties;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.Message.Builder;
import com.google.protobuf.util.JsonFormat;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
Expand All @@ -22,15 +19,17 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.Message.Builder;
import com.google.protobuf.util.JsonFormat;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Properties;

import static org.jsmart.zerocode.core.kafka.KafkaConstants.RAW;
import static org.jsmart.zerocode.core.kafka.common.CommonConfigs.BOOTSTRAP_SERVERS;
import static org.jsmart.zerocode.core.kafka.common.KafkaCommonUtils.resolveValuePlaceHolders;
import static org.jsmart.zerocode.core.kafka.error.KafkaMessageConstants.NO_RECORD_FOUND_TO_SEND;

public class KafkaProducerHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(KafkaProducerHelper.class);
Expand Down

0 comments on commit 569a8cd

Please sign in to comment.