[#134] Asserting JSON via JSON Assert

This commit is contained in:
Marcin Grzejszczak
2016-02-08 21:33:32 +01:00
parent 5388ead646
commit a9e837ed88
22 changed files with 870 additions and 225 deletions

View File

@@ -1,6 +1,7 @@
package io.codearte.accurest
import groovy.transform.PackageScope
import groovy.util.logging.Slf4j
import io.codearte.accurest.builder.ClassBuilder
import io.codearte.accurest.config.AccurestConfigProperties
import io.codearte.accurest.config.TestFramework
@@ -11,8 +12,12 @@ import static io.codearte.accurest.builder.ClassBuilder.createClass
import static io.codearte.accurest.builder.MethodBuilder.createTestMethod
import static io.codearte.accurest.util.NamesUtil.capitalize
@Slf4j
class SingleTestGenerator {
private static final String JSON_ASSERT_STATIC_IMPORT = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThat'
private static final String JSON_ASSERT_CLASS = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion'
private final AccurestConfigProperties configProperties
SingleTestGenerator(AccurestConfigProperties configProperties) {
@@ -76,8 +81,20 @@ class SingleTestGenerator {
private ClassBuilder addJsonPathRelatedImports(ClassBuilder clazz) {
clazz.addImport(['com.jayway.jsonpath.DocumentContext',
'com.jayway.jsonpath.JsonPath',
'net.minidev.json.JSONArray'])
'com.jayway.jsonpath.JsonPath'])
if (jsonAssertPresent()) {
clazz.addStaticImport(JSON_ASSERT_STATIC_IMPORT)
}
}
private static boolean jsonAssertPresent() {
try {
Class.forName(JSON_ASSERT_CLASS)
return true
} catch (ClassNotFoundException e) {
log.debug("JsonAssert is not present on classpath. Will not add a static import")
return false
}
}
}

View File

@@ -90,9 +90,7 @@ abstract class SpockMethodBodyBuilder {
appendJsonPath(bb, responseAsString)
JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(responseBody)
jsonPaths.each {
it.buildJsonPathComparison('parsedJson').each {
bb.addLine(it)
}
bb.addLine("assertThat(parsedJson)" + it.method())
}
processBodyElement(bb, "", responseBody)
} else if (contentType == ContentType.XML) {

View File

@@ -34,6 +34,11 @@ class AccurestConfigProperties {
*/
String ruleClassForTests
/**
* Which version of JSON Assert (com.blogspot.toomuchcoding:jsonassert) to use
*/
String jsonAssertVersion = "+"
/**
* Patterns that should not be taken into account for processing
*/

View File

@@ -68,7 +68,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
requestPattern.bodyPatterns = [new ValuePattern(jsonCompareMode: org.skyscreamer.jsonassert.JSONCompareMode.LENIENT,
equalToJson: JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue) ) ]
} else {
requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath) } ?: null
requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath()) } ?: null
}
} else if (contentType == ContentType.XML) {
requestPattern.bodyPatterns = [new ValuePattern(equalToXml: getMatchingStrategy(request.body.clientValue).clientValue.toString())]

View File

@@ -26,4 +26,15 @@ class Headers {
}
}
boolean equals(o) {
if (this.is(o)) return true
if (getClass() != o.class) return false
Headers headers = (Headers) o
if (entries != headers.entries) return false
return true
}
int hashCode() {
return entries.hashCode()
}
}

View File

