diff --git a/consumer/java8/src/test/groovy/io/pactfoundation/consumer/dsl/LambdaDslSpec.groovy b/consumer/java8/src/test/groovy/io/pactfoundation/consumer/dsl/LambdaDslSpec.groovy index 2737029c52..28ec246b40 100644 --- a/consumer/java8/src/test/groovy/io/pactfoundation/consumer/dsl/LambdaDslSpec.groovy +++ b/consumer/java8/src/test/groovy/io/pactfoundation/consumer/dsl/LambdaDslSpec.groovy @@ -207,7 +207,7 @@ class LambdaDslSpec extends Specification { def result = LambdaDsl.newJsonBody(body).build() then: - result.body.toString() == '{"number":1,"bigdecimal":1.1,"bigint":1,"long":1}' + result.body.toString() == '{"bigdecimal":1.1,"bigint":1,"long":1,"number":1}' } @Issue('#910') @@ -228,7 +228,7 @@ class LambdaDslSpec extends Specification { def result = LambdaDsl.newJsonBody(body).build() then: - result.body.toString() == '{"date3":"' + date3 + '","date1":"' + date1 + '"}' + result.body.toString() == "{\"date1\":\"$date1\",\"date3\":\"$date3\"}" } } diff --git a/consumer/junit/src/test/java/au/com/dius/pact/consumer/junit/Defect464Test.java b/consumer/junit/src/test/java/au/com/dius/pact/consumer/junit/Defect464Test.java index 63816f1168..502a41f0b5 100644 --- a/consumer/junit/src/test/java/au/com/dius/pact/consumer/junit/Defect464Test.java +++ b/consumer/junit/src/test/java/au/com/dius/pact/consumer/junit/Defect464Test.java @@ -52,10 +52,10 @@ public RequestResponsePact createFragment(PactDslWithProvider builder) { public void runTest() throws IOException { String jsonString = Request.Get(provider.getUrl() + PROVIDER_URI).execute().returnContent().asString(); - JsonValue root = JsonParser.INSTANCE.parseString(jsonString); + JsonValue root = JsonParser.parseString(jsonString); JsonValue.Array myArrayElement = root.asObject().get(JSON_ARRAY_MEMBER_NAME).asArray(); List myArray = myArrayElement.getValues().stream() - .map(e -> new ElementOfMyArray(e.asString())) + .map(e -> new ElementOfMyArray(e.get("id").asString())) .collect(Collectors.toList()); List ids = new ArrayList<>(); diff --git a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/DslPart.java b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/DslPart.java deleted file mode 100644 index 8dbfcf5dfc..0000000000 --- a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/DslPart.java +++ /dev/null @@ -1,425 +0,0 @@ -package au.com.dius.pact.consumer.dsl; - -import au.com.dius.pact.core.model.generators.Generators; -import au.com.dius.pact.core.model.matchingrules.Category; -import au.com.dius.pact.core.model.matchingrules.DateMatcher; -import au.com.dius.pact.core.model.matchingrules.IncludeMatcher; -import au.com.dius.pact.core.model.matchingrules.MaxTypeMatcher; -import au.com.dius.pact.core.model.matchingrules.MinMaxTypeMatcher; -import au.com.dius.pact.core.model.matchingrules.MinTypeMatcher; -import au.com.dius.pact.core.model.matchingrules.RegexMatcher; -import au.com.dius.pact.core.model.matchingrules.TimeMatcher; -import au.com.dius.pact.core.model.matchingrules.TimestampMatcher; - -/** - * Abstract base class to support Object and Array JSON DSL builders - */ -public abstract class DslPart { - public static final String HEXADECIMAL = "[0-9a-fA-F]+"; - public static final String IP_ADDRESS = "(\\d{1,3}\\.)+\\d{1,3}"; - public static final String UUID_REGEX = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"; - public static final long DATE_2000 = 949323600000L; - - protected final DslPart parent; - protected final String rootPath; - protected final String rootName; - protected Category matchers = new Category("body"); - protected Generators generators = new Generators(); - protected boolean closed = false; - - public DslPart(DslPart parent, String rootPath, String rootName) { - this.parent = parent; - this.rootPath = rootPath; - this.rootName = rootName; - } - - public DslPart(String rootPath, String rootName) { - this.parent = null; - this.rootPath = rootPath; - this.rootName = rootName; - } - - protected abstract void putObject(DslPart object); - protected abstract void putArray(DslPart object); - public abstract Object getBody(); - - /** - * Field which is an array - * @param name field name - */ - public abstract PactDslJsonArray array(String name); - - /** - * Element as an array - */ - public abstract PactDslJsonArray array(); - - /** - * Close of the previous array element - */ - public abstract DslPart closeArray(); - - /** - * Array field where each element must match the following object - * @param name field name - */ - public abstract PactDslJsonBody eachLike(String name); - - /** - * Array field where each element must match the following object - * @param name field name - */ - public abstract PactDslJsonBody eachLike(String name, DslPart object); - - /** - * Array element where each element of the array must match the following object - */ - public abstract PactDslJsonBody eachLike(); - - /** - * Array element where each element of the array must match the provided object - */ - public abstract PactDslJsonArray eachLike(DslPart object); - - /** - * Array field where each element must match the following object - * @param name field name - * @param numberExamples number of examples to generate - */ - public abstract PactDslJsonBody eachLike(String name, int numberExamples); - - /** - * Array element where each element of the array must match the following object - * @param numberExamples number of examples to generate - */ - public abstract PactDslJsonBody eachLike(int numberExamples); - - /** - * Array field with a minumum size and each element must match the following object - * @param name field name - * @param size minimum size - */ - public abstract PactDslJsonBody minArrayLike(String name, Integer size); - - /** - * Array element with a minumum size and each element of the array must match the following object - * @param size minimum size - */ - public abstract PactDslJsonBody minArrayLike(Integer size); - - /** - * Array field with a minumum size and each element must match the provided object - * @param name field name - * @param size minimum size - */ - public abstract PactDslJsonBody minArrayLike(String name, Integer size, DslPart object); - - /** - * Array element with a minumum size and each element of the array must match the provided object - * @param size minimum size - */ - public abstract PactDslJsonArray minArrayLike(Integer size, DslPart object); - - /** - * Array field with a minumum size and each element must match the following object - * @param name field name - * @param size minimum size - * @param numberExamples number of examples to generate - */ - public abstract PactDslJsonBody minArrayLike(String name, Integer size, int numberExamples); - - /** - * Array element with a minumum size and each element of the array must match the following object - * @param size minimum size - * @param numberExamples number of examples to generate - */ - public abstract PactDslJsonBody minArrayLike(Integer size, int numberExamples); - - /** - * Array field with a maximum size and each element must match the following object - * @param name field name - * @param size maximum size - */ - public abstract PactDslJsonBody maxArrayLike(String name, Integer size); - - /** - * Array element with a maximum size and each element of the array must match the following object - * @param size minimum size - */ - public abstract PactDslJsonBody maxArrayLike(Integer size); - - /** - * Array field with a maximum size and each element must match the provided object - * @param name field name - * @param size maximum size - */ - public abstract PactDslJsonBody maxArrayLike(String name, Integer size, DslPart object); - - /** - * Array element with a maximum size and each element of the array must match the provided object - * @param size minimum size - */ - public abstract PactDslJsonArray maxArrayLike(Integer size, DslPart object); - - /** - * Array field with a maximum size and each element must match the following object - * @param name field name - * @param size maximum size - * @param numberExamples number of examples to generate - */ - public abstract PactDslJsonBody maxArrayLike(String name, Integer size, int numberExamples); - - /** - * Array element with a maximum size and each element of the array must match the following object - * @param size minimum size - * @param numberExamples number of examples to generate - */ - public abstract PactDslJsonBody maxArrayLike(Integer size, int numberExamples); - - /** - * Array field with a minimum and maximum size and each element must match the following object - * @param name field name - * @param minSize minimum size - * @param maxSize maximum size - */ - public abstract PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize); - - /** - * Array field with a minimum and maximum size and each element must match the provided object - * @param name field name - * @param minSize minimum size - * @param maxSize maximum size - */ - public abstract PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, DslPart object); - - /** - * Array element with a minimum and maximum size and each element of the array must match the following object - * @param minSize minimum size - * @param maxSize maximum size - */ - public abstract PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize); - - /** - * Array element with a minimum and maximum size and each element of the array must match the provided object - * @param minSize minimum size - * @param maxSize maximum size - */ - public abstract PactDslJsonArray minMaxArrayLike(Integer minSize, Integer maxSize, DslPart object); - - /** - * Array field with a minimum and maximum size and each element must match the following object - * @param name field name - * @param minSize minimum size - * @param maxSize maximum size - * @param numberExamples number of examples to generate - */ - public abstract PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, int numberExamples); - - /** - * Array element with a minimum and maximum size and each element of the array must match the following object - * @param minSize minimum size - * @param maxSize maximum size - * @param numberExamples number of examples to generate - */ - public abstract PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize, int numberExamples); - - /** - * Array field where each element is an array and must match the following object - * @param name field name - */ - public abstract PactDslJsonArray eachArrayLike(String name); - - /** - * Array element where each element of the array is an array and must match the following object - */ - public abstract PactDslJsonArray eachArrayLike(); - - /** - * Array field where each element is an array and must match the following object - * @param name field name - * @param numberExamples number of examples to generate - */ - public abstract PactDslJsonArray eachArrayLike(String name, int numberExamples); - - /** - * Array element where each element of the array is an array and must match the following object - * @param numberExamples number of examples to generate - */ - public abstract PactDslJsonArray eachArrayLike(int numberExamples); - - /** - * Array field where each element is an array and must match the following object - * @param name field name - * @param size Maximum size of the outer array - */ - public abstract PactDslJsonArray eachArrayWithMaxLike(String name, Integer size); - - /** - * Array element where each element of the array is an array and must match the following object - * @param size Maximum size of the outer array - */ - public abstract PactDslJsonArray eachArrayWithMaxLike(Integer size); - - /** - * Array field where each element is an array and must match the following object - * @param name field name - * @param numberExamples number of examples to generate - * @param size Maximum size of the outer array - */ - public abstract PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, Integer size); - - /** - * Array element where each element of the array is an array and must match the following object - * @param numberExamples number of examples to generate - * @param size Maximum size of the outer array - */ - public abstract PactDslJsonArray eachArrayWithMaxLike(int numberExamples, Integer size); - - /** - * Array field where each element is an array and must match the following object - * @param name field name - * @param size Minimum size of the outer array - */ - public abstract PactDslJsonArray eachArrayWithMinLike(String name, Integer size); - - /** - * Array element where each element of the array is an array and must match the following object - * @param size Minimum size of the outer array - */ - public abstract PactDslJsonArray eachArrayWithMinLike(Integer size); - - /** - * Array field where each element is an array and must match the following object - * @param name field name - * @param numberExamples number of examples to generate - * @param size Minimum size of the outer array - */ - public abstract PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, Integer size); - - /** - * Array element where each element of the array is an array and must match the following object - * @param numberExamples number of examples to generate - * @param size Minimum size of the outer array - */ - public abstract PactDslJsonArray eachArrayWithMinLike(int numberExamples, Integer size); - - /** - * Array field where each element is an array and must match the following object - * @param name field name - * @param minSize minimum size - * @param maxSize maximum size - */ - public abstract PactDslJsonArray eachArrayWithMinMaxLike(String name, Integer minSize, Integer maxSize); - - /** - * Array element where each element of the array is an array and must match the following object - * @param minSize minimum size - * @param maxSize maximum size - */ - public abstract PactDslJsonArray eachArrayWithMinMaxLike(Integer minSize, Integer maxSize); - - /** - * Array field where each element is an array and must match the following object - * @param name field name - * @param numberExamples number of examples to generate - * @param minSize minimum size - * @param maxSize maximum size - */ - public abstract PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, Integer minSize, - Integer maxSize); - - /** - * Array element where each element of the array is an array and must match the following object - * @param numberExamples number of examples to generate - * @param minSize minimum size - * @param maxSize maximum size - */ - public abstract PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, Integer minSize, Integer maxSize); - - /** - * Object field - * @param name field name - */ - public abstract PactDslJsonBody object(String name); - - /** - * Object element - */ - public abstract PactDslJsonBody object(); - - /** - * Close off the previous object - * @return - */ - public abstract DslPart closeObject(); - - public Category getMatchers() { - return matchers; - } - - public void setMatchers(Category matchers) { - this.matchers = matchers; - } - - protected RegexMatcher regexp(String regex) { - return new RegexMatcher(regex); - } - - protected TimestampMatcher matchTimestamp(String format) { - return new TimestampMatcher(format); - } - - protected DateMatcher matchDate(String format) { - return new DateMatcher(format); - } - - protected TimeMatcher matchTime(String format) { - return new TimeMatcher(format); - } - - protected MinTypeMatcher matchMin(Integer min) { - return new MinTypeMatcher(min); - } - - protected MaxTypeMatcher matchMax(Integer max) { - return new MaxTypeMatcher(max); - } - - protected MinMaxTypeMatcher matchMinMax(Integer minSize, Integer maxSize) { - return new MinMaxTypeMatcher(minSize, maxSize); - } - - protected IncludeMatcher includesMatcher(Object value) { - return new IncludeMatcher(String.valueOf(value)); - } - - public PactDslJsonBody asBody() { - return (PactDslJsonBody) this; - } - - public PactDslJsonArray asArray() { - return (PactDslJsonArray) this; - } - - /** - * This closes off the object graph build from the DSL in case any close[Object|Array] methods have not been called. - * @return The root object of the object graph - */ - public abstract DslPart close(); - - public Generators getGenerators() { - return generators; - } - - public void setGenerators(Generators generators) { - this.generators = generators; - } - - /** - * Returns the parent of this part (object or array) - * @return parent, or null if it is the root - */ - public DslPart getParent() { - return parent; - } -} diff --git a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonArray.java b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonArray.java index ef5bfe465a..a8310d3019 100644 --- a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonArray.java +++ b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonArray.java @@ -19,12 +19,11 @@ import au.com.dius.pact.core.model.matchingrules.NumberTypeMatcher; import au.com.dius.pact.core.model.matchingrules.RuleLogic; import au.com.dius.pact.core.model.matchingrules.TypeMatcher; +import au.com.dius.pact.core.support.Json; import au.com.dius.pact.core.support.expressions.DataType; -import com.mifmif.common.regex.Generex; +import au.com.dius.pact.core.support.json.JsonValue; import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.FastDateFormat; -import org.json.JSONArray; -import org.json.JSONObject; import java.math.BigDecimal; import java.time.Instant; @@ -36,75 +35,77 @@ * DSL to define a JSON array */ public class PactDslJsonArray extends DslPart { - - private static final String EXAMPLE = "Example \""; - private final JSONArray body; - private boolean wildCard; - private int numberExamples = 1; + private static final String EXAMPLE = "Example \""; + private final JsonValue.Array body; + private boolean wildCard; + private int numberExamples = 1; /** * Construct a root level array */ public PactDslJsonArray() { - this("", "", null, false); - } + this("", "", null, false); + } /** * Construct an array as a child + * * @param rootPath Path to the child array * @param rootName Name to associate the child as - * @param parent Parent to attach the child to + * @param parent Parent to attach the child to */ public PactDslJsonArray(String rootPath, String rootName, DslPart parent) { - this(rootPath, rootName, parent, false); + this(rootPath, rootName, parent, false); } /** * Construct an array as a child copied from an existing array + * * @param rootPath Path to the child array * @param rootName Name to associate the child as - * @param parent Parent to attach the child to - * @param array Array to copy + * @param parent Parent to attach the child to + * @param array Array to copy */ public PactDslJsonArray(String rootPath, String rootName, DslPart parent, PactDslJsonArray array) { super(parent, rootPath, rootName); this.body = array.body; this.wildCard = array.wildCard; - this.matchers = array.matchers.copyWithUpdatedMatcherRootPrefix(rootPath); - this.generators = array.generators; + this.setMatchers(array.getMatchers().copyWithUpdatedMatcherRootPrefix(rootPath)); + this.setGenerators(array.getGenerators()); } /** * Construct a array as a child + * * @param rootPath Path to the child array * @param rootName Name to associate the child as - * @param parent Parent to attach the child to + * @param parent Parent to attach the child to * @param wildCard If it should be matched as a wild card */ public PactDslJsonArray(String rootPath, String rootName, DslPart parent, boolean wildCard) { - super(parent, rootPath, rootName); - this.wildCard = wildCard; - body = new JSONArray(); + super(parent, rootPath, rootName); + this.wildCard = wildCard; + body = new JsonValue.Array(); } - /** - * Closes the current array - */ - public DslPart closeArray() { - if (parent != null) { - parent.putArray(this); - } else { - getMatchers().applyMatcherRootPrefix("$"); - getGenerators().applyRootPrefix("$"); - } - closed = true; - return parent; + /** + * Closes the current array + */ + public DslPart closeArray() { + if (getParent() != null) { + getParent().putArrayPrivate(this); + } else { + getMatchers().applyMatcherRootPrefix("$"); + getGenerators().applyRootPrefix("$"); } + setClosed(true); + return getParent(); + } - @Override - public PactDslJsonBody eachLike(String name) { - throw new UnsupportedOperationException("use the eachLike() form"); - } + @Override + public PactDslJsonBody eachLike(String name) { + throw new UnsupportedOperationException("use the eachLike() form"); + } @Override public PactDslJsonBody eachLike(String name, DslPart object) { @@ -116,497 +117,521 @@ public PactDslJsonBody eachLike(String name, int numberExamples) { throw new UnsupportedOperationException("use the eachLike(numberExamples) form"); } - /** - * Element that is an array where each item must match the following example - */ - @Override - public PactDslJsonBody eachLike() { - return eachLike(1); - } + /** + * Element that is an array where each item must match the following example + */ + @Override + public PactDslJsonBody eachLike() { + return eachLike(1); + } @Override public PactDslJsonArray eachLike(DslPart object) { - matchers.addRule(rootPath + appendArrayIndex(1), TypeMatcher.INSTANCE); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMin(0)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); parent.setNumberExamples(numberExamples); if (object instanceof PactDslJsonBody) { - parent.putObject(object); + parent.putObjectPrivate(object); } else if (object instanceof PactDslJsonArray) { - parent.putArray(object); + parent.putArrayPrivate(object); } return parent.closeArray().asArray(); } /** - * Element that is an array where each item must match the following example - * @param numberExamples Number of examples to generate - */ - @Override - public PactDslJsonBody eachLike(int numberExamples) { - matchers.addRule(rootPath + appendArrayIndex(1), TypeMatcher.INSTANCE); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); - parent.setNumberExamples(numberExamples); - return new PactDslJsonBody(".", "", parent); - } + * Element that is an array where each item must match the following example + * + * @param numberExamples Number of examples to generate + */ + @Override + public PactDslJsonBody eachLike(int numberExamples) { + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMin(0)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); + parent.setNumberExamples(numberExamples); + return new PactDslJsonBody(".", "", parent); + } - @Override - public PactDslJsonBody minArrayLike(String name, Integer size) { - throw new UnsupportedOperationException("use the minArrayLike(Integer size) form"); - } + @Override + public PactDslJsonBody minArrayLike(String name, int size) { + throw new UnsupportedOperationException("use the minArrayLike(Integer size) form"); + } - /** - * Element that is an array with a minimum size where each item must match the following example - * @param size minimum size of the array - */ - @Override - public PactDslJsonBody minArrayLike(Integer size) { - return minArrayLike(size, size); - } + /** + * Element that is an array with a minimum size where each item must match the following example + * + * @param size minimum size of the array + */ + @Override + public PactDslJsonBody minArrayLike(int size) { + return minArrayLike(size, size); + } @Override - public PactDslJsonBody minArrayLike(String name, Integer size, DslPart object) { + public PactDslJsonBody minArrayLike(String name, int size, DslPart object) { throw new UnsupportedOperationException("use the minArrayLike(Integer size, DslPart object) form"); } @Override - public PactDslJsonArray minArrayLike(Integer size, DslPart object) { - matchers.addRule(rootPath + appendArrayIndex(1), matchMin(size)); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + public PactDslJsonArray minArrayLike(int size, DslPart object) { + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMin(size)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); parent.setNumberExamples(size); if (object instanceof PactDslJsonBody) { - parent.putObject(object); + parent.putObjectPrivate(object); } else if (object instanceof PactDslJsonArray) { - parent.putArray(object); + parent.putArrayPrivate(object); } return parent.closeArray().asArray(); } @Override - public PactDslJsonBody minArrayLike(String name, Integer size, int numberExamples) { - throw new UnsupportedOperationException("use the minArrayLike(Integer size, int numberExamples) form"); - } + public PactDslJsonBody minArrayLike(String name, int size, int numberExamples) { + throw new UnsupportedOperationException("use the minArrayLike(Integer size, int numberExamples) form"); + } - /** - * Element that is an array with a minimum size where each item must match the following example - * @param size minimum size of the array - * @param numberExamples number of examples to generate - */ - @Override - public PactDslJsonBody minArrayLike(Integer size, int numberExamples) { - if (numberExamples < size) { - throw new IllegalArgumentException(String.format("Number of example %d is less than the minimum size of %d", - numberExamples, size)); - } - matchers.addRule(rootPath + appendArrayIndex(1), matchMin(size)); - PactDslJsonArray parent = new PactDslJsonArray("", "", this, true); - parent.setNumberExamples(numberExamples); - return new PactDslJsonBody(".", "", parent); + /** + * Element that is an array with a minimum size where each item must match the following example + * + * @param size minimum size of the array + * @param numberExamples number of examples to generate + */ + @Override + public PactDslJsonBody minArrayLike(int size, int numberExamples) { + if (numberExamples < size) { + throw new IllegalArgumentException(String.format("Number of example %d is less than the minimum size of %d", + numberExamples, size)); } + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMin(size)); + PactDslJsonArray parent = new PactDslJsonArray("", "", this, true); + parent.setNumberExamples(numberExamples); + return new PactDslJsonBody(".", "", parent); + } - @Override - public PactDslJsonBody maxArrayLike(String name, Integer size) { - throw new UnsupportedOperationException("use the maxArrayLike(Integer size) form"); - } + @Override + public PactDslJsonBody maxArrayLike(String name, int size) { + throw new UnsupportedOperationException("use the maxArrayLike(Integer size) form"); + } - /** - * Element that is an array with a maximum size where each item must match the following example - * @param size maximum size of the array - */ - @Override - public PactDslJsonBody maxArrayLike(Integer size) { - return maxArrayLike(size, 1); - } + /** + * Element that is an array with a maximum size where each item must match the following example + * + * @param size maximum size of the array + */ + @Override + public PactDslJsonBody maxArrayLike(int size) { + return maxArrayLike(size, 1); + } @Override - public PactDslJsonBody maxArrayLike(String name, Integer size, DslPart object) { + public PactDslJsonBody maxArrayLike(String name, int size, DslPart object) { throw new UnsupportedOperationException("use the maxArrayLike(Integer size, DslPart object) form"); } @Override - public PactDslJsonArray maxArrayLike(Integer size, DslPart object) { - matchers.addRule(rootPath + appendArrayIndex(1), matchMax(size)); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + public PactDslJsonArray maxArrayLike(int size, DslPart object) { + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMax(size)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); if (object instanceof PactDslJsonBody) { - parent.putObject(object); + parent.putObjectPrivate(object); } else if (object instanceof PactDslJsonArray) { - parent.putArray(object); + parent.putArrayPrivate(object); } return parent.closeArray().asArray(); } @Override - public PactDslJsonBody maxArrayLike(String name, Integer size, int numberExamples) { - throw new UnsupportedOperationException("use the maxArrayLike(Integer size, int numberExamples) form"); - } + public PactDslJsonBody maxArrayLike(String name, int size, int numberExamples) { + throw new UnsupportedOperationException("use the maxArrayLike(Integer size, int numberExamples) form"); + } - /** - * Element that is an array with a maximum size where each item must match the following example - * @param size maximum size of the array - * @param numberExamples number of examples to generate - */ - @Override - public PactDslJsonBody maxArrayLike(Integer size, int numberExamples) { - if (numberExamples > size) { - throw new IllegalArgumentException(String.format("Number of example %d is more than the maximum size of %d", - numberExamples, size)); - } - matchers.addRule(rootPath + appendArrayIndex(1), matchMax(size)); - PactDslJsonArray parent = new PactDslJsonArray("", "", this, true); - parent.setNumberExamples(numberExamples); - return new PactDslJsonBody(".", "", parent); + /** + * Element that is an array with a maximum size where each item must match the following example + * + * @param size maximum size of the array + * @param numberExamples number of examples to generate + */ + @Override + public PactDslJsonBody maxArrayLike(int size, int numberExamples) { + if (numberExamples > size) { + throw new IllegalArgumentException(String.format("Number of example %d is more than the maximum size of %d", + numberExamples, size)); } + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMax(size)); + PactDslJsonArray parent = new PactDslJsonArray("", "", this, true); + parent.setNumberExamples(numberExamples); + return new PactDslJsonBody(".", "", parent); + } - protected void putObject(DslPart object) { - for(String matcherName: object.matchers.getMatchingRules().keySet()) { - matchers.setRules(rootPath + appendArrayIndex(1) + matcherName, - object.matchers.getMatchingRules().get(matcherName)); - } - generators.addGenerators(object.generators, rootPath + appendArrayIndex(1)); - for (int i = 0; i < getNumberExamples(); i++) { - body.put(object.getBody()); - } + public void putObjectPrivate(DslPart object) { + for (String matcherName : object.getMatchers().getMatchingRules().keySet()) { + getMatchers().setRules(getRootPath() + appendArrayIndex(1) + matcherName, + object.getMatchers().getMatchingRules().get(matcherName)); } - - protected void putArray(DslPart object) { - for(String matcherName: object.matchers.getMatchingRules().keySet()) { - matchers.setRules(rootPath + appendArrayIndex(1) + matcherName, - object.matchers.getMatchingRules().get(matcherName)); - } - generators.addGenerators(object.generators, rootPath + appendArrayIndex(1)); - for (int i = 0; i < getNumberExamples(); i++) { - body.put(object.getBody()); - } + getGenerators().addGenerators(object.getGenerators(), getRootPath() + appendArrayIndex(1)); + for (int i = 0; i < getNumberExamples(); i++) { + body.add(object.getBody()); } + } - @Override - public Object getBody() { - return body; + public void putArrayPrivate(DslPart object) { + for (String matcherName : object.getMatchers().getMatchingRules().keySet()) { + getMatchers().setRules(getRootPath() + appendArrayIndex(1) + matcherName, + object.getMatchers().getMatchingRules().get(matcherName)); } - - /** - * Element that must be the specified value - * @param value string value - */ - public PactDslJsonArray stringValue(String value) { - if (value == null) { - body.put(JSONObject.NULL); - } else { - body.put(value); - } - return this; + getGenerators().addGenerators(object.getGenerators(), getRootPath() + appendArrayIndex(1)); + for (int i = 0; i < getNumberExamples(); i++) { + body.add(object.getBody()); } + } - /** - * Element that must be the specified value - * @param value string value - */ - public PactDslJsonArray string(String value) { - return stringValue(value); - } + @Override + public JsonValue getBody() { + return body; + } - public PactDslJsonArray numberValue(Number value) { - body.put(value); - return this; + /** + * Element that must be the specified value + * + * @param value string value + */ + public PactDslJsonArray stringValue(String value) { + if (value == null) { + body.add(JsonValue.Null.INSTANCE); + } else { + body.add(new JsonValue.StringValue(value.toCharArray())); } + return this; + } - /** - * Element that must be the specified value - * @param value number value - */ - public PactDslJsonArray number(Number value) { - return numberValue(value); - } + /** + * Element that must be the specified value + * + * @param value string value + */ + public PactDslJsonArray string(String value) { + return stringValue(value); + } - /** - * Element that must be the specified value - * @param value boolean value - */ - public PactDslJsonArray booleanValue(Boolean value) { - body.put(value); - return this; - } + public PactDslJsonArray numberValue(Number value) { + body.add(new JsonValue.Decimal(value.toString().toCharArray())); + return this; + } - /** - * Element that must be the same type as the example - */ - public PactDslJsonArray like(Object example) { - body.put(example); - matchers.addRule(rootPath + appendArrayIndex(0), TypeMatcher.INSTANCE); - return this; - } + /** + * Element that must be the specified value + * + * @param value number value + */ + public PactDslJsonArray number(Number value) { + return numberValue(value); + } - /** - * Element that can be any string - */ - public PactDslJsonArray stringType() { - body.put("string"); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new RandomStringGenerator(20)); - matchers.addRule(rootPath + appendArrayIndex(0), TypeMatcher.INSTANCE); - return this; - } + /** + * Element that must be the specified value + * + * @param value boolean value + */ + public PactDslJsonArray booleanValue(Boolean value) { + body.add(value ? JsonValue.True.INSTANCE : JsonValue.False.INSTANCE); + return this; + } - /** - * Element that can be any string - * @param example example value to use for generated bodies - */ - public PactDslJsonArray stringType(String example) { - body.put(example); - matchers.addRule(rootPath + appendArrayIndex(0), TypeMatcher.INSTANCE); - return this; - } + /** + * Element that must be the same type as the example + */ + public PactDslJsonArray like(Object example) { + body.add(Json.toJson(example)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), TypeMatcher.INSTANCE); + return this; + } - /** - * Element that can be any number - */ - public PactDslJsonArray numberType() { - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(1), new RandomIntGenerator(0, Integer.MAX_VALUE)); - return numberType(100); - } + /** + * Element that can be any string + */ + public PactDslJsonArray stringType() { + body.add(new JsonValue.StringValue("string".toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new RandomStringGenerator(20)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), TypeMatcher.INSTANCE); + return this; + } - /** - * Element that can be any number - * @param number example number to use for generated bodies - */ - public PactDslJsonArray numberType(Number number) { - body.put(number); - matchers.addRule(rootPath + appendArrayIndex(0), new NumberTypeMatcher(NumberTypeMatcher.NumberType.NUMBER)); - return this; - } + /** + * Element that can be any string + * + * @param example example value to use for generated bodies + */ + public PactDslJsonArray stringType(String example) { + body.add(new JsonValue.StringValue(example.toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), TypeMatcher.INSTANCE); + return this; + } - /** - * Element that must be an integer - */ - public PactDslJsonArray integerType() { - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(1), new RandomIntGenerator(0, Integer.MAX_VALUE)); - return integerType(100L); - } + /** + * Element that can be any number + */ + public PactDslJsonArray numberType() { + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(1), new RandomIntGenerator(0, Integer.MAX_VALUE)); + return numberType(100); + } - /** - * Element that must be an integer - * @param number example integer value to use for generated bodies - */ - public PactDslJsonArray integerType(Long number) { - body.put(number); - matchers.addRule(rootPath + appendArrayIndex(0), new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER)); - return this; - } + /** + * Element that can be any number + * + * @param number example number to use for generated bodies + */ + public PactDslJsonArray numberType(Number number) { + body.add(new JsonValue.Decimal(number.toString().toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), new NumberTypeMatcher(NumberTypeMatcher.NumberType.NUMBER)); + return this; + } + + /** + * Element that must be an integer + */ + public PactDslJsonArray integerType() { + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(1), new RandomIntGenerator(0, Integer.MAX_VALUE)); + return integerType(100L); + } + + /** + * Element that must be an integer + * + * @param number example integer value to use for generated bodies + */ + public PactDslJsonArray integerType(Long number) { + body.add(new JsonValue.Integer(number.toString().toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER)); + return this; + } /** * Element that must be a decimal value */ public PactDslJsonArray decimalType() { - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(1), new RandomDecimalGenerator(10)); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(1), new RandomDecimalGenerator(10)); return decimalType(new BigDecimal("100")); } /** * Element that must be a decimalType value + * * @param number example decimalType value */ public PactDslJsonArray decimalType(BigDecimal number) { - body.put(number); - matchers.addRule(rootPath + appendArrayIndex(0), new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)); - return this; + body.add(new JsonValue.Decimal(number.toString().toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)); + return this; } /** * Attribute that must be a decimalType value + * * @param number example decimalType value */ public PactDslJsonArray decimalType(Double number) { - body.put(number); - matchers.addRule(rootPath + appendArrayIndex(0), new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)); - return this; + body.add(new JsonValue.Decimal(number.toString().toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)); + return this; } - /** - * Element that must be a boolean - */ - public PactDslJsonArray booleanType() { - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(1), RandomBooleanGenerator.INSTANCE); - body.put(true); - matchers.addRule(rootPath + appendArrayIndex(0), TypeMatcher.INSTANCE); - return this; - } + /** + * Element that must be a boolean + */ + public PactDslJsonArray booleanType() { + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(1), RandomBooleanGenerator.INSTANCE); + body.add(JsonValue.True.INSTANCE); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), TypeMatcher.INSTANCE); + return this; + } - /** - * Element that must be a boolean - * @param example example boolean to use for generated bodies - */ - public PactDslJsonArray booleanType(Boolean example) { - body.put(example); - matchers.addRule(rootPath + appendArrayIndex(0), TypeMatcher.INSTANCE); - return this; - } + /** + * Element that must be a boolean + * + * @param example example boolean to use for generated bodies + */ + public PactDslJsonArray booleanType(Boolean example) { + body.add(example ? JsonValue.True.INSTANCE : JsonValue.False.INSTANCE); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), TypeMatcher.INSTANCE); + return this; + } - /** - * Element that must match the regular expression - * @param regex regular expression - * @param value example value to use for generated bodies - */ - public PactDslJsonArray stringMatcher(String regex, String value) { - if (!value.matches(regex)) { - throw new InvalidMatcherException(EXAMPLE + value + "\" does not match regular expression \"" + - regex + "\""); - } - body.put(value); - matchers.addRule(rootPath + appendArrayIndex(0), regexp(regex)); - return this; + /** + * Element that must match the regular expression + * + * @param regex regular expression + * @param value example value to use for generated bodies + */ + public PactDslJsonArray stringMatcher(String regex, String value) { + if (!value.matches(regex)) { + throw new InvalidMatcherException(EXAMPLE + value + "\" does not match regular expression \"" + + regex + "\""); } + body.add(new JsonValue.StringValue(value.toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), regexp(regex)); + return this; + } - /** - * Element that must be an ISO formatted timestamp - */ - public PactDslJsonArray timestamp() { - String pattern = DateFormatUtils.ISO_DATETIME_FORMAT.getPattern(); - body.put(DateFormatUtils.ISO_DATETIME_FORMAT.format(new Date(DATE_2000))); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new DateTimeGenerator(pattern)); - matchers.addRule(rootPath + appendArrayIndex(0), matchTimestamp(pattern)); - return this; - } + /** + * Element that must be an ISO formatted timestamp + */ + public PactDslJsonArray timestamp() { + String pattern = DateFormatUtils.ISO_DATETIME_FORMAT.getPattern(); + body.add(new JsonValue.StringValue( + DateFormatUtils.ISO_DATETIME_FORMAT.format(new Date(DATE_2000)).toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new DateTimeGenerator(pattern)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchTimestamp(pattern)); + return this; + } - /** - * Element that must match the given timestamp format - * @param format timestamp format - */ - public PactDslJsonArray timestamp(String format) { - FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(instance.format(new Date(DATE_2000))); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new DateTimeGenerator(format)); - matchers.addRule(rootPath + appendArrayIndex(0), matchTimestamp(format)); - return this; - } + /** + * Element that must match the given timestamp format + * + * @param format timestamp format + */ + public PactDslJsonArray timestamp(String format) { + FastDateFormat instance = FastDateFormat.getInstance(format); + body.add(new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new DateTimeGenerator(format)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchTimestamp(format)); + return this; + } - /** - * Element that must match the given timestamp format - * @param format timestamp format - * @param example example date and time to use for generated bodies - */ - public PactDslJsonArray timestamp(String format, Date example) { - FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(instance.format(example)); - matchers.addRule(rootPath + appendArrayIndex(0), matchTimestamp(format)); - return this; - } + /** + * Element that must match the given timestamp format + * + * @param format timestamp format + * @param example example date and time to use for generated bodies + */ + public PactDslJsonArray timestamp(String format, Date example) { + FastDateFormat instance = FastDateFormat.getInstance(format); + body.add(new JsonValue.StringValue(instance.format(example).toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchTimestamp(format)); + return this; + } - /** - * Element that must match the given timestamp format - * @param format timestamp format - * @param example example date and time to use for generated bodies - */ - public PactDslJsonArray timestamp(String format, Instant example) { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); - body.put(formatter.format(example)); - matchers.addRule(rootPath + appendArrayIndex(0), matchTimestamp(format)); - return this; - } + /** + * Element that must match the given timestamp format + * + * @param format timestamp format + * @param example example date and time to use for generated bodies + */ + public PactDslJsonArray timestamp(String format, Instant example) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); + body.add(new JsonValue.StringValue(formatter.format(example).toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchTimestamp(format)); + return this; + } - /** - * Element that must be formatted as an ISO date - */ - public PactDslJsonArray date() { - String pattern = DateFormatUtils.ISO_DATE_FORMAT.getPattern(); - body.put(DateFormatUtils.ISO_DATE_FORMAT.format(new Date(DATE_2000))); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new DateGenerator(pattern)); - matchers.addRule(rootPath + appendArrayIndex(0), matchDate(pattern)); - return this; - } + /** + * Element that must be formatted as an ISO date + */ + public PactDslJsonArray date() { + String pattern = DateFormatUtils.ISO_DATE_FORMAT.getPattern(); + body.add(new JsonValue.StringValue(DateFormatUtils.ISO_DATE_FORMAT.format(new Date(DATE_2000)).toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new DateGenerator(pattern)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchDate(pattern)); + return this; + } - /** - * Element that must match the provided date format - * @param format date format to match - */ - public PactDslJsonArray date(String format) { - FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(instance.format(new Date(DATE_2000))); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new DateTimeGenerator(format)); - matchers.addRule(rootPath + appendArrayIndex(0), matchDate(format)); - return this; - } + /** + * Element that must match the provided date format + * + * @param format date format to match + */ + public PactDslJsonArray date(String format) { + FastDateFormat instance = FastDateFormat.getInstance(format); + body.add(new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new DateTimeGenerator(format)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchDate(format)); + return this; + } - /** - * Element that must match the provided date format - * @param format date format to match - * @param example example date to use for generated values - */ - public PactDslJsonArray date(String format, Date example) { - FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(instance.format(example)); - matchers.addRule(rootPath + appendArrayIndex(0), matchDate(format)); - return this; - } + /** + * Element that must match the provided date format + * + * @param format date format to match + * @param example example date to use for generated values + */ + public PactDslJsonArray date(String format, Date example) { + FastDateFormat instance = FastDateFormat.getInstance(format); + body.add(new JsonValue.StringValue(instance.format(example).toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchDate(format)); + return this; + } - /** - * Element that must be an ISO formatted time - */ - public PactDslJsonArray time() { - String pattern = DateFormatUtils.ISO_TIME_FORMAT.getPattern(); - body.put(DateFormatUtils.ISO_TIME_FORMAT.format(new Date(DATE_2000))); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new TimeGenerator(pattern)); - matchers.addRule(rootPath + appendArrayIndex(0), matchTime(pattern)); - return this; - } + /** + * Element that must be an ISO formatted time + */ + public PactDslJsonArray time() { + String pattern = DateFormatUtils.ISO_TIME_FORMAT.getPattern(); + body.add(new JsonValue.StringValue(DateFormatUtils.ISO_TIME_FORMAT.format(new Date(DATE_2000)).toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new TimeGenerator(pattern)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchTime(pattern)); + return this; + } - /** - * Element that must match the given time format - * @param format time format to match - */ - public PactDslJsonArray time(String format) { - FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(instance.format(new Date(DATE_2000))); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new TimeGenerator(format)); - matchers.addRule(rootPath + appendArrayIndex(0), matchTime(format)); - return this; - } + /** + * Element that must match the given time format + * + * @param format time format to match + */ + public PactDslJsonArray time(String format) { + FastDateFormat instance = FastDateFormat.getInstance(format); + body.add(new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new TimeGenerator(format)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchTime(format)); + return this; + } - /** - * Element that must match the given time format - * @param format time format to match - * @param example example time to use for generated bodies - */ - public PactDslJsonArray time(String format, Date example) { - FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(instance.format(example)); - matchers.addRule(rootPath + appendArrayIndex(0), matchTime(format)); - return this; - } + /** + * Element that must match the given time format + * + * @param format time format to match + * @param example example time to use for generated bodies + */ + public PactDslJsonArray time(String format, Date example) { + FastDateFormat instance = FastDateFormat.getInstance(format); + body.add(new JsonValue.StringValue(instance.format(example).toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchTime(format)); + return this; + } - /** - * Element that must be an IP4 address - */ - public PactDslJsonArray ipAddress() { - body.put("127.0.0.1"); - matchers.addRule(rootPath + appendArrayIndex(0), regexp("(\\d{1,3}\\.)+\\d{1,3}")); - return this; - } + /** + * Element that must be an IP4 address + */ + public PactDslJsonArray ipAddress() { + body.add(new JsonValue.StringValue("127.0.0.1".toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), regexp("(\\d{1,3}\\.)+\\d{1,3}")); + return this; + } - public PactDslJsonBody object(String name) { - throw new UnsupportedOperationException("use the object() form"); - } + public PactDslJsonBody object(String name) { + throw new UnsupportedOperationException("use the object() form"); + } - /** - * Element that is a JSON object - */ - public PactDslJsonBody object() { - return new PactDslJsonBody(".", "", this); - } + /** + * Element that is a JSON object + */ + public PactDslJsonBody object() { + return new PactDslJsonBody(".", "", this); + } - @Override - public DslPart closeObject() { - throw new UnsupportedOperationException("can't call closeObject on an Array"); - } + @Override + public DslPart closeObject() { + throw new UnsupportedOperationException("can't call closeObject on an Array"); + } @Override public DslPart close() { DslPart parentToReturn = this; - if (!closed) { + if (!getClosed()) { DslPart parent = closeArray(); while (parent != null) { parentToReturn = parent; @@ -622,43 +647,55 @@ public DslPart close() { } public PactDslJsonArray array(String name) { - throw new UnsupportedOperationException("use the array() form"); - } + throw new UnsupportedOperationException("use the array() form"); + } - /** - * Element that is a JSON array - */ - public PactDslJsonArray array() { - return new PactDslJsonArray("", "", this); - } + /** + * Element that is a JSON array + */ + public PactDslJsonArray array() { + return new PactDslJsonArray("", "", this); + } - /** - * Element that must be a numeric identifier - */ - public PactDslJsonArray id() { - body.put(100L); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new RandomIntGenerator(0, Integer.MAX_VALUE)); - matchers.addRule(rootPath + appendArrayIndex(0), TypeMatcher.INSTANCE); - return this; - } + /** + * Matches rule for all elements in array + * + * @param rule Matching rule to apply across array + */ + public PactDslJsonArray wildcardArrayMatcher(MatchingRule rule) { + wildCard = true; + getMatchers().addRule(getRootPath() + appendArrayIndex(1), rule); + return this; + } - /** - * Element that must be a numeric identifier - * @param id example id to use for generated bodies - */ - public PactDslJsonArray id(Long id) { - body.put(id); - matchers.addRule(rootPath + appendArrayIndex(0), TypeMatcher.INSTANCE); - return this; - } + /** + * Element that must be a numeric identifier + */ + public PactDslJsonArray id() { + body.add(new JsonValue.Integer("100".toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new RandomIntGenerator(0, Integer.MAX_VALUE)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), TypeMatcher.INSTANCE); + return this; + } - /** - * Element that must be encoded as a hexadecimal value - */ - public PactDslJsonArray hexValue() { - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(1), new RandomHexadecimalGenerator(10)); - return hexValue("1234a"); - } + /** + * Element that must be a numeric identifier + * + * @param id example id to use for generated bodies + */ + public PactDslJsonArray id(Long id) { + body.add(new JsonValue.Integer(id.toString().toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), TypeMatcher.INSTANCE); + return this; + } + + /** + * Element that must be encoded as a hexadecimal value + */ + public PactDslJsonArray hexValue() { + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(1), new RandomHexadecimalGenerator(10)); + return hexValue("1234a"); + } /** * Element that must be encoded as a hexadecimal value @@ -668,65 +705,68 @@ public PactDslJsonArray hexValue(String hexValue) { if (!hexValue.matches(HEXADECIMAL)) { throw new InvalidMatcherException(EXAMPLE + hexValue + "\" is not a hexadecimal value"); } - body.put(hexValue); - matchers.addRule(rootPath + appendArrayIndex(0), regexp("[0-9a-fA-F]+")); + body.add(Json.toJson(hexValue)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), regexp("[0-9a-fA-F]+")); return this; } - /** - * Element that must be encoded as an UUID - */ - public PactDslJsonArray uuid() { - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(1), UuidGenerator.INSTANCE); - return uuid("e2490de5-5bd3-43d5-b7c4-526e33f71304"); + /** + * Element that must be encoded as an UUID + */ + public PactDslJsonArray uuid() { + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(1), UuidGenerator.INSTANCE); + return uuid("e2490de5-5bd3-43d5-b7c4-526e33f71304"); + } + + /** + * Element that must be encoded as an UUID + * + * @param uuid example UUID to use for generated bodies + */ + public PactDslJsonArray uuid(String uuid) { + if (!uuid.matches(UUID_REGEX)) { + throw new InvalidMatcherException(EXAMPLE + uuid + "\" is not an UUID"); } + body.add(new JsonValue.StringValue(uuid.toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), regexp(UUID_REGEX)); + return this; + } - /** - * Element that must be encoded as an UUID - * @param uuid example UUID to use for generated bodies - */ - public PactDslJsonArray uuid(String uuid) { - if (!uuid.matches(UUID_REGEX)) { - throw new InvalidMatcherException(EXAMPLE + uuid + "\" is not an UUID"); - } - body.put(uuid); - matchers.addRule(rootPath + appendArrayIndex(0), regexp(UUID_REGEX)); - return this; + /** + * Adds the template object to the array + * + * @param template template object + */ + public PactDslJsonArray template(DslPart template) { + putObjectPrivate(template); + return this; + } + + /** + * Adds a number of template objects to the array + * + * @param template template object + * @param occurrences number to add + */ + public PactDslJsonArray template(DslPart template, int occurrences) { + for (int i = 0; i < occurrences; i++) { + template(template); } + return this; + } - /** - * Adds the template object to the array - * @param template template object - */ - public PactDslJsonArray template(DslPart template) { - putObject(template); - return this; - } + @Override + public String toString() { + return body.toString(); + } - /** - * Adds a number of template objects to the array - * @param template template object - * @param occurrences number to add - */ - public PactDslJsonArray template(DslPart template, int occurrences) { - for(int i = 0; i < occurrences; i++) { - template(template); - } - return this; - } - - @Override - public String toString() { - return body.toString(); - } - - private String appendArrayIndex(Integer offset) { - String index = "*"; - if (!wildCard) { - index = String.valueOf(body.length() - 1 + offset); - } - return "[" + index + "]"; + private String appendArrayIndex(Integer offset) { + String index = "*"; + if (!wildCard) { + index = String.valueOf(body.getSize() - 1 + offset); } + return "[" + index + "]"; + } /** * Array where each item must match the following example @@ -737,12 +777,13 @@ public static PactDslJsonBody arrayEachLike() { /** * Array where each item must match the following example + * * @param numberExamples Number of examples to generate */ public static PactDslJsonBody arrayEachLike(Integer numberExamples) { PactDslJsonArray parent = new PactDslJsonArray("", "", null, true); parent.setNumberExamples(numberExamples); - parent.matchers.addRule("", TypeMatcher.INSTANCE); + parent.getMatchers().addRule("", TypeMatcher.INSTANCE); return new PactDslJsonBody(".", "", parent); } @@ -755,27 +796,30 @@ public static PactDslJsonArray arrayEachLike(PactDslJsonRootValue rootValue) { /** * Root level array where each item must match the provided matcher + * * @param numberExamples Number of examples to generate */ public static PactDslJsonArray arrayEachLike(Integer numberExamples, PactDslJsonRootValue value) { PactDslJsonArray parent = new PactDslJsonArray("", "", null, true); parent.setNumberExamples(numberExamples); - parent.matchers.addRule("", TypeMatcher.INSTANCE); - parent.putObject(value); + parent.getMatchers().addRule("", TypeMatcher.INSTANCE); + parent.putObjectPrivate(value); return parent; } /** * Array with a minimum size where each item must match the following example + * * @param minSize minimum size */ public static PactDslJsonBody arrayMinLike(int minSize) { - return arrayMinLike(minSize, minSize); + return arrayMinLike(minSize, minSize); } /** * Array with a minimum size where each item must match the following example - * @param minSize minimum size + * + * @param minSize minimum size * @param numberExamples Number of examples to generate */ public static PactDslJsonBody arrayMinLike(int minSize, int numberExamples) { @@ -785,12 +829,13 @@ public static PactDslJsonBody arrayMinLike(int minSize, int numberExamples) { } PactDslJsonArray parent = new PactDslJsonArray("", "", null, true); parent.setNumberExamples(numberExamples); - parent.matchers.addRule("", parent.matchMin(minSize)); + parent.getMatchers().addRule("", parent.matchMin(minSize)); return new PactDslJsonBody(".", "", parent); } /** * Root level array with minimum size where each item must match the provided matcher + * * @param minSize minimum size */ public static PactDslJsonArray arrayMinLike(int minSize, PactDslJsonRootValue value) { @@ -799,7 +844,8 @@ public static PactDslJsonArray arrayMinLike(int minSize, PactDslJsonRootValue va /** * Root level array with minimum size where each item must match the provided matcher - * @param minSize minimum size + * + * @param minSize minimum size * @param numberExamples Number of examples to generate */ public static PactDslJsonArray arrayMinLike(int minSize, int numberExamples, PactDslJsonRootValue value) { @@ -809,22 +855,24 @@ public static PactDslJsonArray arrayMinLike(int minSize, int numberExamples, Pac } PactDslJsonArray parent = new PactDslJsonArray("", "", null, true); parent.setNumberExamples(numberExamples); - parent.matchers.addRule("", parent.matchMin(minSize)); - parent.putObject(value); + parent.getMatchers().addRule("", parent.matchMin(minSize)); + parent.putObjectPrivate(value); return parent; } /** * Array with a maximum size where each item must match the following example + * * @param maxSize maximum size */ public static PactDslJsonBody arrayMaxLike(int maxSize) { - return arrayMaxLike(maxSize, 1); + return arrayMaxLike(maxSize, 1); } /** * Array with a maximum size where each item must match the following example - * @param maxSize maximum size + * + * @param maxSize maximum size * @param numberExamples Number of examples to generate */ public static PactDslJsonBody arrayMaxLike(int maxSize, int numberExamples) { @@ -834,12 +882,13 @@ public static PactDslJsonBody arrayMaxLike(int maxSize, int numberExamples) { } PactDslJsonArray parent = new PactDslJsonArray("", "", null, true); parent.setNumberExamples(numberExamples); - parent.matchers.addRule("", parent.matchMax(maxSize)); + parent.getMatchers().addRule("", parent.matchMax(maxSize)); return new PactDslJsonBody(".", "", parent); } /** * Root level array with maximum size where each item must match the provided matcher + * * @param maxSize maximum size */ public static PactDslJsonArray arrayMaxLike(int maxSize, PactDslJsonRootValue value) { @@ -848,7 +897,8 @@ public static PactDslJsonArray arrayMaxLike(int maxSize, PactDslJsonRootValue va /** * Root level array with maximum size where each item must match the provided matcher - * @param maxSize maximum size + * + * @param maxSize maximum size * @param numberExamples Number of examples to generate */ public static PactDslJsonArray arrayMaxLike(int maxSize, int numberExamples, PactDslJsonRootValue value) { @@ -858,13 +908,14 @@ public static PactDslJsonArray arrayMaxLike(int maxSize, int numberExamples, Pac } PactDslJsonArray parent = new PactDslJsonArray("", "", null, true); parent.setNumberExamples(numberExamples); - parent.matchers.addRule("", parent.matchMax(maxSize)); - parent.putObject(value); + parent.getMatchers().addRule("", parent.matchMax(maxSize)); + parent.putObjectPrivate(value); return parent; } /** * Array with a minimum and maximum size where each item must match the following example + * * @param minSize minimum size * @param maxSize maximum size */ @@ -874,8 +925,9 @@ public static PactDslJsonBody arrayMinMaxLike(int minSize, int maxSize) { /** * Array with a minimum and maximum size where each item must match the following example - * @param minSize minimum size - * @param maxSize maximum size + * + * @param minSize minimum size + * @param maxSize maximum size * @param numberExamples Number of examples to generate */ public static PactDslJsonBody arrayMinMaxLike(int minSize, int maxSize, int numberExamples) { @@ -888,12 +940,13 @@ public static PactDslJsonBody arrayMinMaxLike(int minSize, int maxSize, int numb } PactDslJsonArray parent = new PactDslJsonArray("", "", null, true); parent.setNumberExamples(numberExamples); - parent.matchers.addRule("", parent.matchMinMax(minSize, maxSize)); + parent.getMatchers().addRule("", parent.matchMinMax(minSize, maxSize)); return new PactDslJsonBody(".", "", parent); } /** * Root level array with minimum and maximum size where each item must match the provided matcher + * * @param minSize minimum size * @param maxSize maximum size */ @@ -903,22 +956,24 @@ public static PactDslJsonArray arrayMinMaxLike(int minSize, int maxSize, PactDsl /** * Root level array with minimum and maximum size where each item must match the provided matcher - * @param minSize minimum size - * @param maxSize maximum size + * + * @param minSize minimum size + * @param maxSize maximum size * @param numberExamples Number of examples to generate */ public static PactDslJsonArray arrayMinMaxLike(int minSize, int maxSize, int numberExamples, PactDslJsonRootValue value) { if (numberExamples < minSize) { throw new IllegalArgumentException(String.format("Number of example %d is less than the minimum size of %d", numberExamples, minSize)); - } if (numberExamples > maxSize) { + } + if (numberExamples > maxSize) { throw new IllegalArgumentException(String.format("Number of example %d is more than the maximum size of %d", numberExamples, maxSize)); } PactDslJsonArray parent = new PactDslJsonArray("", "", null, true); parent.setNumberExamples(numberExamples); - parent.matchers.addRule("", parent.matchMinMax(minSize, maxSize)); - parent.putObject(value); + parent.getMatchers().addRule("", parent.matchMinMax(minSize, maxSize)); + parent.putObjectPrivate(value); return parent; } @@ -926,7 +981,7 @@ public static PactDslJsonArray arrayMinMaxLike(int minSize, int maxSize, int num * Adds a null value to the list */ public PactDslJsonArray nullValue() { - body.put(JSONObject.NULL); + body.add(JsonValue.Null.INSTANCE); return this; } @@ -961,68 +1016,69 @@ public PactDslJsonArray eachArrayLike() { @Override public PactDslJsonArray eachArrayLike(int numberExamples) { - matchers.addRule(rootPath + appendArrayIndex(1), matchMin(0)); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMin(0)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonArray("", "", parent); } @Override - public PactDslJsonArray eachArrayWithMaxLike(String name, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(String name, int size) { throw new UnsupportedOperationException("use the eachArrayWithMaxLike() form"); } @Override - public PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, int size) { throw new UnsupportedOperationException("use the eachArrayWithMaxLike(numberExamples) form"); } @Override - public PactDslJsonArray eachArrayWithMaxLike(Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(int size) { return eachArrayWithMaxLike(1, size); } @Override - public PactDslJsonArray eachArrayWithMaxLike(int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(int numberExamples, int size) { if (numberExamples > size) { throw new IllegalArgumentException(String.format("Number of example %d is more than the maximum size of %d", numberExamples, size)); } - matchers.addRule(rootPath + appendArrayIndex(1), matchMax(size)); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMax(size)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonArray("", "", parent); } @Override - public PactDslJsonArray eachArrayWithMinLike(String name, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(String name, int size) { throw new UnsupportedOperationException("use the eachArrayWithMinLike() form"); } @Override - public PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, int size) { throw new UnsupportedOperationException("use the eachArrayWithMinLike(numberExamples) form"); } @Override - public PactDslJsonArray eachArrayWithMinLike(Integer size) { + public PactDslJsonArray eachArrayWithMinLike(int size) { return eachArrayWithMinLike(size, size); } @Override - public PactDslJsonArray eachArrayWithMinLike(int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(int numberExamples, int size) { if (numberExamples < size) { throw new IllegalArgumentException(String.format("Number of example %d is less than the minimum size of %d", numberExamples, size)); } - matchers.addRule(rootPath + appendArrayIndex(1), matchMin(size)); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMin(size)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonArray("", "", parent); } /** * Array of values that are not objects where each item must match the provided example + * * @param value Value to use to match each item */ public PactDslJsonArray eachLike(PactDslJsonRootValue value) { @@ -1031,7 +1087,8 @@ public PactDslJsonArray eachLike(PactDslJsonRootValue value) { /** * Array of values that are not objects where each item must match the provided example - * @param value Value to use to match each item + * + * @param value Value to use to match each item * @param numberExamples number of examples to generate */ public PactDslJsonArray eachLike(PactDslJsonRootValue value, int numberExamples) { @@ -1040,16 +1097,17 @@ public PactDslJsonArray eachLike(PactDslJsonRootValue value, int numberExamples) "example in the Pact provider implementation. See https://github.com/DiUS/pact-jvm/issues/546"); } - matchers.addRule(rootPath + appendArrayIndex(1), TypeMatcher.INSTANCE); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + getMatchers().addRule(getRootPath() + appendArrayIndex(1), TypeMatcher.INSTANCE); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); parent.setNumberExamples(numberExamples); - parent.putObject(value); + parent.putObjectPrivate(value); return (PactDslJsonArray) parent.closeArray(); } /** * Array of values with a minimum size that are not objects where each item must match the provided example - * @param size minimum size of the array + * + * @param size minimum size of the array * @param value Value to use to match each item */ public PactDslJsonArray minArrayLike(Integer size, PactDslJsonRootValue value) { @@ -1058,8 +1116,9 @@ public PactDslJsonArray minArrayLike(Integer size, PactDslJsonRootValue value) { /** * Array of values with a minimum size that are not objects where each item must match the provided example - * @param size minimum size of the array - * @param value Value to use to match each item + * + * @param size minimum size of the array + * @param value Value to use to match each item * @param numberExamples number of examples to generate */ public PactDslJsonArray minArrayLike(Integer size, PactDslJsonRootValue value, int numberExamples) { @@ -1067,16 +1126,17 @@ public PactDslJsonArray minArrayLike(Integer size, PactDslJsonRootValue value, i throw new IllegalArgumentException(String.format("Number of example %d is less than the minimum size of %d", numberExamples, size)); } - matchers.addRule(rootPath + appendArrayIndex(1), matchMin(size)); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMin(size)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); parent.setNumberExamples(numberExamples); - parent.putObject(value); + parent.putObjectPrivate(value); return (PactDslJsonArray) parent.closeArray(); } /** * Array of values with a maximum size that are not objects where each item must match the provided example - * @param size maximum size of the array + * + * @param size maximum size of the array * @param value Value to use to match each item */ public PactDslJsonArray maxArrayLike(Integer size, PactDslJsonRootValue value) { @@ -1085,8 +1145,9 @@ public PactDslJsonArray maxArrayLike(Integer size, PactDslJsonRootValue value) { /** * Array of values with a maximum size that are not objects where each item must match the provided example - * @param size maximum size of the array - * @param value Value to use to match each item + * + * @param size maximum size of the array + * @param value Value to use to match each item * @param numberExamples number of examples to generate */ public PactDslJsonArray maxArrayLike(Integer size, PactDslJsonRootValue value, int numberExamples) { @@ -1094,112 +1155,135 @@ public PactDslJsonArray maxArrayLike(Integer size, PactDslJsonRootValue value, i throw new IllegalArgumentException(String.format("Number of example %d is more than the maximum size of %d", numberExamples, size)); } - matchers.addRule(rootPath + appendArrayIndex(1), matchMax(size)); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMax(size)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); parent.setNumberExamples(numberExamples); - parent.putObject(value); + parent.putObjectPrivate(value); return (PactDslJsonArray) parent.closeArray(); } /** * List item that must include the provided string + * * @param value Value that must be included */ public PactDslJsonArray includesStr(String value) { - body.put(value); - matchers.addRule(rootPath + appendArrayIndex(0), includesMatcher(value)); + body.add(new JsonValue.StringValue(value.toCharArray())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), includesMatcher(value)); return this; } /** * Attribute that must be equal to the provided value. + * * @param value Value that will be used for comparisons */ public PactDslJsonArray equalsTo(Object value) { - body.put(value); - matchers.addRule(rootPath + appendArrayIndex(0), EqualsMatcher.INSTANCE); + body.add(Json.toJson(value)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), EqualsMatcher.INSTANCE); return this; } /** * Combine all the matchers using AND + * * @param value Attribute example value * @param rules Matching rules to apply */ public PactDslJsonArray and(Object value, MatchingRule... rules) { - if (value != null) { - body.put(value); - } else { - body.put(JSONObject.NULL); - } - matchers.setRules(rootPath + appendArrayIndex(0), new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.AND)); + body.add(Json.toJson(value)); + getMatchers().setRules(getRootPath() + appendArrayIndex(0), new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.AND)); return this; } /** * Combine all the matchers using OR + * * @param value Attribute example value * @param rules Matching rules to apply */ public PactDslJsonArray or(Object value, MatchingRule... rules) { - if (value != null) { - body.put(value); - } else { - body.put(JSONObject.NULL); - } - matchers.setRules(rootPath + appendArrayIndex(0), new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.OR)); + body.add(Json.toJson(value)); + getMatchers().setRules(getRootPath() + appendArrayIndex(0), new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.OR)); return this; } /** * Matches a URL that is composed of a base path and a sequence of path expressions - * @param basePath The base path for the URL (like "http://localhost:8080/") which will be excluded from the matching + * + * @param basePath The base path for the URL (like "http://localhost:8080/") which will be excluded from the matching * @param pathFragments Series of path fragments to match on. These can be strings or regular expressions. */ public PactDslJsonArray matchUrl(String basePath, Object... pathFragments) { UrlMatcherSupport urlMatcher = new UrlMatcherSupport(basePath, Arrays.asList(pathFragments)); - body.put(urlMatcher.getExampleValue()); - matchers.addRule(rootPath + appendArrayIndex(0), regexp(urlMatcher.getRegexExpression())); + body.add(Json.toJson(urlMatcher.getExampleValue())); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), regexp(urlMatcher.getRegexExpression())); return this; } @Override - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize) { + public DslPart matchUrl(String name, String basePath, Object... pathFragments) { + throw new UnsupportedOperationException( + "URL matcher with an attribute name is not supported for arrays. " + + "Use matchUrl(String base, Object... fragments)"); + } + + @Override + public PactDslJsonBody matchUrl2(String name, Object... pathFragments) { + throw new UnsupportedOperationException( + "URL matcher with an attribute name is not supported for arrays. " + + "Use matchUrl2(Object... pathFragments)"); + } + + /** + * Matches a URL that is composed of a base path and a sequence of path expressions. Base path from the mock server + * will be used. + * + * @param pathFragments Series of path fragments to match on. These can be strings or regular expressions. + */ + @Override + public DslPart matchUrl2(Object... pathFragments) { + return matchUrl(null, pathFragments); + } + + + @Override + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize) { throw new UnsupportedOperationException("use the minMaxArrayLike(minSize, maxSize) form"); } @Override - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, DslPart object) { + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, DslPart object) { throw new UnsupportedOperationException("use the minMaxArrayLike(minSize, maxSize, object) form"); } @Override - public PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize) { + public PactDslJsonBody minMaxArrayLike(int minSize, int maxSize) { return minMaxArrayLike(minSize, maxSize, minSize); } @Override - public PactDslJsonArray minMaxArrayLike(Integer minSize, Integer maxSize, DslPart object) { - matchers.addRule(rootPath + appendArrayIndex(1), matchMinMax(minSize, maxSize)); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + public PactDslJsonArray minMaxArrayLike(int minSize, int maxSize, DslPart object) { + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMinMax(minSize, maxSize)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); parent.setNumberExamples(minSize); if (object instanceof PactDslJsonBody) { - parent.putObject(object); + parent.putObjectPrivate(object); } else if (object instanceof PactDslJsonArray) { - parent.putArray(object); + parent.putArrayPrivate(object); } return parent.closeArray().asArray(); } @Override - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, int numberExamples) { + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, int numberExamples) { throw new UnsupportedOperationException("use the minMaxArrayLike(minSize, maxSize, numberExamples) form"); } @Override - public PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize, int numberExamples) { + public PactDslJsonBody minMaxArrayLike(int minSize, int maxSize, int numberExamples) { if (minSize > maxSize) { throw new IllegalArgumentException(String.format("The minimum size of %d is greater than the maximum of %d", minSize, maxSize)); @@ -1210,29 +1294,29 @@ public PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize, int num throw new IllegalArgumentException(String.format("Number of example %d is more than the maximum size of %d", numberExamples, maxSize)); } - matchers.addRule(rootPath + appendArrayIndex(1), matchMinMax(minSize, maxSize)); + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMinMax(minSize, maxSize)); PactDslJsonArray parent = new PactDslJsonArray("", "", this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonBody(".", "", parent); } @Override - public PactDslJsonArray eachArrayWithMinMaxLike(String name, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(String name, int minSize, int maxSize) { throw new UnsupportedOperationException("use the eachArrayWithMinMaxLike(minSize, maxSize) form"); } @Override - public PactDslJsonArray eachArrayWithMinMaxLike(Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(int minSize, int maxSize) { return eachArrayWithMinMaxLike(minSize, minSize, maxSize); } @Override - public PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, int minSize, int maxSize) { throw new UnsupportedOperationException("use the eachArrayWithMinMaxLike(numberExamples, minSize, maxSize) form"); } @Override - public PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, int minSize, int maxSize) { if (minSize > maxSize) { throw new IllegalArgumentException(String.format("The minimum size of %d is greater than the maximum of %d", minSize, maxSize)); @@ -1243,27 +1327,29 @@ public PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, Integer minS throw new IllegalArgumentException(String.format("Number of example %d is more than the maximum size of %d", numberExamples, maxSize)); } - matchers.addRule(rootPath + appendArrayIndex(1), matchMinMax(minSize, maxSize)); - PactDslJsonArray parent = new PactDslJsonArray(rootPath, "", this, true); + getMatchers().addRule(getRootPath() + appendArrayIndex(1), matchMinMax(minSize, maxSize)); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath(), "", this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonArray("", "", parent); } /** * Adds an element that will have it's value injected from the provider state + * * @param expression Expression to be evaluated from the provider state - * @param example Example value to be used in the consumer test + * @param example Example value to be used in the consumer test */ public PactDslJsonArray valueFromProviderState(String expression, Object example) { - body.put(example); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), - new ProviderStateGenerator(expression, DataType.from(example))); - matchers.addRule(rootPath + appendArrayIndex(0), TypeMatcher.INSTANCE); + body.add(Json.toJson(example)); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), + new ProviderStateGenerator(expression, DataType.from(example))); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), TypeMatcher.INSTANCE); return this; } /** * Adds a date value formatted as an ISO date with the value generated by the date expression + * * @param expression Date expression to use to generate the values */ public PactDslJsonArray dateExpression(String expression) { @@ -1272,19 +1358,21 @@ public PactDslJsonArray dateExpression(String expression) { /** * Adds a date value with the value generated by the date expression + * * @param expression Date expression to use to generate the values - * @param format Date format to use + * @param format Date format to use */ public PactDslJsonArray dateExpression(String expression, String format) { FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(instance.format(new Date(DATE_2000))); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new DateGenerator(format, expression)); - matchers.addRule(rootPath + appendArrayIndex(0), matchDate(format)); + body.add(new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new DateGenerator(format, expression)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchDate(format)); return this; } /** * Adds a time value formatted as an ISO time with the value generated by the time expression + * * @param expression Time expression to use to generate the values */ public PactDslJsonArray timeExpression(String expression) { @@ -1293,19 +1381,21 @@ public PactDslJsonArray timeExpression(String expression) { /** * Adds a time value with the value generated by the time expression + * * @param expression Time expression to use to generate the values - * @param format Time format to use + * @param format Time format to use */ public PactDslJsonArray timeExpression(String expression, String format) { FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(instance.format(new Date(DATE_2000))); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new TimeGenerator(format, expression)); - matchers.addRule(rootPath + appendArrayIndex(0), matchTime(format)); + body.add(new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new TimeGenerator(format, expression)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchTime(format)); return this; } /** * Adds a datetime value formatted as an ISO datetime with the value generated by the expression + * * @param expression Datetime expression to use to generate the values */ public PactDslJsonArray datetimeExpression(String expression) { @@ -1314,14 +1404,15 @@ public PactDslJsonArray datetimeExpression(String expression) { /** * Adds a datetime value with the value generated by the expression + * * @param expression Datetime expression to use to generate the values - * @param format Datetime format to use + * @param format Datetime format to use */ public PactDslJsonArray datetimeExpression(String expression, String format) { FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(instance.format(new Date(DATE_2000))); - generators.addGenerator(Category.BODY, rootPath + appendArrayIndex(0), new DateTimeGenerator(format, expression)); - matchers.addRule(rootPath + appendArrayIndex(0), matchTimestamp(format)); + body.add(new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getGenerators().addGenerator(Category.BODY, getRootPath() + appendArrayIndex(0), new DateTimeGenerator(format, expression)); + getMatchers().addRule(getRootPath() + appendArrayIndex(0), matchTimestamp(format)); return this; } } diff --git a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonBody.java b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonBody.java index 676360d218..52992bc6ad 100755 --- a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonBody.java +++ b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonBody.java @@ -22,12 +22,13 @@ import au.com.dius.pact.core.model.matchingrules.RuleLogic; import au.com.dius.pact.core.model.matchingrules.TypeMatcher; import au.com.dius.pact.core.model.matchingrules.ValuesMatcher; +import au.com.dius.pact.core.support.Json; import au.com.dius.pact.core.support.expressions.DataType; +import au.com.dius.pact.core.support.json.JsonValue; import com.mifmif.common.regex.Generex; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.FastDateFormat; -import org.json.JSONObject; import java.math.BigDecimal; import java.time.Instant; @@ -47,15 +48,15 @@ */ public class PactDslJsonBody extends DslPart { - private static final String EXAMPLE = "Example \""; - private final JSONObject body; + private static final String EXAMPLE = "Example \""; + private final JsonValue.Object body; /** * Constructs a new body as a root */ public PactDslJsonBody() { - super(".", ""); - body = new JSONObject(); + super(".", ""); + body = new JsonValue.Object(); } /** @@ -65,8 +66,8 @@ public PactDslJsonBody() { * @param parent Parent to attach to */ public PactDslJsonBody(String rootPath, String rootName, DslPart parent) { - super(parent, rootPath, rootName); - body = new JSONObject(); + super(parent, rootPath, rootName); + body = new JsonValue.Object(); } /** @@ -79,48 +80,48 @@ public PactDslJsonBody(String rootPath, String rootName, DslPart parent) { public PactDslJsonBody(String rootPath, String rootName, DslPart parent, PactDslJsonBody body) { super(parent, rootPath, rootName); this.body = body.body; - this.matchers = body.matchers.copyWithUpdatedMatcherRootPrefix(rootPath); - this.generators = body.generators.copyWithUpdatedMatcherRootPrefix(rootPath); + this.setMatchers(body.getMatchers().copyWithUpdatedMatcherRootPrefix(rootPath)); + this.setGenerators(body.getGenerators().copyWithUpdatedMatcherRootPrefix(rootPath)); } public String toString() { return body.toString(); } - protected void putObject(DslPart object) { - for (String matcherName: object.matchers.getMatchingRules().keySet()) { - matchers.setRules(matcherName, object.matchers.getMatchingRules().get(matcherName)); - } - generators.addGenerators(object.generators); - String elementBase = StringUtils.difference(this.rootPath, object.rootPath); - if (StringUtils.isNotEmpty(object.rootName)) { - body.put(object.rootName, object.getBody()); - } else { - String name = StringUtils.strip(elementBase, "."); - Pattern p = Pattern.compile("\\['(.+)'\\]"); - Matcher matcher = p.matcher(name); - if (matcher.matches()) { - body.put(matcher.group(1), object.getBody()); - } else { - body.put(name, object.getBody()); - } - } + public void putObjectPrivate(DslPart object) { + for (String matcherName: object.getMatchers().getMatchingRules().keySet()) { + getMatchers().setRules(matcherName, object.getMatchers().getMatchingRules().get(matcherName)); + } + getGenerators().addGenerators(object.getGenerators()); + String elementBase = StringUtils.difference(this.getRootPath(), object.getRootPath()); + if (StringUtils.isNotEmpty(object.getRootName())) { + body.add(object.getRootName(), object.getBody()); + } else { + String name = StringUtils.strip(elementBase, "."); + Pattern p = Pattern.compile("\\['(.+)'\\]"); + Matcher matcher = p.matcher(name); + if (matcher.matches()) { + body.add(matcher.group(1), object.getBody()); + } else { + body.add(name, object.getBody()); + } } + } - protected void putArray(DslPart object) { - for(String matcherName: object.matchers.getMatchingRules().keySet()) { - matchers.setRules(matcherName, object.matchers.getMatchingRules().get(matcherName)); - } - generators.addGenerators(object.generators); - if (StringUtils.isNotEmpty(object.rootName)) { - body.put(object.rootName, object.getBody()); - } else { - body.put(StringUtils.difference(this.rootPath, object.rootPath), object.getBody()); - } + public void putArrayPrivate(DslPart object) { + for(String matcherName: object.getMatchers().getMatchingRules().keySet()) { + getMatchers().setRules(matcherName, object.getMatchers().getMatchingRules().get(matcherName)); } + getGenerators().addGenerators(object.getGenerators()); + if (StringUtils.isNotEmpty(object.getRootName())) { + body.add(object.getRootName(), object.getBody()); + } else { + body.add(StringUtils.difference(this.getRootPath(), object.getRootPath()), object.getBody()); + } + } @Override - public Object getBody() { + public JsonValue getBody() { return body; } @@ -130,12 +131,12 @@ public Object getBody() { * @param value string value */ public PactDslJsonBody stringValue(String name, String value) { - if (value == null) { - body.put(name, JSONObject.NULL); - } else { - body.put(name, value); - } - return this; + if (value == null) { + body.add(name, JsonValue.Null.INSTANCE); + } else { + body.add(name, new JsonValue.StringValue(value.toCharArray())); + } + return this; } /** @@ -144,8 +145,8 @@ public PactDslJsonBody stringValue(String name, String value) { * @param value number value */ public PactDslJsonBody numberValue(String name, Number value) { - body.put(name, value); - return this; + body.add(name, new JsonValue.Decimal(value.toString().toCharArray())); + return this; } /** @@ -154,8 +155,8 @@ public PactDslJsonBody numberValue(String name, Number value) { * @param value boolean value */ public PactDslJsonBody booleanValue(String name, Boolean value) { - body.put(name, value); - return this; + body.add(name, value ? JsonValue.True.INSTANCE : JsonValue.False.INSTANCE); + return this; } /** @@ -163,8 +164,8 @@ public PactDslJsonBody booleanValue(String name, Boolean value) { * @param name attribute name */ public PactDslJsonBody like(String name, Object example) { - body.put(name, example); - matchers.addRule(matcherKey(name, rootPath), TypeMatcher.INSTANCE); + body.add(name, Json.toJson(example)); + getMatchers().addRule(matcherKey(name, getRootPath()), TypeMatcher.INSTANCE); return this; } @@ -173,7 +174,7 @@ public PactDslJsonBody like(String name, Object example) { * @param name attribute name */ public PactDslJsonBody stringType(String name) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new RandomStringGenerator(20)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new RandomStringGenerator(20)); return stringType(name, "string"); } @@ -194,9 +195,9 @@ public PactDslJsonBody stringType(String... names) { * @param example example value to use for generated bodies */ public PactDslJsonBody stringType(String name, String example) { - body.put(name, example); - matchers.addRule(matcherKey(name, rootPath), TypeMatcher.INSTANCE); - return this; + body.add(name, new JsonValue.StringValue(example.toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), TypeMatcher.INSTANCE); + return this; } /** @@ -204,7 +205,7 @@ public PactDslJsonBody stringType(String name, String example) { * @param name attribute name */ public PactDslJsonBody numberType(String name) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new RandomIntGenerator(0, Integer.MAX_VALUE)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new RandomIntGenerator(0, Integer.MAX_VALUE)); return numberType(name, 100); } @@ -225,9 +226,9 @@ public PactDslJsonBody numberType(String... names) { * @param number example number to use for generated bodies */ public PactDslJsonBody numberType(String name, Number number) { - body.put(name, number); - matchers.addRule(matcherKey(name, rootPath), new NumberTypeMatcher(NumberTypeMatcher.NumberType.NUMBER)); - return this; + body.add(name, new JsonValue.Decimal(number.toString().toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), new NumberTypeMatcher(NumberTypeMatcher.NumberType.NUMBER)); + return this; } /** @@ -235,7 +236,7 @@ public PactDslJsonBody numberType(String name, Number number) { * @param name attribute name */ public PactDslJsonBody integerType(String name) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new RandomIntGenerator(0, Integer.MAX_VALUE)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new RandomIntGenerator(0, Integer.MAX_VALUE)); return integerType(name, 100); } @@ -256,9 +257,9 @@ public PactDslJsonBody integerType(String... names) { * @param number example integer value to use for generated bodies */ public PactDslJsonBody integerType(String name, Long number) { - body.put(name, number); - matchers.addRule(matcherKey(name, rootPath), new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER)); - return this; + body.add(name, new JsonValue.Integer(number.toString().toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER)); + return this; } /** @@ -267,9 +268,9 @@ public PactDslJsonBody integerType(String name, Long number) { * @param number example integer value to use for generated bodies */ public PactDslJsonBody integerType(String name, Integer number) { - body.put(name, number); - matchers.addRule(matcherKey(name, rootPath), new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER)); - return this; + body.add(name, new JsonValue.Integer(number.toString().toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER)); + return this; } /** @@ -277,7 +278,7 @@ public PactDslJsonBody integerType(String name, Integer number) { * @param name attribute name */ public PactDslJsonBody decimalType(String name) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new RandomDecimalGenerator(10)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new RandomDecimalGenerator(10)); return decimalType(name, 100.0); } @@ -298,9 +299,9 @@ public PactDslJsonBody decimalType(String... names) { * @param number example decimalType value */ public PactDslJsonBody decimalType(String name, BigDecimal number) { - body.put(name, number); - matchers.addRule(matcherKey(name, rootPath), new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)); - return this; + body.add(name, new JsonValue.Decimal(number.toString().toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)); + return this; } /** @@ -309,8 +310,8 @@ public PactDslJsonBody decimalType(String name, BigDecimal number) { * @param number example decimalType value */ public PactDslJsonBody decimalType(String name, Double number) { - body.put(name, number); - matchers.addRule(matcherKey(name, rootPath), new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)); + body.add(name, new JsonValue.Decimal(number.toString().toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)); return this; } @@ -339,9 +340,9 @@ public PactDslJsonBody booleanType(String... names) { * @param example example boolean to use for generated bodies */ public PactDslJsonBody booleanType(String name, Boolean example) { - body.put(name, example); - matchers.addRule(matcherKey(name, rootPath), TypeMatcher.INSTANCE); - return this; + body.add(name, example ? JsonValue.True.INSTANCE : JsonValue.False.INSTANCE); + getMatchers().addRule(matcherKey(name, getRootPath()), TypeMatcher.INSTANCE); + return this; } /** @@ -351,13 +352,13 @@ public PactDslJsonBody booleanType(String name, Boolean example) { * @param value example value to use for generated bodies */ public PactDslJsonBody stringMatcher(String name, String regex, String value) { - if (!value.matches(regex)) { - throw new InvalidMatcherException(EXAMPLE + value + "\" does not match regular expression \"" + - regex + "\""); - } - body.put(name, value); - matchers.addRule(matcherKey(name, rootPath), regexp(regex)); - return this; + if (!value.matches(regex)) { + throw new InvalidMatcherException(EXAMPLE + value + "\" does not match regular expression \"" + + regex + "\""); + } + body.add(name, new JsonValue.StringValue(value.toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), regexp(regex)); + return this; } /** @@ -366,7 +367,7 @@ public PactDslJsonBody stringMatcher(String name, String regex, String value) { * @param regex regular expression */ public PactDslJsonBody stringMatcher(String name, String regex) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new RegexGenerator(regex)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new RegexGenerator(regex)); stringMatcher(name, regex, new Generex(regex).random()); return this; } @@ -459,9 +460,10 @@ public PactDslJsonBody timestamp(String name, String format, Instant example, Ti */ public PactDslJsonBody datetime(String name) { String pattern = DateFormatUtils.ISO_DATETIME_FORMAT.getPattern(); - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new DateTimeGenerator(pattern, null)); - body.put(name, DateFormatUtils.ISO_DATETIME_FORMAT.format(new Date(DATE_2000))); - matchers.addRule(matcherKey(name, rootPath), matchTimestamp(pattern)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new DateTimeGenerator(pattern, null)); + body.add(name, new JsonValue.StringValue( + DateFormatUtils.ISO_DATETIME_FORMAT.format(new Date(DATE_2000)).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchTimestamp(pattern)); return this; } @@ -471,10 +473,10 @@ public PactDslJsonBody datetime(String name) { * @param format datetime format */ public PactDslJsonBody datetime(String name, String format) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new DateTimeGenerator(format, null)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new DateTimeGenerator(format, null)); DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withZone(ZoneId.systemDefault()); - body.put(name, formatter.format(new Date(DATE_2000).toInstant())); - matchers.addRule(matcherKey(name, rootPath), matchTimestamp(format)); + body.add(name, new JsonValue.StringValue(formatter.format(new Date(DATE_2000).toInstant()).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchTimestamp(format)); return this; } @@ -497,8 +499,8 @@ public PactDslJsonBody datetime(String name, String format, Date example) { */ public PactDslJsonBody datetime(String name, String format, Date example, TimeZone timeZone) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withZone(timeZone.toZoneId()); - body.put(name, formatter.format(example.toInstant())); - matchers.addRule(matcherKey(name, rootPath), matchTimestamp(format)); + body.add(name, new JsonValue.StringValue(formatter.format(example.toInstant()).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchTimestamp(format)); return this; } @@ -521,8 +523,8 @@ public PactDslJsonBody datetime(String name, String format, Instant example) { */ public PactDslJsonBody datetime(String name, String format, Instant example, TimeZone timeZone) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withZone(timeZone.toZoneId()); - body.put(name, formatter.format(example)); - matchers.addRule(matcherKey(name, rootPath), matchTimestamp(format)); + body.add(name, new JsonValue.StringValue(formatter.format(example).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchTimestamp(format)); return this; } @@ -539,9 +541,10 @@ public PactDslJsonBody date() { */ public PactDslJsonBody date(String name) { String pattern = DateFormatUtils.ISO_DATE_FORMAT.getPattern(); - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new DateGenerator(pattern, null)); - body.put(name, DateFormatUtils.ISO_DATE_FORMAT.format(new Date(DATE_2000))); - matchers.addRule(matcherKey(name, rootPath), matchDate(pattern)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new DateGenerator(pattern, null)); + body.add(name, new JsonValue.StringValue( + DateFormatUtils.ISO_DATE_FORMAT.format(new Date(DATE_2000)).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchDate(pattern)); return this; } @@ -551,10 +554,10 @@ public PactDslJsonBody date(String name) { * @param format date format to match */ public PactDslJsonBody date(String name, String format) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new DateGenerator(format, null)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new DateGenerator(format, null)); FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(name, instance.format(new Date(DATE_2000))); - matchers.addRule(matcherKey(name, rootPath), matchDate(format)); + body.add(name, new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchDate(format)); return this; } @@ -576,10 +579,10 @@ public PactDslJsonBody date(String name, String format, Date example) { * @param timeZone time zone used for formatting of example date */ public PactDslJsonBody date(String name, String format, Date example, TimeZone timeZone) { - FastDateFormat instance = FastDateFormat.getInstance(format, timeZone); - body.put(name, instance.format(example)); - matchers.addRule(matcherKey(name, rootPath), matchDate(format)); - return this; + FastDateFormat instance = FastDateFormat.getInstance(format, timeZone); + body.add(name, new JsonValue.StringValue(instance.format(example).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchDate(format)); + return this; } /** @@ -595,9 +598,10 @@ public PactDslJsonBody time() { */ public PactDslJsonBody time(String name) { String pattern = DateFormatUtils.ISO_TIME_FORMAT.getPattern(); - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new TimeGenerator(pattern, null)); - body.put(name, DateFormatUtils.ISO_TIME_FORMAT.format(new Date(DATE_2000))); - matchers.addRule(matcherKey(name, rootPath), matchTime(pattern)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new TimeGenerator(pattern, null)); + body.add(name, new JsonValue.StringValue( + DateFormatUtils.ISO_TIME_FORMAT.format(new Date(DATE_2000)).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchTime(pattern)); return this; } @@ -607,10 +611,10 @@ public PactDslJsonBody time(String name) { * @param format time format to match */ public PactDslJsonBody time(String name, String format) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new TimeGenerator(format, null)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new TimeGenerator(format, null)); FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(name, instance.format(new Date(DATE_2000))); - matchers.addRule(matcherKey(name, rootPath), matchTime(format)); + body.add(name, new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchTime(format)); return this; } @@ -632,10 +636,10 @@ public PactDslJsonBody time(String name, String format, Date example) { * @param timeZone time zone used for formatting of example time */ public PactDslJsonBody time(String name, String format, Date example, TimeZone timeZone) { - FastDateFormat instance = FastDateFormat.getInstance(format, timeZone); - body.put(name, instance.format(example)); - matchers.addRule(matcherKey(name, rootPath), matchTime(format)); - return this; + FastDateFormat instance = FastDateFormat.getInstance(format, timeZone); + body.add(name, new JsonValue.StringValue(instance.format(example).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchTime(format)); + return this; } /** @@ -643,9 +647,9 @@ public PactDslJsonBody time(String name, String format, Date example, TimeZone t * @param name attribute name */ public PactDslJsonBody ipAddress(String name) { - body.put(name, "127.0.0.1"); - matchers.addRule(matcherKey(name, rootPath), regexp("(\\d{1,3}\\.)+\\d{1,3}")); - return this; + body.add(name, new JsonValue.StringValue("127.0.0.1".toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), regexp("(\\d{1,3}\\.)+\\d{1,3}")); + return this; } /** @@ -653,7 +657,7 @@ public PactDslJsonBody ipAddress(String name) { * @param name field name */ public PactDslJsonBody object(String name) { - return new PactDslJsonBody(matcherKey(name, rootPath) + ".", "", this); + return new PactDslJsonBody(matcherKey(name, getRootPath()) + ".", "", this); } public PactDslJsonBody object() { @@ -666,13 +670,13 @@ public PactDslJsonBody object() { * @param value DSL Part to set the value as */ public PactDslJsonBody object(String name, DslPart value) { - String base = matcherKey(name, rootPath); + String base = matcherKey(name, getRootPath()); if (value instanceof PactDslJsonBody) { PactDslJsonBody object = new PactDslJsonBody(base, "", this, (PactDslJsonBody) value); - putObject(object); + putObjectPrivate(object); } else if (value instanceof PactDslJsonArray) { PactDslJsonArray object = new PactDslJsonArray(base, "", this, (PactDslJsonArray) value); - putArray(object); + putArrayPrivate(object); } return this; } @@ -681,21 +685,21 @@ public PactDslJsonBody object(String name, DslPart value) { * Closes the current JSON object */ public DslPart closeObject() { - if (parent != null) { - parent.putObject(this); + if (getParent() != null) { + getParent().putObjectPrivate(this); } else { getMatchers().applyMatcherRootPrefix("$"); getGenerators().applyRootPrefix("$"); } - closed = true; - return parent; + setClosed(true); + return getParent(); } @Override public DslPart close() { DslPart parentToReturn = this; - if (!closed) { + if (!getClosed()) { DslPart parent = closeObject(); while (parent != null) { parentToReturn = parent; @@ -715,7 +719,7 @@ public DslPart close() { * @param name field name */ public PactDslJsonArray array(String name) { - return new PactDslJsonArray(matcherKey(name, rootPath), name, this); + return new PactDslJsonArray(matcherKey(name, getRootPath()), name, this); } public PactDslJsonArray array() { @@ -727,9 +731,9 @@ public PactDslJsonArray array() { */ @Override public DslPart closeArray() { - if (parent instanceof PactDslJsonArray) { + if (getParent() instanceof PactDslJsonArray) { closeObject(); - return parent.closeArray(); + return getParent().closeArray(); } else { throw new UnsupportedOperationException("can't call closeArray on an Object"); } @@ -746,14 +750,14 @@ public PactDslJsonBody eachLike(String name) { @Override public PactDslJsonBody eachLike(String name, DslPart object) { - String base = matcherKey(name, rootPath); - matchers.addRule(base, TypeMatcher.INSTANCE); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + String base = matcherKey(name, getRootPath()); + getMatchers().addRule(base, TypeMatcher.INSTANCE); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); if (object instanceof PactDslJsonBody) { - parent.putObject(object); + parent.putObjectPrivate(object); } else if (object instanceof PactDslJsonArray) { - parent.putArray(object); + parent.putArrayPrivate(object); } return (PactDslJsonBody) parent.closeArray(); @@ -776,8 +780,8 @@ public PactDslJsonArray eachLike(DslPart object) { */ @Override public PactDslJsonBody eachLike(String name, int numberExamples) { - matchers.addRule(matcherKey(name, rootPath), TypeMatcher.INSTANCE); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), TypeMatcher.INSTANCE); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonBody(".", ".", parent); } @@ -803,10 +807,10 @@ public PactDslJsonBody eachLike(String name, PactDslJsonRootValue value) { * @param numberExamples number of examples to generate */ public PactDslJsonBody eachLike(String name, PactDslJsonRootValue value, int numberExamples) { - matchers.addRule(matcherKey(name, rootPath), TypeMatcher.INSTANCE); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), TypeMatcher.INSTANCE); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); parent.setNumberExamples(numberExamples); - parent.putObject(value); + parent.putObjectPrivate(value); return (PactDslJsonBody) parent.closeArray(); } @@ -816,32 +820,32 @@ public PactDslJsonBody eachLike(String name, PactDslJsonRootValue value, int num * @param size minimum size of the array */ @Override - public PactDslJsonBody minArrayLike(String name, Integer size) { + public PactDslJsonBody minArrayLike(String name, int size) { return minArrayLike(name, size, size); } @Override - public PactDslJsonBody minArrayLike(Integer size) { + public PactDslJsonBody minArrayLike(int size) { throw new UnsupportedOperationException("use the minArrayLike(String name, Integer size) form"); } @Override - public PactDslJsonBody minArrayLike(String name, Integer size, DslPart object) { - String base = matcherKey(name, rootPath); - matchers.addRule(base, matchMin(size)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + public PactDslJsonBody minArrayLike(String name, int size, DslPart object) { + String base = matcherKey(name, getRootPath()); + getMatchers().addRule(base, matchMin(size)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); if (object instanceof PactDslJsonBody) { - parent.putObject(object); + parent.putObjectPrivate(object); } else if (object instanceof PactDslJsonArray) { - parent.putArray(object); + parent.putArrayPrivate(object); } return (PactDslJsonBody) parent.closeArray(); } @Override - public PactDslJsonArray minArrayLike(Integer size, DslPart object) { + public PactDslJsonArray minArrayLike(int size, DslPart object) { throw new UnsupportedOperationException("use the minArrayLike(String name, Integer size, DslPart object) form"); } @@ -852,19 +856,19 @@ public PactDslJsonArray minArrayLike(Integer size, DslPart object) { * @param numberExamples number of examples to generate */ @Override - public PactDslJsonBody minArrayLike(String name, Integer size, int numberExamples) { + public PactDslJsonBody minArrayLike(String name, int size, int numberExamples) { if (numberExamples < size) { throw new IllegalArgumentException(String.format("Number of example %d is less than the minimum size of %d", numberExamples, size)); } - matchers.addRule(matcherKey(name, rootPath), matchMin(size)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), matchMin(size)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonBody(".", "", parent); } @Override - public PactDslJsonBody minArrayLike(Integer size, int numberExamples) { + public PactDslJsonBody minArrayLike(int size, int numberExamples) { throw new UnsupportedOperationException("use the minArrayLike(String name, Integer size, int numberExamples) form"); } @@ -874,7 +878,7 @@ public PactDslJsonBody minArrayLike(Integer size, int numberExamples) { * @param size minimum size of the array * @param value Value to use to match each item */ - public PactDslJsonBody minArrayLike(String name, Integer size, PactDslJsonRootValue value) { + public PactDslJsonBody minArrayLike(String name, int size, PactDslJsonRootValue value) { return minArrayLike(name, size, value, 2); } @@ -885,15 +889,15 @@ public PactDslJsonBody minArrayLike(String name, Integer size, PactDslJsonRootVa * @param value Value to use to match each item * @param numberExamples number of examples to generate */ - public PactDslJsonBody minArrayLike(String name, Integer size, PactDslJsonRootValue value, int numberExamples) { + public PactDslJsonBody minArrayLike(String name, int size, PactDslJsonRootValue value, int numberExamples) { if (numberExamples < size) { throw new IllegalArgumentException(String.format("Number of example %d is less than the minimum size of %d", numberExamples, size)); } - matchers.addRule(matcherKey(name, rootPath), matchMin(size)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), matchMin(size)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); parent.setNumberExamples(numberExamples); - parent.putObject(value); + parent.putObjectPrivate(value); return (PactDslJsonBody) parent.closeArray(); } @@ -903,32 +907,32 @@ public PactDslJsonBody minArrayLike(String name, Integer size, PactDslJsonRootVa * @param size maximum size of the array */ @Override - public PactDslJsonBody maxArrayLike(String name, Integer size) { + public PactDslJsonBody maxArrayLike(String name, int size) { return maxArrayLike(name, size, 1); } @Override - public PactDslJsonBody maxArrayLike(Integer size) { + public PactDslJsonBody maxArrayLike(int size) { throw new UnsupportedOperationException("use the maxArrayLike(String name, Integer size) form"); } @Override - public PactDslJsonBody maxArrayLike(String name, Integer size, DslPart object) { - String base = matcherKey(name, rootPath); - matchers.addRule(base, matchMax(size)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + public PactDslJsonBody maxArrayLike(String name, int size, DslPart object) { + String base = matcherKey(name, getRootPath()); + getMatchers().addRule(base, matchMax(size)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); if (object instanceof PactDslJsonBody) { - parent.putObject(object); + parent.putObjectPrivate(object); } else if (object instanceof PactDslJsonArray) { - parent.putArray(object); + parent.putArrayPrivate(object); } return (PactDslJsonBody) parent.closeArray(); } @Override - public PactDslJsonArray maxArrayLike(Integer size, DslPart object) { + public PactDslJsonArray maxArrayLike(int size, DslPart object) { throw new UnsupportedOperationException("use the maxArrayLike(String name, Integer size, DslPart object) form"); } @@ -939,19 +943,19 @@ public PactDslJsonArray maxArrayLike(Integer size, DslPart object) { * @param numberExamples number of examples to generate */ @Override - public PactDslJsonBody maxArrayLike(String name, Integer size, int numberExamples) { + public PactDslJsonBody maxArrayLike(String name, int size, int numberExamples) { if (numberExamples > size) { throw new IllegalArgumentException(String.format("Number of example %d is more than the maximum size of %d", numberExamples, size)); } - matchers.addRule(matcherKey(name, rootPath), matchMax(size)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), matchMax(size)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonBody(".", "", parent); } @Override - public PactDslJsonBody maxArrayLike(Integer size, int numberExamples) { + public PactDslJsonBody maxArrayLike(int size, int numberExamples) { throw new UnsupportedOperationException("use the maxArrayLike(String name, Integer size, int numberExamples) form"); } @@ -961,7 +965,7 @@ public PactDslJsonBody maxArrayLike(Integer size, int numberExamples) { * @param size maximum size of the array * @param value Value to use to match each item */ - public PactDslJsonBody maxArrayLike(String name, Integer size, PactDslJsonRootValue value) { + public PactDslJsonBody maxArrayLike(String name, int size, PactDslJsonRootValue value) { return maxArrayLike(name, size, value, 1); } @@ -972,15 +976,15 @@ public PactDslJsonBody maxArrayLike(String name, Integer size, PactDslJsonRootVa * @param value Value to use to match each item * @param numberExamples number of examples to generate */ - public PactDslJsonBody maxArrayLike(String name, Integer size, PactDslJsonRootValue value, int numberExamples) { + public PactDslJsonBody maxArrayLike(String name, int size, PactDslJsonRootValue value, int numberExamples) { if (numberExamples > size) { throw new IllegalArgumentException(String.format("Number of example %d is more than the maximum size of %d", numberExamples, size)); } - matchers.addRule(matcherKey(name, rootPath), matchMax(size)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), matchMax(size)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); parent.setNumberExamples(numberExamples); - parent.putObject(value); + parent.putObjectPrivate(value); return (PactDslJsonBody) parent.closeArray(); } @@ -996,9 +1000,9 @@ public PactDslJsonBody id() { * @param name attribute name */ public PactDslJsonBody id(String name) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new RandomIntGenerator(0, Integer.MAX_VALUE)); - body.put(name, 1234567890L); - matchers.addRule(matcherKey(name, rootPath), TypeMatcher.INSTANCE); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new RandomIntGenerator(0, Integer.MAX_VALUE)); + body.add(name, new JsonValue.Integer("1234567890".toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), TypeMatcher.INSTANCE); return this; } @@ -1008,9 +1012,9 @@ public PactDslJsonBody id(String name) { * @param id example id to use for generated bodies */ public PactDslJsonBody id(String name, Long id) { - body.put(name, id); - matchers.addRule(matcherKey(name, rootPath), TypeMatcher.INSTANCE); - return this; + body.add(name, new JsonValue.Integer(id.toString().toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), TypeMatcher.INSTANCE); + return this; } /** @@ -1018,7 +1022,7 @@ public PactDslJsonBody id(String name, Long id) { * @param name attribute name */ public PactDslJsonBody hexValue(String name) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new RandomHexadecimalGenerator(10)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new RandomHexadecimalGenerator(10)); return hexValue(name, "1234a"); } @@ -1028,12 +1032,12 @@ public PactDslJsonBody hexValue(String name) { * @param hexValue example value to use for generated bodies */ public PactDslJsonBody hexValue(String name, String hexValue) { - if (!hexValue.matches(HEXADECIMAL)) { - throw new InvalidMatcherException(EXAMPLE + hexValue + "\" is not a hexadecimal value"); - } - body.put(name, hexValue); - matchers.addRule(matcherKey(name, rootPath), regexp("[0-9a-fA-F]+")); - return this; + if (!hexValue.matches(HEXADECIMAL)) { + throw new InvalidMatcherException(EXAMPLE + hexValue + "\" is not a hexadecimal value"); + } + body.add(name, new JsonValue.StringValue(hexValue.toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), regexp("[0-9a-fA-F]+")); + return this; } /** @@ -1041,7 +1045,7 @@ public PactDslJsonBody hexValue(String name, String hexValue) { * @param name attribute name */ public PactDslJsonBody uuid(String name) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), UuidGenerator.INSTANCE); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), UuidGenerator.INSTANCE); return uuid(name, "e2490de5-5bd3-43d5-b7c4-526e33f71304"); } @@ -1060,12 +1064,12 @@ public PactDslJsonBody uuid(String name, UUID uuid) { * @param uuid example UUID to use for generated bodies */ public PactDslJsonBody uuid(String name, String uuid) { - if (!uuid.matches(UUID_REGEX)) { - throw new InvalidMatcherException(EXAMPLE + uuid + "\" is not an UUID"); - } - body.put(name, uuid); - matchers.addRule(matcherKey(name, rootPath), regexp(UUID_REGEX)); - return this; + if (!uuid.matches(UUID_REGEX)) { + throw new InvalidMatcherException(EXAMPLE + uuid + "\" is not an UUID"); + } + body.add(name, new JsonValue.StringValue(uuid.toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), regexp(UUID_REGEX)); + return this; } /** @@ -1073,8 +1077,8 @@ public PactDslJsonBody uuid(String name, String uuid) { * @param fieldName field name */ public PactDslJsonBody nullValue(String fieldName) { - body.put(fieldName, JSONObject.NULL); - return this; + body.add(fieldName, JsonValue.Null.INSTANCE); + return this; } @Override @@ -1089,8 +1093,8 @@ public PactDslJsonArray eachArrayLike() { @Override public PactDslJsonArray eachArrayLike(String name, int numberExamples) { - matchers.addRule(matcherKey(name, rootPath), TypeMatcher.INSTANCE); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), name, this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), TypeMatcher.INSTANCE); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), name, this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonArray("", "", parent); } @@ -1101,56 +1105,56 @@ public PactDslJsonArray eachArrayLike(int numberExamples) { } @Override - public PactDslJsonArray eachArrayWithMaxLike(String name, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(String name, int size) { return eachArrayWithMaxLike(name, 1, size); } @Override - public PactDslJsonArray eachArrayWithMaxLike(Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(int size) { throw new UnsupportedOperationException("use the eachArrayWithMaxLike(String name, Integer size) form"); } @Override - public PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, int size) { if (numberExamples > size) { throw new IllegalArgumentException(String.format("Number of example %d is more than the maximum size of %d", numberExamples, size)); } - matchers.addRule(matcherKey(name, rootPath), matchMax(size)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), name, this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), matchMax(size)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), name, this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonArray("", "", parent); } @Override - public PactDslJsonArray eachArrayWithMaxLike(int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(int numberExamples, int size) { throw new UnsupportedOperationException("use the eachArrayWithMaxLike(String name, int numberExamples, Integer size) form"); } @Override - public PactDslJsonArray eachArrayWithMinLike(String name, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(String name, int size) { return eachArrayWithMinLike(name, size, size); } @Override - public PactDslJsonArray eachArrayWithMinLike(Integer size) { + public PactDslJsonArray eachArrayWithMinLike(int size) { throw new UnsupportedOperationException("use the eachArrayWithMinLike(String name, Integer size) form"); } @Override - public PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, int size) { if (numberExamples < size) { throw new IllegalArgumentException(String.format("Number of example %d is less than the minimum size of %d", numberExamples, size)); } - matchers.addRule(matcherKey(name, rootPath), matchMin(size)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), name, this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), matchMin(size)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), name, this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonArray("", "", parent); } @Override - public PactDslJsonArray eachArrayWithMinLike(int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(int numberExamples, int size) { throw new UnsupportedOperationException("use the eachArrayWithMinLike(String name, int numberExamples, Integer size) form"); } @@ -1161,11 +1165,11 @@ public PactDslJsonArray eachArrayWithMinLike(int numberExamples, Integer size) { */ public PactDslJsonBody eachKeyMappedToAnArrayLike(String exampleKey) { if (FeatureToggles.isFeatureSet(Feature.UseMatchValuesMatcher)) { - matchers.addRule(rootPath.endsWith(".") ? rootPath.substring(0, rootPath.length() - 1) : rootPath, ValuesMatcher.INSTANCE); + getMatchers().addRule(getRootPath().endsWith(".") ? getRootPath().substring(0, getRootPath().length() - 1) : getRootPath(), ValuesMatcher.INSTANCE); } else { - matchers.addRule(rootPath + "*", TypeMatcher.INSTANCE); + getMatchers().addRule(getRootPath() + "*", TypeMatcher.INSTANCE); } - PactDslJsonArray parent = new PactDslJsonArray(rootPath + "*", exampleKey, this, true); + PactDslJsonArray parent = new PactDslJsonArray(getRootPath() + "*", exampleKey, this, true); return new PactDslJsonBody(".", "", parent); } @@ -1176,11 +1180,11 @@ public PactDslJsonBody eachKeyMappedToAnArrayLike(String exampleKey) { */ public PactDslJsonBody eachKeyLike(String exampleKey) { if (FeatureToggles.isFeatureSet(Feature.UseMatchValuesMatcher)) { - matchers.addRule(rootPath.endsWith(".") ? rootPath.substring(0, rootPath.length() - 1) : rootPath, ValuesMatcher.INSTANCE); + getMatchers().addRule(getRootPath().endsWith(".") ? getRootPath().substring(0, getRootPath().length() - 1) : getRootPath(), ValuesMatcher.INSTANCE); } else { - matchers.addRule(rootPath + "*", TypeMatcher.INSTANCE); + getMatchers().addRule(getRootPath() + "*", TypeMatcher.INSTANCE); } - return new PactDslJsonBody(rootPath + "*.", exampleKey, this); + return new PactDslJsonBody(getRootPath() + "*.", exampleKey, this); } /** @@ -1190,12 +1194,12 @@ public PactDslJsonBody eachKeyLike(String exampleKey) { * @param value Value to use for matching and generated bodies */ public PactDslJsonBody eachKeyLike(String exampleKey, PactDslJsonRootValue value) { - body.put(exampleKey, value.getBody()); + body.add(exampleKey, value.getBody()); if (FeatureToggles.isFeatureSet(Feature.UseMatchValuesMatcher)) { - matchers.addRule(rootPath.endsWith(".") ? rootPath.substring(0, rootPath.length() - 1) : rootPath, ValuesMatcher.INSTANCE); + getMatchers().addRule(getRootPath().endsWith(".") ? getRootPath().substring(0, getRootPath().length() - 1) : getRootPath(), ValuesMatcher.INSTANCE); } - for(String matcherName: value.matchers.getMatchingRules().keySet()) { - matchers.addRules(rootPath + "*" + matcherName, value.matchers.getMatchingRules().get(matcherName).getRules()); + for(String matcherName: value.getMatchers().getMatchingRules().keySet()) { + getMatchers().addRules(getRootPath() + "*" + matcherName, value.getMatchers().getMatchingRules().get(matcherName).getRules()); } return this; } @@ -1206,8 +1210,8 @@ public PactDslJsonBody eachKeyLike(String exampleKey, PactDslJsonRootValue value * @param value Value that must be included */ public PactDslJsonBody includesStr(String name, String value) { - body.put(name, value); - matchers.addRule(matcherKey(name, rootPath), includesMatcher(value)); + body.add(name, new JsonValue.StringValue(value.toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), includesMatcher(value)); return this; } @@ -1217,8 +1221,8 @@ public PactDslJsonBody includesStr(String name, String value) { * @param value Value that will be used for comparisons */ public PactDslJsonBody equalTo(String name, Object value) { - body.put(name, value); - matchers.addRule(matcherKey(name, rootPath), EqualsMatcher.INSTANCE); + body.add(name, Json.toJson(value)); + getMatchers().addRule(matcherKey(name, getRootPath()), EqualsMatcher.INSTANCE); return this; } @@ -1229,12 +1233,8 @@ public PactDslJsonBody equalTo(String name, Object value) { * @param rules Matching rules to apply */ public PactDslJsonBody and(String name, Object value, MatchingRule... rules) { - if (value != null) { - body.put(name, value); - } else { - body.put(name, JSONObject.NULL); - } - matchers.setRules(matcherKey(name, rootPath), new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.AND)); + body.add(name, Json.toJson(value)); + getMatchers().setRules(matcherKey(name, getRootPath()), new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.AND)); return this; } @@ -1245,12 +1245,8 @@ public PactDslJsonBody and(String name, Object value, MatchingRule... rules) { * @param rules Matching rules to apply */ public PactDslJsonBody or(String name, Object value, MatchingRule... rules) { - if (value != null) { - body.put(name, value); - } else { - body.put(name, JSONObject.NULL); - } - matchers.setRules(matcherKey(name, rootPath), new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.OR)); + body.add(name, Json.toJson(value)); + getMatchers().setRules(matcherKey(name, getRootPath()), new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.OR)); return this; } @@ -1260,49 +1256,75 @@ public PactDslJsonBody or(String name, Object value, MatchingRule... rules) { * @param basePath The base path for the URL (like "http://localhost:8080/") which will be excluded from the matching * @param pathFragments Series of path fragments to match on. These can be strings or regular expressions. */ + @Override public PactDslJsonBody matchUrl(String name, String basePath, Object... pathFragments) { UrlMatcherSupport urlMatcher = new UrlMatcherSupport(basePath, Arrays.asList(pathFragments)); - body.put(name, urlMatcher.getExampleValue()); - matchers.addRule(matcherKey(name, rootPath), regexp(urlMatcher.getRegexExpression())); + body.add(name, Json.toJson(urlMatcher.getExampleValue())); + getMatchers().addRule(matcherKey(name, getRootPath()), regexp(urlMatcher.getRegexExpression())); return this; } @Override - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize) { + public DslPart matchUrl(String basePath, Object... pathFragments) { + throw new UnsupportedOperationException( + "URL matcher without an attribute name is not supported for objects. " + + "Use matchUrl(String name, String basePath, Object... pathFragments)"); + } + + /** + * Matches a URL that is composed of a base path and a sequence of path expressions. Base path from the mock server + * will be used. + * @param name Attribute name + * @param pathFragments Series of path fragments to match on. These can be strings or regular expressions. + */ + @Override + public PactDslJsonBody matchUrl2(String name, Object... pathFragments) { + return matchUrl(name, null, pathFragments); + } + + @Override + public DslPart matchUrl2(Object... pathFragments) { + throw new UnsupportedOperationException( + "URL matcher without an attribute name is not supported for objects. " + + "Use matchUrl2(Object... pathFragments)"); + } + + @Override + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize) { return minMaxArrayLike(name, minSize, maxSize, minSize); } @Override - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, DslPart object) { + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, DslPart object) { validateMinAndMaxAndExamples(minSize, maxSize, minSize); - String base = matcherKey(name, rootPath); - matchers.addRule(base, matchMinMax(minSize, maxSize)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + String base = matcherKey(name, getRootPath()); + getMatchers().addRule(base, matchMinMax(minSize, maxSize)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); if (object instanceof PactDslJsonBody) { - parent.putObject(object); + parent.putObjectPrivate(object); } else if (object instanceof PactDslJsonArray) { - parent.putArray(object); + parent.putArrayPrivate(object); } return (PactDslJsonBody) parent.closeArray(); } @Override - public PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize) { + public PactDslJsonBody minMaxArrayLike(int minSize, int maxSize) { throw new UnsupportedOperationException("use the minMaxArrayLike(String name, Integer minSize, Integer maxSize) form"); } @Override - public PactDslJsonArray minMaxArrayLike(Integer minSize, Integer maxSize, DslPart object) { + public PactDslJsonArray minMaxArrayLike(int minSize, int maxSize, DslPart object) { throw new UnsupportedOperationException("use the minMaxArrayLike(String name, Integer minSize, Integer maxSize, DslPart object) form"); } @Override - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, int numberExamples) { + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, int numberExamples) { validateMinAndMaxAndExamples(minSize, maxSize, numberExamples); - matchers.addRule(matcherKey(name, rootPath), matchMinMax(minSize, maxSize)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), matchMinMax(minSize, maxSize)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonBody(".", "", parent); } @@ -1321,31 +1343,31 @@ private void validateMinAndMaxAndExamples(Integer minSize, Integer maxSize, int } @Override - public PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize, int numberExamples) { + public PactDslJsonBody minMaxArrayLike(int minSize, int maxSize, int numberExamples) { throw new UnsupportedOperationException("use the minMaxArrayLike(String name, Integer minSize, Integer maxSize, int numberExamples) form"); } @Override - public PactDslJsonArray eachArrayWithMinMaxLike(String name, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(String name, int minSize, int maxSize) { return eachArrayWithMinMaxLike(name, minSize, minSize, maxSize); } @Override - public PactDslJsonArray eachArrayWithMinMaxLike(Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(int minSize, int maxSize) { throw new UnsupportedOperationException("use the eachArrayWithMinMaxLike(String name, Integer minSize, Integer maxSize) form"); } @Override - public PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, int minSize, int maxSize) { validateMinAndMaxAndExamples(minSize, maxSize, numberExamples); - matchers.addRule(matcherKey(name, rootPath), matchMinMax(minSize, maxSize)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), name, this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), matchMinMax(minSize, maxSize)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), name, this, true); parent.setNumberExamples(numberExamples); return new PactDslJsonArray("", "", parent); } @Override - public PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, int minSize, int maxSize) { throw new UnsupportedOperationException("use the eachArrayWithMinMaxLike(String name, int numberExamples, Integer minSize, Integer maxSize) form"); } @@ -1358,13 +1380,13 @@ public PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, Integer minS * @param value Value to use to match each item * @param numberExamples number of examples to generate */ - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, PactDslJsonRootValue value, + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, PactDslJsonRootValue value, int numberExamples) { validateMinAndMaxAndExamples(minSize, maxSize, numberExamples); - matchers.addRule(matcherKey(name, rootPath), matchMinMax(minSize, maxSize)); - PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, rootPath), "", this, true); + getMatchers().addRule(matcherKey(name, getRootPath()), matchMinMax(minSize, maxSize)); + PactDslJsonArray parent = new PactDslJsonArray(matcherKey(name, getRootPath()), "", this, true); parent.setNumberExamples(numberExamples); - parent.putObject(value); + parent.putObjectPrivate(value); return (PactDslJsonBody) parent.closeArray(); } @@ -1375,9 +1397,9 @@ public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer max * @param example Example value to be used in the consumer test */ public PactDslJsonBody valueFromProviderState(String name, String expression, Object example) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new ProviderStateGenerator(expression, DataType.from(example))); - body.put(name, example); - matchers.addRule(matcherKey(name, rootPath), TypeMatcher.INSTANCE); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new ProviderStateGenerator(expression, DataType.from(example))); + body.add(name, Json.toJson(example)); + getMatchers().addRule(matcherKey(name, getRootPath()), TypeMatcher.INSTANCE); return this; } @@ -1397,10 +1419,10 @@ public PactDslJsonBody dateExpression(String name, String expression) { * @param format Date format to use */ public PactDslJsonBody dateExpression(String name, String expression, String format) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new DateGenerator(format, expression)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new DateGenerator(format, expression)); FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(name, instance.format(new Date(DATE_2000))); - matchers.addRule(matcherKey(name, rootPath), matchDate(format)); + body.add(name, new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchDate(format)); return this; } @@ -1420,10 +1442,10 @@ public PactDslJsonBody timeExpression(String name, String expression) { * @param format Time format to use */ public PactDslJsonBody timeExpression(String name, String expression, String format) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new TimeGenerator(format, expression)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new TimeGenerator(format, expression)); FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(name, instance.format(new Date(DATE_2000))); - matchers.addRule(matcherKey(name, rootPath), matchTime(format)); + body.add(name, new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchTime(format)); return this; } @@ -1443,10 +1465,10 @@ public PactDslJsonBody datetimeExpression(String name, String expression) { * @param format Datetime format to use */ public PactDslJsonBody datetimeExpression(String name, String expression, String format) { - generators.addGenerator(Category.BODY, matcherKey(name, rootPath), new DateTimeGenerator(format, expression)); + getGenerators().addGenerator(Category.BODY, matcherKey(name, getRootPath()), new DateTimeGenerator(format, expression)); FastDateFormat instance = FastDateFormat.getInstance(format); - body.put(name, instance.format(new Date(DATE_2000))); - matchers.addRule(matcherKey(name, rootPath), matchTimestamp(format)); + body.add(name, new JsonValue.StringValue(instance.format(new Date(DATE_2000)).toCharArray())); + getMatchers().addRule(matcherKey(name, getRootPath()), matchTimestamp(format)); return this; } } diff --git a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonRootValue.java b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonRootValue.java index 312901607d..be1a5748ad 100644 --- a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonRootValue.java +++ b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslJsonRootValue.java @@ -21,7 +21,9 @@ import au.com.dius.pact.core.model.matchingrules.TypeMatcher; import au.com.dius.pact.core.support.Json; import au.com.dius.pact.core.support.expressions.DataType; +import au.com.dius.pact.core.support.json.JsonValue; import com.mifmif.common.regex.Generex; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.FastDateFormat; import org.json.JSONObject; @@ -38,42 +40,24 @@ public class PactDslJsonRootValue extends DslPart { private static final String EXAMPLE = "Example \""; private Object value; - private boolean encodeJson = false; public PactDslJsonRootValue() { super("", ""); } @Override - protected void putObject(DslPart object) { + public void putObjectPrivate(DslPart object) { throw new UnsupportedOperationException(); } @Override - protected void putArray(DslPart object) { + public void putArrayPrivate(DslPart object) { throw new UnsupportedOperationException(); } @Override - public Object getBody() { - if (encodeJson) { - return Json.toJson(value).serialise(); - } - return value; - } - - /** - * If the value should be encoded to be safe as JSON - */ - public boolean isEncodeJson() { - return encodeJson; - } - - /** - * If the value should be encoded to be safe as JSON - */ - public void setEncodeJson(boolean encodeJson) { - this.encodeJson = encodeJson; + public JsonValue getBody() { + return Json.toJson(value); } /** @@ -156,7 +140,7 @@ public PactDslJsonArray eachLike(DslPart object) { */ @Override @Deprecated - public PactDslJsonBody minArrayLike(String name, Integer size) { + public PactDslJsonBody minArrayLike(String name, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -165,19 +149,19 @@ public PactDslJsonBody minArrayLike(String name, Integer size) { */ @Override @Deprecated - public PactDslJsonBody minArrayLike(Integer size) { + public PactDslJsonBody minArrayLike(int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override @Deprecated - public PactDslJsonBody minArrayLike(String name, Integer size, DslPart object) { + public PactDslJsonBody minArrayLike(String name, int size, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override @Deprecated - public PactDslJsonArray minArrayLike(Integer size, DslPart object) { + public PactDslJsonArray minArrayLike(int size, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -186,7 +170,7 @@ public PactDslJsonArray minArrayLike(Integer size, DslPart object) { */ @Override @Deprecated - public PactDslJsonBody minArrayLike(String name, Integer size, int numberExamples) { + public PactDslJsonBody minArrayLike(String name, int size, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -195,7 +179,7 @@ public PactDslJsonBody minArrayLike(String name, Integer size, int numberExample */ @Override @Deprecated - public PactDslJsonBody minArrayLike(Integer size, int numberExamples) { + public PactDslJsonBody minArrayLike(int size, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -204,7 +188,7 @@ public PactDslJsonBody minArrayLike(Integer size, int numberExamples) { */ @Override @Deprecated - public PactDslJsonBody maxArrayLike(String name, Integer size) { + public PactDslJsonBody maxArrayLike(String name, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -213,19 +197,19 @@ public PactDslJsonBody maxArrayLike(String name, Integer size) { */ @Override @Deprecated - public PactDslJsonBody maxArrayLike(Integer size) { + public PactDslJsonBody maxArrayLike(int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override @Deprecated - public PactDslJsonBody maxArrayLike(String name, Integer size, DslPart object) { + public PactDslJsonBody maxArrayLike(String name, int size, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override @Deprecated - public PactDslJsonArray maxArrayLike(Integer size, DslPart object) { + public PactDslJsonArray maxArrayLike(int size, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -234,7 +218,7 @@ public PactDslJsonArray maxArrayLike(Integer size, DslPart object) { */ @Override @Deprecated - public PactDslJsonBody maxArrayLike(String name, Integer size, int numberExamples) { + public PactDslJsonBody maxArrayLike(String name, int size, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -243,7 +227,7 @@ public PactDslJsonBody maxArrayLike(String name, Integer size, int numberExample */ @Override @Deprecated - public PactDslJsonBody maxArrayLike(Integer size, int numberExamples) { + public PactDslJsonBody maxArrayLike(int size, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -252,13 +236,13 @@ public PactDslJsonBody maxArrayLike(Integer size, int numberExamples) { */ @Override @Deprecated - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize) { + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override @Deprecated - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, DslPart object) { + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -267,13 +251,13 @@ public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer max */ @Override @Deprecated - public PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize) { + public PactDslJsonBody minMaxArrayLike(int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override @Deprecated - public PactDslJsonArray minMaxArrayLike(Integer minSize, Integer maxSize, DslPart object) { + public PactDslJsonArray minMaxArrayLike(int minSize, int maxSize, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -282,7 +266,7 @@ public PactDslJsonArray minMaxArrayLike(Integer minSize, Integer maxSize, DslPar */ @Override @Deprecated - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, int numberExamples) { + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -291,7 +275,7 @@ public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer max */ @Override @Deprecated - public PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize, int numberExamples) { + public PactDslJsonBody minMaxArrayLike(int minSize, int maxSize, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -334,7 +318,7 @@ public DslPart close() { */ public static PactDslJsonRootValue stringType() { PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new RandomStringGenerator(20)); + value.getGenerators().addGenerator(Category.BODY, "", new RandomStringGenerator(20)); value.setValue("string"); value.setMatcher(TypeMatcher.INSTANCE); return value; @@ -357,7 +341,7 @@ public static PactDslJsonRootValue stringType(String example) { */ public static PactDslJsonRootValue numberType() { PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new RandomIntGenerator(0, Integer.MAX_VALUE)); + value.getGenerators().addGenerator(Category.BODY, "", new RandomIntGenerator(0, Integer.MAX_VALUE)); value.setValue(100); value.setMatcher(TypeMatcher.INSTANCE); return value; @@ -379,7 +363,7 @@ public static PactDslJsonRootValue numberType(Number number) { */ public static PactDslJsonRootValue integerType() { PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new RandomIntGenerator(0, Integer.MAX_VALUE)); + value.getGenerators().addGenerator(Category.BODY, "", new RandomIntGenerator(0, Integer.MAX_VALUE)); value.setValue(100); value.setMatcher(new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER)); return value; @@ -400,7 +384,7 @@ public static PactDslJsonRootValue integerType(Long number) { * Value that must be an integer * @param number example integer value to use for generated bodies */ - public static PactDslJsonRootValue integerType(Integer number) { + public static PactDslJsonRootValue integerType(int number) { PactDslJsonRootValue value = new PactDslJsonRootValue(); value.setValue(number); value.setMatcher(new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER)); @@ -412,7 +396,7 @@ public static PactDslJsonRootValue integerType(Integer number) { */ public static PactDslJsonRootValue decimalType() { PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new RandomDecimalGenerator(10)); + value.getGenerators().addGenerator(Category.BODY, "", new RandomDecimalGenerator(10)); value.setValue(100); value.setMatcher(new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)); return value; @@ -482,7 +466,7 @@ public static PactDslJsonRootValue stringMatcher(String regex, String value) { @Deprecated public static PactDslJsonRootValue stringMatcher(String regex) { PactDslJsonRootValue rootValue = new PactDslJsonRootValue(); - rootValue.generators.addGenerator(Category.BODY, "", new RegexGenerator(regex)); + rootValue.getGenerators().addGenerator(Category.BODY, "", new RegexGenerator(regex)); rootValue.setValue(new Generex(regex).random()); rootValue.setMatcher(rootValue.regexp(regex)); return rootValue; @@ -501,7 +485,7 @@ public static PactDslJsonRootValue timestamp() { */ public static PactDslJsonRootValue timestamp(String format) { PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new DateTimeGenerator(format)); + value.getGenerators().addGenerator(Category.BODY, "", new DateTimeGenerator(format)); FastDateFormat instance = FastDateFormat.getInstance(format); value.setValue(instance.format(new Date(DATE_2000))); value.setMatcher(value.matchTimestamp(format)); @@ -535,7 +519,7 @@ public static PactDslJsonRootValue date() { public static PactDslJsonRootValue date(String format) { FastDateFormat instance = FastDateFormat.getInstance(format); PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new DateGenerator(format)); + value.getGenerators().addGenerator(Category.BODY, "", new DateGenerator(format)); value.setValue(instance.format(new Date(DATE_2000))); value.setMatcher(value.matchDate(format)); return value; @@ -568,7 +552,7 @@ public static PactDslJsonRootValue time() { public static PactDslJsonRootValue time(String format) { FastDateFormat instance = FastDateFormat.getInstance(format); PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new TimeGenerator(format)); + value.getGenerators().addGenerator(Category.BODY, "", new TimeGenerator(format)); value.setValue(instance.format(new Date(DATE_2000))); value.setMatcher(value.matchTime(format)); return value; @@ -617,7 +601,7 @@ public static PactDslJsonRootValue id(Long id) { */ public static PactDslJsonRootValue hexValue() { PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new RandomHexadecimalGenerator(10)); + value.getGenerators().addGenerator(Category.BODY, "", new RandomHexadecimalGenerator(10)); value.setValue("1234a"); value.setMatcher(value.regexp("[0-9a-fA-F]+")); return value; @@ -642,7 +626,7 @@ public static PactDslJsonRootValue hexValue(String hexValue) { */ public static PactDslJsonRootValue uuid() { PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", UuidGenerator.INSTANCE); + value.getGenerators().addGenerator(Category.BODY, "", UuidGenerator.INSTANCE); value.setValue("e2490de5-5bd3-43d5-b7c4-526e33f71304"); value.setMatcher(value.regexp(UUID_REGEX)); return value; @@ -676,7 +660,7 @@ public void setValue(Object value) { } public void setMatcher(MatchingRule matcher) { - matchers.addRule(matcher); + getMatchers().addRule(matcher); } /** @@ -702,7 +686,7 @@ public PactDslJsonArray eachArrayLike(int numberExamples) { */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMaxLike(String name, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(String name, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -711,7 +695,7 @@ public PactDslJsonArray eachArrayWithMaxLike(String name, Integer size) { */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMaxLike(Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -720,7 +704,7 @@ public PactDslJsonArray eachArrayWithMaxLike(Integer size) { */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -729,7 +713,7 @@ public PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, In */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMaxLike(int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(int numberExamples, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -738,7 +722,7 @@ public PactDslJsonArray eachArrayWithMaxLike(int numberExamples, Integer size) { */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMinLike(String name, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(String name, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -747,7 +731,7 @@ public PactDslJsonArray eachArrayWithMinLike(String name, Integer size) { */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMinLike(Integer size) { + public PactDslJsonArray eachArrayWithMinLike(int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -756,7 +740,7 @@ public PactDslJsonArray eachArrayWithMinLike(Integer size) { */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -765,7 +749,7 @@ public PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, In */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMinLike(int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(int numberExamples, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -774,7 +758,7 @@ public PactDslJsonArray eachArrayWithMinLike(int numberExamples, Integer size) { */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMinMaxLike(String name, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(String name, int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -783,7 +767,7 @@ public PactDslJsonArray eachArrayWithMinMaxLike(String name, Integer minSize, In */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMinMaxLike(Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -792,7 +776,7 @@ public PactDslJsonArray eachArrayWithMinMaxLike(Integer minSize, Integer maxSize */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -801,7 +785,7 @@ public PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, */ @Override @Deprecated - public PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -835,7 +819,7 @@ public static PactDslJsonRootValue and(Object example, MatchingRule... rules) { } else { value.setValue(JSONObject.NULL); } - value.matchers.setRules("", new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.AND)); + value.getMatchers().setRules("", new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.AND)); return value; } @@ -851,7 +835,7 @@ public static PactDslJsonRootValue or(Object example, MatchingRule... rules) { } else { value.setValue(JSONObject.NULL); } - value.matchers.setRules("", new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.OR)); + value.getMatchers().setRules("", new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.OR)); return value; } @@ -868,6 +852,30 @@ public PactDslJsonRootValue matchUrl(String basePath, Object... pathFragments) { return value; } + @Override + public DslPart matchUrl(String name, String basePath, Object... pathFragments) { + throw new UnsupportedOperationException( + "URL matcher with an attribute name is not supported. " + + "Use matchUrl(String basePath, Object... pathFragments)"); + } + + @Override + public PactDslJsonBody matchUrl2(String name, Object... pathFragments) { + throw new UnsupportedOperationException( + "URL matcher with an attribute name is not supported. " + + "Use matchUrl2(Object... pathFragments)"); + } + + /** + * Matches a URL that is composed of a base path and a sequence of path expressions. Base path from the mock server + * will be used. + * @param pathFragments Series of path fragments to match on. These can be strings or regular expressions. + */ + @Override + public DslPart matchUrl2(Object... pathFragments) { + return matchUrl(null, pathFragments); + } + /** * Adds a value that will have it's value injected from the provider state * @param expression Expression to be evaluated from the provider state @@ -875,7 +883,7 @@ public PactDslJsonRootValue matchUrl(String basePath, Object... pathFragments) { */ public static PactDslJsonRootValue valueFromProviderState(String expression, Object example) { PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new ProviderStateGenerator(expression, DataType.from(example))); + value.getGenerators().addGenerator(Category.BODY, "", new ProviderStateGenerator(expression, DataType.from(example))); value.setValue(example); value.setMatcher(TypeMatcher.INSTANCE); return value; @@ -897,7 +905,7 @@ public static PactDslJsonRootValue dateExpression(String expression) { public static PactDslJsonRootValue dateExpression(String expression, String format) { FastDateFormat instance = FastDateFormat.getInstance(format); PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new DateGenerator(format, expression)); + value.getGenerators().addGenerator(Category.BODY, "", new DateGenerator(format, expression)); value.setValue(instance.format(new Date(DATE_2000))); value.setMatcher(value.matchDate(format)); return value; @@ -919,7 +927,7 @@ public static PactDslJsonRootValue timeExpression(String expression) { public static PactDslJsonRootValue timeExpression(String expression, String format) { FastDateFormat instance = FastDateFormat.getInstance(format); PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new TimeGenerator(format, expression)); + value.getGenerators().addGenerator(Category.BODY, "", new TimeGenerator(format, expression)); value.setValue(instance.format(new Date(DATE_2000))); value.setMatcher(value.matchTime(format)); return value; @@ -941,10 +949,9 @@ public static PactDslJsonRootValue datetimeExpression(String expression) { public static PactDslJsonRootValue datetimeExpression(String expression, String format) { FastDateFormat instance = FastDateFormat.getInstance(format); PactDslJsonRootValue value = new PactDslJsonRootValue(); - value.generators.addGenerator(Category.BODY, "", new DateTimeGenerator(format, expression)); + value.getGenerators().addGenerator(Category.BODY, "", new DateTimeGenerator(format, expression)); value.setValue(instance.format(new Date(DATE_2000))); value.setMatcher(value.matchTimestamp(format)); return value; } - } diff --git a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRequestWithPath.java b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRequestWithPath.java index 8d277357e7..f68931bf4e 100644 --- a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRequestWithPath.java +++ b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRequestWithPath.java @@ -288,33 +288,29 @@ public PactDslRequestWithPath body(JSONObject body) { * @param body Built using the Pact body DSL */ public PactDslRequestWithPath body(DslPart body) { - DslPart parent = body.close(); + DslPart parent = body.close(); - if (parent instanceof PactDslJsonRootValue) { - ((PactDslJsonRootValue)parent).setEncodeJson(true); - } - - requestMatchers.addCategory(parent.getMatchers()); - requestGenerators.addGenerators(parent.generators); + requestMatchers.addCategory(parent.getMatchers()); + requestGenerators.addGenerators(parent.getGenerators()); - Charset charset = Charset.defaultCharset(); - String contentType = ContentType.APPLICATION_JSON.toString(); - if (isContentTypeHeaderNotSet()) { - requestHeaders.put(CONTENT_TYPE, Collections.singletonList(contentType)); - } else { - contentType = getContentTypeHeader(); - ContentType ct = ContentType.parse(contentType); - charset = ct.getCharset() != null ? ct.getCharset() : Charset.defaultCharset(); - } + Charset charset = Charset.defaultCharset(); + String contentType = ContentType.APPLICATION_JSON.toString(); + if (isContentTypeHeaderNotSet()) { + requestHeaders.put(CONTENT_TYPE, Collections.singletonList(contentType)); + } else { + contentType = getContentTypeHeader(); + ContentType ct = ContentType.parse(contentType); + charset = ct.getCharset() != null ? ct.getCharset() : Charset.defaultCharset(); + } - if (parent.getBody() != null) { - requestBody = OptionalBody.body(parent.getBody().toString().getBytes(charset), - new au.com.dius.pact.core.model.ContentType(contentType)); - } else { - requestBody = OptionalBody.nullBody(); - } + if (parent.getBody() != null) { + requestBody = OptionalBody.body(parent.getBody().serialise().getBytes(charset), + new au.com.dius.pact.core.model.ContentType(contentType)); + } else { + requestBody = OptionalBody.nullBody(); + } - return this; + return this; } /** diff --git a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRequestWithoutPath.java b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRequestWithoutPath.java index d38a76513e..bf4b3caddd 100644 --- a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRequestWithoutPath.java +++ b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRequestWithoutPath.java @@ -231,18 +231,27 @@ public PactDslRequestWithoutPath body(JSONObject body) { */ public PactDslRequestWithoutPath body(DslPart body) { DslPart parent = body.close(); - requestMatchers.addCategory(parent.matchers); - requestGenerators.addGenerators(parent.generators); + + requestMatchers.addCategory(parent.getMatchers()); + requestGenerators.addGenerators(parent.getGenerators()); + + Charset charset = Charset.defaultCharset(); + String contentType = ContentType.APPLICATION_JSON.toString(); if (isContentTypeHeaderNotSet()) { - requestHeaders.put(CONTENT_TYPE, Collections.singletonList(ContentType.APPLICATION_JSON.toString())); - requestBody = OptionalBody.body(parent.toString().getBytes()); + requestHeaders.put(CONTENT_TYPE, Collections.singletonList(contentType)); } else { - String contentType = getContentTypeHeader(); + contentType = getContentTypeHeader(); ContentType ct = ContentType.parse(contentType); - Charset charset = ct.getCharset() != null ? ct.getCharset() : Charset.defaultCharset(); - requestBody = OptionalBody.body(parent.toString().getBytes(charset), + charset = ct.getCharset() != null ? ct.getCharset() : Charset.defaultCharset(); + } + + if (parent.getBody() != null) { + requestBody = OptionalBody.body(parent.getBody().serialise().getBytes(charset), new au.com.dius.pact.core.model.ContentType(contentType)); + } else { + requestBody = OptionalBody.nullBody(); } + return this; } diff --git a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslResponse.java b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslResponse.java index 790be13a78..c57d315957 100644 --- a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslResponse.java +++ b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslResponse.java @@ -229,12 +229,8 @@ public PactDslResponse body(JSONObject body) { public PactDslResponse body(DslPart body) { DslPart parent = body.close(); - if (parent instanceof PactDslJsonRootValue) { - ((PactDslJsonRootValue)parent).setEncodeJson(true); - } - responseMatchers.addCategory(parent.getMatchers()); - responseGenerators.addGenerators(parent.generators); + responseGenerators.addGenerators(parent.getGenerators()); Charset charset = Charset.defaultCharset(); String contentType = ContentType.APPLICATION_JSON.toString(); @@ -247,7 +243,7 @@ public PactDslResponse body(DslPart body) { } if (parent.getBody() != null) { - responseBody = OptionalBody.body(parent.getBody().toString().getBytes(charset), + responseBody = OptionalBody.body(parent.getBody().serialise().getBytes(charset), new au.com.dius.pact.core.model.ContentType(contentType)); } else { responseBody = OptionalBody.nullBody(); diff --git a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRootValue.java b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRootValue.java index 5fa01e30fb..a0dfbd06c1 100644 --- a/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRootValue.java +++ b/consumer/src/main/java/au/com/dius/pact/consumer/dsl/PactDslRootValue.java @@ -9,7 +9,6 @@ import au.com.dius.pact.core.model.generators.RandomHexadecimalGenerator; import au.com.dius.pact.core.model.generators.RandomIntGenerator; import au.com.dius.pact.core.model.generators.RandomStringGenerator; -import au.com.dius.pact.core.model.generators.RegexGenerator; import au.com.dius.pact.core.model.generators.TimeGenerator; import au.com.dius.pact.core.model.generators.UuidGenerator; import au.com.dius.pact.core.model.matchingrules.MatchingRule; @@ -17,8 +16,9 @@ import au.com.dius.pact.core.model.matchingrules.NumberTypeMatcher; import au.com.dius.pact.core.model.matchingrules.RuleLogic; import au.com.dius.pact.core.model.matchingrules.TypeMatcher; +import au.com.dius.pact.core.support.Json; import au.com.dius.pact.core.support.expressions.DataType; -import com.mifmif.common.regex.Generex; +import au.com.dius.pact.core.support.json.JsonValue; import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.FastDateFormat; import org.json.JSONObject; @@ -37,7 +37,7 @@ public class PactDslRootValue extends DslPart { private static final String USE_PACT_DSL_JSON_BODY_FOR_OBJECTS = "Use PactDslJsonBody for objects"; private static final String EXAMPLE = "Example \""; - private Object value; + private JsonValue value; private boolean encodeJson = false; public PactDslRootValue() { @@ -45,17 +45,17 @@ public PactDslRootValue() { } @Override - protected void putObject(DslPart object) { + public void putObjectPrivate(DslPart object) { throw new UnsupportedOperationException(); } @Override - protected void putArray(DslPart object) { + public void putArrayPrivate(DslPart object) { throw new UnsupportedOperationException(); } @Override - public Object getBody() { + public JsonValue getBody() { return value; } @@ -129,7 +129,7 @@ public PactDslJsonArray eachLike(DslPart object) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody minArrayLike(String name, Integer size) { + public PactDslJsonBody minArrayLike(String name, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -137,17 +137,17 @@ public PactDslJsonBody minArrayLike(String name, Integer size) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody minArrayLike(Integer size) { + public PactDslJsonBody minArrayLike(int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override - public PactDslJsonBody minArrayLike(String name, Integer size, DslPart object) { + public PactDslJsonBody minArrayLike(String name, int size, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override - public PactDslJsonArray minArrayLike(Integer size, DslPart object) { + public PactDslJsonArray minArrayLike(int size, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -155,7 +155,7 @@ public PactDslJsonArray minArrayLike(Integer size, DslPart object) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody minArrayLike(String name, Integer size, int numberExamples) { + public PactDslJsonBody minArrayLike(String name, int size, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -163,7 +163,7 @@ public PactDslJsonBody minArrayLike(String name, Integer size, int numberExample * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody minArrayLike(Integer size, int numberExamples) { + public PactDslJsonBody minArrayLike(int size, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -171,7 +171,7 @@ public PactDslJsonBody minArrayLike(Integer size, int numberExamples) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody maxArrayLike(String name, Integer size) { + public PactDslJsonBody maxArrayLike(String name, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -179,17 +179,17 @@ public PactDslJsonBody maxArrayLike(String name, Integer size) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody maxArrayLike(Integer size) { + public PactDslJsonBody maxArrayLike(int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override - public PactDslJsonBody maxArrayLike(String name, Integer size, DslPart object) { + public PactDslJsonBody maxArrayLike(String name, int size, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override - public PactDslJsonArray maxArrayLike(Integer size, DslPart object) { + public PactDslJsonArray maxArrayLike(int size, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -197,7 +197,7 @@ public PactDslJsonArray maxArrayLike(Integer size, DslPart object) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody maxArrayLike(String name, Integer size, int numberExamples) { + public PactDslJsonBody maxArrayLike(String name, int size, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -205,7 +205,7 @@ public PactDslJsonBody maxArrayLike(String name, Integer size, int numberExample * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody maxArrayLike(Integer size, int numberExamples) { + public PactDslJsonBody maxArrayLike(int size, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -213,12 +213,12 @@ public PactDslJsonBody maxArrayLike(Integer size, int numberExamples) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize) { + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, DslPart object) { + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, DslPart object) { return null; } @@ -226,12 +226,12 @@ public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer max * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize) { + public PactDslJsonBody minMaxArrayLike(int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @Override - public PactDslJsonArray minMaxArrayLike(Integer minSize, Integer maxSize, DslPart object) { + public PactDslJsonArray minMaxArrayLike(int minSize, int maxSize, DslPart object) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -239,7 +239,7 @@ public PactDslJsonArray minMaxArrayLike(Integer minSize, Integer maxSize, DslPar * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, int numberExamples) { + public PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -247,7 +247,7 @@ public PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer max * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize, int numberExamples) { + public PactDslJsonBody minMaxArrayLike(int minSize, int maxSize, int numberExamples) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -287,7 +287,7 @@ public DslPart close() { */ public static PactDslRootValue stringType() { PactDslRootValue value = new PactDslRootValue(); - value.generators.addGenerator(Category.BODY, "", new RandomStringGenerator(20)); + value.getGenerators().addGenerator(Category.BODY, "", new RandomStringGenerator(20)); value.setValue("string"); value.setMatcher(TypeMatcher.INSTANCE); return value; @@ -310,7 +310,7 @@ public static PactDslRootValue stringType(String example) { */ public static PactDslRootValue numberType() { PactDslRootValue value = new PactDslRootValue(); - value.generators.addGenerator(Category.BODY, "", new RandomIntGenerator(0, Integer.MAX_VALUE)); + value.getGenerators().addGenerator(Category.BODY, "", new RandomIntGenerator(0, Integer.MAX_VALUE)); value.setValue(100); value.setMatcher(TypeMatcher.INSTANCE); return value; @@ -332,7 +332,7 @@ public static PactDslRootValue numberType(Number number) { */ public static PactDslRootValue integerType() { PactDslRootValue value = new PactDslRootValue(); - value.generators.addGenerator(Category.BODY, "", new RandomIntGenerator(0, Integer.MAX_VALUE)); + value.getGenerators().addGenerator(Category.BODY, "", new RandomIntGenerator(0, Integer.MAX_VALUE)); value.setValue(100); value.setMatcher(new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER)); return value; @@ -353,7 +353,7 @@ public static PactDslRootValue integerType(Long number) { * Value that must be an integer * @param number example integer value to use for generated bodies */ - public static PactDslRootValue integerType(Integer number) { + public static PactDslRootValue integerType(int number) { PactDslRootValue value = new PactDslRootValue(); value.setValue(number); value.setMatcher(new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER)); @@ -365,7 +365,7 @@ public static PactDslRootValue integerType(Integer number) { */ public static PactDslRootValue decimalType() { PactDslRootValue value = new PactDslRootValue(); - value.generators.addGenerator(Category.BODY, "", new RandomDecimalGenerator(10)); + value.getGenerators().addGenerator(Category.BODY, "", new RandomDecimalGenerator(10)); value.setValue(100); value.setMatcher(new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)); return value; @@ -440,7 +440,7 @@ public static PactDslRootValue timestamp() { */ public static PactDslRootValue timestamp(String format) { PactDslRootValue value = new PactDslRootValue(); - value.generators.addGenerator(Category.BODY, "", new DateTimeGenerator(format)); + value.getGenerators().addGenerator(Category.BODY, "", new DateTimeGenerator(format)); FastDateFormat instance = FastDateFormat.getInstance(format); value.setValue(instance.format(new Date(DATE_2000))); value.setMatcher(value.matchTimestamp(format)); @@ -474,7 +474,7 @@ public static PactDslRootValue date() { public static PactDslRootValue date(String format) { FastDateFormat instance = FastDateFormat.getInstance(format); PactDslRootValue value = new PactDslRootValue(); - value.generators.addGenerator(Category.BODY, "", new DateGenerator(format)); + value.getGenerators().addGenerator(Category.BODY, "", new DateGenerator(format)); value.setValue(instance.format(new Date(DATE_2000))); value.setMatcher(value.matchDate(format)); return value; @@ -507,7 +507,7 @@ public static PactDslRootValue time() { public static PactDslRootValue time(String format) { FastDateFormat instance = FastDateFormat.getInstance(format); PactDslRootValue value = new PactDslRootValue(); - value.generators.addGenerator(Category.BODY, "", new TimeGenerator(format)); + value.getGenerators().addGenerator(Category.BODY, "", new TimeGenerator(format)); value.setValue(instance.format(new Date(DATE_2000))); value.setMatcher(value.matchTime(format)); return value; @@ -556,7 +556,7 @@ public static PactDslRootValue id(Long id) { */ public static PactDslRootValue hexValue() { PactDslRootValue value = new PactDslRootValue(); - value.generators.addGenerator(Category.BODY, "", new RandomHexadecimalGenerator(10)); + value.getGenerators().addGenerator(Category.BODY, "", new RandomHexadecimalGenerator(10)); value.setValue("1234a"); value.setMatcher(value.regexp("[0-9a-fA-F]+")); return value; @@ -581,7 +581,7 @@ public static PactDslRootValue hexValue(String hexValue) { */ public static PactDslRootValue uuid() { PactDslRootValue value = new PactDslRootValue(); - value.generators.addGenerator(Category.BODY, "", UuidGenerator.INSTANCE); + value.getGenerators().addGenerator(Category.BODY, "", UuidGenerator.INSTANCE); value.setValue("e2490de5-5bd3-43d5-b7c4-526e33f71304"); value.setMatcher(value.regexp(UUID_REGEX)); return value; @@ -611,11 +611,11 @@ public static PactDslRootValue uuid(String uuid) { } public void setValue(Object value) { - this.value = value; + this.value = Json.toJson(value); } public void setMatcher(MatchingRule matcher) { - matchers.addRule(matcher); + getMatchers().addRule(matcher); } /** @@ -638,7 +638,7 @@ public PactDslJsonArray eachArrayLike(int numberExamples) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMaxLike(String name, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(String name, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -646,7 +646,7 @@ public PactDslJsonArray eachArrayWithMaxLike(String name, Integer size) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMaxLike(Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -654,7 +654,7 @@ public PactDslJsonArray eachArrayWithMaxLike(Integer size) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -662,7 +662,7 @@ public PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, In * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMaxLike(int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMaxLike(int numberExamples, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -670,7 +670,7 @@ public PactDslJsonArray eachArrayWithMaxLike(int numberExamples, Integer size) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMinLike(String name, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(String name, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -678,7 +678,7 @@ public PactDslJsonArray eachArrayWithMinLike(String name, Integer size) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMinLike(Integer size) { + public PactDslJsonArray eachArrayWithMinLike(int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -686,7 +686,7 @@ public PactDslJsonArray eachArrayWithMinLike(Integer size) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -694,7 +694,7 @@ public PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, In * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMinLike(int numberExamples, Integer size) { + public PactDslJsonArray eachArrayWithMinLike(int numberExamples, int size) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -702,7 +702,7 @@ public PactDslJsonArray eachArrayWithMinLike(int numberExamples, Integer size) { * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMinMaxLike(String name, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(String name, int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -710,7 +710,7 @@ public PactDslJsonArray eachArrayWithMinMaxLike(String name, Integer minSize, In * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMinMaxLike(Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -718,7 +718,7 @@ public PactDslJsonArray eachArrayWithMinMaxLike(Integer minSize, Integer maxSize * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -726,7 +726,7 @@ public PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, * @deprecated Use PactDslJsonArray for arrays */ @Override - public PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, Integer minSize, Integer maxSize) { + public PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, int minSize, int maxSize) { throw new UnsupportedOperationException(USE_PACT_DSL_JSON_ARRAY_FOR_ARRAYS); } @@ -758,7 +758,7 @@ public static PactDslRootValue and(Object example, MatchingRule... rules) { } else { value.setValue(JSONObject.NULL); } - value.matchers.setRules("", new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.AND)); + value.getMatchers().setRules("", new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.AND)); return value; } @@ -774,7 +774,7 @@ public static PactDslRootValue or(Object example, MatchingRule... rules) { } else { value.setValue(JSONObject.NULL); } - value.matchers.setRules("", new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.OR)); + value.getMatchers().setRules("", new MatchingRuleGroup(Arrays.asList(rules), RuleLogic.OR)); return value; } @@ -785,9 +785,28 @@ public static PactDslRootValue or(Object example, MatchingRule... rules) { */ public static PactDslRootValue valueFromProviderState(String expression, Object example) { PactDslRootValue value = new PactDslRootValue(); - value.generators.addGenerator(Category.BODY, "", new ProviderStateGenerator(expression, DataType.from(example))); + value.getGenerators().addGenerator(Category.BODY, "", new ProviderStateGenerator(expression, DataType.from(example))); value.setValue(example); return value; } + @Override + public DslPart matchUrl(String name, String basePath, Object... pathFragments) { + throw new UnsupportedOperationException("matchUrl is not currently supported for PactDslRootValue"); + } + + @Override + public DslPart matchUrl(String basePath, Object... pathFragments) { + throw new UnsupportedOperationException("matchUrl is not currently supported for PactDslRootValue"); + } + + @Override + public DslPart matchUrl2(String name, Object... pathFragments) { + throw new UnsupportedOperationException("matchUrl2 is not currently supported for PactDslRootValue"); + } + + @Override + public DslPart matchUrl2(Object... pathFragments) { + throw new UnsupportedOperationException("matchUrl2 is not currently supported for PactDslRootValue"); + } } diff --git a/consumer/src/main/kotlin/au/com/dius/pact/consumer/MessagePactBuilder.kt b/consumer/src/main/kotlin/au/com/dius/pact/consumer/MessagePactBuilder.kt index ef24a58d28..f40c0fe223 100644 --- a/consumer/src/main/kotlin/au/com/dius/pact/consumer/MessagePactBuilder.kt +++ b/consumer/src/main/kotlin/au/com/dius/pact/consumer/MessagePactBuilder.kt @@ -157,7 +157,7 @@ class MessagePactBuilder @JvmOverloads constructor( metadata["contentType"] = contentTypeEntry.value } - val parent = body.close() + val parent = body.close()!! message.contents = OptionalBody.body(parent.toString().toByteArray(contentType.asCharset()), contentType) message.metaData = metadata message.matchingRules.addCategory(parent.matchers) diff --git a/consumer/src/main/kotlin/au/com/dius/pact/consumer/dsl/ArrayOfPrimitivesBuilder.kt b/consumer/src/main/kotlin/au/com/dius/pact/consumer/dsl/ArrayOfPrimitivesBuilder.kt index 1948f30a01..e972495411 100644 --- a/consumer/src/main/kotlin/au/com/dius/pact/consumer/dsl/ArrayOfPrimitivesBuilder.kt +++ b/consumer/src/main/kotlin/au/com/dius/pact/consumer/dsl/ArrayOfPrimitivesBuilder.kt @@ -86,18 +86,18 @@ class ArrayOfPrimitivesBuilder { val array = PactDslJsonArray("", "", null, true) array.numberExamples = this.examples if (this.minLength != null && this.maxLength != null) { - array.getMatchers().addRule("", MinMaxTypeMatcher(this.minLength!!, this.maxLength!!)) + array.matchers.addRule("", MinMaxTypeMatcher(this.minLength!!, this.maxLength!!)) } else if (this.minLength != null) { - array.getMatchers().addRule("", MinTypeMatcher(this.minLength!!)) + array.matchers.addRule("", MinTypeMatcher(this.minLength!!)) } else if (this.maxLength != null) { - array.getMatchers().addRule("", MaxTypeMatcher(this.maxLength!!)) + array.matchers.addRule("", MaxTypeMatcher(this.maxLength!!)) } if (matcher != null) { - array.getMatchers().addRule("[*]", matcher!!) + array.matchers.addRule("[*]", matcher!!) } if (generator != null) { - array.getGenerators().addGenerator(Category.BODY, "[*]", generator!!) + array.generators.addGenerator(Category.BODY, "[*]", generator!!) } for (i in 0 until this.examples) { (array.body as JSONArray).put(this.value) diff --git a/consumer/src/main/kotlin/au/com/dius/pact/consumer/dsl/DslPart.kt b/consumer/src/main/kotlin/au/com/dius/pact/consumer/dsl/DslPart.kt new file mode 100644 index 0000000000..aa310887eb --- /dev/null +++ b/consumer/src/main/kotlin/au/com/dius/pact/consumer/dsl/DslPart.kt @@ -0,0 +1,460 @@ +package au.com.dius.pact.consumer.dsl + +import au.com.dius.pact.core.model.generators.Generators +import au.com.dius.pact.core.model.matchingrules.Category +import au.com.dius.pact.core.model.matchingrules.DateMatcher +import au.com.dius.pact.core.model.matchingrules.IncludeMatcher +import au.com.dius.pact.core.model.matchingrules.MaxTypeMatcher +import au.com.dius.pact.core.model.matchingrules.MinMaxTypeMatcher +import au.com.dius.pact.core.model.matchingrules.MinTypeMatcher +import au.com.dius.pact.core.model.matchingrules.RegexMatcher +import au.com.dius.pact.core.model.matchingrules.TimeMatcher +import au.com.dius.pact.core.model.matchingrules.TimestampMatcher +import au.com.dius.pact.core.support.json.JsonValue + +/** + * Abstract base class to support Object and Array JSON DSL builders + */ +@Suppress("TooManyFunctions") +abstract class DslPart { + /** + * Returns the parent of this part (object or array) + * @return parent, or null if it is the root + */ + val parent: DslPart? + val rootPath: String + val rootName: String + var matchers = Category("body") + var generators = Generators() + protected var closed = false + + constructor(parent: DslPart?, rootPath: String, rootName: String) { + this.parent = parent + this.rootPath = rootPath + this.rootName = rootName + } + + constructor(rootPath: String, rootName: String) { + parent = null + this.rootPath = rootPath + this.rootName = rootName + } + + abstract fun putObjectPrivate(obj: DslPart) + abstract fun putArrayPrivate(obj: DslPart) + abstract val body: JsonValue + + /** + * Field which is an array + * @param name field name + */ + abstract fun array(name: String): PactDslJsonArray + + /** + * Element as an array + */ + abstract fun array(): PactDslJsonArray + + /** + * Close of the previous array element + */ + abstract fun closeArray(): DslPart + + /** + * Array field where each element must match the following object + * @param name field name + */ + abstract fun eachLike(name: String): PactDslJsonBody + + /** + * Array field where each element must match the following object + * @param name field name + */ + abstract fun eachLike(name: String, obj: DslPart): PactDslJsonBody + + /** + * Array element where each element of the array must match the following object + */ + abstract fun eachLike(): PactDslJsonBody + + /** + * Array element where each element of the array must match the provided object + */ + abstract fun eachLike(obj: DslPart): PactDslJsonArray + + /** + * Array field where each element must match the following object + * @param name field name + * @param numberExamples number of examples to generate + */ + abstract fun eachLike(name: String, numberExamples: Int): PactDslJsonBody + + /** + * Array element where each element of the array must match the following object + * @param numberExamples number of examples to generate + */ + abstract fun eachLike(numberExamples: Int): PactDslJsonBody + + /** + * Array field with a minimum size and each element must match the following object + * @param name field name + * @param size minimum size + */ + abstract fun minArrayLike(name: String, size: Int): PactDslJsonBody + + /** + * Array element with a minimum size and each element of the array must match the following object + * @param size minimum size + */ + abstract fun minArrayLike(size: Int): PactDslJsonBody + + /** + * Array field with a minimum size and each element must match the provided object + * @param name field name + * @param size minimum size + */ + abstract fun minArrayLike(name: String, size: Int, obj: DslPart): PactDslJsonBody + + /** + * Array element with a minumum size and each element of the array must match the provided object + * @param size minimum size + */ + abstract fun minArrayLike(size: Int, obj: DslPart): PactDslJsonArray + + /** + * Array field with a minumum size and each element must match the following object + * @param name field name + * @param size minimum size + * @param numberExamples number of examples to generate + */ + abstract fun minArrayLike(name: String, size: Int, numberExamples: Int): PactDslJsonBody + + /** + * Array element with a minimum size and each element of the array must match the following object + * @param size minimum size + * @param numberExamples number of examples to generate + */ + abstract fun minArrayLike(size: Int, numberExamples: Int): PactDslJsonBody + + /** + * Array field with a maximum size and each element must match the following object + * @param name field name + * @param size maximum size + */ + abstract fun maxArrayLike(name: String, size: Int): PactDslJsonBody + + /** + * Array element with a maximum size and each element of the array must match the following object + * @param size maximum size + */ + abstract fun maxArrayLike(size: Int): PactDslJsonBody + + /** + * Array field with a maximum size and each element must match the provided object + * @param name field name + * @param size maximum size + */ + abstract fun maxArrayLike(name: String, size: Int, obj: DslPart): PactDslJsonBody + + /** + * Array element with a maximum size and each element of the array must match the provided object + * @param size minimum size + */ + abstract fun maxArrayLike(size: Int, obj: DslPart): PactDslJsonArray + + /** + * Array field with a maximum size and each element must match the following object + * @param name field name + * @param size maximum size + * @param numberExamples number of examples to generate + */ + abstract fun maxArrayLike(name: String, size: Int, numberExamples: Int): PactDslJsonBody + + /** + * Array element with a maximum size and each element of the array must match the following object + * @param size maximum size + * @param numberExamples number of examples to generate + */ + abstract fun maxArrayLike(size: Int, numberExamples: Int): PactDslJsonBody + + /** + * Array field with a minimum and maximum size and each element must match the following object + * @param name field name + * @param minSize minimum size + * @param maxSize maximum size + */ + abstract fun minMaxArrayLike(name: String, minSize: Int, maxSize: Int): PactDslJsonBody + + /** + * Array field with a minimum and maximum size and each element must match the provided object + * @param name field name + * @param minSize minimum size + * @param maxSize maximum size + */ + abstract fun minMaxArrayLike(name: String, minSize: Int, maxSize: Int, obj: DslPart): PactDslJsonBody + + /** + * Array element with a minimum and maximum size and each element of the array must match the following object + * @param minSize minimum size + * @param maxSize maximum size + */ + abstract fun minMaxArrayLike(minSize: Int, maxSize: Int): PactDslJsonBody + + /** + * Array element with a minimum and maximum size and each element of the array must match the provided object + * @param minSize minimum size + * @param maxSize maximum size + */ + abstract fun minMaxArrayLike(minSize: Int, maxSize: Int, obj: DslPart): PactDslJsonArray + + /** + * Array field with a minimum and maximum size and each element must match the following object + * @param name field name + * @param minSize minimum size + * @param maxSize maximum size + * @param numberExamples number of examples to generate + */ + abstract fun minMaxArrayLike(name: String, minSize: Int, maxSize: Int, numberExamples: Int): PactDslJsonBody + + /** + * Array element with a minimum and maximum size and each element of the array must match the following object + * @param minSize minimum size + * @param maxSize maximum size + * @param numberExamples number of examples to generate + */ + abstract fun minMaxArrayLike(minSize: Int, maxSize: Int, numberExamples: Int): PactDslJsonBody + + /** + * Array field where each element is an array and must match the following object + * @param name field name + */ + abstract fun eachArrayLike(name: String): PactDslJsonArray + + /** + * Array element where each element of the array is an array and must match the following object + */ + abstract fun eachArrayLike(): PactDslJsonArray + + /** + * Array field where each element is an array and must match the following object + * @param name field name + * @param numberExamples number of examples to generate + */ + abstract fun eachArrayLike(name: String, numberExamples: Int): PactDslJsonArray + + /** + * Array element where each element of the array is an array and must match the following object + * @param numberExamples number of examples to generate + */ + abstract fun eachArrayLike(numberExamples: Int): PactDslJsonArray + + /** + * Array field where each element is an array and must match the following object + * @param name field name + * @param size Maximum size of the outer array + */ + abstract fun eachArrayWithMaxLike(name: String, size: Int): PactDslJsonArray + + /** + * Array element where each element of the array is an array and must match the following object + * @param size Maximum size of the outer array + */ + abstract fun eachArrayWithMaxLike(size: Int): PactDslJsonArray + + /** + * Array field where each element is an array and must match the following object + * @param name field name + * @param numberExamples number of examples to generate + * @param size Maximum size of the outer array + */ + abstract fun eachArrayWithMaxLike(name: String, numberExamples: Int, size: Int): PactDslJsonArray + + /** + * Array element where each element of the array is an array and must match the following object + * @param numberExamples number of examples to generate + * @param size Maximum size of the outer array + */ + abstract fun eachArrayWithMaxLike(numberExamples: Int, size: Int): PactDslJsonArray + + /** + * Array field where each element is an array and must match the following object + * @param name field name + * @param size Minimum size of the outer array + */ + abstract fun eachArrayWithMinLike(name: String, size: Int): PactDslJsonArray + + /** + * Array element where each element of the array is an array and must match the following object + * @param size Minimum size of the outer array + */ + abstract fun eachArrayWithMinLike(size: Int): PactDslJsonArray + + /** + * Array field where each element is an array and must match the following object + * @param name field name + * @param numberExamples number of examples to generate + * @param size Minimum size of the outer array + */ + abstract fun eachArrayWithMinLike(name: String, numberExamples: Int, size: Int): PactDslJsonArray + + /** + * Array element where each element of the array is an array and must match the following object + * @param numberExamples number of examples to generate + * @param size Minimum size of the outer array + */ + abstract fun eachArrayWithMinLike(numberExamples: Int, size: Int): PactDslJsonArray + + /** + * Array field where each element is an array and must match the following object + * @param name field name + * @param minSize minimum size + * @param maxSize maximum size + */ + abstract fun eachArrayWithMinMaxLike(name: String, minSize: Int, maxSize: Int): PactDslJsonArray + + /** + * Array element where each element of the array is an array and must match the following object + * @param minSize minimum size + * @param maxSize maximum size + */ + abstract fun eachArrayWithMinMaxLike(minSize: Int, maxSize: Int): PactDslJsonArray + + /** + * Array field where each element is an array and must match the following object + * @param name field name + * @param numberExamples number of examples to generate + * @param minSize minimum size + * @param maxSize maximum size + */ + abstract fun eachArrayWithMinMaxLike(name: String, numberExamples: Int, minSize: Int, + maxSize: Int): PactDslJsonArray + + /** + * Array element where each element of the array is an array and must match the following object + * @param numberExamples number of examples to generate + * @param minSize minimum size + * @param maxSize maximum size + */ + abstract fun eachArrayWithMinMaxLike(numberExamples: Int, minSize: Int, maxSize: Int): PactDslJsonArray + + /** + * Object field + * @param name field name + */ + abstract fun `object`(name: String): PactDslJsonBody + + /** + * Object element + */ + abstract fun `object`(): PactDslJsonBody + + /** + * Close off the previous object + * @return + */ + abstract fun closeObject(): DslPart? + + protected fun regexp(regex: String): RegexMatcher { + return RegexMatcher(regex) + } + + protected fun matchTimestamp(format: String): TimestampMatcher { + return TimestampMatcher(format) + } + + protected fun matchDate(format: String): DateMatcher { + return DateMatcher(format) + } + + protected fun matchTime(format: String): TimeMatcher { + return TimeMatcher(format) + } + + protected fun matchMin(min: Int): MinTypeMatcher { + return MinTypeMatcher(min) + } + + protected fun matchMax(max: Int): MaxTypeMatcher { + return MaxTypeMatcher(max) + } + + protected fun matchMinMax(minSize: Int, maxSize: Int): MinMaxTypeMatcher { + return MinMaxTypeMatcher(minSize, maxSize) + } + + protected fun includesMatcher(value: Any): IncludeMatcher { + return IncludeMatcher(value.toString()) + } + + fun asBody(): PactDslJsonBody { + return this as PactDslJsonBody + } + + fun asArray(): PactDslJsonArray { + return this as PactDslJsonArray + } + + /** + * This closes off the object graph build from the DSL in case any close[Object|Array] methods have not been called. + * @return The root object of the object graph + */ + abstract fun close(): DslPart? + + /** + * Matches a URL that is composed of a base path and a sequence of path expressions + * @param name Attribute name + * @param basePath The base path for the URL (like "http://localhost:8080/") which will be excluded from the matching + * @param pathFragments Series of path fragments to match on. These can be strings or regular expressions. + */ + abstract fun matchUrl(name: String, basePath: String?, vararg pathFragments: Any): DslPart + + /** + * Matches a URL that is composed of a base path and a sequence of path expressions + * @param basePath The base path for the URL (like "http://localhost:8080/") which will be excluded from the matching + * @param pathFragments Series of path fragments to match on. These can be strings or regular expressions. + */ + abstract fun matchUrl(basePath: String?, vararg pathFragments: Any): DslPart + + /** + * Matches a URL that is composed of a base path and a sequence of path expressions. Base path from the mock server + * will be used. + * @param name Attribute name + * @param pathFragments Series of path fragments to match on. These can be strings or regular expressions. + */ + abstract fun matchUrl2(name: String, vararg pathFragments: Any): DslPart + + /** + * Matches a URL that is composed of a base path and a sequence of path expressions. Base path from the mock server + * * will be used. + * @param pathFragments Series of path fragments to match on. These can be strings or regular expressions. + */ + abstract fun matchUrl2(vararg pathFragments: Any): DslPart + + companion object { + const val HEXADECIMAL = "[0-9a-fA-F]+" + const val IP_ADDRESS = "(\\d{1,3}\\.)+\\d{1,3}" + const val UUID_REGEX = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" + const val DATE_2000 = 949323600000L + + /** + * Returns a regular expression matcher + * @param regex Regex to match with + * @param example Example value to use + * @return + */ + @JvmStatic + fun regex(regex: String, example: String): RegexMatcher { + return RegexMatcher(regex, example) + } + + /** + * Returns a regular expression matcher. Will generate random examples from the regex. + * @param regex Regex to match with + * @return + */ + @JvmStatic + fun regex(regex: String): RegexMatcher { + return RegexMatcher(regex) + } + } +} diff --git a/consumer/src/test/groovy/au/com/dius/pact/consumer/PactDslJsonBodyMatcherSpec.groovy b/consumer/src/test/groovy/au/com/dius/pact/consumer/PactDslJsonBodyMatcherSpec.groovy index 69f3570f52..ceaaaeb477 100644 --- a/consumer/src/test/groovy/au/com/dius/pact/consumer/PactDslJsonBodyMatcherSpec.groovy +++ b/consumer/src/test/groovy/au/com/dius/pact/consumer/PactDslJsonBodyMatcherSpec.groovy @@ -188,8 +188,8 @@ class PactDslJsonBodyMatcherSpec extends Specification { def keys = ['type', 'features'] as Set then: - bodyJson == '{"features":[{"geometry":{"coordinates":[[-7.55717,49.766896]],"type":"Point"},"type":"Feature",' + - '"properties":{"prop0":"value0"}}],"type":"FeatureCollection"}' + bodyJson == '{"features":[{"geometry":{"coordinates":[[-7.55717,49.766896]],"type":"Point"},' + + '"properties":{"prop0":"value0"},"type":"Feature"}],"type":"FeatureCollection"}' result.size() == 2 result.keySet() == keys result.features[0].geometry.coordinates[0] == [-7.55717, 49.766896] @@ -205,7 +205,6 @@ class PactDslJsonBodyMatcherSpec extends Specification { '.features[*].geometry.coordinates[*][1]': new MatchingRuleGroup([ new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL)]) ] - } def 'each like generates the correct JSON for arrays of strings'() { diff --git a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/DslPartSpec.groovy b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/DslPartSpec.groovy index 30aa39b8d7..f9059c4b08 100644 --- a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/DslPartSpec.groovy +++ b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/DslPartSpec.groovy @@ -1,6 +1,7 @@ package au.com.dius.pact.consumer.dsl import au.com.dius.pact.core.model.PactSpecVersion +import au.com.dius.pact.core.support.json.JsonValue import spock.lang.Specification import spock.lang.Unroll @@ -10,12 +11,12 @@ class DslPartSpec extends Specification { private static final DslPart subject = new DslPart('', '') { @Override - protected void putObject(DslPart object) { } + void putObjectPrivate(DslPart object) { } @Override - protected void putArray(DslPart object) { } + void putArrayPrivate(DslPart object) { } - Object body = null + JsonValue.Object body = null @Override PactDslJsonArray array(String name) { null } @@ -49,48 +50,48 @@ class DslPartSpec extends Specification { PactDslJsonBody eachLike(int numberExamples) { null } @Override - PactDslJsonBody minArrayLike(String name, Integer size) { null } + PactDslJsonBody minArrayLike(String name, int size) { null } @Override - PactDslJsonBody minArrayLike(Integer size) { null } + PactDslJsonBody minArrayLike(int size) { null } @Override - PactDslJsonBody minArrayLike(String name, Integer size, DslPart object) { + PactDslJsonBody minArrayLike(String name, int size, DslPart object) { null } @Override - PactDslJsonArray minArrayLike(Integer size, DslPart object) { + PactDslJsonArray minArrayLike(int size, DslPart object) { null } @Override - PactDslJsonBody minArrayLike(String name, Integer size, int numberExamples) { null } + PactDslJsonBody minArrayLike(String name, int size, int numberExamples) { null } @Override - PactDslJsonBody minArrayLike(Integer size, int numberExamples) { null } + PactDslJsonBody minArrayLike(int size, int numberExamples) { null } @Override - PactDslJsonBody maxArrayLike(String name, Integer size) { null } + PactDslJsonBody maxArrayLike(String name, int size) { null } @Override - PactDslJsonBody maxArrayLike(Integer size) { null } + PactDslJsonBody maxArrayLike(int size) { null } @Override - PactDslJsonBody maxArrayLike(String name, Integer size, DslPart object) { + PactDslJsonBody maxArrayLike(String name, int size, DslPart object) { null } @Override - PactDslJsonArray maxArrayLike(Integer size, DslPart object) { + PactDslJsonArray maxArrayLike(int size, DslPart object) { null } @Override - PactDslJsonBody maxArrayLike(String name, Integer size, int numberExamples) { null } + PactDslJsonBody maxArrayLike(String name, int size, int numberExamples) { null } @Override - PactDslJsonBody maxArrayLike(Integer size, int numberExamples) { null } + PactDslJsonBody maxArrayLike(int size, int numberExamples) { null } @Override PactDslJsonArray eachArrayLike(String name) { null } @@ -105,28 +106,28 @@ class DslPartSpec extends Specification { PactDslJsonArray eachArrayLike(int numberExamples) { null } @Override - PactDslJsonArray eachArrayWithMaxLike(String name, Integer size) { null } + PactDslJsonArray eachArrayWithMaxLike(String name, int size) { null } @Override - PactDslJsonArray eachArrayWithMaxLike(Integer size) { null } + PactDslJsonArray eachArrayWithMaxLike(int size) { null } @Override - PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, Integer size) { null } + PactDslJsonArray eachArrayWithMaxLike(String name, int numberExamples, int size) { null } @Override - PactDslJsonArray eachArrayWithMaxLike(int numberExamples, Integer size) { null } + PactDslJsonArray eachArrayWithMaxLike(int numberExamples, int size) { null } @Override - PactDslJsonArray eachArrayWithMinLike(String name, Integer size) { null } + PactDslJsonArray eachArrayWithMinLike(String name, int size) { null } @Override - PactDslJsonArray eachArrayWithMinLike(Integer size) { null } + PactDslJsonArray eachArrayWithMinLike(int size) { null } @Override - PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, Integer size) { null } + PactDslJsonArray eachArrayWithMinLike(String name, int numberExamples, int size) { null } @Override - PactDslJsonArray eachArrayWithMinLike(int numberExamples, Integer size) { null } + PactDslJsonArray eachArrayWithMinLike(int numberExamples, int size) { null } @Override PactDslJsonBody object(String name) { null } @@ -141,52 +142,72 @@ class DslPartSpec extends Specification { DslPart close() { null } @Override - PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize) { + PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize) { null } @Override - PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, DslPart object) { + PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, DslPart object) { null } @Override - PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize) { + PactDslJsonBody minMaxArrayLike(int minSize, int maxSize) { null } @Override - PactDslJsonArray minMaxArrayLike(Integer minSize, Integer maxSize, DslPart object) { + PactDslJsonArray minMaxArrayLike(int minSize, int maxSize, DslPart object) { null } @Override - PactDslJsonBody minMaxArrayLike(String name, Integer minSize, Integer maxSize, int numberExamples) { + PactDslJsonBody minMaxArrayLike(String name, int minSize, int maxSize, int numberExamples) { null } @Override - PactDslJsonBody minMaxArrayLike(Integer minSize, Integer maxSize, int numberExamples) { + PactDslJsonBody minMaxArrayLike(int minSize, int maxSize, int numberExamples) { null } @Override - PactDslJsonArray eachArrayWithMinMaxLike(String name, Integer minSize, Integer maxSize) { + PactDslJsonArray eachArrayWithMinMaxLike(String name, int minSize, int maxSize) { null } @Override - PactDslJsonArray eachArrayWithMinMaxLike(Integer minSize, Integer maxSize) { + PactDslJsonArray eachArrayWithMinMaxLike(int minSize, int maxSize) { null } @Override - PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, Integer minSize, Integer maxSize) { + PactDslJsonArray eachArrayWithMinMaxLike(String name, int numberExamples, int minSize, int maxSize) { null } @Override - PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, Integer minSize, Integer maxSize) { + PactDslJsonArray eachArrayWithMinMaxLike(int numberExamples, int minSize, int maxSize) { + null + } + + @Override + DslPart matchUrl(String name, String basePath, Object... pathFragments) { + null + } + + @Override + DslPart matchUrl(String basePath, Object... pathFragments) { + null + } + + @Override + DslPart matchUrl2(String name, Object... pathFragments) { + null + } + + @Override + DslPart matchUrl2(Object... pathFragments) { null } } diff --git a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonArraySpec.groovy b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonArraySpec.groovy index e27c28f014..21008bddf6 100644 --- a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonArraySpec.groovy +++ b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonArraySpec.groovy @@ -26,7 +26,7 @@ class PactDslJsonArraySpec extends Specification { def 'min array like function should set the example size to the min size'() { expect: - obj.close().body.get(0).length() == 2 + obj.close().body.get(0).size() == 2 where: obj = new PactDslJsonArray().minArrayLike(2).id() diff --git a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonBodySpec.groovy b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonBodySpec.groovy index f91efd9e23..1892066465 100644 --- a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonBodySpec.groovy +++ b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonBodySpec.groovy @@ -33,7 +33,7 @@ class PactDslJsonBodySpec extends Specification { @Unroll def 'min array like function should set the example size to the min size'() { expect: - obj.close().body.getJSONArray('test').length() == 2 + obj.close().body.get('test').size() == 2 where: obj << [ @@ -317,8 +317,8 @@ class PactDslJsonBodySpec extends Specification { '$.contactDetails2.mobile.subscriberNumber': [type: 'RandomInt', min: 0, max: 2147483647] ] ] - pactDslJsonBody.toString() == '{"contactDetails2":{"mobile":{"countryCode":"64","prefix":"21","subscriberNumber":' + - '100}},"contactDetails":{"mobile":{"countryCode":"64","prefix":"21","subscriberNumber":100}}}' + pactDslJsonBody.toString() == '{"contactDetails":{"mobile":{"countryCode":"64","prefix":"21",' + + '"subscriberNumber":100}},"contactDetails2":{"mobile":{"countryCode":"64","prefix":"21","subscriberNumber":100}}}' } @Issue('#895') @@ -381,7 +381,7 @@ class PactDslJsonBodySpec extends Specification { .like('num', 100) expect: - body.body.toString() == '{"test":"Test","num":100}' + body.body.toString() == '{"num":100,"test":"Test"}' body.matchers.toMap(PactSpecVersion.V3) == [ '.test': [matchers: [[match: 'type']], combine: 'AND'], '.num': [matchers: [[match: 'type']], combine: 'AND'] @@ -396,7 +396,7 @@ class PactDslJsonBodySpec extends Specification { .booleanType('01/01/1900', true) expect: - body.body.toString() == '{"01/01/2001":"1234","01/01/1900":true}' + body.body.toString() == '{"01/01/1900":true,"01/01/2001":"1234"}' body.matchers.toMap(PactSpecVersion.V2) == [ '$.body[\'01/01/2001\']': [match: 'type'], '$.body[\'01/01/1900\']': [match: 'type'] diff --git a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonRootValueSpec.groovy b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonRootValueSpec.groovy index fbdfc949f8..bc805f58f0 100644 --- a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonRootValueSpec.groovy +++ b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslJsonRootValueSpec.groovy @@ -13,7 +13,7 @@ class PactDslJsonRootValueSpec extends Specification { @Unroll def 'correctly converts the value #value to JSON'() { expect: - value.with { it.setEncodeJson(true); it }.body as String == json + value.body.serialise() == json where: diff --git a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslRequestWithPathSpec.groovy b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslRequestWithPathSpec.groovy index 20886f6bb6..6215e60eac 100644 --- a/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslRequestWithPathSpec.groovy +++ b/consumer/src/test/groovy/au/com/dius/pact/consumer/dsl/PactDslRequestWithPathSpec.groovy @@ -100,10 +100,10 @@ class PactDslRequestWithPathSpec extends Specification { def response = pact.interactions[0].response then: - request.body.value == 'example'.bytes + request.body.value == '"example"'.bytes request.matchingRules.rulesForCategory('body').matchingRules['$'].rules*.class.simpleName == [ 'TypeMatcher'] - response.body.value == 'example'.bytes + response.body.value == '"example"'.bytes response.matchingRules.rulesForCategory('body').matchingRules['$'].rules*.class.simpleName == [ 'TypeMatcher'] diff --git a/consumer/src/test/java/au/com/dius/pact/consumer/PactDslJsonBodyTest.java b/consumer/src/test/java/au/com/dius/pact/consumer/PactDslJsonBodyTest.java index bc6fb0b767..e6675196f1 100644 --- a/consumer/src/test/java/au/com/dius/pact/consumer/PactDslJsonBodyTest.java +++ b/consumer/src/test/java/au/com/dius/pact/consumer/PactDslJsonBodyTest.java @@ -2,303 +2,263 @@ import au.com.dius.pact.consumer.dsl.DslPart; import au.com.dius.pact.consumer.dsl.PactDslJsonBody; - -import java.util.Collections; -import java.util.Date; -import java.util.TimeZone; - import au.com.dius.pact.consumer.dsl.PactDslJsonRootValue; -import au.com.dius.pact.core.support.json.JsonParser; import au.com.dius.pact.core.support.json.JsonValue; -import org.json.JSONArray; -import org.json.JSONObject; import org.junit.Test; import java.util.Arrays; +import java.util.Collections; +import java.util.Date; import java.util.HashSet; import java.util.Set; +import java.util.TimeZone; import static org.cthul.matchers.CthulMatchers.matchesPattern; +import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsEqual.equalTo; public class PactDslJsonBodyTest { - private static final String NUMBERS = "numbers"; - private static final String K_DEPRECIATION_BIPS = "10k-depreciation-bips"; - private static final String FIRST = "first"; - private static final String LEVEL_1 = "level1"; - private static final String L_1_EXAMPLE = "l1example"; - private static final String SECOND = "second"; - private static final String LEVEL_2 = "level2"; - private static final String L_2_EXAMPLE = "l2example"; - private static final String THIRD = "@third"; - - @Test - public void noSpecialHandlingForObjectNames() { - DslPart body = new PactDslJsonBody() - .id() - .object("2") - .id() - .stringValue("test", "A Test String") - .closeObject() - .array(NUMBERS) - .id() - .number(100) - .numberValue(101) - .hexValue() - .object() - .id() - .stringValue("name", "Rogger the Dogger") - .timestamp() - .date("dob", "MM/dd/yyyy") - .object(K_DEPRECIATION_BIPS) - .id() - .closeObject() - .closeObject() - .closeArray(); - - Set expectedMatchers = new HashSet(Arrays.asList( - ".id", - ".2.id", - ".numbers[3]", - ".numbers[0]", - ".numbers[4].timestamp", - ".numbers[4].dob", - ".numbers[4].id", - ".numbers[4].10k-depreciation-bips.id" - )); - assertThat(body.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers))); - - assertThat(((JSONObject) body.getBody()).keySet(), is(equalTo((Set) - new HashSet(Arrays.asList("2", NUMBERS, "id"))))); - } - - @Test - public void matcherPathTest() { - DslPart body = new PactDslJsonBody() - .id("1") - .stringType("@field") - .hexValue("200", "abc") - .integerType(K_DEPRECIATION_BIPS); - - Set expectedMatchers = new HashSet(Arrays.asList( - ".200", ".1", ".@field", ".10k-depreciation-bips" - )); - assertThat(body.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers))); - - assertThat(((JSONObject) body.getBody()).keySet(), is(equalTo((Set) - new HashSet(Arrays.asList("200", K_DEPRECIATION_BIPS, "1", "@field"))))); - } - - @Test - public void eachLikeMatcherTest() { - DslPart body = new PactDslJsonBody() - .eachLike("ids") - .id() - .closeObject() - .closeArray(); - - DslPart idsBody = new PactDslJsonBody().id(); - DslPart body2 = new PactDslJsonBody() - .eachLike("ids", idsBody); - - Set expectedMatchers = new HashSet(Arrays.asList( - ".ids", - ".ids[*].id" - )); - assertThat(body.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers))); - assertThat(body2.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers))); - - Set ids = new HashSet<>(Collections.singletonList("ids")); - assertThat(((JSONObject) body.getBody()).keySet(), is(equalTo(ids))); - assertThat(((JSONObject) body2.getBody()).keySet(), is(equalTo(ids))); - assertThat(body.getBody().toString(), is(equalTo(body2.getBody().toString()))); - } - - @Test - public void nestedObjectMatcherTest() { - DslPart body = new PactDslJsonBody() - .object(FIRST) - .stringType(LEVEL_1, L_1_EXAMPLE) - .stringType("@level1") - .object(SECOND) - .stringType(LEVEL_2, L_2_EXAMPLE) - .object(THIRD) - .stringType("level3", "l3example") - .object("fourth") - .stringType("level4", "l4example") - .closeObject() - .closeObject() - .closeObject() - .closeObject(); - - Set expectedMatchers = new HashSet<>(Arrays.asList( - ".first.second.@third.fourth.level4", - ".first.second.@third.level3", - ".first.second.level2", - ".first.level1", - ".first.@level1" - )); - - assertThat(body.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers))); - - assertThat(((JSONObject)body.getBody()) - .getJSONObject(FIRST) - .getString(LEVEL_1), is(equalTo(L_1_EXAMPLE))); - - assertThat(((JSONObject)body.getBody()) - .getJSONObject(FIRST) - .getJSONObject(SECOND) - .getString(LEVEL_2), is(equalTo(L_2_EXAMPLE))); - - assertThat(((JSONObject)body.getBody()) - .getJSONObject(FIRST) - .getJSONObject(SECOND) - .getJSONObject(THIRD) - .getString("level3"), is(equalTo("l3example"))); - - assertThat(((JSONObject)body.getBody()) - .getJSONObject(FIRST) - .getJSONObject(SECOND) - .getJSONObject(THIRD) - .getJSONObject("fourth") - .getString("level4"), is(equalTo("l4example"))); - } - - @Test - public void nestedArrayMatcherTest() { - DslPart body = new PactDslJsonBody() - .array(FIRST) - .stringType(L_1_EXAMPLE) - .array() - .stringType(L_2_EXAMPLE) - .closeArray() - .closeArray(); - - Set expectedMatchers = new HashSet(Arrays.asList( - ".first[0]", - ".first[1][0]" - )); - - assertThat(body.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers))); - - assertThat(((JSONObject)body.getBody()) - .getJSONArray(FIRST) - .getString(0), is(equalTo(L_1_EXAMPLE))); + private static final String NUMBERS = "numbers"; + private static final String K_DEPRECIATION_BIPS = "10k-depreciation-bips"; + private static final String FIRST = "first"; + private static final String LEVEL_1 = "level1"; + private static final String L_1_EXAMPLE = "l1example"; + private static final String SECOND = "second"; + private static final String LEVEL_2 = "level2"; + private static final String L_2_EXAMPLE = "l2example"; + private static final String THIRD = "@third"; - assertThat(((JSONObject)body.getBody()) - .getJSONArray(FIRST) - .getJSONArray(1) - .getString(0), is(equalTo(L_2_EXAMPLE))); - } - - @Test - public void nestedArrayAndObjectMatcherTest() { - DslPart body = new PactDslJsonBody() - .object(FIRST) - .stringType(LEVEL_1, L_1_EXAMPLE) - .array(SECOND) - .stringType("al2example") - .object() - .stringType(LEVEL_2, L_2_EXAMPLE) - .array("third") - .stringType("al3example") - .closeArray() - .closeObject() - .closeArray() - .closeObject(); - - Set expectedMatchers = new HashSet(Arrays.asList( - ".first.level1", - ".first.second[1].level2", - ".first.second[0]", - ".first.second[1].third[0]" - )); - - assertThat(body.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers))); - - assertThat(((JSONObject)body.getBody()) - .getJSONObject(FIRST) - .getString(LEVEL_1), is(equalTo(L_1_EXAMPLE))); - - assertThat(((JSONObject)body.getBody()) - .getJSONObject(FIRST) - .getJSONArray(SECOND) - .getString(0), is(equalTo("al2example"))); + @Test + public void noSpecialHandlingForObjectNames() { + DslPart body = new PactDslJsonBody() + .id() + .object("2") + .id() + .stringValue("test", "A Test String") + .closeObject() + .array(NUMBERS) + .id() + .number(100) + .numberValue(101) + .hexValue() + .object() + .id() + .stringValue("name", "Rogger the Dogger") + .timestamp() + .date("dob", "MM/dd/yyyy") + .object(K_DEPRECIATION_BIPS) + .id() + .closeObject() + .closeObject() + .closeArray(); + + Set expectedMatchers = new HashSet(Arrays.asList( + ".id", + ".2.id", + ".numbers[3]", + ".numbers[0]", + ".numbers[4].timestamp", + ".numbers[4].dob", + ".numbers[4].id", + ".numbers[4].10k-depreciation-bips.id" + )); + assertThat(body.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers))); + + assertThat(body.getBody().asObject().keys(), is(equalTo(new HashSet(Arrays.asList("2", NUMBERS, "id"))))); + } - assertThat(((JSONObject)body.getBody()) - .getJSONObject(FIRST) - .getJSONArray(SECOND) - .getJSONObject(1) - .getString(LEVEL_2), is(equalTo(L_2_EXAMPLE))); + @Test + public void matcherPathTest() { + DslPart body = new PactDslJsonBody() + .id("1") + .stringType("@field") + .hexValue("200", "abc") + .integerType(K_DEPRECIATION_BIPS); + + Set expectedMatchers = new HashSet(Arrays.asList( + ".200", ".1", ".@field", ".10k-depreciation-bips" + )); + assertThat(body.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers))); + + assertThat(body.getBody().asObject().keys(), + is(equalTo(new HashSet(Arrays.asList("200", K_DEPRECIATION_BIPS, "1", "@field"))))); + } - assertThat(((JSONObject)body.getBody()) - .getJSONObject(FIRST) - .getJSONArray(SECOND) - .getJSONObject(1) - .getJSONArray("third") - .getString(0), is(equalTo("al3example"))); + @Test + public void eachLikeMatcherTest() { + DslPart body = new PactDslJsonBody() + .eachLike("ids") + .id() + .closeObject() + .closeArray(); + + DslPart idsBody = new PactDslJsonBody().id(); + DslPart body2 = new PactDslJsonBody() + .eachLike("ids", idsBody);Set expectedMatchers = new HashSet(Arrays.asList( + ".ids", + ".ids[*].id" + )); + assertThat(body.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers)));assertThat(body2.getMatchers().getMatchingRules().keySet(), is(equalTo(expectedMatchers))); + + Set ids = new HashSet<>(Collections.singletonList("ids")); + assertThat(body.getBody().asObject().keys(), is(equalTo(ids))); + assertThat(body2.getBody().asObject().keys(), is(equalTo(ids))); + assertThat(body.getBody().toString(), is(equalTo(body2.getBody().toString()))); + } - } + @Test + public void nestedObjectMatcherTest() { + DslPart body = new PactDslJsonBody() + .object(FIRST) + .stringType(LEVEL_1, L_1_EXAMPLE) + .stringType("@level1") + .object(SECOND) + .stringType(LEVEL_2, L_2_EXAMPLE) + .object(THIRD) + .stringType("level3", "l3example") + .object("fourth") + .stringType("level4", "l4example") + .closeObject() + .closeObject() + .closeObject() + .closeObject(); + + Set expectedMatchers = new HashSet<>(Arrays.asList( + ".first.second.@third.fourth.level4", + ".first.second.@third.level3", + ".first.second.level2", + ".first.level1", + ".first.@level1" + )); + + assertThat(body.getMatchers().getMatchingRules().keySet(), + is(equalTo(expectedMatchers))); + assertThat(body.getBody().asObject().get(FIRST).get(LEVEL_1).asString(), + is(equalTo(L_1_EXAMPLE))); + assertThat(body.getBody().asObject().get(FIRST).get(SECOND).get(LEVEL_2).asString(), + is(equalTo(L_2_EXAMPLE))); + assertThat(body.getBody().asObject().get(FIRST).get(SECOND).get(THIRD).get("level3").asString(), + is(equalTo("l3example"))); + assertThat(body.getBody().asObject().get(FIRST).get(SECOND).get(THIRD).get("fourth").get("level4").asString(), + is(equalTo("l4example"))); + } - @Test - public void allowSettingFieldsToNull() { - DslPart body = new PactDslJsonBody() - .id() - .object("2") - .id() - .stringValue("test", null) - .nullValue("nullValue") - .closeObject() - .array(NUMBERS) - .id() - .nullValue() - .stringValue(null) - .closeArray(); + @Test + public void nestedArrayMatcherTest() { + DslPart body = new PactDslJsonBody() + .array(FIRST) + .stringType(L_1_EXAMPLE) + .array() + .stringType(L_2_EXAMPLE) + .closeArray() + .closeArray(); + + Set expectedMatchers = new HashSet(Arrays.asList( + ".first[0]", + ".first[1][0]" + )); + + assertThat(body.getMatchers().getMatchingRules().keySet(), + is(equalTo(expectedMatchers))); + assertThat(body.getBody().asObject().get(FIRST).get(0).asString(), + is(equalTo(L_1_EXAMPLE))); + assertThat(body.getBody().asObject().get(FIRST).get(1).get(0).asString(), + is(equalTo(L_2_EXAMPLE))); + } - JSONObject jsonObject = (JSONObject) body.getBody(); - assertThat(jsonObject.keySet(), is(equalTo((Set) new HashSet(Arrays.asList("2", NUMBERS, "id"))))); + @Test + public void nestedArrayAndObjectMatcherTest() { + DslPart body = new PactDslJsonBody() + .object(FIRST) + .stringType(LEVEL_1, L_1_EXAMPLE) + .array(SECOND) + .stringType("al2example") + .object() + .stringType(LEVEL_2, L_2_EXAMPLE) + .array("third") + .stringType("al3example") + .closeArray() + .closeObject() + .closeArray() + .closeObject(); + + Set expectedMatchers = new HashSet(Arrays.asList( + ".first.level1", + ".first.second[1].level2", + ".first.second[0]", + ".first.second[1].third[0]" + )); + + assertThat(body.getMatchers().getMatchingRules().keySet(), + is(equalTo(expectedMatchers))); + assertThat(body.getBody().asObject().get(FIRST).get(LEVEL_1).asString(), + is(equalTo(L_1_EXAMPLE))); + assertThat(body.getBody().asObject().get(FIRST).get(SECOND).get(0).asString(), + is(equalTo("al2example"))); + assertThat(body.getBody().asObject().get(FIRST).get(SECOND).get(1).get(LEVEL_2).asString(), + is(equalTo(L_2_EXAMPLE))); + assertThat(body.getBody().asObject().get(FIRST).get(SECOND).get(1).get("third").get(0).asString(), + is(equalTo("al3example"))); + } - assertThat(jsonObject.getJSONObject("2").get("test"), is(JSONObject.NULL)); - JSONArray numbers = jsonObject.getJSONArray(NUMBERS); - assertThat(numbers.length(), is(3)); - assertThat(numbers.get(0), is(notNullValue())); - assertThat(numbers.get(1), is(JSONObject.NULL)); - assertThat(numbers.get(2), is(JSONObject.NULL)); - } + @Test + public void allowSettingFieldsToNull() { + DslPart body = new PactDslJsonBody() + .id() + .object("2") + .id() + .stringValue("test", null) + .nullValue("nullValue") + .closeObject() + .array(NUMBERS) + .id() + .nullValue() + .stringValue(null) + .closeArray(); + + JsonValue.Object jsonObject = body.getBody().asObject(); + assertThat(jsonObject.keys(), is(equalTo(new HashSet(Arrays.asList("2", NUMBERS, "id"))))); + + assertThat(jsonObject.get("2").get("test"), is(JsonValue.Null.INSTANCE)); + JsonValue.Array numbers = jsonObject.get(NUMBERS).asArray(); + assertThat(numbers.size(), is(3)); + assertThat(numbers.get(0), is(not(JsonValue.Null.INSTANCE))); + assertThat(numbers.get(1), is(JsonValue.Null.INSTANCE)); + assertThat(numbers.get(2), is(JsonValue.Null.INSTANCE)); + } - @Test - public void testLargeDateFormat() { - String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss +HHMM 'GMT'"; - final PactDslJsonBody response = new PactDslJsonBody(); - response - .date("lastUpdate", DATE_FORMAT) - .date("creationDate", DATE_FORMAT); - JSONObject jsonObject = (JSONObject) response.getBody(); - assertThat(jsonObject.get("lastUpdate").toString(), matchesPattern("\\w{2,3}\\.?, \\d{2} \\w{3}\\.? \\d{4} \\d{2}:00:00 \\+\\d+ GMT")); - } + @Test + public void testLargeDateFormat() { + String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss +HHMM 'GMT'"; + final PactDslJsonBody response = new PactDslJsonBody(); + response + .date("lastUpdate", DATE_FORMAT) + .date("creationDate", DATE_FORMAT); + JsonValue.Object jsonObject = response.getBody().asObject(); + assertThat(jsonObject.get("lastUpdate").toString(), matchesPattern("\\w{2,3}\\.?, \\d{2} \\w{3}\\.? \\d{4} \\d{2}:00:00 \\+\\d+ GMT")); + } - @Test - public void testExampleTimestampTimezone() { - final PactDslJsonBody response = new PactDslJsonBody(); - response - .datetime("timestampLosAngeles", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", new Date(0), TimeZone.getTimeZone("America/Los_Angeles")) - .datetime("timestampBerlin", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", new Date(0), TimeZone.getTimeZone("Europe/Berlin")) - .date("dateLosAngeles", "yyyy-MM-dd", new Date(0), TimeZone.getTimeZone("America/Los_Angeles")) - .date("dateBerlin", "yyyy-MM-dd", new Date(0), TimeZone.getTimeZone("Europe/Berlin")) - .time("timeLosAngeles", "HH:mm:ss", new Date(0), TimeZone.getTimeZone("America/Los_Angeles")) - .time("timeBerlin", "HH:mm:ss", new Date(0), TimeZone.getTimeZone("Europe/Berlin")); - JSONObject jsonObject = (JSONObject) response.getBody(); - assertThat(jsonObject.get("timestampLosAngeles").toString(), is(equalTo("1969-12-31T16:00:00.000Z"))); - assertThat(jsonObject.get("timestampBerlin").toString(), is(equalTo("1970-01-01T01:00:00.000Z"))); - assertThat(jsonObject.get("dateLosAngeles").toString(), is(equalTo("1969-12-31"))); - assertThat(jsonObject.get("dateBerlin").toString(), is(equalTo("1970-01-01"))); - assertThat(jsonObject.get("timeLosAngeles").toString(), is(equalTo("16:00:00"))); - assertThat(jsonObject.get("timeBerlin").toString(), is(equalTo("01:00:00"))); - } + @Test + public void testExampleTimestampTimezone() { + final PactDslJsonBody response = new PactDslJsonBody(); + response + .datetime("timestampLosAngeles", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", new Date(0), TimeZone.getTimeZone("America/Los_Angeles")) + .datetime("timestampBerlin", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", new Date(0), TimeZone.getTimeZone("Europe/Berlin")) + .date("dateLosAngeles", "yyyy-MM-dd", new Date(0), TimeZone.getTimeZone("America/Los_Angeles")) + .date("dateBerlin", "yyyy-MM-dd", new Date(0), TimeZone.getTimeZone("Europe/Berlin")) + .time("timeLosAngeles", "HH:mm:ss", new Date(0), TimeZone.getTimeZone("America/Los_Angeles")) + .time("timeBerlin", "HH:mm:ss", new Date(0), TimeZone.getTimeZone("Europe/Berlin")); + JsonValue.Object jsonObject = response.getBody().asObject(); + assertThat(jsonObject.get("timestampLosAngeles").toString(), is(equalTo("1969-12-31T16:00:00.000Z"))); + assertThat(jsonObject.get("timestampBerlin").toString(), is(equalTo("1970-01-01T01:00:00.000Z"))); + assertThat(jsonObject.get("dateLosAngeles").toString(), is(equalTo("1969-12-31"))); + assertThat(jsonObject.get("dateBerlin").toString(), is(equalTo("1970-01-01"))); + assertThat(jsonObject.get("timeLosAngeles").toString(), is(equalTo("16:00:00"))); + assertThat(jsonObject.get("timeBerlin").toString(), is(equalTo("01:00:00"))); + } @Test public void largeBodyTest() { @@ -309,17 +269,17 @@ public void largeBodyTest() { .stringType("mainTitle", "Lorem ipsum dolor sit amet, consectetur adipiscing elit") .stringType("webTitle", "sample_data") .minArrayLike("attributes", 1) - .stringType("key", "sample_data") - .stringType("value", "sample_data") - .closeObject() + .stringType("key", "sample_data") + .stringType("value", "sample_data") + .closeObject() .closeArray().asBody(); PactDslJsonBody description = new PactDslJsonBody() .stringType("longDescription", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras. Nunc sed id semper risus in. Sit amet consectetur adipiscing elit pellentesque. Gravida neque convallis a cras. Auctor augue mauris augue neque gravida. Lectus quam id leo in vitae turpis massa sed elementum. Quisque sagittis purus sit amet volutpat consequat. Interdum velit euismod in pellentesque massa. Eu scelerisque felis imperdiet proin fermentum leo. Vel orci porta non pulvinar neque laoreet suspendisse. Netus et malesuada fames ac turpis egestas maecenas pharetra convallis. Sagittis aliquam malesuada bibendum arcu vitae. Risus in hendrerit gravida rutrum. Varius duis at consectetur lorem donec massa sapien. Platea dictumst quisque sagittis purus sit amet volutpat. Dui sapien eget mi proin sed libero enim. Tincidunt praesent semper feugiat nibh sed pulvinar. Sollicitudin tempor id eu nisl nunc mi. Hac habitasse platea dictumst vestibulum rhoncus.") .stringType("shortDescription", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tellus pellentesque eu tincidunt tortor aliquam nulla facilisi cras. Nunc sed id semper risus in. Sit amet consectetur adipiscing elit pellentesque. Gravida neque convallis a cras. Auctor augue mauris augue neque gravida. Lectus quam id leo in vitae turpis massa sed elementum. Quisque sagittis purus sit amet volutpat consequat. Interdum velit euismod in pellentesque massa. Eu scelerisque felis imperdiet proin fermentum leo. Vel orci porta non pulvinar neque laoreet suspendisse. Netus et malesuada fames ac turpis egestas maecenas pharetra convallis. Sagittis aliquam malesuada bibendum arcu vitae. Risus in hendrerit gravida rutrum. Varius duis at consectetur lorem donec massa sapien. Platea dictumst quisque sagittis purus sit amet volutpat. Dui sapien eget mi proin sed libero enim.") .minArrayLike("attributes", 1) - .stringType("key", "sample_data") - .stringType("value", "sample_data") - .closeObject() + .stringType("key", "sample_data") + .stringType("value", "sample_data") + .closeObject() .closeArray().asBody(); PactDslJsonBody productSpecification = new PactDslJsonBody().integerType("multiPackQuantity", 1) .booleanType("copyrightInd", false) @@ -376,240 +336,239 @@ public void largeBodyTest() { .object("metadata", metadata) .integerType("version", 1) .object("wrapper") - .stringType("w", "17f78aqr") - .minArrayLike("identifiers", 1) - .stringType("alias", "sku") - .minArrayLike("value", 1, PactDslJsonRootValue.stringType("7908284"), 1) - .closeArray().asBody() - .minArrayLike("aliases", 1, PactDslJsonRootValue.stringType("17f78aqr"), 1) + .stringType("w", "17f78aqr") + .minArrayLike("identifiers", 1) + .stringType("alias", "sku") + .minArrayLike("value", 1, PactDslJsonRootValue.stringType("7908284"), 1) + .closeArray().asBody() + .minArrayLike("aliases", 1, PactDslJsonRootValue.stringType("17f78aqr"), 1) .closeObject().asBody() .stringType("itemType", "ITEM") .object("parentWrapper") - .stringType("p", "xf7kabqd") - .minArrayLike("identifiers", 1) - .stringType("alias", "sku") - .minArrayLike("value", 1, PactDslJsonRootValue.stringType("135325620.P"), 1) - .closeArray().asBody() - .minArrayLike("aliases", 1, PactDslJsonRootValue.stringType("xf7kabqd"), 1) - .closeObject().asBody() - .object("master") - .stringType("source", "PDS") - .object("title", title) - .object("description", description) - .object("brand", brand) - .object("productSpecification", productSpecification) - .minArrayLike("attributes", 1) - .stringType("scope", "DESCRIPTIVE") - .stringType("key", "sample_data") - .minArrayLike("values", 1, PactDslJsonRootValue.stringType("sample_data"), 1) - .closeObject() - .closeArray().asBody() - .minArrayLike("colours", 1, colours) - .object("weightsAndMeasures") - .object("dimensions", dimensions) - .object("weight") - .decimalType("weight", 10.10) - .decimalType("netWeight", 10.10) - .decimalType("catchWeight", 10.10) - .decimalType("pileWeight", 10.10) - .stringType("uom", "KILOGRAM") - .closeObject().asBody() - .object("volume") - .decimalType("liquidVolume", 10.10) - .stringType("uom", "LITRE") - .closeObject().asBody() - .object("scannedData") - .datetimeExpression("fileTimestamp", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .decimalType("averageWeight", 10.10) - .stringType("averageWeightUom", "GRAM") - .object("shipmentCase", caseDimensions) - .object("vendorCase", caseDimensions) - .closeObject().asBody() - .closeObject().asBody() - .minArrayLike("packages", 1) - .integerType("packageType", 1) - .object("weightsAndMeasures") - .object("dimensions", dimensions) - .object("weight") - .decimalType("weight", 10.10) - .decimalType("netWeight", 10.10) - .decimalType("catchWeight", 10.10) - .decimalType("pileWeight", 10.10) - .stringType("uom", "KILOGRAM") - .closeObject().asBody() - .object("volume") - .decimalType("liquidVolume", 10.10) - .stringType("uom", "LITRE") - .closeObject().asBody() - .object("scannedData") - .datetimeExpression("fileTimestamp", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .decimalType("averageWeight", 10.10) - .stringType("averageWeightUom", "GRAM") - .object("shipmentCase", caseDimensions) - .object("vendorCase", caseDimensions) - .closeObject().asBody() - .closeObject().asBody() - .closeObject() - .closeArray().asBody() - .object("media") - .minArrayLike("images", 1, images) - .closeObject().asBody() - .object("safety") - .booleanType("ageRestrictedFlag", false) - .booleanType("safetyIndicator", false) - .booleanType("safetyIndicatorFlag", false) - .booleanType("safetyIndicatorOverrideFlag", false) - .closeObject().asBody() - .object("waste") - .stringType("wasteType", "sample_data") - .decimalType("percentage", 10.10) - .decimalType("defaultPercentage", 10.10) - .datetimeExpression("effectiveFromDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .datetimeExpression("effectiveToDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .minArrayLike("attributes", 1) - .stringType("key", "associatedProductNumber") - .stringType("value", "sample_data") - .closeObject() - .closeArray().asBody() - .closeObject().asBody() - .object("optionalTypes") - .object("jewellery") - .decimalType("totalWeight", 10.10) - .decimalType("metalWeight", 10.10) - .decimalType("stoneWeight", 10.10) - .decimalType("chainLength", 10.10) - .stringType("ringSize", "sample_data") - .stringType("ringSizeFrom", "sample_data") - .stringType("ringSizeTo", "sample_data") - .closeObject().asBody() - .object("clothing") - .stringType("size", "sample_data") - .closeObject().asBody() - .eachLike("batteries", 0) - .closeArray().asBody() - .closeObject().asBody() - .object("productDataAudit") - .datetimeExpression("createdDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .datetimeExpression("lastModifiedDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .stringType("lastModifiedBy", "argos-pim-backfeed-adapter-service") - .datetimeExpression("deletedDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .closeObject().asBody() - .closeObject().asBody() - .object("division") - .stringType("masterSource", "DIV") - .object("title", title) - .object("description", description) - .object("brand", brand) - .object("productSpecification", productSpecification) - .minArrayLike("attributes", 1) - .stringType("scope", "DESCRIPTIVE") - .stringType("key", "sample_data") - .minArrayLike("values", 1, PactDslJsonRootValue.stringType("sample_data"), 1) - .closeObject() - .closeArray().asBody() - .minArrayLike("colours", 1, colours) - .object("weightsAndMeasures") - .object("dimensions", dimensions) - .object("weight") - .decimalType("weight", 10.10) - .decimalType("netWeight", 10.10) - .decimalType("catchWeight", 10.10) - .decimalType("pileWeight", 10.10) - .stringType("uom", "KILOGRAM") - .closeObject().asBody() - .object("volume") - .decimalType("liquidVolume", 10.10) - .stringType("uom", "LITRE") - .closeObject().asBody() - .object("scannedData") - .datetimeExpression("fileTimestamp", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .decimalType("averageWeight", 10.10) - .stringType("averageWeightUom", "GRAM") - .object("shipmentCase", caseDimensions) - .object("vendorCase", caseDimensions) - .closeObject().asBody() - .closeObject().asBody() - .minArrayLike("packages", 1) - .integerType("packageType", 1) - .object("weightsAndMeasures") - .object("dimensions", dimensions) - .object("weight") - .decimalType("weight", 10.10) - .decimalType("netWeight", 10.10) - .decimalType("catchWeight", 10.10) - .decimalType("pileWeight", 10.10) - .stringType("uom", "KILOGRAM") - .closeObject().asBody() - .object("volume") - .decimalType("liquidVolume", 10.10) - .stringType("uom", "LITRE") - .closeObject().asBody() - .object("scannedData") - .datetimeExpression("fileTimestamp", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .decimalType("averageWeight", 10.10) - .stringType("averageWeightUom", "GRAM") - .object("shipmentCase", caseDimensions) - .object("vendorCase", caseDimensions) - .closeObject().asBody() - .closeObject().asBody() - .closeObject() - .closeArray().asBody() - .object("media") - .minArrayLike("images", 1, images) - .closeObject().asBody() - .object("safety") - .booleanType("ageRestrictedFlag", false) - .booleanType("safetyIndicator", false) - .booleanType("safetyIndicatorFlag", false) - .booleanType("safetyIndicatorOverrideFlag", false) - .closeObject().asBody() - .object("waste") - .stringType("wasteType", "sample_data") - .decimalType("percentage", 10.10) - .decimalType("defaultPercentage", 10.10) - .datetimeExpression("effectiveFromDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .datetimeExpression("effectiveToDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .minArrayLike("attributes", 1) - .stringType("key", "weeeAssociatedProductNumber") - .stringType("value", "sample_data") - .closeObject() - .closeArray().asBody() - .closeObject().asBody() - .object("optionalTypes") - .object("jewellery") - .decimalType("totalWeight", 10.10) - .decimalType("metalWeight", 10.10) - .decimalType("stoneWeight", 10.10) - .decimalType("chainLength", 10.10) - .stringType("ringSize", "sample_data") - .stringType("ringSizeFrom", "sample_data") - .stringType("ringSizeTo", "sample_data") - .closeObject().asBody() - .object("clothing") - .stringType("size", "sample_data") - .closeObject().asBody() - .eachLike("batteries", 0) - .closeArray().asBody() - .closeObject().asBody() - .object("productDataAudit") - .datetimeExpression("createdDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .datetimeExpression("lastModifiedDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .stringType("lastModifiedBy", "bam") - .datetimeExpression("deletedDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .closeObject().asBody() + .stringType("p", "xf7kabqd") + .minArrayLike("identifiers", 1) + .stringType("alias", "sku") + .minArrayLike("value", 1, PactDslJsonRootValue.stringType("135325620.P"), 1) + .closeArray().asBody() + .minArrayLike("aliases", 1, PactDslJsonRootValue.stringType("xf7kabqd"), 1) + .closeObject().asBody() + .object("master") + .stringType("source", "PDS") + .object("title", title) + .object("description", description) + .object("brand", brand) + .object("productSpecification", productSpecification) + .minArrayLike("attributes", 1) + .stringType("scope", "DESCRIPTIVE") + .stringType("key", "sample_data") + .minArrayLike("values", 1, PactDslJsonRootValue.stringType("sample_data"), 1) + .closeObject() + .closeArray().asBody() + .minArrayLike("colours", 1, colours) + .object("weightsAndMeasures") + .object("dimensions", dimensions) + .object("weight") + .decimalType("weight", 10.10) + .decimalType("netWeight", 10.10) + .decimalType("catchWeight", 10.10) + .decimalType("pileWeight", 10.10) + .stringType("uom", "KILOGRAM") + .closeObject().asBody() + .object("volume") + .decimalType("liquidVolume", 10.10) + .stringType("uom", "LITRE") + .closeObject().asBody() + .object("scannedData") + .datetimeExpression("fileTimestamp", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .decimalType("averageWeight", 10.10) + .stringType("averageWeightUom", "GRAM") + .object("shipmentCase", caseDimensions) + .object("vendorCase", caseDimensions) + .closeObject().asBody() + .closeObject().asBody() + .minArrayLike("packages", 1) + .integerType("packageType", 1) + .object("weightsAndMeasures") + .object("dimensions", dimensions) + .object("weight") + .decimalType("weight", 10.10) + .decimalType("netWeight", 10.10) + .decimalType("catchWeight", 10.10) + .decimalType("pileWeight", 10.10) + .stringType("uom", "KILOGRAM") + .closeObject().asBody() + .object("volume") + .decimalType("liquidVolume", 10.10) + .stringType("uom", "LITRE") + .closeObject().asBody() + .object("scannedData") + .datetimeExpression("fileTimestamp", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .decimalType("averageWeight", 10.10) + .stringType("averageWeightUom", "GRAM") + .object("shipmentCase", caseDimensions) + .object("vendorCase", caseDimensions) + .closeObject().asBody() + .closeObject().asBody() + .closeObject() + .closeArray().asBody() + .object("media") + .minArrayLike("images", 1, images) + .closeObject().asBody() + .object("safety") + .booleanType("ageRestrictedFlag", false) + .booleanType("safetyIndicator", false) + .booleanType("safetyIndicatorFlag", false) + .booleanType("safetyIndicatorOverrideFlag", false) + .closeObject().asBody() + .object("waste") + .stringType("wasteType", "sample_data") + .decimalType("percentage", 10.10) + .decimalType("defaultPercentage", 10.10) + .datetimeExpression("effectiveFromDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .datetimeExpression("effectiveToDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .minArrayLike("attributes", 1) + .stringType("key", "associatedProductNumber") + .stringType("value", "sample_data") + .closeObject() + .closeArray().asBody() + .closeObject().asBody() + .object("optionalTypes") + .object("jewellery") + .decimalType("totalWeight", 10.10) + .decimalType("metalWeight", 10.10) + .decimalType("stoneWeight", 10.10) + .decimalType("chainLength", 10.10) + .stringType("ringSize", "sample_data") + .stringType("ringSizeFrom", "sample_data") + .stringType("ringSizeTo", "sample_data") + .closeObject().asBody() + .object("clothing") + .stringType("size", "sample_data") + .closeObject().asBody() + .eachLike("batteries", 0) + .closeArray().asBody() + .closeObject().asBody() + .object("productDataAudit") + .datetimeExpression("createdDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .datetimeExpression("lastModifiedDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .stringType("lastModifiedBy", "argos-pim-backfeed-adapter-service") + .datetimeExpression("deletedDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .closeObject().asBody() + .closeObject().asBody() + .object("division") + .stringType("masterSource", "DIV") + .object("title", title) + .object("description", description) + .object("brand", brand) + .object("productSpecification", productSpecification) + .minArrayLike("attributes", 1) + .stringType("scope", "DESCRIPTIVE") + .stringType("key", "sample_data") + .minArrayLike("values", 1, PactDslJsonRootValue.stringType("sample_data"), 1) + .closeObject() + .closeArray().asBody() + .minArrayLike("colours", 1, colours) + .object("weightsAndMeasures") + .object("dimensions", dimensions) + .object("weight") + .decimalType("weight", 10.10) + .decimalType("netWeight", 10.10) + .decimalType("catchWeight", 10.10) + .decimalType("pileWeight", 10.10) + .stringType("uom", "KILOGRAM") + .closeObject().asBody() + .object("volume") + .decimalType("liquidVolume", 10.10) + .stringType("uom", "LITRE") + .closeObject().asBody() + .object("scannedData") + .datetimeExpression("fileTimestamp", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .decimalType("averageWeight", 10.10) + .stringType("averageWeightUom", "GRAM") + .object("shipmentCase", caseDimensions) + .object("vendorCase", caseDimensions) + .closeObject().asBody() + .closeObject().asBody() + .minArrayLike("packages", 1) + .integerType("packageType", 1) + .object("weightsAndMeasures") + .object("dimensions", dimensions) + .object("weight") + .decimalType("weight", 10.10) + .decimalType("netWeight", 10.10) + .decimalType("catchWeight", 10.10) + .decimalType("pileWeight", 10.10) + .stringType("uom", "KILOGRAM") + .closeObject().asBody() + .object("volume") + .decimalType("liquidVolume", 10.10) + .stringType("uom", "LITRE") + .closeObject().asBody() + .object("scannedData") + .datetimeExpression("fileTimestamp", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .decimalType("averageWeight", 10.10) + .stringType("averageWeightUom", "GRAM") + .object("shipmentCase", caseDimensions) + .object("vendorCase", caseDimensions) + .closeObject().asBody() + .closeObject().asBody() + .closeObject() + .closeArray().asBody() + .object("media") + .minArrayLike("images", 1, images) + .closeObject().asBody() + .object("safety") + .booleanType("ageRestrictedFlag", false) + .booleanType("safetyIndicator", false) + .booleanType("safetyIndicatorFlag", false) + .booleanType("safetyIndicatorOverrideFlag", false) + .closeObject().asBody() + .object("waste") + .stringType("wasteType", "sample_data") + .decimalType("percentage", 10.10) + .decimalType("defaultPercentage", 10.10) + .datetimeExpression("effectiveFromDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .datetimeExpression("effectiveToDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .minArrayLike("attributes", 1) + .stringType("key", "weeeAssociatedProductNumber") + .stringType("value", "sample_data") + .closeObject() + .closeArray().asBody() + .closeObject().asBody() + .object("optionalTypes") + .object("jewellery") + .decimalType("totalWeight", 10.10) + .decimalType("metalWeight", 10.10) + .decimalType("stoneWeight", 10.10) + .decimalType("chainLength", 10.10) + .stringType("ringSize", "sample_data") + .stringType("ringSizeFrom", "sample_data") + .stringType("ringSizeTo", "sample_data") + .closeObject().asBody() + .object("clothing") + .stringType("size", "sample_data") + .closeObject().asBody() + .eachLike("batteries", 0) + .closeArray().asBody() + .closeObject().asBody() + .object("productDataAudit") + .datetimeExpression("createdDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .datetimeExpression("lastModifiedDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .stringType("lastModifiedBy", "bam") + .datetimeExpression("deletedDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .closeObject().asBody() .closeObject().asBody() .object("exxer") - .stringType("masterSource", "EXXER") + .stringType("masterSource", "EXXER") .closeObject().asBody() .object("itemAudit") - .datetimeExpression("createdDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .datetimeExpression("lastModifiedDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") - .stringType("lastModifiedBy", "bam") - .minArrayLike("eventHistories", 1, eventHistories) + .datetimeExpression("createdDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .datetimeExpression("lastModifiedDate", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") + .stringType("lastModifiedBy", "bam") + .minArrayLike("eventHistories", 1, eventHistories) .closeObject().asBody(); - JSONObject jsonObject = (JSONObject) body.getBody(); - JsonValue jsonValue = JsonParser.parseString(jsonObject.toString()); + JsonValue jsonValue = body.getBody(); assertThat(jsonValue.asObject().getEntries().keySet(), is(equalTo(new HashSet<>(Arrays.asList("division", "metadata", "itemType", "itemAudit", "exxer", "wrapper", "parentWrapper", "version", "master"))))); diff --git a/core/matchers/src/main/kotlin/au/com/dius/pact/core/matchers/MatcherExecutor.kt b/core/matchers/src/main/kotlin/au/com/dius/pact/core/matchers/MatcherExecutor.kt index a5cc7f44f2..f5d6a34045 100755 --- a/core/matchers/src/main/kotlin/au/com/dius/pact/core/matchers/MatcherExecutor.kt +++ b/core/matchers/src/main/kotlin/au/com/dius/pact/core/matchers/MatcherExecutor.kt @@ -62,7 +62,7 @@ fun safeToString(value: Any?): String { is Text -> value.wholeText is Element -> value.textContent is Attr -> value.nodeValue - is JsonValue -> value.asString() + is JsonValue -> value.toString() else -> value.toString() } } @@ -187,7 +187,9 @@ fun matchType( actual: Any?, mismatchFactory: MismatchFactory ): List { - logger.debug { "comparing type of ${valueOf(actual)} to ${valueOf(expected)} at $path" } + logger.debug { + "comparing type of ${valueOf(actual)} (${typeOf(actual)}) to ${valueOf(expected)} (${typeOf(expected)}) at $path" + } return if (expected is String && actual is String || expected is Number && actual is Number || expected is Boolean && actual is Boolean || @@ -265,7 +267,7 @@ fun matchDecimal(actual: Any?): Boolean { val bigDecimal = actual.toBigDecimal() bigDecimal == BigDecimal.ZERO || bigDecimal.scale() > 0 } - actual is JsonValue.Integer -> decimalRegex.matches(actual.asString()) + actual is JsonValue.Integer -> decimalRegex.matches(actual.toString()) actual is Attr -> decimalRegex.matches(actual.nodeValue) else -> false } @@ -280,7 +282,7 @@ fun matchInteger(actual: Any?): Boolean { actual is BigInteger -> true actual is JsonValue.Integer -> true actual is BigDecimal && actual.scale() == 0 -> true - actual is JsonValue.Decimal -> integerRegex.matches(actual.asString()) + actual is JsonValue.Decimal -> integerRegex.matches(actual.toString()) actual is Attr -> integerRegex.matches(actual.nodeValue) else -> false } diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/BaseRequest.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/BaseRequest.kt index 1ee07d41ea..516829d4b8 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/BaseRequest.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/BaseRequest.kt @@ -50,7 +50,7 @@ abstract class BaseRequest : HttpPart() { null -> emptyMap() is JsonValue.Object -> query.entries.entries.associate { entry -> val list = when (entry.value) { - is JsonValue.Array -> entry.value.asArray().values.map { Json.toString(it) } + is JsonValue.Array -> (entry.value as JsonValue.Array).values.map { Json.toString(it) } else -> emptyList() } entry.key to list diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/HttpPart.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/HttpPart.kt index bb3515cf13..4e57d88f5e 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/HttpPart.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/HttpPart.kt @@ -72,7 +72,7 @@ abstract class HttpPart { ): OptionalBody { return when (val b = json["body"]) { is JsonValue.Null -> OptionalBody.nullBody() - is JsonValue.StringValue -> decodeBody(b.asString(), contentType, decoder) + is JsonValue.StringValue -> decodeBody(b.asString()!!, contentType, decoder) else -> decodeBody(b.serialise(), contentType, decoder) } } diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/PactReader.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/PactReader.kt index 99eb5cccfb..1624ab46d3 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/PactReader.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/PactReader.kt @@ -7,10 +7,10 @@ import au.com.dius.pact.core.pactbroker.PactBrokerResult import au.com.dius.pact.core.pactbroker.util.HttpClientUtils import au.com.dius.pact.core.pactbroker.util.HttpClientUtils.isJsonResponse import au.com.dius.pact.core.support.Auth -import au.com.dius.pact.core.support.Utils import au.com.dius.pact.core.support.CustomServiceUnavailableRetryStrategy import au.com.dius.pact.core.support.HttpClient import au.com.dius.pact.core.support.Json +import au.com.dius.pact.core.support.Utils import au.com.dius.pact.core.support.json.JsonException import au.com.dius.pact.core.support.json.JsonParser import au.com.dius.pact.core.support.json.JsonValue @@ -42,7 +42,6 @@ import java.net.URI import java.net.URL import java.net.URLDecoder import kotlin.collections.set -import kotlin.text.isNotEmpty private val logger = KotlinLogging.logger {} @@ -62,7 +61,11 @@ fun loadPactFromUrl( pactResponse.pactFile to source.copy(attributes = pactResponse.links, options = options, tag = source.tag) } else -> when (val jsonResource = fetchJsonResource(http, source)) { - is Ok -> jsonResource.value.first.asObject() to jsonResource.value.second + is Ok -> if (jsonResource.value.first is JsonValue.Object) { + jsonResource.value.first.asObject()!! to jsonResource.value.second + } else { + throw UnsupportedOperationException("Was expected a JSON document, got ${jsonResource.value}") + } is Err -> throw jsonResource.error } } @@ -211,9 +214,9 @@ object DefaultPactReader : PactReader, KLogging() { fun determineSpecVersion(pactInfo: JsonValue.Object): String { var version = "2.0.0" if (pactInfo.has("metadata")) { - val metadata = pactInfo["metadata"].asObject() + val metadata: JsonValue.Object = pactInfo["metadata"].downcast() version = when { - metadata.has("pactSpecificationVersion") -> metadata["pactSpecificationVersion"].asString() + metadata.has("pactSpecificationVersion") -> Json.toString(metadata["pactSpecificationVersion"]) metadata.has("pactSpecification") -> specVersion(metadata["pactSpecification"], version) metadata.has("pact-specification") -> specVersion(metadata["pact-specification"], version) else -> version @@ -228,7 +231,7 @@ object DefaultPactReader : PactReader, KLogging() { private fun specVersion(specification: JsonValue, defaultVersion: String): String { return if (specification is JsonValue.Object && specification.has("version") && specification["version"].isString) { - specification["version"].asString() + specification["version"].asString()!! } else { return defaultVersion } @@ -285,15 +288,23 @@ object DefaultPactReader : PactReader, KLogging() { } @JvmStatic - fun extractResponse(responseJson: JsonValue.Object): Response { - formatBody(responseJson) - return Response.fromJson(responseJson) + fun extractResponse(responseJson: JsonValue.Object?): Response { + return if (responseJson != null) { + formatBody(responseJson) + Response.fromJson(responseJson) + } else { + Response() + } } @JvmStatic - fun extractRequest(requestJson: JsonValue.Object): Request { - formatBody(requestJson) - return Request.fromJson(requestJson) + fun extractRequest(requestJson: JsonValue.Object?): Request { + return if (requestJson != null) { + formatBody(requestJson) + Request.fromJson(requestJson) + } else { + Request() + } } private fun formatBody(json: JsonValue) { @@ -326,7 +337,7 @@ object DefaultPactReader : PactReader, KLogging() { } if (pactJson.has("metadata") && pactJson["metadata"] is JsonValue.Object) { - pactJson["metadata"] = jsonObject(pactJson["metadata"].asObject().entries.entries.map { entry -> + pactJson["metadata"] = jsonObject(pactJson["metadata"].asObject()!!.entries.entries.map { entry -> when (entry.key) { "pact-specification" -> "pactSpecification" to entry.value else -> entry.toPair() @@ -337,15 +348,19 @@ object DefaultPactReader : PactReader, KLogging() { return pactJson } - private fun transformRequestResponseJson(requestJson: JsonValue.Object): JsonValue.Object { - return jsonObject(requestJson.entries.entries.map { (k, v) -> - when (k) { - "responseMatchingRules" -> "matchingRules" to v - "requestMatchingRules" -> "matchingRules" to v - "method" -> "method" to Json.toString(v).toUpperCase() - else -> k to v - } - }) + private fun transformRequestResponseJson(requestJson: JsonValue.Object?): JsonValue.Object? { + return if (requestJson != null) { + jsonObject(requestJson.entries.entries.map { (k, v) -> + when (k) { + "responseMatchingRules" -> "matchingRules" to v + "requestMatchingRules" -> "matchingRules" to v + "method" -> "method" to Json.toString(v).toUpperCase() + else -> k to v + } + }) + } else { + null + } } @Suppress("ReturnCount") @@ -353,7 +368,7 @@ object DefaultPactReader : PactReader, KLogging() { if (source is ClosurePactSource) { return loadFile(source.closure.get(), options) } else if (source is FileSource<*>) { - return source.file.bufferedReader().use { JsonParser.parseReader(it).asObject() to source } + return source.file.bufferedReader().use { JsonParser.parseReader(it).downcast() to source } } else if (source is InputStream || source is Reader || source is File) { return loadPactFromFile(source) } else if (source is BrokerUrlSource) { @@ -386,10 +401,10 @@ object DefaultPactReader : PactReader, KLogging() { return loadPactFromClasspath(source.substring(CLASSPATH_URI_START.length)) } else if (source is String && fileExists(source)) { val file = File(source) - return file.bufferedReader().use { JsonParser.parseReader(it).asObject() to FileSource(file) } + return file.bufferedReader().use { JsonParser.parseReader(it).downcast() to FileSource(file) } } else { try { - return JsonParser.parseString(source.toString()).asObject() to UnknownPactSource + return JsonParser.parseString(source.toString()).downcast() to UnknownPactSource } catch (e: JsonException) { throw UnsupportedOperationException( "Unable to load pact file from '$source' as it is neither a json document, file, input stream, " + @@ -400,10 +415,11 @@ object DefaultPactReader : PactReader, KLogging() { private fun loadPactFromFile(source: Any): Pair { return when (source) { - is InputStream -> JsonParser.parseReader(InputStreamReader(source)).asObject() to InputStreamPactSource - is Reader -> JsonParser.parseReader(source).asObject() to ReaderPactSource + is InputStream -> JsonParser.parseReader(InputStreamReader(source)).downcast() to + InputStreamPactSource + is Reader -> JsonParser.parseReader(source).downcast() to ReaderPactSource is File -> source.bufferedReader().use { - JsonParser.parseReader(it).asObject() } to FileSource(source) + JsonParser.parseReader(it).downcast() } to FileSource(source) else -> throw IllegalArgumentException("loadPactFromFile expects either an InputStream, Reader or File. " + "Got a ${source.javaClass.name} instead") } @@ -423,7 +439,7 @@ object DefaultPactReader : PactReader, KLogging() { .invoke(s3Client, bucket, key) val s3ObjectClass = Class.forName("com.amazonaws.services.s3.model.S3Object") val objectContent = s3ObjectClass.getMethod("getObjectContent").invoke(s3Pact) as InputStream - return JsonParser.parseReader(InputStreamReader(objectContent)).asObject() to S3PactSource(source) + return JsonParser.parseReader(InputStreamReader(objectContent)).downcast() to S3PactSource(source) } private fun loadPactFromClasspath(source: String): Pair { diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/Request.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/Request.kt index faa96d2ff7..2a97906f0e 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/Request.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/Request.kt @@ -104,7 +104,7 @@ class Request @JvmOverloads constructor( val path = if (json.has("path")) Json.toString(json["path"]) else DEFAULT_PATH val query = parseQueryParametersToMap(json["query"]) val headers = if (json.has("headers") && json["headers"] is JsonValue.Object) { - json["headers"].asObject().entries.entries.associate { (key, value) -> + json["headers"].asObject()!!.entries.entries.associate { (key, value) -> key to HeaderParser.fromJson(key, value) } } else { diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/Response.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/Response.kt index 2aeb9ecf4a..34d3d5d66e 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/Response.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/Response.kt @@ -66,24 +66,8 @@ class Response @JvmOverloads constructor( @JvmStatic fun fromJson(json: JsonValue.Object): Response { - val status = when { - json.has("status") -> { - val statusJson = json["status"] - when { - statusJson.isNumber -> statusJson.asNumber().toInt() - statusJson is JsonValue.StringValue -> statusJson.asString().toInt() - else -> DEFAULT_STATUS - } - } - else -> DEFAULT_STATUS - } - val headers = if (json.has("headers") && json["headers"] is JsonValue.Object) { - json["headers"].asObject().entries.entries.associate { (key, value) -> - key to HeaderParser.fromJson(key, value) - } - } else { - emptyMap() - } + val status = statusFromJson(json) + val headers = headersFromJson(json) var contentType = ContentType.UNKNOWN val contentTypeEntry = headers.entries.find { it.key.toUpperCase() == "CONTENT-TYPE" } @@ -102,5 +86,26 @@ class Response @JvmOverloads constructor( else Generators() return Response(status, headers.toMutableMap(), body, matchingRules, generators) } + + private fun headersFromJson(json: JsonValue.Object) = + if (json.has("headers") && json["headers"] is JsonValue.Object) { + json["headers"].asObject()!!.entries.entries.associate { (key, value) -> + key to HeaderParser.fromJson(key, value) + } + } else { + emptyMap() + } + + private fun statusFromJson(json: JsonValue.Object) = when { + json.has("status") -> { + val statusJson = json["status"] + when { + statusJson.isNumber -> statusJson.asNumber()!!.toInt() + statusJson is JsonValue.StringValue -> statusJson.asString()?.toInt() ?: DEFAULT_STATUS + else -> DEFAULT_STATUS + } + } + else -> DEFAULT_STATUS + } } } diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/generators/Generator.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/generators/Generator.kt index ef1f1db30b..5c74a51d02 100755 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/generators/Generator.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/generators/Generator.kt @@ -33,26 +33,31 @@ const val DEFAULT_GENERATOR_PACKAGE = "au.com.dius.pact.core.model.generators" * au.com.dius.pact.model.generators package, but this can be extended by adding a comma separated list to the * pact.generators.packages system property. The generator class name needs to be Generator. */ -fun lookupGenerator(generatorJson: JsonValue.Object): Generator? { +fun lookupGenerator(generatorJson: JsonValue?): Generator? { var generator: Generator? = null - try { - val generatorClass = findGeneratorClass(Json.toString(generatorJson["type"])).kotlin - val fromJson = when { - generatorClass.companionObject != null -> - generatorClass.companionObjectInstance to generatorClass.companionObject?.declaredMemberFunctions?.find { - it.name == "fromJson" } - generatorClass.objectInstance != null -> - generatorClass.objectInstance to generatorClass.declaredMemberFunctions.find { it.name == "fromJson" } - else -> null - } - if (fromJson?.second != null) { - generator = fromJson.second!!.call(fromJson.first, generatorJson) as Generator? - } else { - logger.warn { "Could not invoke generator class 'fromJson' for generator config '$generatorJson'" } + if (generatorJson is JsonValue.Object) { + try { + val generatorClass = findGeneratorClass(Json.toString(generatorJson["type"])).kotlin + val fromJson = when { + generatorClass.companionObject != null -> + generatorClass.companionObjectInstance to generatorClass.companionObject?.declaredMemberFunctions?.find { + it.name == "fromJson" + } + generatorClass.objectInstance != null -> + generatorClass.objectInstance to generatorClass.declaredMemberFunctions.find { it.name == "fromJson" } + else -> null + } + if (fromJson?.second != null) { + generator = fromJson.second!!.call(fromJson.first, generatorJson) as Generator? + } else { + logger.warn { "Could not invoke generator class 'fromJson' for generator config '$generatorJson'" } + } + } catch (e: ClassNotFoundException) { + logger.warn(e) { "Could not find generator class for generator config '$generatorJson'" } } - } catch (e: ClassNotFoundException) { - logger.warn(e) { "Could not find generator class for generator config '$generatorJson'" } + } else { + logger.warn { "'$generatorJson' is not a valid generator JSON value" } } return generator @@ -104,13 +109,13 @@ data class RandomIntGenerator(val min: Int, val max: Int) : Generator { companion object { fun fromJson(json: JsonValue.Object): RandomIntGenerator { val min = if (json["min"].isNumber) { - json["min"].asNumber().toInt() + json["min"].asNumber()!!.toInt() } else { logger.warn { "Ignoring invalid value for min: '${json["min"]}'" } 0 } val max = if (json["max"].isNumber) { - json["max"].asNumber().toInt() + json["max"].asNumber()!!.toInt() } else { logger.warn { "Ignoring invalid value for max: '${json["max"]}'" } Int.MAX_VALUE @@ -156,7 +161,7 @@ data class RandomDecimalGenerator(val digits: Int) : Generator { companion object { fun fromJson(json: JsonValue.Object): RandomDecimalGenerator { val digits = if (json["digits"].isNumber) { - json["digits"].asNumber().toInt() + json["digits"].asNumber()!!.toInt() } else { logger.warn { "Ignoring invalid value for digits: '${json["digits"]}'" } 10 @@ -179,7 +184,7 @@ data class RandomHexadecimalGenerator(val digits: Int) : Generator { companion object { fun fromJson(json: JsonValue.Object): RandomHexadecimalGenerator { val digits = if (json["digits"].isNumber) { - json["digits"].asNumber().toInt() + json["digits"].asNumber()!!.toInt() } else { logger.warn { "Ignoring invalid value for digits: '${json["digits"]}'" } 10 @@ -204,7 +209,7 @@ data class RandomStringGenerator(val size: Int = 20) : Generator { companion object { fun fromJson(json: JsonValue.Object): RandomStringGenerator { val size = if (json["size"].isNumber) { - json["size"].asNumber().toInt() + json["size"].asNumber()!!.toInt() } else { logger.warn { "Ignoring invalid value for size: '${json["size"]}'" } 10 diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/generators/Generators.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/generators/Generators.kt index c69f0498a5..0e2e4c6598 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/generators/Generators.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/generators/Generators.kt @@ -118,7 +118,7 @@ data class Generators(val categories: MutableMap generatorJson.asObject().entries.forEach { (generatorKey, generatorValue) -> + else -> generatorJson.asObject()?.entries?.forEach { (generatorKey, generatorValue) -> if (generatorValue is JsonValue.Object && generatorValue.has("type")) { val generator = lookupGenerator(generatorValue) if (generator != null) { diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/Message.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/Message.kt index 3ffdb702b7..3dcb398420 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/Message.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/Message.kt @@ -171,13 +171,13 @@ class Message @JvmOverloads constructor( @JvmStatic fun fromJson(json: JsonValue.Object): Message { val providerStates = when { - json.has("providerStates") -> json["providerStates"].asArray().values.map { ProviderState.fromJson(it) } + json.has("providerStates") -> json["providerStates"].asArray()?.values?.map { ProviderState.fromJson(it) } json.has("providerState") -> listOf(ProviderState(Json.toString(json["providerState"]))) else -> listOf() } - val metaData = if (json.has("metaData")) - json["metaData"].asObject().entries.entries.associate { it.key to Json.fromJson(it.value) } + val metaData = if (json.has("metaData") && json["metaData"].isObject) + json["metaData"].asObject()!!.entries.entries.associate { it.key to Json.fromJson(it.value) } else emptyMap() @@ -185,7 +185,7 @@ class Message @JvmOverloads constructor( val contents = if (json.has("contents")) { when (val contents = json["contents"]) { is JsonValue.Null -> OptionalBody.nullBody() - is JsonValue.StringValue -> OptionalBody.body(contents.asString().toByteArray(contentType.asCharset()), + is JsonValue.StringValue -> OptionalBody.body(contents.asString()!!.toByteArray(contentType.asCharset()), contentType) else -> OptionalBody.body(contents.serialise().toByteArray(contentType.asCharset()), contentType) } @@ -199,7 +199,7 @@ class Message @JvmOverloads constructor( Generators.fromJson(json["generators"]) else Generators() - return Message(Json.toString(json["description"]), providerStates, + return Message(Json.toString(json["description"]), providerStates ?: emptyList(), contents, matchingRules, generators, metaData.toMutableMap(), Json.toString(json["_id"])) } diff --git a/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/MessagePact.kt b/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/MessagePact.kt index c8c5dbe321..aadd2a27b5 100644 --- a/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/MessagePact.kt +++ b/core/model/src/main/kotlin/au/com/dius/pact/core/model/messaging/MessagePact.kt @@ -60,8 +60,8 @@ class MessagePact @JvmOverloads constructor ( "(it contains request/response interactions)") } - val messages = ((newPact["messages"] as List>) + - json["messages"].asArray().values.map { Json.toMap(it) }) + val messages = (newPact["messages"] as List>) + + (json["messages"].asArray()?.values?.map { Json.toMap(it) } ?: emptyList()) .distinctBy { it["description"] } newPact["messages"] = messages return newPact @@ -120,7 +120,9 @@ class MessagePact @JvmOverloads constructor ( val transformedJson = DefaultPactReader.transformJson(json) val consumer = Consumer.fromJson(transformedJson["consumer"]) val provider = Provider.fromJson(transformedJson["provider"]) - val messages = transformedJson["messages"].asArray().values.map { Message.fromJson(it.asObject()) } + val messages = transformedJson["messages"].asArray()?.values?.map { + Message.fromJson(it.downcast()) + } ?: emptyList() val metadata = if (transformedJson.has("metadata")) Json.toMap(transformedJson["metadata"]) else emptyMap() diff --git a/core/model/src/test/groovy/au/com/dius/pact/core/model/PactReaderTransformSpec.groovy b/core/model/src/test/groovy/au/com/dius/pact/core/model/PactReaderTransformSpec.groovy index 43d0586a2d..445b2f1421 100644 --- a/core/model/src/test/groovy/au/com/dius/pact/core/model/PactReaderTransformSpec.groovy +++ b/core/model/src/test/groovy/au/com/dius/pact/core/model/PactReaderTransformSpec.groovy @@ -46,9 +46,6 @@ class PactReaderTransformSpec extends Specification { then: Json.INSTANCE.prettyPrint(result) == '''{ - | "provider": { - | "name": "Alice Service" - | }, | "consumer": { | "name": "Consumer" | }, @@ -56,23 +53,26 @@ class PactReaderTransformSpec extends Specification { | { | "description": "a retrieve Mallory request", | "request": { - | "method": "GET", - | "path": "/mallory", - | "query": "name=ron&status=good", | "body": { | "id": "123", | "method": "create" - | } + | }, + | "method": "GET", + | "path": "/mallory", + | "query": "name=ron&status=good" | }, | "response": { - | "status": 200, + | "body": "\\"That is some good Mallory.\\"", | "headers": { | "Content-Type": "text/html" | }, - | "body": "\\"That is some good Mallory.\\"" + | "status": 200 | } | } - | ] + | ], + | "provider": { + | "name": "Alice Service" + | } |}'''.stripMargin() } @@ -86,35 +86,35 @@ class PactReaderTransformSpec extends Specification { then: Json.INSTANCE.prettyPrint(result) == '''{ - | "provider": { - | "name": "Alice Service" - | }, - | "consumer": { - | "name": "Consumer" - | }, - | "interactions": [ - | { - | "description": "a retrieve Mallory request", - | "request": { - | "method": "GET", - | "path": "/mallory", - | "query": "name=ron&status=good", - | "body": { - | "id": "123", - | "method": "create" - | } - | }, - | "response": { - | "status": 200, - | "headers": { - | "Content-Type": "text/html" - | }, - | "body": "\\"That is some good Mallory.\\"" - | }, - | "providerState": "provider state" - | } - | ] - |}'''.stripMargin() + | "consumer": { + | "name": "Consumer" + | }, + | "interactions": [ + | { + | "description": "a retrieve Mallory request", + | "providerState": "provider state", + | "request": { + | "body": { + | "id": "123", + | "method": "create" + | }, + | "method": "GET", + | "path": "/mallory", + | "query": "name=ron&status=good" + | }, + | "response": { + | "body": "\\"That is some good Mallory.\\"", + | "headers": { + | "Content-Type": "text/html" + | }, + | "status": 200 + | } + | } + | ], + | "provider": { + | "name": "Alice Service" + | } + |}'''.stripMargin() } def 'handles both a snake and camel case provider state'() { @@ -129,34 +129,34 @@ class PactReaderTransformSpec extends Specification { then: Json.INSTANCE.prettyPrint(result) == '''{ - | "provider": { - | "name": "Alice Service" - | }, | "consumer": { | "name": "Consumer" | }, | "interactions": [ | { | "description": "a retrieve Mallory request", + | "providerState": "provider state 2", | "request": { - | "method": "GET", - | "path": "/mallory", - | "query": "name=ron&status=good", | "body": { | "id": "123", | "method": "create" - | } + | }, + | "method": "GET", + | "path": "/mallory", + | "query": "name=ron&status=good" | }, | "response": { - | "status": 200, + | "body": "\\"That is some good Mallory.\\"", | "headers": { | "Content-Type": "text/html" | }, - | "body": "\\"That is some good Mallory.\\"" - | }, - | "providerState": "provider state 2" + | "status": 200 + | } | } - | ] + | ], + | "provider": { + | "name": "Alice Service" + | } |}'''.stripMargin() } @@ -172,9 +172,6 @@ class PactReaderTransformSpec extends Specification { then: Json.INSTANCE.prettyPrint(result) == '''{ - | "provider": { - | "name": "Alice Service" - | }, | "consumer": { | "name": "Consumer" | }, @@ -182,9 +179,6 @@ class PactReaderTransformSpec extends Specification { | { | "description": "a retrieve Mallory request", | "request": { - | "method": "GET", - | "path": "/mallory", - | "query": "name=ron&status=good", | "body": { | "id": "123", | "method": "create" @@ -197,14 +191,16 @@ class PactReaderTransformSpec extends Specification { | } | ] | } - | } + | }, + | "method": "GET", + | "path": "/mallory", + | "query": "name=ron&status=good" | }, | "response": { - | "status": 200, + | "body": "\\"That is some good Mallory.\\"", | "headers": { | "Content-Type": "text/html" | }, - | "body": "\\"That is some good Mallory.\\"", | "matchingRules": { | "body": { | "$": [ @@ -213,10 +209,14 @@ class PactReaderTransformSpec extends Specification { | } | ] | } - | } + | }, + | "status": 200 | } | } - | ] + | ], + | "provider": { + | "name": "Alice Service" + | } |}'''.stripMargin() } @@ -230,9 +230,6 @@ class PactReaderTransformSpec extends Specification { then: Json.INSTANCE.prettyPrint(result) == '''{ - | "provider": { - | "name": "Alice Service" - | }, | "consumer": { | "name": "Consumer" | }, @@ -240,23 +237,26 @@ class PactReaderTransformSpec extends Specification { | { | "description": "a retrieve Mallory request", | "request": { - | "method": "POST", - | "path": "/mallory", - | "query": "name=ron&status=good", | "body": { | "id": "123", | "method": "create" - | } + | }, + | "method": "POST", + | "path": "/mallory", + | "query": "name=ron&status=good" | }, | "response": { - | "status": 200, + | "body": "\\"That is some good Mallory.\\"", | "headers": { | "Content-Type": "text/html" | }, - | "body": "\\"That is some good Mallory.\\"" + | "status": 200 | } | } - | ] + | ], + | "provider": { + | "name": "Alice Service" + | } |}'''.stripMargin() } } diff --git a/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/HalClient.kt b/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/HalClient.kt index 3060c8ae2c..31c8cba887 100644 --- a/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/HalClient.kt +++ b/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/HalClient.kt @@ -4,6 +4,7 @@ import au.com.dius.pact.core.pactbroker.util.HttpClientUtils.buildUrl import au.com.dius.pact.core.pactbroker.util.HttpClientUtils.isJsonResponse import au.com.dius.pact.core.support.Auth import au.com.dius.pact.core.support.HttpClient +import au.com.dius.pact.core.support.Json import au.com.dius.pact.core.support.Json.fromJson import au.com.dius.pact.core.support.handleWith import au.com.dius.pact.core.support.isNotEmpty @@ -360,7 +361,7 @@ open class HalClient @JvmOverloads constructor( return if (linkByName is JsonValue.Object && linkByName["templated"].isBoolean) { parseLinkUrl(linkByName["href"].toString(), options) } else if (linkByName is JsonValue.Object) { - linkByName["href"].asString() + Json.toString(linkByName["href"]) } else { throw InvalidNavigationRequest("Link '$link' does not have an entry with name '${options["name"]}'. " + "URL: '$baseUrl', LINK: '$link'") @@ -371,9 +372,9 @@ open class HalClient @JvmOverloads constructor( } } else if (linkData is JsonValue.Object) { return if (linkData.has("templated") && linkData["templated"].isBoolean) { - parseLinkUrl(linkData["href"].asString(), options) + parseLinkUrl(Json.toString(linkData["href"]), options) } else { - linkData["href"].asString() + Json.toString(linkData["href"]) } } else { throw InvalidHalResponse("Expected link in map form in the response, but " + @@ -425,11 +426,11 @@ open class HalClient @JvmOverloads constructor( if (jsonBody.has("errors")) { val errors = jsonBody["errors"] if (errors is JsonValue.Array) { - error = " - " + errors.values.joinToString(", ") { it.asString() } + error = " - " + errors.values.joinToString(", ") { Json.toString(it) } } else if (errors is JsonValue.Object) { error = " - " + errors.entries.entries.joinToString(", ") { entry -> if (entry.value is JsonValue.Array) { - "${entry.key}: ${(entry.value as JsonValue.Array).values.joinToString(", ") { it.asString() }}" + "${entry.key}: ${(entry.value as JsonValue.Array).values.joinToString(", ") { Json.toString(it) }}" } else { "${entry.key}: ${entry.value.asString()}" } @@ -514,7 +515,8 @@ open class HalClient @JvmOverloads constructor( val URL_TEMPLATE_REGEX = Regex("\\{(\\w+)}") @JvmStatic - fun asMap(jsonObject: JsonValue.Object) = jsonObject.entries.entries - .associate { entry -> entry.key to fromJson(entry.value) } + fun asMap(jsonObject: JsonValue.Object?) = jsonObject?.entries?.entries?.associate { + entry -> entry.key to fromJson(entry.value) + } ?: emptyMap() } } diff --git a/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt b/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt index 7a75aaf23c..f8acec1e5d 100644 --- a/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt +++ b/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerClient.kt @@ -19,6 +19,7 @@ import com.github.michaelbull.result.map import com.github.michaelbull.result.mapError import com.github.michaelbull.result.unwrap import com.google.common.net.UrlEscapers.urlFormParameterEscaper +import com.google.common.net.UrlEscapers.urlPathSegmentEscaper import mu.KLogging import java.io.File import java.io.IOException @@ -401,7 +402,7 @@ interface IPactBrokerClient { fun uploadPactFile(pactFile: File, version: String, tags: List): Result /** - * Uploads the given pact file to the broker and applies any tags/Branch + * Uploads the given pact file to the broker and applies any tags/branches */ fun uploadPactFile(pactFile: File, config: PublishConfiguration): Result } @@ -590,13 +591,14 @@ open class PactBrokerClient( val href = Json.toString(selfLink["href"]) val name = Json.toString(selfLink["name"]) val properties = pactJson["verificationProperties"] - val notices = properties["notices"].asArray() - .map { VerificationNotice.fromJson(it.asObject()) } + val notices = properties["notices"].asArray()?.map { VerificationNotice.fromJson(it) }?.filterNotNull() ?: + emptyList() var pending = false if (properties is JsonValue.Object && properties.has("pending") && properties["pending"].isBoolean) { - pending = properties["pending"].asBoolean() + pending = properties["pending"].asBoolean()!! } - val wip = if (properties.has("wip") && properties["wip"].isBoolean) properties["wip"].asBoolean() + val wip = if (properties.has("wip") && properties["wip"].isBoolean) + properties["wip"].asBoolean()!! else false PactBrokerResult(name, href, pactBrokerUrl, halClient.getAuth()?.legacyForm() ?: emptyList(), @@ -621,8 +623,8 @@ open class PactBrokerClient( val pactText = pactFile.readText() val pact = JsonParser.parseString(pactText) val halClient = newHalClient().navigate() - val providerName = pact["provider"]["name"].asString() - val consumerName = pact["consumer"]["name"].asString() + val providerName = Json.toString(pact["provider"]["name"]) + val consumerName = Json.toString(pact["consumer"]["name"]) val publishContractsLink = halClient.linkUrl(PUBLISH_CONTRACTS_LINK) return if (publishContractsLink != null) { @@ -690,7 +692,7 @@ open class PactBrokerClient( if (error is RequestFailedException && error.body != null) { when (val json = handleWith { JsonParser.parseString(error.body) }) { is Ok -> if (json.value is JsonValue.Object) { - val body = json.value.asObject() + val body: JsonValue.Object = json.value.downcast() displayNotices(body) if (error.status.statusCode == 400) { displayErrors(body) @@ -731,7 +733,7 @@ open class PactBrokerClient( if (notices is JsonValue.Array) { for (noticeJson in notices.values) { if (noticeJson.isObject) { - val notice = noticeJson.asObject() + val notice: JsonValue.Object = noticeJson.downcast() val level = notice["level"].asString() val text = notice["text"].asString() when (level) { @@ -754,7 +756,7 @@ open class PactBrokerClient( if (errors is JsonValue.Object) { for ((key, errorJson) in errors.entries) { if (errorJson.isArray) { - for (error in errorJson.asArray().values) { + for (error in errorJson.asArray()!!.values) { logger.error("$key: $error") } } else { @@ -1004,7 +1006,7 @@ open class PactBrokerClient( ) { when (val result = halClient.getJson(path, false)) { is Ok -> { - val summary = result.value["summary"].asObject() + val summary = result.value["summary"].asObject()!! val matrix = result.value["matrix"] val verificationResultUrl = if (matrix.isArray) { matrix.asArray() @@ -1017,7 +1019,7 @@ open class PactBrokerClient( } else { null } - CanIDeployResult(Json.toBoolean(summary["deployable"]), "", Json.toString(summary["reason"]), + CanIDeployResult(Json.toBoolean(summary["deployable"])!!, "", Json.toString(summary["reason"]), Json.toInteger(summary["unknown"]), verificationResultUrl) } is Err -> { diff --git a/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerResult.kt b/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerResult.kt index b69bac1a1d..6399d27a9b 100644 --- a/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerResult.kt +++ b/core/pactbroker/src/main/kotlin/au/com/dius/pact/core/pactbroker/PactBrokerResult.kt @@ -23,8 +23,12 @@ data class VerificationNotice( val text: String ) { companion object { - fun fromJson(json: JsonValue.Object): VerificationNotice { - return VerificationNotice(Json.toString(json["when"]), Json.toString(json["text"])) + fun fromJson(json: JsonValue): VerificationNotice? { + return if (json is JsonValue.Object) { + VerificationNotice(Json.toString(json["when"]), Json.toString(json["text"])) + } else { + null + } } } } diff --git a/core/support/src/main/kotlin/au/com/dius/pact/core/support/Json.kt b/core/support/src/main/kotlin/au/com/dius/pact/core/support/Json.kt index c2552e5695..9421181dfd 100644 --- a/core/support/src/main/kotlin/au/com/dius/pact/core/support/Json.kt +++ b/core/support/src/main/kotlin/au/com/dius/pact/core/support/Json.kt @@ -98,7 +98,7 @@ object Json { fun toInteger(value: JsonValue?) = when { value == null -> null - value.isNumber -> value.asNumber().toInt() + value.isNumber -> value.asNumber()?.toInt() else -> null } diff --git a/core/support/src/main/kotlin/au/com/dius/pact/core/support/json/JsonValue.kt b/core/support/src/main/kotlin/au/com/dius/pact/core/support/json/JsonValue.kt index a34a7b8a32..536cd5f813 100644 --- a/core/support/src/main/kotlin/au/com/dius/pact/core/support/json/JsonValue.kt +++ b/core/support/src/main/kotlin/au/com/dius/pact/core/support/json/JsonValue.kt @@ -17,14 +17,32 @@ sealed class JsonValue { constructor(value: CharArray) : this(JsonToken.StringValue(value)) constructor(value: String) : this(JsonToken.StringValue(value.toCharArray())) override fun toString() = String(value.chars) + + override fun equals(other: Any?): Boolean { + if (this === other) return true + return when (other) { + is StringValue -> value == other.value + is String -> value.chars.contentEquals(other.toCharArray()) + else -> false + } + } + + override fun hashCode(): Int { + var result = super.hashCode() + result = 31 * result + value.hashCode() + return result + } } object True : JsonValue() object False : JsonValue() object Null : JsonValue() - class Array(val values: MutableList = mutableListOf()) : JsonValue() { + class Array @JvmOverloads constructor (val values: MutableList = mutableListOf()) : JsonValue() { fun find(function: (JsonValue) -> Boolean) = values.find(function) + operator fun get(i: Int): JsonValue { + return values[i] + } operator fun set(i: Int, value: JsonValue) { values[i] = value } @@ -39,9 +57,13 @@ sealed class JsonValue { } fun last() = values.last() + + fun append(value: JsonValue) { + values.add(value) + } } - class Object(val entries: MutableMap) : JsonValue() { + class Object @JvmOverloads constructor (val entries: MutableMap = mutableMapOf()) : JsonValue() { constructor(vararg values: Pair) : this(values.associate { it }.toMutableMap()) operator fun get(name: String) = entries[name] ?: Null override fun has(field: String) = entries.containsKey(field) @@ -58,46 +80,63 @@ sealed class JsonValue { fun add(key: String, value: JsonValue) { entries[key] = value } + + fun keys(): Set = entries.keys } - fun asObject(): Object { - if (this is Object) { - return this + fun asObject(): Object? { + return if (this is Object) { + this } else { - throw UnsupportedOperationException("Expected an Object, but found a $this") + null } } - fun asArray(): Array { - if (this is Array) { - return this + fun asArray(): Array? { + return if (this is Array) { + this } else { - throw UnsupportedOperationException("Expected an Array, but found a $this") + null } } - fun asString(): String { + fun asString(): String? { return if (this is StringValue) { String(value.chars) } else { - serialise() + null + } + } + + override fun toString(): String { + return when (this) { + is Null -> "null" + is Decimal -> String(this.value.chars) + is Integer -> String(this.value.chars) + is StringValue -> this.value.toString() + is True -> "true" + is False -> "false" + is Array -> "[${this.values.joinToString(",") { it.serialise() }}]" + is Object -> "{${this.entries.entries.sortedBy { it.key }.joinToString(",") { + "\"${it.key}\":" + it.value.serialise() + }}}" } } fun asBoolean() = when (this) { is True -> true is False -> false - else -> throw UnsupportedOperationException("Expected a Boolean, but found a $this") + else -> null } - fun asNumber(): Number = when (this) { + fun asNumber(): Number? = when (this) { is Integer -> this.toBigInteger() is Decimal -> this.toBigDecimal() - else -> throw UnsupportedOperationException("Expected a Number, but found a $this") + else -> null } operator fun get(field: Any): JsonValue = when { - this is Object -> this.asObject()[field.toString()] + this is Object -> this[field.toString()] this is Array && field is Int -> this.values[field] else -> throw UnsupportedOperationException("Indexed lookups only work on Arrays and Objects, not $this") } @@ -112,16 +151,11 @@ sealed class JsonValue { is Null -> "null" is Decimal -> String(this.value.chars) is Integer -> String(this.value.chars) - is StringValue -> "\"${Json.escape(this.asString())}\"" + is StringValue -> "\"${Json.escape(this.asString()!!)}\"" is True -> "true" is False -> "false" is Array -> "[${this.values.joinToString(",") { it.serialise() }}]" - is Object -> { - val s = this.entries.entries - .sortedBy { it.key } - .joinToString(",") { "\"${it.key}\":" + it.value.serialise() } - "{$s}" - } + is Object -> "{${this.entries.entries.sortedBy { it.key }.joinToString(",") { "\"${it.key}\":" + it.value.serialise() }}}" } } @@ -177,7 +211,7 @@ sealed class JsonValue { is Null -> 0.hashCode() is Decimal -> this.toBigDecimal().hashCode() is Integer -> this.toBigInteger().hashCode() - is StringValue -> this.asString().hashCode() + is StringValue -> this.asString()!!.hashCode() is True -> true.hashCode() is False -> false.hashCode() is Array -> this.values.hashCode() @@ -191,7 +225,7 @@ sealed class JsonValue { when (this) { is Array -> "[\n" + this.values.joinToString(",\n") { it.prettyPrint(indent + 2) } + "\n$indentStr]" - is Object -> "{\n" + this.entries.entries.joinToString(",\n") { + is Object -> "{\n" + this.entries.entries.sortedBy { it.key }.joinToString(",\n") { "$indentStr2\"${it.key}\": ${it.value.prettyPrint(indent + 2, true)}" } + "\n$indentStr}" else -> this.serialise() @@ -200,7 +234,7 @@ sealed class JsonValue { when (this) { is Array -> "$indentStr$indentStr[\n" + this.values.joinToString(",\n") { it.prettyPrint(indent + 2) } + "\n$indentStr]" - is Object -> "$indentStr{\n" + this.entries.entries.joinToString(",\n") { + is Object -> "$indentStr{\n" + this.entries.entries.sortedBy { it.key }.joinToString(",\n") { "$indentStr2\"${it.key}\": ${it.value.prettyPrint(indent + 2, true)}" } + "\n$indentStr}" else -> indentStr + this.serialise() @@ -257,6 +291,14 @@ sealed class JsonValue { is Array -> true else -> false } + + inline fun downcast() : T { + return if (this is T) { + this + } else { + throw UnsupportedOperationException("Can not downcast ${this.name} to type ${T::class}") + } + } } fun JsonValue?.map(transform: (JsonValue) -> R): List = when { diff --git a/provider/scalasupport/src/main/kotlin/au/com/dius/pact/provider/scalasupport/SbtSupport.kt b/provider/scalasupport/src/main/kotlin/au/com/dius/pact/provider/scalasupport/SbtSupport.kt index 4cd6fc11ae..793581a209 100644 --- a/provider/scalasupport/src/main/kotlin/au/com/dius/pact/provider/scalasupport/SbtSupport.kt +++ b/provider/scalasupport/src/main/kotlin/au/com/dius/pact/provider/scalasupport/SbtSupport.kt @@ -18,16 +18,16 @@ data class Address @JvmOverloads constructor ( companion object { fun from(json: JsonValue): Address { val host = if (json.has("host")) { - json["host"].asString() + json["host"].toString() } else null val port = if (json.has("port")) { - json["port"].asNumber().toInt() + json["port"].asNumber()!!.toInt() } else null val path = if (json.has("path")) { - json["path"].asString() + json["path"].toString() } else "" val scheme = if (json.has("scheme")) { - json["scheme"].asString() + json["scheme"].toString() } else "http" return Address(host, port, path, scheme) } diff --git a/provider/src/main/kotlin/au/com/dius/pact/provider/reporters/JsonReporter.kt b/provider/src/main/kotlin/au/com/dius/pact/provider/reporters/JsonReporter.kt index d28e6ac2c2..45e5b54298 100644 --- a/provider/src/main/kotlin/au/com/dius/pact/provider/reporters/JsonReporter.kt +++ b/provider/src/main/kotlin/au/com/dius/pact/provider/reporters/JsonReporter.kt @@ -77,7 +77,7 @@ class JsonReporter( if (existingContents is JsonValue.Object && existingContents.has("provider") && providerName == existingContents["provider"]["name"].asString()) { existingContents["metaData"] = jsonData["metaData"] - existingContents["execution"].asArray().addAll(jsonData["execution"]) + existingContents["execution"].asArray()!!.addAll(jsonData["execution"]) reportFile.writeText(existingContents.serialise()) } else { reportFile.writeText(jsonData.serialise()) @@ -101,11 +101,11 @@ class JsonReporter( } override fun verifyConsumerFromUrl(pactUrl: UrlPactSource, consumer: IConsumerInfo) { - jsonData["execution"].asArray().last()["consumer"].asObject()["source"] = jsonObject("url" to pactUrl.url) + jsonData["execution"].asArray()!!.last()["consumer"].asObject()!!["source"] = jsonObject("url" to pactUrl.url) } override fun verifyConsumerFromFile(pactFile: PactSource, consumer: IConsumerInfo) { - jsonData["execution"].asArray().last()["consumer"].asObject()["source"] = jsonObject( + jsonData["execution"].asArray()!!.last()["consumer"].asObject()!!["source"] = jsonObject( "file" to if (pactFile is FileSource<*>) pactFile.file.toString() else pactFile.description() ) } @@ -117,7 +117,7 @@ class JsonReporter( "interactions" to JsonValue.Array() )) } - jsonData["execution"].asArray().last().asObject()["result"] = jsonObject( + jsonData["execution"].asArray()!!.last().asObject()!!["result"] = jsonObject( "state" to "Pact Load Failure", "message" to message ) @@ -128,7 +128,7 @@ class JsonReporter( override fun warnPactFileHasNoInteractions(pact: Pact) { } override fun interactionDescription(interaction: Interaction) { - jsonData["execution"].asArray().last()["interactions"].asArray().add(jsonObject( + jsonData["execution"].asArray()!!.last()["interactions"].asArray()!!.add(jsonObject( "interaction" to Json.toJson(interaction.toMap(PactSpecVersion.V3)), "verification" to jsonObject("result" to "OK") )) @@ -149,7 +149,7 @@ class JsonReporter( e: Exception, printStackTrace: Boolean ) { - val interactions = jsonData["execution"].asArray().last()["interactions"].asArray() + val interactions = jsonData["execution"].asArray()!!.last()["interactions"].asArray()!! val error = jsonObject( "result" to FAILED, "message" to "State change '$state' callback failed", @@ -163,7 +163,7 @@ class JsonReporter( "verification" to error )) } else { - interactions.last().asObject()["verification"] = error + interactions.last().asObject()!!["verification"] = error } } @@ -184,14 +184,15 @@ class JsonReporter( e: Exception, printStackTrace: Boolean ) { - jsonData["execution"].asArray().last()["interactions"].asArray().last().asObject()["verification"] = jsonObject( - "result" to FAILED, - "message" to interactionMessage, - "exception" to jsonObject( - "message" to e.message, - "stackTrace" to jsonArray(ExceptionUtils.getStackFrames(e).toList()) + jsonData["execution"].asArray()!!.last()["interactions"].asArray()!!.last().asObject()!!["verification"] = + jsonObject( + "result" to FAILED, + "message" to interactionMessage, + "exception" to jsonObject( + "message" to e.message, + "stackTrace" to jsonArray(ExceptionUtils.getStackFrames(e).toList()) + ) ) - ) } override fun returnsAResponseWhich() { } @@ -199,8 +200,8 @@ class JsonReporter( override fun statusComparisonOk(status: Int) { } override fun statusComparisonFailed(status: Int, comparison: Any) { - val verification = jsonData["execution"].asArray().last()["interactions"].asArray().last()["verification"] - .asObject() + val verification = jsonData["execution"].asArray()!!.last()["interactions"].asArray()!!.last()["verification"] + .asObject()!! verification["result"] = FAILED val statusJson = jsonArray( if (comparison.hasProperty("message")) { @@ -217,13 +218,13 @@ class JsonReporter( override fun headerComparisonOk(key: String, value: List) { } override fun headerComparisonFailed(key: String, value: List, comparison: Any) { - val verification = jsonData["execution"].asArray().last()["interactions"].asArray().last()["verification"] - .asObject() + val verification = jsonData["execution"].asArray()!!.last()["interactions"].asArray()!!.last()["verification"] + .asObject()!! verification["result"] = FAILED if (!verification.has("header")) { verification["header"] = jsonObject() } - verification["header"].asObject()[key] = when (comparison) { + verification["header"].asObject()!![key] = when (comparison) { is List<*> -> Json.toJson(comparison.map { when (it) { is HeaderMismatch -> JsonValue.StringValue(JsonToken.StringValue(it.mismatch.toCharArray())) @@ -237,8 +238,8 @@ class JsonReporter( override fun bodyComparisonOk() { } override fun bodyComparisonFailed(comparison: Any) { - val verification = jsonData["execution"].asArray().last()["interactions"].asArray().last()["verification"] - .asObject() + val verification = jsonData["execution"].asArray()!!.last()["interactions"].asArray()!!.last()["verification"] + .asObject()!! verification["result"] = FAILED verification["body"] = when (comparison) { is Err<*> -> Json.toJson((comparison as Err).error.description()) @@ -248,19 +249,21 @@ class JsonReporter( } override fun errorHasNoAnnotatedMethodsFoundForInteraction(interaction: Interaction) { - jsonData["execution"].asArray().last()["interactions"].asArray().last().asObject()["verification"] = jsonObject( - "result" to FAILED, - "cause" to jsonObject("message" to "No Annotated Methods Found For Interaction") - ) + jsonData["execution"].asArray()!!.last()["interactions"].asArray()!!.last().asObject()!!["verification"] = + jsonObject( + "result" to FAILED, + "cause" to jsonObject("message" to "No Annotated Methods Found For Interaction") + ) } override fun verificationFailed(interaction: Interaction, e: Exception, printStackTrace: Boolean) { - jsonData["execution"].asArray().last()["interactions"].asArray().last().asObject()["verification"] = jsonObject( - "result" to FAILED, - "exception" to jsonObject( - "message" to e.message, - "stackTrace" to ExceptionUtils.getStackFrames(e) - ) + jsonData["execution"].asArray()!!.last()["interactions"].asArray()!!.last().asObject()!!["verification"] = + jsonObject( + "result" to FAILED, + "exception" to jsonObject( + "message" to e.message, + "stackTrace" to ExceptionUtils.getStackFrames(e) + ) ) } @@ -271,13 +274,13 @@ class JsonReporter( override fun displayFailures(failures: List) { } override fun metadataComparisonFailed(key: String, value: Any?, comparison: Any) { - val verification = jsonData["execution"].asArray().last()["interactions"].asArray().last()["verification"] - .asObject() + val verification = jsonData["execution"].asArray()!!.last()["interactions"].asArray()!!.last()["verification"] + .asObject()!! verification["result"] = FAILED if (!verification.has("metadata")) { verification["metadata"] = jsonObject() } - verification["metadata"].asObject()[key] = comparison + verification["metadata"].asObject()!![key] = comparison } override fun includesMetadata() { } @@ -291,7 +294,7 @@ class JsonReporter( provider: IProviderInfo, notices: List ) { - jsonData["execution"].asArray().last()["consumer"].asObject()["notices"] = jsonArray(notices.map { it.text }) + jsonData["execution"].asArray()!!.last()["consumer"].asObject()!!["notices"] = jsonArray(notices.map { it.text }) } override fun warnPublishResultsSkippedBecauseFiltered() { }