@@ -0,0 +1,227 @@
package io.codearte.accurest.util;
import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable;
/**
* @author Marcin Grzejszczak
*/
class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable {
private final JsonVerifiable delegate;
private final StringBuffer methodsBuffer;
DelegatingJsonVerifiable(JsonVerifiable delegate,
StringBuffer methodsBuffer) {
this.delegate = delegate;
this.methodsBuffer = new StringBuffer(methodsBuffer.toString());
}
DelegatingJsonVerifiable(JsonVerifiable delegate) {
this.delegate = delegate;
this.methodsBuffer = new StringBuffer();
}
private static String stringWithEscapedQuotes(Object object) {
String stringValue = object.toString();
return stringValue.replaceAll("\"", "\\\\\"");
}
private static String wrapValueWithQuotes(Object value) {
return value instanceof String ?
"\"" + stringWithEscapedQuotes(value).replaceAll("\\$", "\\\\\\$") + "\"" :
value.toString();
}
@Override
public MethodBufferingJsonVerifiable contains(Object value) {
DelegatingJsonVerifiable verifiable = new FinishedDelegatingJsonVerifiable(delegate.contains(value), methodsBuffer);
verifiable.methodsBuffer.append(".contains(").append(wrapValueWithQuotes(value))
.append(")");
if (isAssertingAValueInArray()) {
verifiable.methodsBuffer.append(".value()");
}
return verifiable;
}
@Override
public MethodBufferingJsonVerifiable field(Object value) {
Object valueToPut = value instanceof ShouldTraverse ? ((ShouldTraverse) value).value : value;
DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.field(valueToPut), methodsBuffer);
if (delegate.isIteratingOverArray() && !(value instanceof ShouldTraverse)) {
verifiable.methodsBuffer.append(".contains(").append(wrapValueWithQuotes(valueToPut))
.append(")");
} else {
verifiable.methodsBuffer.append(".field(").append(wrapValueWithQuotes(valueToPut))
.append(")");
}
return verifiable;
}
@Override
public MethodBufferingJsonVerifiable array(Object value) {
DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.array(value), methodsBuffer);
verifiable.methodsBuffer.append(".array(").append(wrapValueWithQuotes(value))
.append(")");
return verifiable;
}
@Override
public MethodBufferingJsonVerifiable arrayField(Object value) {
DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.field(value).arrayField(), methodsBuffer);
verifiable.methodsBuffer.append(".array(").append(wrapValueWithQuotes(value))
.append(")");
return verifiable;
}
@Override
public MethodBufferingJsonVerifiable arrayField() {
return new DelegatingJsonVerifiable(delegate.arrayField(), methodsBuffer);
}
@Override
public MethodBufferingJsonVerifiable array() {
DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.array(), methodsBuffer);
verifiable.methodsBuffer.append(".array()");
return verifiable;
}
@Override
public MethodBufferingJsonVerifiable iterationPassingArray() {
return new DelegatingJsonVerifiable(delegate, methodsBuffer);
}
@Override
public MethodBufferingJsonVerifiable isEqualTo(String value) {
DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isEqualTo(value), methodsBuffer);
if (delegate.isAssertingAValueInArray()) {
readyToCheck.methodsBuffer.append(".value()");
} else {
readyToCheck.methodsBuffer.append(".isEqualTo(")
.append(wrapValueWithQuotes(value)).append(")");
}
return readyToCheck;
}
@Override
public MethodBufferingJsonVerifiable isEqualTo(Object value) {
if (value == null) {
return isNull();
}
return isEqualTo(value.toString());
}
@Override
public MethodBufferingJsonVerifiable isEqualTo(Number value) {
DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isEqualTo(value), methodsBuffer);
if (delegate.isAssertingAValueInArray()) {
readyToCheck.methodsBuffer.append(".value()");
} else {
readyToCheck.methodsBuffer.append(".isEqualTo(").append(String.valueOf(value))
.append(")");
}
return readyToCheck;
}
@Override
public MethodBufferingJsonVerifiable isNull() {
DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isNull(), methodsBuffer);
readyToCheck.methodsBuffer.append(".isNull()");
return readyToCheck;
}
@Override
public MethodBufferingJsonVerifiable matches(String value) {
DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.matches(value), methodsBuffer);
if (delegate.isAssertingAValueInArray()) {
readyToCheck.methodsBuffer.append(".value()");
} else {
readyToCheck.methodsBuffer.append(".matches(").append(wrapValueWithQuotes(value))
.append(")");
}
return readyToCheck;
}
@Override
public MethodBufferingJsonVerifiable isEqualTo(Boolean value) {
DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isEqualTo(value), methodsBuffer);
if (delegate.isAssertingAValueInArray()) {
readyToCheck.methodsBuffer.append(".value()");
} else {
readyToCheck.methodsBuffer.append(".isEqualTo(").append(String.valueOf(value))
.append(")");
}
return readyToCheck;
}
@Override
public MethodBufferingJsonVerifiable value() {
return new FinishedDelegatingJsonVerifiable(delegate, methodsBuffer);
}
@Override
public JsonVerifiable withoutThrowingException() {
return delegate.withoutThrowingException();
}
@Override
public String jsonPath() {
return delegate.jsonPath();
}
@Override
public void matchesJsonPath(String s) {
delegate.matchesJsonPath(s);
}
@Override
public boolean isIteratingOverNamelessArray() {
return delegate.isIteratingOverNamelessArray();
}
@Override
public boolean isIteratingOverArray() {
return delegate.isIteratingOverArray();
}
@Override
public boolean isAssertingAValueInArray() {
return delegate.isAssertingAValueInArray();
}
@Override
public String method() {
return methodsBuffer.toString();
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
DelegatingJsonVerifiable that = (DelegatingJsonVerifiable) o;
if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null)
return false;
return methodsBuffer != null ?
methodsBuffer.equals(that.methodsBuffer) :
that.methodsBuffer == null;
}
@Override
public int hashCode() {
int result = delegate != null ? delegate.hashCode() : 0;
result = 31 * result + (methodsBuffer != null ? methodsBuffer.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "DelegatingJsonVerifiable{" +
"delegate=\n" + delegate +
", methodsBuffer=" + methodsBuffer +
'}';
}
}

View File

@@ -0,0 +1,19 @@
package io.codearte.accurest.util;
import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable;
/**
* @author Marcin Grzejszczak
*/
class FinishedDelegatingJsonVerifiable extends DelegatingJsonVerifiable {
FinishedDelegatingJsonVerifiable(JsonVerifiable delegate,
StringBuffer methodsBuffer) {
super(delegate, methodsBuffer);
}
FinishedDelegatingJsonVerifiable(JsonVerifiable delegate) {
super(delegate, new StringBuffer());
}
}

View File

@@ -1,40 +0,0 @@
package io.codearte.accurest.util
import java.util.regex.Pattern
class JsonPathEntry {
final String jsonPath
final String optionalSuffix
final Object value
JsonPathEntry(String jsonPath, String optionalSuffix, Object value) {
this.jsonPath = jsonPath
this.optionalSuffix = optionalSuffix
this.value = value
}
List<String> buildJsonPathComparison(String parsedJsonVariable) {
if (optionalSuffix) {
return ["!${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).empty"]
} else if (traversesOverCollections()) {
return ["${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).get(0) ${operator()} ${potentiallyWrappedWithQuotesValue()}"]
}
return ["${parsedJsonVariable}.read('''${jsonPath}''') ${operator()} ${potentiallyWrappedWithQuotesValue()}"]
}
private boolean traversesOverCollections() {
return jsonPath.contains('[*]')
}
String operator() {
return value instanceof Pattern ? "==~" : "=="
}
String potentiallyWrappedWithQuotesValue() {
return value instanceof Number ? value : "'''$value'''"
}
static JsonPathEntry simple(String jsonPath, Object value) {
return new JsonPathEntry(jsonPath, "", value)
}
}

View File

@@ -1,23 +1,6 @@
package io.codearte.accurest.util
class JsonPaths extends HashSet<JsonPathEntry> {
class JsonPaths extends HashSet<MethodBufferingJsonVerifiable> {
Object getAt(String key) {
return find {
it.jsonPath == key
}?.value
}
Object putAt(String key, Object value) {
JsonPathEntry entry = find {
it.jsonPath == key
}
if (!entry) {
return null
}
Object oldValue = entry.value
add(new JsonPathEntry(entry.jsonPath, entry.optionalSuffix, value))
return oldValue
}
}

View File

@@ -1,9 +1,12 @@
package io.codearte.accurest.util
import java.util.regex.Pattern
import com.blogspot.toomuchcoding.jsonassert.JsonAssertion
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import io.codearte.accurest.dsl.internal.ExecutionProperty
import io.codearte.accurest.dsl.internal.OptionalProperty
import java.util.regex.Pattern
/**
* @author Marcin Grzejszczak
*/
@@ -12,9 +15,6 @@ class JsonToJsonPathsConverter {
private static final Boolean SERVER_SIDE = false
private static final Boolean CLIENT_SIDE = true
public static final String ROOT_JSON_PATH_ELEMENT = '$'
public static final String ALL_ELEMENTS = "[*]"
public static JsonPaths transformToJsonPathWithTestsSideValues(def json) {
return transformToJsonPathWithValues(json, SERVER_SIDE)
}
@@ -29,17 +29,19 @@ class JsonToJsonPathsConverter {
}
JsonPaths pathsAndValues = [] as Set
Object convertedJson = MapConverter.getClientOrServerSideValues(json, clientSide)
traverseRecursivelyForKey(convertedJson, ROOT_JSON_PATH_ELEMENT) { String key, Object value ->
if (value instanceof ExecutionProperty) {
MethodBufferingJsonVerifiable methodBufferingJsonPathVerifiable =
new DelegatingJsonVerifiable(JsonAssertion.assertThat(JsonOutput.toJson(convertedJson)).withoutThrowingException())
traverseRecursivelyForKey(convertedJson, methodBufferingJsonPathVerifiable)
{ MethodBufferingJsonVerifiable key, Object value ->
if (value instanceof ExecutionProperty || !(key instanceof FinishedDelegatingJsonVerifiable)) {
return
}
JsonPathEntry entry = getValueToInsert(key, value)
pathsAndValues.add(entry)
pathsAndValues.add(key)
}
return pathsAndValues
}
protected static def traverseRecursively(Class parentType, String key, def value, Closure closure) {
protected static def traverseRecursively(Class parentType, MethodBufferingJsonVerifiable key, def value, Closure closure) {
if (value instanceof String && value) {
try {
def json = new JsonSlurper().parseText(value)
@@ -47,7 +49,7 @@ class JsonToJsonPathsConverter {
return convertWithKey(parentType, key, json, closure)
}
} catch (Exception ignore) {
return closure(key, value)
return runClosure(closure, key, value)
}
} else if (isAnEntryWithNonCollectionLikeValue(value)) {
return convertWithKey(List, key, value as Map, closure)
@@ -56,18 +58,51 @@ class JsonToJsonPathsConverter {
} else if (value instanceof Map) {
return convertWithKey(Map, key, value as Map, closure)
} else if (value instanceof List) {
MethodBufferingJsonVerifiable jsonPathVerifiable = createAsserterFromList(key, value)
value.each { def element ->
traverseRecursively(List, "$key[*]", element, closure)
traverseRecursively(List, createAsserterFromListElement(jsonPathVerifiable, element),
element, closure)
}
return value
} else if (key.isIteratingOverArray()) {
traverseRecursively(Object, key.arrayField().contains(value), value, closure)
}
try {
return closure(key, value)
return runClosure(closure, key, value)
} catch (Exception ignore) {
return value
}
}
private static MethodBufferingJsonVerifiable createAsserterFromList(MethodBufferingJsonVerifiable key, List value) {
if (key.isIteratingOverNamelessArray()) {
return key.array()
} else if (key.isIteratingOverArray() && isAnEntryWithLists(value)) {
if (!value.every { listContainsOnlyPrimitives(it as List)} ) {
return key.array()
} else {
return key.iterationPassingArray()
}
} else if (key.isIteratingOverArray()) {
return key.iterationPassingArray()
}
return key
}
private static MethodBufferingJsonVerifiable createAsserterFromListElement(MethodBufferingJsonVerifiable jsonPathVerifiable, def element) {
if (jsonPathVerifiable.isAssertingAValueInArray()) {
return jsonPathVerifiable.contains(element)
}
return jsonPathVerifiable
}
private static def runClosure(Closure closure, MethodBufferingJsonVerifiable key, def value) {
if (key.isAssertingAValueInArray()) {
return closure(valueToAsserter(key, value), value)
}
return closure(key, value)
}
private static boolean isAnEntryWithNonCollectionLikeValue(def value) {
if (!(value instanceof Map)) {
return false
@@ -87,74 +122,52 @@ class JsonToJsonPathsConverter {
}
Map valueAsMap = ((Map) value)
return valueAsMap.entrySet().every { Map.Entry entry ->
[String, Number].any { entry.value.getClass().isAssignableFrom(it) }
[String, Number, Boolean].any { it.isAssignableFrom(entry.value.getClass()) }
}
}
private static Map convertWithKey(Class parentType, String parentKey, Map map, Closure closureToExecute) {
private static boolean listContainsOnlyPrimitives(List list) {
return list.every { def element ->
[String, Number, Boolean].any {
it.isAssignableFrom(element.getClass())
}
}
}
private static boolean isAnEntryWithLists(def value) {
if (!(value instanceof Iterable)) {
return false
}
return value.every { def entry ->
entry instanceof List
}
}
private static Map convertWithKey(Class parentType, MethodBufferingJsonVerifiable parentKey, Map map, Closure closureToExecute) {
return map.collectEntries {
Object entrykey, value ->
[entrykey, traverseRecursively(parentType, "${parentKey}.${entrykey}", value, closureToExecute)]
[entrykey, traverseRecursively(parentType,
value instanceof List ? listContainsOnlyPrimitives(value) ?
parentKey.arrayField(entrykey) :
parentKey.array(entrykey) :
value instanceof Map ? parentKey.field(new ShouldTraverse(entrykey)) :
valueToAsserter(parentKey.field(entrykey), value)
, value, closureToExecute)]
}
}
private static void traverseRecursivelyForKey(def json, String rootKey, Closure closure) {
private static void traverseRecursivelyForKey(def json, MethodBufferingJsonVerifiable rootKey, Closure closure) {
traverseRecursively(Map, rootKey, json, closure)
}
private static JsonPathEntry getValueToInsert(String key, Object value) {
return convertToListElementFiltering(key, value)
}
protected static JsonPathEntry convertToListElementFiltering(String key, Object value) {
if (key.endsWith(ALL_ELEMENTS)) {
int lastAllElements = key.lastIndexOf(ALL_ELEMENTS)
String keyWithoutAllElements = key.substring(0, lastAllElements)
return JsonPathEntry.simple("""$keyWithoutAllElements[?(@ ${compareWith(value)})]""".toString(), value)
}
return getKeyForTraversalOfListWithNonPrimitiveTypes(key, value)
}
private static JsonPathEntry getKeyForTraversalOfListWithNonPrimitiveTypes(String key, Object value) {
int lastDot = key.lastIndexOf('.')
String keyWithoutLastElement = key.substring(0, lastDot)
String lastElement = key.substring(lastDot + 1).replaceAll(~/\[\*\]/, "")
return new JsonPathEntry(
"""$keyWithoutLastElement[?(@.$lastElement ${compareWith(value)})]""".toString(),
lastElement,
value
)
}
protected static String compareWith(Object value) {
protected static MethodBufferingJsonVerifiable valueToAsserter(MethodBufferingJsonVerifiable key, Object value) {
if (value instanceof Pattern) {
return patternComparison((value as Pattern).pattern())
return key.matches((value as Pattern).pattern())
} else if (value instanceof OptionalProperty) {
return patternComparison((value as OptionalProperty).optionalPattern())
return key.matches((value as OptionalProperty).optionalPattern())
} else if (value instanceof GString) {
return """=~ /${RegexpBuilders.buildGStringRegexpForTestSide(value)}/"""
return key.matches(RegexpBuilders.buildGStringRegexpForTestSide(value))
}
return """== ${potentiallyWrappedWithQuotesValue(value)}"""
}
protected static String patternComparison(String pattern){
return """=~ /$pattern/"""
}
protected static String potentiallyWrappedWithQuotesValue(Object value) {
return isNumber(value) || isBoolean(value) || isNull(value) ? value : "'$value'"
}
private static boolean isNull(value) {
return value == null
}
private static boolean isBoolean(value) {
return value instanceof Boolean
}
private static boolean isNumber(value) {
return value instanceof Number
return key.isEqualTo(value)
}
}

View File

@@ -0,0 +1,9 @@
package io.codearte.accurest.util;
/**
* @author Marcin Grzejszczak
*/
public interface MethodBuffering {
String method();
}

View File

@@ -0,0 +1,49 @@
package io.codearte.accurest.util;
import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable;
/**
* @author Marcin Grzejszczak
*/
public interface MethodBufferingJsonVerifiable
extends JsonVerifiable, MethodBuffering, MethodBufferingReadyToCheck {
@Override
MethodBufferingJsonVerifiable contains(Object value);
@Override
MethodBufferingJsonVerifiable field(Object value);
@Override
MethodBufferingJsonVerifiable array(Object value);
MethodBufferingJsonVerifiable arrayField(Object value);
@Override
MethodBufferingJsonVerifiable arrayField();
@Override
MethodBufferingJsonVerifiable array();
MethodBufferingJsonVerifiable iterationPassingArray();
@Override
MethodBufferingJsonVerifiable isEqualTo(String value);
@Override
MethodBufferingJsonVerifiable isEqualTo(Object value);
@Override
MethodBufferingJsonVerifiable isEqualTo(Number value);
@Override
MethodBufferingJsonVerifiable isNull();
@Override
MethodBufferingJsonVerifiable matches(String value);
@Override
MethodBufferingJsonVerifiable isEqualTo(Boolean value);
@Override
MethodBufferingJsonVerifiable value();
}

View File

@@ -0,0 +1,8 @@
package io.codearte.accurest.util;
/**
* @author Marcin Grzejszczak
*/
interface MethodBufferingReadyToCheck extends MethodBuffering {
}

View File

@@ -0,0 +1,12 @@
package io.codearte.accurest.util;
/**
* @author Marcin Grzejszczak
*/
class ShouldTraverse {
final Object value;
ShouldTraverse(Object value) {
this.value = value;
}
}

View File

@@ -29,8 +29,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
blockBuilder.toString().contains("\$[?(@.property2 == 'b')]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -57,9 +57,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property1 == 'true')]")
blockBuilder.toString().contains("\$[?(@.property2 == null)]")
blockBuilder.toString().contains("\$[?(@.property3 == false)]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property3").isEqualTo(false)""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isNull()""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("true")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -88,9 +88,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]")
blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("a").isEqualTo("sth")""")
blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -115,7 +115,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("entity('{\"items\":[\"HOP\"]}', 'application/json')")
blockBuilder.toString().contains("""entity('{\"items\":[\"HOP\"]}', 'application/json')""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -140,7 +140,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("entity('property1=VAL1', 'application/octet-stream')")
blockBuilder.toString().contains("""entity('property1=VAL1', 'application/octet-stream')""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -168,8 +168,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]")
blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]")
blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property1").isEqualTo("a")""")
blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property2").isEqualTo("b")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -196,8 +196,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]")
blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]")
blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property2").isEqualTo("test1")""")
blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property3").isEqualTo("test2")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -224,8 +224,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]")
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").field("property3").isEqualTo("b")""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -258,15 +258,15 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]")
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
def "should generate regex assertions for string objects in response body"() {
given:
GroovyDsl contractDsl = GroovyDsl.make {
GroovyDsl contractDsl = GroovyDsl.make {
request {
method "GET"
url "test"
@@ -286,8 +286,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]")
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -337,9 +337,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("entity('', 'text/plain')")
blockBuilder.toString().contains("header('Timer', '123')")
!blockBuilder.toString().contains("header('Content-Type'")
blockBuilder.toString().contains("""entity('', 'text/plain')""")
blockBuilder.toString().contains("""header('Timer', '123')""")
!blockBuilder.toString().contains("""header('Content-Type'""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -388,8 +388,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
spockTest.contains("queryParam('age', '99'")
spockTest.contains("queryParam('name', 'Denis.Stepanov'")
spockTest.contains("queryParam('email', 'bob@email.com'")
spockTest.contains('$[?(@.property2 == \'b\')]')
spockTest.contains('$[?(@.property1 == \'a\')]')
spockTest.contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
spockTest.contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -439,8 +439,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
spockTest.contains("queryParam('age', '99'")
spockTest.contains("queryParam('name', 'Denis.Stepanov'")
spockTest.contains("queryParam('email', 'bob@email.com'")
spockTest.contains('$[?(@.property2 == \'b\')]')
spockTest.contains('$[?(@.property1 == \'a\')]')
spockTest.contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
spockTest.contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -486,7 +486,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc
builder.appendTo(blockBuilder)
def spockTest = blockBuilder.toString()
then:
spockTest.contains('String responseAsString = response.readEntity(String)')
spockTest.contains("String responseAsString = response.readEntity(String)")
spockTest.contains('responseBody == "test"')
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())

View File

@@ -9,7 +9,6 @@ import spock.lang.Specification
import spock.lang.Unroll
import java.util.regex.Pattern
/**
* @author Jakub Kubrynski
*/
@@ -35,8 +34,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
blockBuilder.toString().contains("\$[?(@.property2 == 'b')]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -63,9 +62,9 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property1 == 'true')]")
blockBuilder.toString().contains("\$[?(@.property2 == null)]")
blockBuilder.toString().contains("\$[?(@.property3 == false)]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("true")""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isNull()""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property3").isEqualTo(false)""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -94,9 +93,9 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]")
blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("a").isEqualTo("sth")""")
blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -121,7 +120,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains(".body('''{\"items\":[\"HOP\"]}''')")
blockBuilder.toString().contains(""".body('''{\"items\":[\"HOP\"]}''')""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -146,7 +145,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains(".body('''property1=VAL1''')")
blockBuilder.toString().contains(""".body('''property1=VAL1''')""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -174,8 +173,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$.property[?(@.7 == 0.0)]")
blockBuilder.toString().contains("\$.property[?(@.14 == 0.0)]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(7).isEqualTo(0.0)""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(14).isEqualTo(0.0)""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -203,8 +202,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]")
blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]")
blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property2").isEqualTo("b")""")
blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property1").isEqualTo("a")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -231,8 +230,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]")
blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]")
blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property2").isEqualTo("test1")""")
blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property3").isEqualTo("test2")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -259,15 +258,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]")
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").field("property3").isEqualTo("b")""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
def "should generate regex assertions for map objects in response body"() {
given:
GroovyDsl contractDsl = GroovyDsl.make {
GroovyDsl contractDsl = GroovyDsl.make {
request {
method "GET"
url "test"
@@ -293,8 +292,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]")
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -321,8 +320,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]")
blockBuilder.toString().contains("\$[?(@.property1 == 'a')]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -348,7 +347,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
when:
builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("\$[?(@.property =~ /\\d+/)]")
blockBuilder.toString().contains("""assertThat(parsedJson).field("property").matches("\\d+")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -390,8 +389,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
def spockTest = blockBuilder.toString()
then:
spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")')
spockTest.contains('$[?(@.property2 == \'b\')]')
spockTest.contains('$[?(@.property1 == \'a\')]')
spockTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")')
spockTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")')
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -434,8 +433,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
def spockTest = blockBuilder.toString()
then:
spockTest.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")')
spockTest.contains('$[?(@.property2 == \'b\')]')
spockTest.contains('$[?(@.property1 == \'a\')]')
spockTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")')
spockTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")')
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -588,8 +587,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
builder.appendTo(blockBuilder)
def spockTest = blockBuilder.toString()
then:
spockTest.contains('''$.errors[*][?(@.property == 'bank_account_number')]''')
spockTest.contains('''$.errors[*][?(@.message == 'incorrect_format')]''')
spockTest.contains("""assertThat(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number")""")
spockTest.contains("""assertThat(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format")""")
and:
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
}
@@ -655,7 +654,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
builder.appendTo(blockBuilder)
def spockTest = blockBuilder.toString()
then:
spockTest.contains('''$[?(@.message =~ /User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]/)]''')
spockTest.contains("""assertThat(parsedJson).field("message").matches("User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]")""")
}
@Issue('42')
@@ -669,7 +668,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
def spockTest = blockBuilder.toString()
then:
spockTest.contains('''"email":"abc@abc.com"''')
spockTest.contains('''parsedJson.read(\'\'\'$[?(@.code =~ /(123123)?/)]''')
spockTest.contains("""assertThat(parsedJson).field("code").matches("(123123)?")""")
!spockTest.contains('''REGEXP''')
!spockTest.contains('''OPTIONAL''')
!spockTest.contains('''OptionalProperty''')

View File

@@ -1,10 +1,11 @@
package io.codearte.accurest.util
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import com.jayway.jsonpath.Configuration
import com.jayway.jsonpath.DocumentContext
import com.jayway.jsonpath.JsonPath
import com.jayway.jsonpath.Option
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import net.minidev.json.JSONArray
import spock.lang.Specification
import spock.lang.Unroll
@@ -18,11 +19,26 @@ class JsonToJsonPathsConverterSpec extends Specification {
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues['''$[*].some.nested[?(@.json == 'with value')]'''] == 'with value'
pathAndValues['''$[*].some.nested[?(@.anothervalue == 4)]'''] == 4
pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1'
pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name2')]'''] == 'name2'
pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name == 'name3')]'''] == 'name3'
pathAndValues.find {
it.method() == """.array().field("some").field("nested").field("json").isEqualTo("with value")""" &&
it.jsonPath() == '''$[*].some.nested[?(@.json == 'with value')]'''
}
pathAndValues.find {
it.method() == """.array().field("some").field("nested").field("anothervalue").isEqualTo(4)""" &&
it.jsonPath() == '''$[*].some.nested[?(@.anothervalue == 4)]'''
}
pathAndValues.find {
it.method() == """.array().field("some").field("nested").array("withlist").contains("name").isEqualTo("name1")""" &&
it.jsonPath() == '''$[*].some.nested.withlist[*][?(@.name == 'name1')]'''
}
pathAndValues.find {
it.method() == """.array().field("some").field("nested").array("withlist").contains("name").isEqualTo("name2")""" &&
it.jsonPath() == '''$[*].some.nested.withlist[*][?(@.name == 'name2')]'''
}
pathAndValues.find {
it.method() == """.array().field("some").field("nested").array("withlist").field("anothernested").field("name").isEqualTo("name3")""" &&
it.jsonPath() == '''$[*].some.nested.withlist[*].anothernested[?(@.name == 'name3')]'''
}
and:
assertThatJsonPathsInMapAreValid(json, pathAndValues)
where:
@@ -96,10 +112,22 @@ class JsonToJsonPathsConverterSpec extends Specification {
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues['''$.some.nested[?(@.json == 'with value')]'''] == 'with value'
pathAndValues['''$.some.nested[?(@.anothervalue == 4)]'''] == 4
pathAndValues['''$.some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1'
pathAndValues['''$.some.nested.withlist[*][?(@.name == 'name2')]'''] == 'name2'
pathAndValues.find {
it.method() == """.field("some").field("nested").field("json").isEqualTo("with value")""" &&
it.jsonPath() == '''$.some.nested[?(@.json == 'with value')]'''
}
pathAndValues.find {
it.method() == """.field("some").field("nested").field("anothervalue").isEqualTo(4)""" &&
it.jsonPath() == '''$.some.nested[?(@.anothervalue == 4)]'''
}
pathAndValues.find {
it.method() == """.field("some").field("nested").array("withlist").contains("name").isEqualTo("name1")""" &&
it.jsonPath() == '''$.some.nested.withlist[*][?(@.name == 'name1')]'''
}
pathAndValues.find {
it.method() == """.field("some").field("nested").array("withlist").contains("name").isEqualTo("name2")""" &&
it.jsonPath() == '''$.some.nested.withlist[*][?(@.name == 'name2')]'''
}
and:
assertThatJsonPathsInMapAreValid(json, pathAndValues)
}
@@ -114,7 +142,10 @@ class JsonToJsonPathsConverterSpec extends Specification {
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues['''$.items[?(@ == 'HOP')]'''] == 'HOP'
pathAndValues.find {
it.method() == """.array("items").contains("HOP").value()""" &&
it.jsonPath() == '''$.items[?(@ == 'HOP')]'''
}
and:
assertThatJsonPathsInMapAreValid(json, pathAndValues)
}
@@ -130,8 +161,14 @@ class JsonToJsonPathsConverterSpec extends Specification {
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues['''$[?(@.property1 == null)]'''] == null
pathAndValues['''$[?(@.property2 == true)]'''] == true
pathAndValues.find {
it.method() == """.field("property1").isNull()""" &&
it.jsonPath() == '''$[?(@.property1 == null)]'''
}
pathAndValues.find {
it.method() == """.field("property2").isEqualTo(true)""" &&
it.jsonPath() == '''$[?(@.property2 == true)]'''
}
}
def "should convert numbers map"() {
@@ -143,9 +180,18 @@ class JsonToJsonPathsConverterSpec extends Specification {
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues['''$.extensions[?(@.7 == 28)]'''] == 28.0
pathAndValues['''$.extensions[?(@.14 == 41)]'''] == 41.0
pathAndValues['''$.extensions[?(@.30 == 60)]'''] == 60.0
pathAndValues.find {
it.method() == """.field("extensions").field("7").isEqualTo(28)""" &&
it.jsonPath() == '''$.extensions[?(@.7 == 28)]'''
}
pathAndValues.find {
it.method() == """.field("extensions").field("14").isEqualTo(41)""" &&
it.jsonPath() == '''$.extensions[?(@.14 == 41)]'''
}
pathAndValues.find {
it.method() == """.field("extensions").field("30").isEqualTo(60)""" &&
it.jsonPath() == '''$.extensions[?(@.30 == 60)]'''
}
and:
assertThatJsonPathsInMapAreValid(json, pathAndValues)
}
@@ -163,15 +209,22 @@ class JsonToJsonPathsConverterSpec extends Specification {
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues['''$.errors[*][?(@.property == 'email')]'''] == 'email'
pathAndValues['''$.errors[*][?(@.message == 'inconsistent value')]'''] == 'inconsistent value'
pathAndValues['''$.errors[*][?(@.message == 'inconsistent value2')]'''] == 'inconsistent value2'
pathAndValues['''$.errors[*][?(@.property == 'email')]'''] == 'email'
pathAndValues.find {
it.method() == """.array("errors").contains("property").isEqualTo("email")""" &&
it.jsonPath() == '''$.errors[*][?(@.property == 'email')]'''
}
pathAndValues.find {
it.method() == """.array("errors").contains("message").isEqualTo("inconsistent value")""" &&
it.jsonPath() == '''$.errors[*][?(@.message == 'inconsistent value')]'''
}
pathAndValues.find {
it.method() == """.array("errors").contains("message").isEqualTo("inconsistent value2")""" &&
it.jsonPath() == '''$.errors[*][?(@.message == 'inconsistent value2')]'''
}
and:
assertThatJsonPathsInMapAreValid(json, pathAndValues)
}
def 'should convert a map json with a regex pattern'() {
given:
List json = [
@@ -184,7 +237,7 @@ class JsonToJsonPathsConverterSpec extends Specification {
[name: "name2"],
[name: "name1"],
[anothernested:
[name: Pattern.compile('[a-zA-Z]+')]
[name: Pattern.compile("[a-zA-Z]+")]
],
[age: "123456789"]
]
@@ -207,23 +260,304 @@ class JsonToJsonPathsConverterSpec extends Specification {
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json)
then:
pathAndValues['''$[*].some.nested[?(@.json == 'with value')]'''] == 'with value'
pathAndValues['''$[*].some.nested[?(@.anothervalue == 4)]'''] == 4
pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1'
pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name2')]''']
(pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name =~ /[a-zA-Z]+/)]'''] as Pattern).pattern() == '[a-zA-Z]+'
pathAndValues.find {
it.method() == """.array().field("some").field("nested").field("json").isEqualTo("with value")""" &&
it.jsonPath() == '''$[*].some.nested[?(@.json == 'with value')]'''
}
pathAndValues.find {
it.method() == """.array().field("some").field("nested").field("anothervalue").isEqualTo(4)""" &&
it.jsonPath() == '''$[*].some.nested[?(@.anothervalue == 4)]'''
}
pathAndValues.find {
it.method() == """.array().field("some").field("nested").array("withlist").contains("name").isEqualTo("name1")""" &&
it.jsonPath() == '''$[*].some.nested.withlist[*][?(@.name == 'name1')]'''
}
pathAndValues.find {
it.method() == """.array().field("some").field("nested").array("withlist").contains("name").isEqualTo("name2")""" &&
it.jsonPath() == '''$[*].some.nested.withlist[*][?(@.name == 'name2')]'''
}
pathAndValues.find {
it.method() == """.array().field("some").field("nested").array("withlist").field("anothernested").field("name").matches("[a-zA-Z]+")""" &&
it.jsonPath() == '''$[*].some.nested.withlist[*].anothernested[?(@.name =~ /[a-zA-Z]+/)]'''
}
when:
pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name =~ /[a-zA-Z]+/)]'''] = "Kowalski"
json.some.nested.withlist[0][2].anothernested.name = "Kowalski"
then:
assertThatJsonPathsInMapAreValid(JsonOutput.prettyPrint(JsonOutput.toJson(json)), pathAndValues)
}
def "should generate assertions for simple response body"() {
given:
String json = """{
"property1": "a",
"property2": "b"
}"""
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues.find {
it.method()== """.field("property1").isEqualTo("a")""" &&
it.jsonPath() == """\$[?(@.property1 == 'a')]"""
}
pathAndValues.find {
it.method()== """.field("property2").isEqualTo("b")""" &&
it.jsonPath() == """\$[?(@.property2 == 'b')]"""
}
and:
pathAndValues.size() == 2
}
def "should generate assertions for null and boolean values"() {
given:
String json = """{
"property1": "true",
"property2": null,
"property3": false
}"""
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues.find {
it.method()== """.field("property1").isEqualTo("true")""" &&
it.jsonPath() == """\$[?(@.property1 == 'true')]"""
}
pathAndValues.find {
it.method()== """.field("property2").isNull()""" &&
it.jsonPath() == """\$[?(@.property2 == null)]"""
}
pathAndValues.find {
it.method()== """.field("property3").isEqualTo(false)""" &&
it.jsonPath() == """\$[?(@.property3 == false)]"""
}
and:
pathAndValues.size() == 3
}
def "should generate assertions for simple response body constructed from map with a list"() {
given:
Map json = [
property1: 'a',
property2: [
[a: 'sth'],
[b: 'sthElse']
]
]
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json)
then:
pathAndValues.find {
it.method()== """.field("property1").isEqualTo("a")""" &&
it.jsonPath() == """\$[?(@.property1 == 'a')]"""
}
pathAndValues.find {
it.method()== """.array("property2").contains("a").isEqualTo("sth")""" &&
it.jsonPath() == """\$.property2[*][?(@.a == 'sth')]"""
}
pathAndValues.find {
it.method()== """.array("property2").contains("b").isEqualTo("sthElse")""" &&
it.jsonPath() == """\$.property2[*][?(@.b == 'sthElse')]"""
}
and:
pathAndValues.size() == 3
}
def "should generate assertions for a response body containing map with integers as keys"() {
given:
Map json = [
property: [
14: 0.0,
7 : 0.0
]
]
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json)
then:
pathAndValues.find {
it.method()== """.field("property").field(7).isEqualTo(0.0)""" &&
it.jsonPath() == """\$.property[?(@.7 == 0.0)]"""
}
pathAndValues.find {
it.method()== """.field("property").field(14).isEqualTo(0.0)""" &&
it.jsonPath() == """\$.property[?(@.14 == 0.0)]"""
}
and:
pathAndValues.size() == 2
}
def "should generate assertions for array in response body"() {
given:
String json = """[
{
"property1": "a"
},
{
"property2": "b"
}]"""
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues.find {
it.method()== """.array().contains("property1").isEqualTo("a")""" &&
it.jsonPath() == """\$[*][?(@.property1 == 'a')]"""
}
pathAndValues.find {
it.method()== """.array().contains("property2").isEqualTo("b")""" &&
it.jsonPath() == """\$[*][?(@.property2 == 'b')]"""
}
and:
pathAndValues.size() == 2
}
def "should generate assertions for array inside response body element"() {
given:
String json = """{
"property1": [
{ "property2": "test1"},
{ "property3": "test2"}
]
}"""
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues.find {
it.method()== """.array("property1").contains("property2").isEqualTo("test1")""" &&
it.jsonPath() == """\$.property1[*][?(@.property2 == 'test1')]"""
}
pathAndValues.find {
it.method()== """.array("property1").contains("property3").isEqualTo("test2")""" &&
it.jsonPath() == """\$.property1[*][?(@.property3 == 'test2')]"""
}
and:
pathAndValues.size() == 2
}
def "should generate assertions for nested objects in response body"() {
given:
String json = """{
"property1": "a",
"property2": {"property3": "b"}
}"""
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues.find {
it.method()== """.field("property2").field("property3").isEqualTo("b")""" &&
it.jsonPath() == """\$.property2[?(@.property3 == 'b')]"""
}
pathAndValues.find {
it.method()== """.field("property1").isEqualTo("a")""" &&
it.jsonPath() == """\$[?(@.property1 == 'a')]"""
}
and:
pathAndValues.size() == 2
}
def "should generate regex assertions for map objects in response body"() {
given:
Map json = [
property1: "a",
property2: Pattern.compile('[0-9]{3}')
]
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json)
then:
pathAndValues.find {
it.method()== """.field("property2").matches("[0-9]{3}")""" &&
it.jsonPath() == """\$[?(@.property2 =~ /[0-9]{3}/)]"""
}
pathAndValues.find {
it.method()== """.field("property1").isEqualTo("a")""" &&
it.jsonPath() == """\$[?(@.property1 == 'a')]"""
}
and:
pathAndValues.size() == 2
}
def "should generate escaped regex assertions for string objects in response body"() {
given:
Map json = [
property2: Pattern.compile('\\d+')
]
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json)
then:
pathAndValues.find {
it.method()== """.field("property2").matches("\\d+")""" &&
it.jsonPath() == """\$[?(@.property2 =~ /\\d+/)]"""
}
and:
pathAndValues.size() == 1
}
def "should work with more complex stuff and jsonpaths"() {
given:
Map json = [
errors: [
[property: "bank_account_number",
message: "incorrect_format"]
]
]
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json)
then:
pathAndValues.find {
it.method()== """.array("errors").contains("property").isEqualTo("bank_account_number")""" &&
it.jsonPath() == """\$.errors[*][?(@.property == 'bank_account_number')]"""
}
pathAndValues.find {
it.method()== """.array("errors").contains("message").isEqualTo("incorrect_format")""" &&
it.jsonPath() == """\$.errors[*][?(@.message == 'incorrect_format')]"""
}
and:
pathAndValues.size() == 2
}
def "should manage to parse a double array"() {
given:
String json = '''
[{
"place":
{
"bounding_box":
{
"coordinates":
[[
[-77.119759,38.995548],
[-76.909393,38.791645]
]]
}
}
}]
'''
when:
JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
then:
pathAndValues.find {
it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(38.995548).value()""" &&
it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]"""
}
pathAndValues.find {
it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(-77.119759).value()""" &&
it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]"""
}
pathAndValues.find {
it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(-76.909393).value()""" &&
it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]"""
}
pathAndValues.find {
it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(38.791645).value()""" &&
it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]"""
}
and:
pathAndValues.size() == 4
}
private void assertThatJsonPathsInMapAreValid(String json, JsonPaths pathAndValues) {
DocumentContext parsedJson = JsonPath.using(Configuration.builder().options(Option.ALWAYS_RETURN_LIST).build()).parse(json);
pathAndValues.each {
def at = parsedJson.read(it.jsonPath, JSONArray).getAt(it.optionalSuffix ?: 0)
assert at == it.optionalSuffix ? [it.value] : it.value
assert !parsedJson.read(it.jsonPath(), JSONArray).empty
}
}

View File

@@ -4,8 +4,6 @@ import io.codearte.accurest.config.AccurestConfigProperties
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.DependencyResolveDetails
/**
* @author Jakub Kubrynski
*/
@@ -31,6 +29,7 @@ class AccurestGradlePlugin implements Plugin<Project> {
createAndConfigureGenerateWireMockClientStubsFromDslTask(extension)
deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask()
project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.5-beta")
project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:jsonassert:${extension.getJsonAssertVersion()}")
project.afterEvaluate {
def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS)

View File

@@ -22,7 +22,6 @@ class GenerateWireMockClientStubsFromDslTask extends ConventionTask {
void generate() {
logger.info("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion")
logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'")
RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), getConfigProperties())
converter.processFiles()
}

View File

@@ -29,6 +29,7 @@ configurations {
repositories {
mavenCentral()
mavenLocal()
}
dependencies {

View File

@@ -72,6 +72,7 @@ project(':accurest-core') {
compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5'
compile 'asm:asm:3.3.1'
compile "com.github.tomakehurst:wiremock:$wiremockVersion"
compile "com.blogspot.toomuchcoding:jsonassert:$jsonassertVersion"
testCompile 'cglib:cglib-nodep:2.2'
testCompile 'org.objenesis:objenesis:2.1'
testCompile project(':accurest-testing-utils')

View File

@@ -2,3 +2,4 @@ nexusUsername =
nexusPassword =
wiremockVersion = 2.0.5-beta
jsonassertVersion = 0.1.0