First implementation based on existing tests

This commit is contained in:
Tim Ysewyn
2019-08-02 11:13:45 +02:00
parent 746fe40f80
commit 9935b24a25
25 changed files with 1661 additions and 342 deletions

View File

@@ -24,6 +24,7 @@
<modules>
<module>spring-cloud-contract-spec-java</module>
<module>spring-cloud-contract-spec-groovy</module>
<module>spring-cloud-contract-spec-kotlin</module>
<module>spring-cloud-contract-spec</module>
</modules>

View File

@@ -36,8 +36,6 @@ public class BodyMatchers {
protected final List<BodyMatcher> matchers = new LinkedList<>();
private final RegexPatterns regexPatterns = new RegexPatterns();
public void jsonPath(String path, MatchingTypeValue matchingType) {
this.matchers.add(new PathBodyMatcher(path, matchingType));
}
@@ -71,16 +69,15 @@ public class BodyMatchers {
}
public MatchingTypeValue byDate() {
return new MatchingTypeValue(MatchingType.DATE, this.regexPatterns.isoDate());
return new MatchingTypeValue(MatchingType.DATE, RegexPatterns.isoDate());
}
public MatchingTypeValue byTime() {
return new MatchingTypeValue(MatchingType.TIME, this.regexPatterns.isoTime());
return new MatchingTypeValue(MatchingType.TIME, RegexPatterns.isoTime());
}
public MatchingTypeValue byTimestamp() {
return new MatchingTypeValue(MatchingType.TIMESTAMP,
this.regexPatterns.isoDateTime());
return new MatchingTypeValue(MatchingType.TIMESTAMP, RegexPatterns.isoDateTime());
}
public RegexMatchingTypeValue byRegex(String regex) {

View File

@@ -32,12 +32,12 @@ import java.util.stream.Collectors;
/**
* Contains useful common methods for the DSL.
*
* @author Marcin Grzejszczak
* @author Tim Ysewyn
* @since 1.0.0
*/
public class Common {
private final RegexPatterns regexPatterns = new RegexPatterns();
public Map<String, DslProperty> convertObjectsToDslProperties(
Map<String, Object> body) {
return body.entrySet().stream().collect(Collectors.toMap(
@@ -324,79 +324,79 @@ public class Common {
}
public RegexProperty onlyAlphaUnicode() {
return regexPatterns.onlyAlphaUnicode();
return RegexPatterns.onlyAlphaUnicode();
}
public RegexProperty alphaNumeric() {
return regexPatterns.alphaNumeric();
return RegexPatterns.alphaNumeric();
}
public RegexProperty number() {
return regexPatterns.number();
return RegexPatterns.number();
}
public RegexProperty positiveInt() {
return regexPatterns.positiveInt();
return RegexPatterns.positiveInt();
}
public RegexProperty anyBoolean() {
return regexPatterns.anyBoolean();
return RegexPatterns.anyBoolean();
}
public RegexProperty anInteger() {
return regexPatterns.anInteger();
return RegexPatterns.anInteger();
}
public RegexProperty aDouble() {
return regexPatterns.aDouble();
return RegexPatterns.aDouble();
}
public RegexProperty ipAddress() {
return regexPatterns.ipAddress();
return RegexPatterns.ipAddress();
}
public RegexProperty hostname() {
return regexPatterns.hostname();
return RegexPatterns.hostname();
}
public RegexProperty email() {
return regexPatterns.email();
return RegexPatterns.email();
}
public RegexProperty url() {
return regexPatterns.url();
return RegexPatterns.url();
}
public RegexProperty httpsUrl() {
return regexPatterns.httpsUrl();
return RegexPatterns.httpsUrl();
}
public RegexProperty uuid() {
return regexPatterns.uuid();
return RegexPatterns.uuid();
}
public RegexProperty isoDate() {
return regexPatterns.isoDate();
return RegexPatterns.isoDate();
}
public RegexProperty isoDateTime() {
return regexPatterns.isoDateTime();
return RegexPatterns.isoDateTime();
}
public RegexProperty isoTime() {
return regexPatterns.isoTime();
return RegexPatterns.isoTime();
}
public RegexProperty iso8601WithOffset() {
return regexPatterns.iso8601WithOffset();
return RegexPatterns.iso8601WithOffset();
}
public RegexProperty nonEmpty() {
return regexPatterns.nonEmpty();
return RegexPatterns.nonEmpty();
}
public RegexProperty nonBlank() {
return regexPatterns.nonBlank();
return RegexPatterns.nonBlank();
}
}

View File

@@ -20,6 +20,7 @@ package org.springframework.cloud.contract.spec.internal;
* Helper functions for HTTP statuses.
*
* @author Marcin Grzejszczak
* @author Tim Ysewyn
* @since 2.0.0
*/
public class HttpStatus {
@@ -29,7 +30,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.2.1" > HTTP/1.1:
* Semantics and Content, section 6.2.1</a>
*/
public int CONTINUE() {
public static int CONTINUE() {
return 100;
}
@@ -38,7 +39,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.2.2" > HTTP/1.1:
* Semantics and Content, section 6.2.2</a>
*/
public int SWITCHING_PROTOCOLS() {
public static int SWITCHING_PROTOCOLS() {
return 101;
}
@@ -46,7 +47,7 @@ public class HttpStatus {
* {@code 102 Processing}.
* @see <ahref="https://tools.ietf.org/html/rfc2518#section-10.1" > WebDAV</a>
*/
public int PROCESSING() {
public static int PROCESSING() {
return 102;
}
@@ -55,7 +56,7 @@ public class HttpStatus {
* @see <ahref="https://code.google.com/p/gears/wiki/ResumableHttpRequestsProposal" >
* A proposal for supporting resumable POST/PUT HTTP requests in HTTP/1.0</a>
*/
public int CHECKPOINT() {
public static int CHECKPOINT() {
return 103;
}
@@ -64,7 +65,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.3.1" > HTTP/1.1:
* Semantics and Content, section 6.3.1</a>
*/
public int OK() {
public static int OK() {
return 200;
}
@@ -73,7 +74,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.3.2" > HTTP/1.1:
* Semantics and Content, section 6.3.2</a>
*/
public int CREATED() {
public static int CREATED() {
return 201;
}
@@ -82,7 +83,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.3.3" > HTTP/1.1:
* Semantics and Content, section 6.3.3</a>
*/
public int ACCEPTED() {
public static int ACCEPTED() {
return 202;
}
@@ -91,7 +92,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.3.4" > HTTP/1.1:
* Semantics and Content, section 6.3.4</a>
*/
public int NON_AUTHORITATIVE_INFORMATION() {
public static int NON_AUTHORITATIVE_INFORMATION() {
return 203;
}
@@ -100,7 +101,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.3.5" > HTTP/1.1:
* Semantics and Content, section 6.3.5</a>
*/
public int NO_CONTENT() {
public static int NO_CONTENT() {
return 204;
}
@@ -109,7 +110,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.3.6" > HTTP/1.1:
* Semantics and Content, section 6.3.6</a>
*/
public int RESET_CONTENT() {
public static int RESET_CONTENT() {
return 205;
}
@@ -118,7 +119,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7233#section-4.1" > HTTP/1.1: Range
* Requests, section 4.1</a>
*/
public int PARTIAL_CONTENT() {
public static int PARTIAL_CONTENT() {
return 206;
}
@@ -126,7 +127,7 @@ public class HttpStatus {
* {@code 207 Multi-Status}.
* @see <ahref="https://tools.ietf.org/html/rfc4918#section-13" > WebDAV</a>
*/
public int MULTI_STATUS() {
public static int MULTI_STATUS() {
return 207;
}
@@ -135,7 +136,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc5842#section-7.1" > WebDAV Binding
* Extensions</a>
*/
public int ALREADY_REPORTED() {
public static int ALREADY_REPORTED() {
return 208;
}
@@ -144,7 +145,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc3229#section-10.4.1" > Delta encoding
* in HTTP</a>
*/
public int IM_USED() {
public static int IM_USED() {
return 226;
}
@@ -153,7 +154,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.4.1" > HTTP/1.1:
* Semantics and Content, section 6.4.1</a>
*/
public int MULTIPLE_CHOICES() {
public static int MULTIPLE_CHOICES() {
return 300;
}
@@ -162,7 +163,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.4.2" > HTTP/1.1:
* Semantics and Content, section 6.4.2</a>
*/
public int MOVED_PERMANENTLY() {
public static int MOVED_PERMANENTLY() {
return 301;
}
@@ -171,7 +172,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.4.3" > HTTP/1.1:
* Semantics and Content, section 6.4.3</a>
*/
public int FOUND() {
public static int FOUND() {
return 302;
}
@@ -183,7 +184,7 @@ public class HttpStatus {
* {@code HttpStatus.valueOf(302)}
*/
@Deprecated
public int MOVED_TEMPORARILY() {
public static int MOVED_TEMPORARILY() {
return 302;
}
@@ -192,7 +193,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.4.4" > HTTP/1.1:
* Semantics and Content, section 6.4.4</a>
*/
public int SEE_OTHER() {
public static int SEE_OTHER() {
return 303;
}
@@ -201,7 +202,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7232#section-4.1" > HTTP/1.1:
* Conditional Requests, section 4.1</a>
*/
public int NOT_MODIFIED() {
public static int NOT_MODIFIED() {
return 304;
}
@@ -212,7 +213,7 @@ public class HttpStatus {
* @deprecated due to security concerns regarding in-band configuration of a proxy
*/
@Deprecated
public int USE_PROXY() {
public static int USE_PROXY() {
return 305;
}
@@ -221,7 +222,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.4.7" > HTTP/1.1:
* Semantics and Content, section 6.4.7</a>
*/
public int TEMPORARY_REDIRECT() {
public static int TEMPORARY_REDIRECT() {
return 307;
}
@@ -229,7 +230,7 @@ public class HttpStatus {
* {@code 308 Permanent Redirect}.
* @see <ahref="https://tools.ietf.org/html/rfc7238" > RFC 7238</a>
*/
public int PERMANENT_REDIRECT() {
public static int PERMANENT_REDIRECT() {
return 308;
}
@@ -238,7 +239,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.1" > HTTP/1.1:
* Semantics and Content, section 6.5.1</a>
*/
public int BAD_REQUEST() {
public static int BAD_REQUEST() {
return 400;
}
@@ -247,7 +248,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7235#section-3.1" > HTTP/1.1:
* Authentication, section 3.1</a>
*/
public int UNAUTHORIZED() {
public static int UNAUTHORIZED() {
return 401;
}
@@ -256,7 +257,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.2" > HTTP/1.1:
* Semantics and Content, section 6.5.2</a>
*/
public int PAYMENT_REQUIRED() {
public static int PAYMENT_REQUIRED() {
return 402;
}
@@ -265,7 +266,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.3" > HTTP/1.1:
* Semantics and Content, section 6.5.3</a>
*/
public int FORBIDDEN() {
public static int FORBIDDEN() {
return 403;
}
@@ -274,7 +275,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.4" > HTTP/1.1:
* Semantics and Content, section 6.5.4</a>
*/
public int NOT_FOUND() {
public static int NOT_FOUND() {
return 404;
}
@@ -283,7 +284,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.5" > HTTP/1.1:
* Semantics and Content, section 6.5.5</a>
*/
public int METHOD_NOT_ALLOWED() {
public static int METHOD_NOT_ALLOWED() {
return 405;
}
@@ -292,7 +293,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.6" > HTTP/1.1:
* Semantics and Content, section 6.5.6</a>
*/
public int NOT_ACCEPTABLE() {
public static int NOT_ACCEPTABLE() {
return 406;
}
@@ -301,7 +302,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7235#section-3.2" > HTTP/1.1:
* Authentication, section 3.2</a>
*/
public int PROXY_AUTHENTICATION_REQUIRED() {
public static int PROXY_AUTHENTICATION_REQUIRED() {
return 407;
}
@@ -310,7 +311,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.7" > HTTP/1.1:
* Semantics and Content, section 6.5.7</a>
*/
public int REQUEST_TIMEOUT() {
public static int REQUEST_TIMEOUT() {
return 408;
}
@@ -319,7 +320,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.8" > HTTP/1.1:
* Semantics and Content, section 6.5.8</a>
*/
public int CONFLICT() {
public static int CONFLICT() {
return 409;
}
@@ -328,7 +329,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.9" > HTTP/1.1:
* Semantics and Content, section 6.5.9</a>
*/
public int GONE() {
public static int GONE() {
return 410;
}
@@ -337,7 +338,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.10" > HTTP/1.1:
* Semantics and Content, section 6.5.10</a>
*/
public int LENGTH_REQUIRED() {
public static int LENGTH_REQUIRED() {
return 411;
}
@@ -346,7 +347,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7232#section-4.2" > HTTP/1.1:
* Conditional Requests, section 4.2</a>
*/
public int PRECONDITION_FAILED() {
public static int PRECONDITION_FAILED() {
return 412;
}
@@ -355,7 +356,7 @@ public class HttpStatus {
* @since 4.1* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.11" >
* HTTP/1.1: Semantics and Content, section 6.5.11</a>
*/
public int PAYLOAD_TOO_LARGE() {
public static int PAYLOAD_TOO_LARGE() {
return 413;
}
@@ -367,7 +368,7 @@ public class HttpStatus {
* {@code HttpStatus.valueOf(413)}
*/
@Deprecated
public int REQUEST_ENTITY_TOO_LARGE() {
public static int REQUEST_ENTITY_TOO_LARGE() {
return 413;
}
@@ -376,7 +377,7 @@ public class HttpStatus {
* @since 4.1* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.12" >
* HTTP/1.1: Semantics and Content, section 6.5.12</a>
*/
public int URI_TOO_LONG() {
public static int URI_TOO_LONG() {
return 414;
}
@@ -388,7 +389,7 @@ public class HttpStatus {
* {@code HttpStatus.valueOf(414)}
*/
@Deprecated
public int REQUEST_URI_TOO_LONG() {
public static int REQUEST_URI_TOO_LONG() {
return 414;
}
@@ -397,7 +398,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.13" > HTTP/1.1:
* Semantics and Content, section 6.5.13</a>
*/
public int UNSUPPORTED_MEDIA_TYPE() {
public static int UNSUPPORTED_MEDIA_TYPE() {
return 415;
}
@@ -406,7 +407,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7233#section-4.4" > HTTP/1.1: Range
* Requests, section 4.4</a>
*/
public int REQUESTED_RANGE_NOT_SATISFIABLE() {
public static int REQUESTED_RANGE_NOT_SATISFIABLE() {
return 416;
}
@@ -415,7 +416,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.5.14" > HTTP/1.1:
* Semantics and Content, section 6.5.14</a>
*/
public int EXPECTATION_FAILED() {
public static int EXPECTATION_FAILED() {
return 417;
}
@@ -423,7 +424,7 @@ public class HttpStatus {
* {@code 418 I'm a teapot}.
* @see <ahref="https://tools.ietf.org/html/rfc2324#section-2.3.2" > HTCPCP/1.0</a>
*/
public int I_AM_A_TEAPOT() {
public static int I_AM_A_TEAPOT() {
return 418;
}
@@ -433,7 +434,7 @@ public class HttpStatus {
* Draft Changes</a>
*/
@Deprecated
public int INSUFFICIENT_SPACE_ON_RESOURCE() {
public static int INSUFFICIENT_SPACE_ON_RESOURCE() {
return 419;
}
@@ -443,7 +444,7 @@ public class HttpStatus {
* Draft Changes</a>
*/
@Deprecated
public int METHOD_FAILURE() {
public static int METHOD_FAILURE() {
return 420;
}
@@ -453,7 +454,7 @@ public class HttpStatus {
* Draft Changes</a>
*/
@Deprecated
public int DESTINATION_LOCKED() {
public static int DESTINATION_LOCKED() {
return 421;
}
@@ -461,7 +462,7 @@ public class HttpStatus {
* {@code 422 Unprocessable Entity}.
* @see <ahref="https://tools.ietf.org/html/rfc4918#section-11.2" > WebDAV</a>
*/
public int UNPROCESSABLE_ENTITY() {
public static int UNPROCESSABLE_ENTITY() {
return 422;
}
@@ -469,7 +470,7 @@ public class HttpStatus {
* {@code 423 Locked}.
* @see <ahref="https://tools.ietf.org/html/rfc4918#section-11.3" > WebDAV</a>
*/
public int LOCKED() {
public static int LOCKED() {
return 423;
}
@@ -477,7 +478,7 @@ public class HttpStatus {
* {@code 424 Failed Dependency}.
* @see <ahref="https://tools.ietf.org/html/rfc4918#section-11.4" > WebDAV</a>
*/
public int FAILED_DEPENDENCY() {
public static int FAILED_DEPENDENCY() {
return 424;
}
@@ -486,7 +487,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc2817#section-6" > Upgrading to TLS
* Within HTTP/1.1</a>
*/
public int UPGRADE_REQUIRED() {
public static int UPGRADE_REQUIRED() {
return 426;
}
@@ -495,7 +496,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc6585#section-3" > Additional HTTP
* Status Codes</a>
*/
public int PRECONDITION_REQUIRED() {
public static int PRECONDITION_REQUIRED() {
return 428;
}
@@ -504,7 +505,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc6585#section-4" > Additional HTTP
* Status Codes</a>
*/
public int TOO_MANY_REQUESTS() {
public static int TOO_MANY_REQUESTS() {
return 429;
}
@@ -513,7 +514,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc6585#section-5" > Additional HTTP
* Status Codes</a>
*/
public int REQUEST_HEADER_FIELDS_TOO_LARGE() {
public static int REQUEST_HEADER_FIELDS_TOO_LARGE() {
return 431;
}
@@ -523,7 +524,7 @@ public class HttpStatus {
* > An HTTP Status Code to Report Legal Obstacles</a>
* @since 4.3
*/
public int UNAVAILABLE_FOR_LEGAL_REASONS() {
public static int UNAVAILABLE_FOR_LEGAL_REASONS() {
return 451;
}
@@ -532,7 +533,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.6.1" > HTTP/1.1:
* Semantics and Content, section 6.6.1</a>
*/
public int INTERNAL_SERVER_ERROR() {
public static int INTERNAL_SERVER_ERROR() {
return 500;
}
@@ -541,7 +542,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.6.2" > HTTP/1.1:
* Semantics and Content, section 6.6.2</a>
*/
public int NOT_IMPLEMENTED() {
public static int NOT_IMPLEMENTED() {
return 501;
}
@@ -550,7 +551,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.6.3" > HTTP/1.1:
* Semantics and Content, section 6.6.3</a>
*/
public int BAD_GATEWAY() {
public static int BAD_GATEWAY() {
return 502;
}
@@ -559,7 +560,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.6.4" > HTTP/1.1:
* Semantics and Content, section 6.6.4</a>
*/
public int SERVICE_UNAVAILABLE() {
public static int SERVICE_UNAVAILABLE() {
return 503;
}
@@ -568,7 +569,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.6.5" > HTTP/1.1:
* Semantics and Content, section 6.6.5</a>
*/
public int GATEWAY_TIMEOUT() {
public static int GATEWAY_TIMEOUT() {
return 504;
}
@@ -577,7 +578,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc7231#section-6.6.6" > HTTP/1.1:
* Semantics and Content, section 6.6.6</a>
*/
public int HTTP_VERSION_NOT_SUPPORTED() {
public static int HTTP_VERSION_NOT_SUPPORTED() {
return 505;
}
@@ -586,7 +587,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc2295#section-8.1" > Transparent Content
* Negotiation</a>
*/
public int VARIANT_ALSO_NEGOTIATES() {
public static int VARIANT_ALSO_NEGOTIATES() {
return 506;
}
@@ -594,7 +595,7 @@ public class HttpStatus {
* {@code 507 Insufficient Storage}
* @see <ahref="https://tools.ietf.org/html/rfc4918#section-11.5" > WebDAV</a>
*/
public int INSUFFICIENT_STORAGE() {
public static int INSUFFICIENT_STORAGE() {
return 507;
}
@@ -603,14 +604,14 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc5842#section-7.2" > WebDAV Binding
* Extensions</a>
*/
public int LOOP_DETECTED() {
public static int LOOP_DETECTED() {
return 508;
}
/**
* {@code 509 Bandwidth Limit Exceeded}
*/
public int BANDWIDTH_LIMIT_EXCEEDED() {
public static int BANDWIDTH_LIMIT_EXCEEDED() {
return 509;
}
@@ -619,7 +620,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc2774#section-7" > HTTP Extension
* Framework</a>
*/
public int NOT_EXTENDED() {
public static int NOT_EXTENDED() {
return 510;
}
@@ -628,7 +629,7 @@ public class HttpStatus {
* @see <ahref="https://tools.ietf.org/html/rfc6585#section-6" > Additional HTTP
* Status Codes</a>
*/
public int NETWORK_AUTHENTICATION_REQUIRED() {
public static int NETWORK_AUTHENTICATION_REQUIRED() {
return 511;
}

View File

@@ -27,9 +27,12 @@ import java.util.stream.Collectors;
* @author Tim Ysewyn
* @since 1.0.0
*/
public class RegexPatterns {
public final class RegexPatterns {
private RegexPatterns() {
// Shouldn't be instantiated
}
// tag::regexps[]
protected static final Pattern TRUE_OR_FALSE = Pattern.compile("(true|false)");
protected static final Pattern ALPHA_NUMERIC = Pattern.compile("[a-zA-Z0-9]+");
@@ -108,82 +111,84 @@ public class RegexPatterns {
return contentType.toString();
}
public RegexProperty onlyAlphaUnicode() {
// tag::regexps[]
public static RegexProperty onlyAlphaUnicode() {
return new RegexProperty(ONLY_ALPHA_UNICODE).asString();
}
public RegexProperty alphaNumeric() {
public static RegexProperty alphaNumeric() {
return new RegexProperty(ALPHA_NUMERIC).asString();
}
public RegexProperty number() {
public static RegexProperty number() {
return new RegexProperty(NUMBER).asDouble();
}
public RegexProperty positiveInt() {
public static RegexProperty positiveInt() {
return new RegexProperty(POSITIVE_INT).asInteger();
}
public RegexProperty anyBoolean() {
public static RegexProperty anyBoolean() {
return new RegexProperty(TRUE_OR_FALSE).asBooleanType();
}
public RegexProperty anInteger() {
public static RegexProperty anInteger() {
return new RegexProperty(INTEGER).asInteger();
}
public RegexProperty aDouble() {
public static RegexProperty aDouble() {
return new RegexProperty(DOUBLE).asDouble();
}
public RegexProperty ipAddress() {
public static RegexProperty ipAddress() {
return new RegexProperty(IP_ADDRESS).asString();
}
public RegexProperty hostname() {
public static RegexProperty hostname() {
return new RegexProperty(HOSTNAME_PATTERN).asString();
}
public RegexProperty email() {
public static RegexProperty email() {
return new RegexProperty(EMAIL).asString();
}
public RegexProperty url() {
public static RegexProperty url() {
return new RegexProperty(URL).asString();
}
public RegexProperty httpsUrl() {
public static RegexProperty httpsUrl() {
return new RegexProperty(HTTPS_URL).asString();
}
public RegexProperty uuid() {
public static RegexProperty uuid() {
return new RegexProperty(UUID).asString();
}
public RegexProperty isoDate() {
public static RegexProperty isoDate() {
return new RegexProperty(ANY_DATE).asString();
}
public RegexProperty isoDateTime() {
public static RegexProperty isoDateTime() {
return new RegexProperty(ANY_DATE_TIME).asString();
}
public RegexProperty isoTime() {
public static RegexProperty isoTime() {
return new RegexProperty(ANY_TIME).asString();
}
public static RegexProperty iso8601WithOffset() {
return new RegexProperty(ISO8601_WITH_OFFSET).asString();
}
public static RegexProperty nonEmpty() {
return new RegexProperty(NON_EMPTY).asString();
}
public static RegexProperty nonBlank() {
return new RegexProperty(NON_BLANK).asString();
}
// end::regexps[]
public RegexProperty iso8601WithOffset() {
return new RegexProperty(ISO8601_WITH_OFFSET).asString();
}
public RegexProperty nonEmpty() {
return new RegexProperty(NON_EMPTY).asString();
}
public RegexProperty nonBlank() {
return new RegexProperty(NON_BLANK).asString();
}
}

View File

@@ -56,8 +56,6 @@ public class Response extends Common implements RegexCreatingProperty<ServerDslP
private ServerPatternValueDslProperty property = new ServerPatternValueDslProperty();
private HttpStatus httpStatus = new HttpStatus();
public Response() {
}
@@ -251,14 +249,6 @@ public class Response extends Common implements RegexCreatingProperty<ServerDslP
this.property = property;
}
public HttpStatus getHttpStatus() {
return httpStatus;
}
public void setHttpStatus(HttpStatus httpStatus) {
this.httpStatus = httpStatus;
}
public DslProperty getStatus() {
return status;
}
@@ -425,278 +415,278 @@ public class Response extends Common implements RegexCreatingProperty<ServerDslP
}
public int CONTINUE() {
return httpStatus.CONTINUE();
return HttpStatus.CONTINUE();
}
public int SWITCHING_PROTOCOLS() {
return httpStatus.SWITCHING_PROTOCOLS();
return HttpStatus.SWITCHING_PROTOCOLS();
}
public int PROCESSING() {
return httpStatus.PROCESSING();
return HttpStatus.PROCESSING();
}
public int CHECKPOINT() {
return httpStatus.CHECKPOINT();
return HttpStatus.CHECKPOINT();
}
public int OK() {
return httpStatus.OK();
return HttpStatus.OK();
}
public int CREATED() {
return httpStatus.CREATED();
return HttpStatus.CREATED();
}
public int ACCEPTED() {
return httpStatus.ACCEPTED();
return HttpStatus.ACCEPTED();
}
public int NON_AUTHORITATIVE_INFORMATION() {
return httpStatus.NON_AUTHORITATIVE_INFORMATION();
return HttpStatus.NON_AUTHORITATIVE_INFORMATION();
}
public int NO_CONTENT() {
return httpStatus.NO_CONTENT();
return HttpStatus.NO_CONTENT();
}
public int RESET_CONTENT() {
return httpStatus.RESET_CONTENT();
return HttpStatus.RESET_CONTENT();
}
public int PARTIAL_CONTENT() {
return httpStatus.PARTIAL_CONTENT();
return HttpStatus.PARTIAL_CONTENT();
}
public int MULTI_STATUS() {
return httpStatus.MULTI_STATUS();
return HttpStatus.MULTI_STATUS();
}
public int ALREADY_REPORTED() {
return httpStatus.ALREADY_REPORTED();
return HttpStatus.ALREADY_REPORTED();
}
public int IM_USED() {
return httpStatus.IM_USED();
return HttpStatus.IM_USED();
}
public int MULTIPLE_CHOICES() {
return httpStatus.MULTIPLE_CHOICES();
return HttpStatus.MULTIPLE_CHOICES();
}
public int MOVED_PERMANENTLY() {
return httpStatus.MOVED_PERMANENTLY();
return HttpStatus.MOVED_PERMANENTLY();
}
public int FOUND() {
return httpStatus.FOUND();
return HttpStatus.FOUND();
}
@Deprecated
public int MOVED_TEMPORARILY() {
return httpStatus.MOVED_TEMPORARILY();
return HttpStatus.MOVED_TEMPORARILY();
}
public int SEE_OTHER() {
return httpStatus.SEE_OTHER();
return HttpStatus.SEE_OTHER();
}
public int NOT_MODIFIED() {
return httpStatus.NOT_MODIFIED();
return HttpStatus.NOT_MODIFIED();
}
@Deprecated
public int USE_PROXY() {
return httpStatus.USE_PROXY();
return HttpStatus.USE_PROXY();
}
public int TEMPORARY_REDIRECT() {
return httpStatus.TEMPORARY_REDIRECT();
return HttpStatus.TEMPORARY_REDIRECT();
}
public int PERMANENT_REDIRECT() {
return httpStatus.PERMANENT_REDIRECT();
return HttpStatus.PERMANENT_REDIRECT();
}
public int BAD_REQUEST() {
return httpStatus.BAD_REQUEST();
return HttpStatus.BAD_REQUEST();
}
public int UNAUTHORIZED() {
return httpStatus.UNAUTHORIZED();
return HttpStatus.UNAUTHORIZED();
}
public int PAYMENT_REQUIRED() {
return httpStatus.PAYMENT_REQUIRED();
return HttpStatus.PAYMENT_REQUIRED();
}
public int FORBIDDEN() {
return httpStatus.FORBIDDEN();
return HttpStatus.FORBIDDEN();
}
public int NOT_FOUND() {
return httpStatus.NOT_FOUND();
return HttpStatus.NOT_FOUND();
}
public int METHOD_NOT_ALLOWED() {
return httpStatus.METHOD_NOT_ALLOWED();
return HttpStatus.METHOD_NOT_ALLOWED();
}
public int NOT_ACCEPTABLE() {
return httpStatus.NOT_ACCEPTABLE();
return HttpStatus.NOT_ACCEPTABLE();
}
public int PROXY_AUTHENTICATION_REQUIRED() {
return httpStatus.PROXY_AUTHENTICATION_REQUIRED();
return HttpStatus.PROXY_AUTHENTICATION_REQUIRED();
}
public int REQUEST_TIMEOUT() {
return httpStatus.REQUEST_TIMEOUT();
return HttpStatus.REQUEST_TIMEOUT();
}
public int CONFLICT() {
return httpStatus.CONFLICT();
return HttpStatus.CONFLICT();
}
public int GONE() {
return httpStatus.GONE();
return HttpStatus.GONE();
}
public int LENGTH_REQUIRED() {
return httpStatus.LENGTH_REQUIRED();
return HttpStatus.LENGTH_REQUIRED();
}
public int PRECONDITION_FAILED() {
return httpStatus.PRECONDITION_FAILED();
return HttpStatus.PRECONDITION_FAILED();
}
public int PAYLOAD_TOO_LARGE() {
return httpStatus.PAYLOAD_TOO_LARGE();
return HttpStatus.PAYLOAD_TOO_LARGE();
}
@Deprecated
public int REQUEST_ENTITY_TOO_LARGE() {
return httpStatus.REQUEST_ENTITY_TOO_LARGE();
return HttpStatus.REQUEST_ENTITY_TOO_LARGE();
}
public int URI_TOO_LONG() {
return httpStatus.URI_TOO_LONG();
return HttpStatus.URI_TOO_LONG();
}
@Deprecated
public int REQUEST_URI_TOO_LONG() {
return httpStatus.REQUEST_URI_TOO_LONG();
return HttpStatus.REQUEST_URI_TOO_LONG();
}
public int UNSUPPORTED_MEDIA_TYPE() {
return httpStatus.UNSUPPORTED_MEDIA_TYPE();
return HttpStatus.UNSUPPORTED_MEDIA_TYPE();
}
public int REQUESTED_RANGE_NOT_SATISFIABLE() {
return httpStatus.REQUESTED_RANGE_NOT_SATISFIABLE();
return HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE();
}
public int EXPECTATION_FAILED() {
return httpStatus.EXPECTATION_FAILED();
return HttpStatus.EXPECTATION_FAILED();
}
public int I_AM_A_TEAPOT() {
return httpStatus.I_AM_A_TEAPOT();
return HttpStatus.I_AM_A_TEAPOT();
}
@Deprecated
public int INSUFFICIENT_SPACE_ON_RESOURCE() {
return httpStatus.INSUFFICIENT_SPACE_ON_RESOURCE();
return HttpStatus.INSUFFICIENT_SPACE_ON_RESOURCE();
}
@Deprecated
public int METHOD_FAILURE() {
return httpStatus.METHOD_FAILURE();
return HttpStatus.METHOD_FAILURE();
}
@Deprecated
public int DESTINATION_LOCKED() {
return httpStatus.DESTINATION_LOCKED();
return HttpStatus.DESTINATION_LOCKED();
}
public int UNPROCESSABLE_ENTITY() {
return httpStatus.UNPROCESSABLE_ENTITY();
return HttpStatus.UNPROCESSABLE_ENTITY();
}
public int LOCKED() {
return httpStatus.LOCKED();
return HttpStatus.LOCKED();
}
public int FAILED_DEPENDENCY() {
return httpStatus.FAILED_DEPENDENCY();
return HttpStatus.FAILED_DEPENDENCY();
}
public int UPGRADE_REQUIRED() {
return httpStatus.UPGRADE_REQUIRED();
return HttpStatus.UPGRADE_REQUIRED();
}
public int PRECONDITION_REQUIRED() {
return httpStatus.PRECONDITION_REQUIRED();
return HttpStatus.PRECONDITION_REQUIRED();
}
public int TOO_MANY_REQUESTS() {
return httpStatus.TOO_MANY_REQUESTS();
return HttpStatus.TOO_MANY_REQUESTS();
}
public int REQUEST_HEADER_FIELDS_TOO_LARGE() {
return httpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE();
return HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE();
}
public int UNAVAILABLE_FOR_LEGAL_REASONS() {
return httpStatus.UNAVAILABLE_FOR_LEGAL_REASONS();
return HttpStatus.UNAVAILABLE_FOR_LEGAL_REASONS();
}
public int INTERNAL_SERVER_ERROR() {
return httpStatus.INTERNAL_SERVER_ERROR();
return HttpStatus.INTERNAL_SERVER_ERROR();
}
public int NOT_IMPLEMENTED() {
return httpStatus.NOT_IMPLEMENTED();
return HttpStatus.NOT_IMPLEMENTED();
}
public int BAD_GATEWAY() {
return httpStatus.BAD_GATEWAY();
return HttpStatus.BAD_GATEWAY();
}
public int SERVICE_UNAVAILABLE() {
return httpStatus.SERVICE_UNAVAILABLE();
return HttpStatus.SERVICE_UNAVAILABLE();
}
public int GATEWAY_TIMEOUT() {
return httpStatus.GATEWAY_TIMEOUT();
return HttpStatus.GATEWAY_TIMEOUT();
}
public int HTTP_VERSION_NOT_SUPPORTED() {
return httpStatus.HTTP_VERSION_NOT_SUPPORTED();
return HttpStatus.HTTP_VERSION_NOT_SUPPORTED();
}
public int VARIANT_ALSO_NEGOTIATES() {
return httpStatus.VARIANT_ALSO_NEGOTIATES();
return HttpStatus.VARIANT_ALSO_NEGOTIATES();
}
public int INSUFFICIENT_STORAGE() {
return httpStatus.INSUFFICIENT_STORAGE();
return HttpStatus.INSUFFICIENT_STORAGE();
}
public int LOOP_DETECTED() {
return httpStatus.LOOP_DETECTED();
return HttpStatus.LOOP_DETECTED();
}
public int BANDWIDTH_LIMIT_EXCEEDED() {
return httpStatus.BANDWIDTH_LIMIT_EXCEEDED();
return HttpStatus.BANDWIDTH_LIMIT_EXCEEDED();
}
public int NOT_EXTENDED() {
return httpStatus.NOT_EXTENDED();
return HttpStatus.NOT_EXTENDED();
}
public int NETWORK_AUTHENTICATION_REQUIRED() {
return httpStatus.NETWORK_AUTHENTICATION_REQUIRED();
return HttpStatus.NETWORK_AUTHENTICATION_REQUIRED();
}
@Override

View File

@@ -0,0 +1,3 @@
=== Spring Cloud Contract Specification Kotlin
This module contains the Contract specification written in Kotlin.

View File

@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<!-- TODO: Bump-->
<!-- <automaton.version>1.12-1</automaton.version>-->
<automaton.version>1.11-8</automaton.version>
<kotlin.version>1.3.41</kotlin.version>
</properties>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-parent</artifactId>
<version>2.2.0.BUILD-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>spring-cloud-contract-spec-kotlin</artifactId>
<packaging>jar</packaging>
<name>Spring Cloud Contract Spec Kotlin</name>
<description>Spring Cloud Contract Spec Kotlin</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-spec-java</artifactId>
</dependency>
<!-- For backward compatibility since Gradle has problems with applying module extensions-->
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>dk.brics.automaton</groupId>
<artifactId>automaton</artifactId>
<version>${automaton.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jcl</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-nio</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-json</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-xml</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.solidsoft.spock</groupId>
<artifactId>spock-global-unroll</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<!-- Based on instructions here - https://kotlinlang.org/docs/reference/using-maven.html -->
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<groupId>org.jetbrains.kotlin</groupId>
<configuration>
<jvmTarget>1.8</jvmTarget>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<!-- Joint compilation -->
<executions>
<execution>
<goals>
<goal>addTestSources</goal>
<goal>generateTestStubs</goal>
<goal>compileTests</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.spec
import org.springframework.cloud.contract.spec.internal.ContractDslMarker
import org.springframework.cloud.contract.spec.internal.InputDsl
import org.springframework.cloud.contract.spec.internal.OutputMessageDsl
import org.springframework.cloud.contract.spec.internal.RequestDsl
import org.springframework.cloud.contract.spec.internal.ResponseDsl
/**
* @author Tim Ysewyn
*/
@ContractDslMarker
class ContractDsl {
val contract = Contract()
companion object {
fun make(block: ContractDsl.() -> Unit): Contract = ContractDsl().apply(block).get()
}
private fun get(): Contract = contract
infix fun priority(priority: Int) = contract.priority(priority)
infix fun label(label: String) = contract.label(label)
infix fun description(description: String) = contract.description(description)
infix fun name(name: String) = contract.name(name)
fun ignored() = contract.ignored()
fun request(block: RequestDsl.() -> Unit) {
contract.request = RequestDsl.make(block)
}
fun response(block: ResponseDsl.() -> Unit) {
contract.response = ResponseDsl.make(block)
}
fun input(block: InputDsl.() -> Unit) {
contract.input = InputDsl.make(block)
}
fun outputMessage(block: OutputMessageDsl.() -> Unit) {
contract.outputMessage = OutputMessageDsl.make(block)
}
}

View File

@@ -0,0 +1,270 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.spec.internal
import org.springframework.cloud.contract.spec.internal.HttpMethods.HttpMethod
import java.util.regex.Pattern
/**
* @author Tim Ysewyn
*/
open class CommonDsl {
/**
* Helper method to provide a better name for the consumer side.
* @param clientValue client value
* @return client dsl property
*/
fun client(clientValue: Any) = ClientDslProperty(clientValue)
/**
* Helper method to provide a better name for the consumer side.
* @param clientValue client value
* @return client dsl property
*/
fun c(clientValue: Any) = ClientDslProperty(clientValue)
/**
* Helper method to provide a better name for the consumer side.
* @param clientValue client value
* @return client dsl property
*/
fun consumer(clientValue: Any) = ClientDslProperty(clientValue)
/**
* Helper method to provide a better name for the consumer side.
* @param clientValue client value
* @return client dsl property
*/
fun stub(clientValue: Any) = ClientDslProperty(clientValue)
/**
* Helper method to provide a better name for the server side.
* @param serverValue server value
* @return server dsl property
*/
fun server(serverValue: Any) = ServerDslProperty(serverValue)
/**
* Helper method to provide a better name for the server side.
* @param serverValue server value
* @return server dsl property
*/
fun p(serverValue: Any) = ServerDslProperty(serverValue)
/**
* Helper method to provide a better name for the server side.
* @param serverValue server value
* @return server dsl property
*/
fun producer(serverValue: Any) = ServerDslProperty(serverValue)
/**
* Helper method to provide a better name for the server side.
* @param serverValue server value
* @return server dsl property
*/
fun test(serverValue: Any) = ServerDslProperty(serverValue)
/* HTTP METHODS */
fun GET() = HttpMethod.GET
fun HEAD() = HttpMethod.HEAD
fun POST() = HttpMethod.POST
fun PUT() = HttpMethod.PUT
fun PATCH() = HttpMethod.PATCH
fun DELETE() = HttpMethod.DELETE
fun OPTIONS() = HttpMethod.OPTIONS
fun TRACE() = HttpMethod.TRACE
/* HTTP STATUS CODES */
fun CONTINUE() = HttpStatus.CONTINUE()
fun SWITCHING_PROTOCOLS() = HttpStatus.SWITCHING_PROTOCOLS()
fun PROCESSING() = HttpStatus.PROCESSING()
fun CHECKPOINT() = HttpStatus.CHECKPOINT()
fun OK() = HttpStatus.OK()
fun CREATED() = HttpStatus.CREATED()
fun ACCEPTED() = HttpStatus.ACCEPTED()
fun NON_AUTHORITATIVE_INFORMATION() = HttpStatus.NON_AUTHORITATIVE_INFORMATION()
fun NO_CONTENT() = HttpStatus.NO_CONTENT()
fun RESET_CONTENT() = HttpStatus.RESET_CONTENT()
fun PARTIAL_CONTENT() = HttpStatus.PARTIAL_CONTENT()
fun MULTI_STATUS() = HttpStatus.MULTI_STATUS()
fun ALREADY_REPORTED() = HttpStatus.ALREADY_REPORTED()
fun IM_USED() = HttpStatus.IM_USED()
fun MULTIPLE_CHOICES() = HttpStatus.MULTIPLE_CHOICES()
fun MOVED_PERMANENTLY() = HttpStatus.MOVED_PERMANENTLY()
fun FOUND() = HttpStatus.FOUND()
fun SEE_OTHER() = HttpStatus.SEE_OTHER()
fun NOT_MODIFIED() = HttpStatus.NOT_MODIFIED()
fun TEMPORARY_REDIRECT() = HttpStatus.TEMPORARY_REDIRECT()
fun PERMANENT_REDIRECT() = HttpStatus.PERMANENT_REDIRECT()
fun BAD_REQUEST() = HttpStatus.BAD_REQUEST()
fun UNAUTHORIZED() = HttpStatus.UNAUTHORIZED()
fun PAYMENT_REQUIRED() = HttpStatus.PAYMENT_REQUIRED()
fun FORBIDDEN() = HttpStatus.FORBIDDEN()
fun NOT_FOUND() = HttpStatus.NOT_FOUND()
fun METHOD_NOT_ALLOWED() = HttpStatus.METHOD_NOT_ALLOWED()
fun NOT_ACCEPTABLE() = HttpStatus.NOT_ACCEPTABLE()
fun PROXY_AUTHENTICATION_REQUIRED() = HttpStatus.PROXY_AUTHENTICATION_REQUIRED()
fun REQUEST_TIMEOUT() = HttpStatus.REQUEST_TIMEOUT()
fun CONFLICT() = HttpStatus.CONFLICT()
fun GONE() = HttpStatus.GONE()
fun LENGTH_REQUIRED() = HttpStatus.LENGTH_REQUIRED()
fun PRECONDITION_FAILED() = HttpStatus.PRECONDITION_FAILED()
fun PAYLOAD_TOO_LARGE() = HttpStatus.PAYLOAD_TOO_LARGE()
fun URI_TOO_LONG() = HttpStatus.URI_TOO_LONG()
fun UNSUPPORTED_MEDIA_TYPE() = HttpStatus.UNSUPPORTED_MEDIA_TYPE()
fun REQUESTED_RANGE_NOT_SATISFIABLE() = HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE()
fun EXPECTATION_FAILED() = HttpStatus.EXPECTATION_FAILED()
fun I_AM_A_TEAPOT() = HttpStatus.I_AM_A_TEAPOT()
fun UNPROCESSABLE_ENTITY() = HttpStatus.UNPROCESSABLE_ENTITY()
fun LOCKED() = HttpStatus.LOCKED()
fun FAILED_DEPENDENCY() = HttpStatus.FAILED_DEPENDENCY()
fun UPGRADE_REQUIRED() = HttpStatus.UPGRADE_REQUIRED()
fun PRECONDITION_REQUIRED() = HttpStatus.PRECONDITION_REQUIRED()
fun TOO_MANY_REQUESTS() = HttpStatus.TOO_MANY_REQUESTS()
fun REQUEST_HEADER_FIELDS_TOO_LARGE() = HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE()
fun UNAVAILABLE_FOR_LEGAL_REASONS() = HttpStatus.UNAVAILABLE_FOR_LEGAL_REASONS()
fun INTERNAL_SERVER_ERROR() = HttpStatus.INTERNAL_SERVER_ERROR()
fun NOT_IMPLEMENTED() = HttpStatus.NOT_IMPLEMENTED()
fun BAD_GATEWAY() = HttpStatus.BAD_GATEWAY()
fun SERVICE_UNAVAILABLE() = HttpStatus.SERVICE_UNAVAILABLE()
fun GATEWAY_TIMEOUT() = HttpStatus.GATEWAY_TIMEOUT()
fun HTTP_VERSION_NOT_SUPPORTED() = HttpStatus.HTTP_VERSION_NOT_SUPPORTED()
fun VARIANT_ALSO_NEGOTIATES() = HttpStatus.VARIANT_ALSO_NEGOTIATES()
fun INSUFFICIENT_STORAGE() = HttpStatus.INSUFFICIENT_STORAGE()
fun LOOP_DETECTED() = HttpStatus.LOOP_DETECTED()
fun BANDWIDTH_LIMIT_EXCEEDED() = HttpStatus.BANDWIDTH_LIMIT_EXCEEDED()
fun NOT_EXTENDED() = HttpStatus.NOT_EXTENDED()
fun NETWORK_AUTHENTICATION_REQUIRED() = HttpStatus.NETWORK_AUTHENTICATION_REQUIRED()
/* REGEX */
fun regexProperty(value: Any) = RegexProperty(value)
fun regex(regex: String) = regexProperty(Pattern.compile(regex))
fun regex(regex: Pattern) = regexProperty(regex)
fun regex(regex: RegexProperty) = regex
fun onlyAlphaUnicode(): RegexProperty = RegexPatterns.onlyAlphaUnicode()
fun alphaNumeric(): RegexProperty = RegexPatterns.alphaNumeric()
fun number(): RegexProperty = RegexPatterns.number()
fun positiveInt(): RegexProperty = RegexPatterns.positiveInt()
fun anyBoolean(): RegexProperty = RegexPatterns.anyBoolean()
fun anInteger(): RegexProperty = RegexPatterns.anInteger()
fun aDouble(): RegexProperty = RegexPatterns.aDouble()
fun ipAddress(): RegexProperty = RegexPatterns.ipAddress()
fun hostname(): RegexProperty = RegexPatterns.hostname()
fun email(): RegexProperty = RegexPatterns.email()
fun url(): RegexProperty = RegexPatterns.url()
fun httpsUrl(): RegexProperty = RegexPatterns.httpsUrl()
fun uuid(): RegexProperty = RegexPatterns.uuid()
fun isoDate(): RegexProperty = RegexPatterns.isoDate()
fun isoDateTime(): RegexProperty = RegexPatterns.isoDateTime()
fun isoTime(): RegexProperty = RegexPatterns.isoTime()
fun iso8601WithOffset(): RegexProperty = RegexPatterns.iso8601WithOffset()
fun nonEmpty(): RegexProperty = RegexPatterns.nonEmpty()
fun nonBlank(): RegexProperty = RegexPatterns.nonBlank()
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.spec.internal
/**
* @author Tim Ysewyn
*/
@DslMarker
annotation class ContractDslMarker

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.spec.internal
/**
* @author Tim Ysewyn
*/
@ContractDslMarker
class InputDsl : CommonDsl(), RegexCreatingProperty<ClientDslProperty> {
private val input = Input()
companion object {
fun make(block: InputDsl.() -> Unit): Input = InputDsl().apply(block).get()
}
private fun get(): Input = input
fun messageFrom(messageFrom: String) = input.messageFrom(messageFrom)
fun messageFrom(messageFrom: DslProperty<Any>) = input.messageFrom(messageFrom)
fun messageBody(vararg pairs: Pair<String, Any>) = input.messageBody(pairs.toMap())
fun messageBody(pair: Pair<String, Any>) = input.messageBody(mapOf(pair))
fun messageBody(value: String) = input.messageBody(value)
fun messageHeaders(block: Headers.() -> Unit) {
input.messageHeaders = Headers().apply(block)
}
override fun anyAlphaUnicode(): ClientDslProperty = input.anyAlphaUnicode()
override fun anyAlphaNumeric(): ClientDslProperty = input.anyAlphaNumeric()
override fun anyNumber(): ClientDslProperty = input.anyNumber()
override fun anyInteger(): ClientDslProperty = input.anyInteger()
override fun anyPositiveInt(): ClientDslProperty = input.anyPositiveInt()
override fun anyDouble(): ClientDslProperty = input.anyDouble()
override fun anyHex(): ClientDslProperty = input.anyHex()
override fun aBoolean(): ClientDslProperty = input.aBoolean()
override fun anyIpAddress(): ClientDslProperty = input.anyIpAddress()
override fun anyHostname(): ClientDslProperty = input.anyHostname()
override fun anyEmail(): ClientDslProperty = input.anyEmail()
override fun anyUrl(): ClientDslProperty = input.anyUrl()
override fun anyHttpsUrl(): ClientDslProperty = input.anyHttpsUrl()
override fun anyUuid(): ClientDslProperty = input.anyUuid()
override fun anyDate(): ClientDslProperty = input.anyDate()
override fun anyDateTime(): ClientDslProperty = input.anyDateTime()
override fun anyTime(): ClientDslProperty = input.anyTime()
override fun anyIso8601WithOffset(): ClientDslProperty = input.anyIso8601WithOffset()
override fun anyNonBlankString(): ClientDslProperty = input.anyNonBlankString()
override fun anyNonEmptyString(): ClientDslProperty = input.anyNonEmptyString()
override fun anyOf(vararg values: String?): ClientDslProperty = input.anyOf(*values)
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.spec.internal
/**
* @author Tim Ysewyn
*/
@ContractDslMarker
class OutputMessageDsl : CommonDsl(), RegexCreatingProperty<ServerDslProperty> {
private val outputMessage = OutputMessage()
companion object {
fun make(block: OutputMessageDsl.() -> Unit): OutputMessage = OutputMessageDsl().apply(block).get()
}
private fun get(): OutputMessage = outputMessage
fun sentTo(value: String) = outputMessage.sentTo(value)
fun sentTo(value: DslProperty<Any>) = outputMessage.sentTo(value)
fun body(vararg pairs: Pair<String, Any>) = outputMessage.body(pairs.toMap())
fun body(pair: Pair<String, Any>) = outputMessage.body(mapOf(pair))
fun body(value: String) = outputMessage.body(value)
fun headers(block: Headers.() -> Unit) {
outputMessage.headers = Headers().apply(block)
}
override fun anyAlphaUnicode(): ServerDslProperty = outputMessage.anyAlphaUnicode()
override fun anyAlphaNumeric(): ServerDslProperty = outputMessage.anyAlphaNumeric()
override fun anyNumber(): ServerDslProperty = outputMessage.anyNumber()
override fun anyInteger(): ServerDslProperty = outputMessage.anyInteger()
override fun anyPositiveInt(): ServerDslProperty = outputMessage.anyPositiveInt()
override fun anyDouble(): ServerDslProperty = outputMessage.anyDouble()
override fun anyHex(): ServerDslProperty = outputMessage.anyHex()
override fun aBoolean(): ServerDslProperty = outputMessage.aBoolean()
override fun anyIpAddress(): ServerDslProperty = outputMessage.anyIpAddress()
override fun anyHostname(): ServerDslProperty = outputMessage.anyHostname()
override fun anyEmail(): ServerDslProperty = outputMessage.anyEmail()
override fun anyUrl(): ServerDslProperty = outputMessage.anyUrl()
override fun anyHttpsUrl(): ServerDslProperty = outputMessage.anyHttpsUrl()
override fun anyUuid(): ServerDslProperty = outputMessage.anyUuid()
override fun anyDate(): ServerDslProperty = outputMessage.anyDate()
override fun anyDateTime(): ServerDslProperty = outputMessage.anyDateTime()
override fun anyTime(): ServerDslProperty = outputMessage.anyTime()
override fun anyIso8601WithOffset(): ServerDslProperty = outputMessage.anyIso8601WithOffset()
override fun anyNonBlankString(): ServerDslProperty = outputMessage.anyNonBlankString()
override fun anyNonEmptyString(): ServerDslProperty = outputMessage.anyNonEmptyString()
override fun anyOf(vararg values: String?): ServerDslProperty = outputMessage.anyOf(*values)
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.spec.internal
/**
* @author Tim Ysewyn
*/
@ContractDslMarker
class RequestDsl : CommonDsl(), RegexCreatingProperty<ClientDslProperty> {
private val request = Request()
companion object {
fun make(block: RequestDsl.() -> Unit): Request = RequestDsl().apply(block).get()
}
private fun get(): Request = request
fun method(value: String) = request.method(value)
fun method(httpMethod: HttpMethods.HttpMethod) = request.method(httpMethod)
fun url(url: String) = request.url(url)
fun url(url: DslProperty<Any>) = request.url(url)
fun urlPath(path: String) = request.urlPath(path)
fun urlPath(path: DslProperty<Any>) = request.urlPath(path)
fun headers(block: Headers.() -> Unit) {
request.headers = Headers().apply(block)
}
fun body(vararg pairs: Pair<String, Any>) = request.body(pairs.toMap())
fun body(pair: Pair<String, Any>) = request.body(mapOf(pair))
fun body(value: String) = request.body(value)
fun bodyMatchers(block: BodyMatchers.() -> Unit) {
request.bodyMatchers = BodyMatchers().apply(block)
}
fun value(value: DslProperty<Any>): DslProperty<Any> = request.value(value)
fun v(value: DslProperty<Any>): DslProperty<Any> = request.value(value)
fun `$`(value: DslProperty<Any>): DslProperty<Any> = request.value(value)
fun value(value: Any): DslProperty<Any> = request.value(value)
fun v(value: Any): DslProperty<Any> = request.value(value)
fun `$`(value: Any): DslProperty<Any> = request.value(value)
fun value(client: ClientDslProperty, server: ServerDslProperty): DslProperty<Any> = request.value(client, server)
fun v(client: ClientDslProperty, server: ServerDslProperty): DslProperty<Any> = request.value(client, server)
fun `$`(client: ClientDslProperty, server: ServerDslProperty): DslProperty<Any> = request.value(client, server)
fun value(server: ServerDslProperty, client: ClientDslProperty): DslProperty<Any> = request.value(client, server)
fun v(server: ServerDslProperty, client: ClientDslProperty): DslProperty<Any> = request.value(client, server)
fun `$`(server: ServerDslProperty, client: ClientDslProperty): DslProperty<Any> = request.value(client, server)
override fun anyAlphaUnicode(): ClientDslProperty = request.anyAlphaUnicode()
override fun anyAlphaNumeric(): ClientDslProperty = request.anyAlphaNumeric()
override fun anyNumber(): ClientDslProperty = request.anyNumber()
override fun anyInteger(): ClientDslProperty = request.anyInteger()
override fun anyPositiveInt(): ClientDslProperty = request.anyPositiveInt()
override fun anyDouble(): ClientDslProperty = request.anyDouble()
override fun anyHex(): ClientDslProperty = request.anyHex()
override fun aBoolean(): ClientDslProperty = request.aBoolean()
override fun anyIpAddress(): ClientDslProperty = request.anyIpAddress()
override fun anyHostname(): ClientDslProperty = request.anyHostname()
override fun anyEmail(): ClientDslProperty = request.anyEmail()
override fun anyUrl(): ClientDslProperty = request.anyUrl()
override fun anyHttpsUrl(): ClientDslProperty = request.anyHttpsUrl()
override fun anyUuid(): ClientDslProperty = request.anyUuid()
override fun anyDate(): ClientDslProperty = request.anyDate()
override fun anyDateTime(): ClientDslProperty = request.anyDateTime()
override fun anyTime(): ClientDslProperty = request.anyTime()
override fun anyIso8601WithOffset(): ClientDslProperty = request.anyIso8601WithOffset()
override fun anyNonBlankString(): ClientDslProperty = request.anyNonBlankString()
override fun anyNonEmptyString(): ClientDslProperty = request.anyNonEmptyString()
override fun anyOf(vararg values: String?): ClientDslProperty = request.anyOf(*values)
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.spec.internal
/**
* @author Tim Ysewyn
*/
@ContractDslMarker
class ResponseDsl : CommonDsl(), RegexCreatingProperty<ServerDslProperty> {
private val response = Response()
companion object {
fun make(block: ResponseDsl.() -> Unit): Response = ResponseDsl().apply(block).get()
}
private fun get(): Response = response
fun status(code: Int) = response.status(code)
fun body(pair: Pair<String, Any>) = response.body(mapOf(pair))
fun body(vararg pairs: Pair<String, Any>) = response.body(pairs.toMap())
fun headers(block: Headers.() -> Unit) {
response.headers = Headers().apply(block)
}
fun bodyMatchers(block: ResponseBodyMatchers.() -> Unit) {
response.bodyMatchers = ResponseBodyMatchers().apply(block)
}
override fun anyAlphaUnicode(): ServerDslProperty = response.anyAlphaUnicode()
override fun anyAlphaNumeric(): ServerDslProperty = response.anyAlphaNumeric()
override fun anyNumber(): ServerDslProperty = response.anyNumber()
override fun anyInteger(): ServerDslProperty = response.anyInteger()
override fun anyPositiveInt(): ServerDslProperty = response.anyPositiveInt()
override fun anyDouble(): ServerDslProperty = response.anyDouble()
override fun anyHex(): ServerDslProperty = response.anyHex()
override fun aBoolean(): ServerDslProperty = response.aBoolean()
override fun anyIpAddress(): ServerDslProperty = response.anyIpAddress()
override fun anyHostname(): ServerDslProperty = response.anyHostname()
override fun anyEmail(): ServerDslProperty = response.anyEmail()
override fun anyUrl(): ServerDslProperty = response.anyUrl()
override fun anyHttpsUrl(): ServerDslProperty = response.anyHttpsUrl()
override fun anyUuid(): ServerDslProperty = response.anyUuid()
override fun anyDate(): ServerDslProperty = response.anyDate()
override fun anyDateTime(): ServerDslProperty = response.anyDateTime()
override fun anyTime(): ServerDslProperty = response.anyTime()
override fun anyIso8601WithOffset(): ServerDslProperty = response.anyIso8601WithOffset()
override fun anyNonBlankString(): ServerDslProperty = response.anyNonBlankString()
override fun anyNonEmptyString(): ServerDslProperty = response.anyNonEmptyString()
override fun anyOf(vararg values: String?): ServerDslProperty = response.anyOf(*values)
}

View File

@@ -0,0 +1,430 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.contract.spec
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertDoesNotThrow
import org.junit.jupiter.api.assertThrows
import org.springframework.cloud.contract.spec.Contract.make
import org.springframework.cloud.contract.spec.internal.DslProperty
/**
* Tests written based on the Java contract tests written in Groovy
*
* @author Tim Ysewyn
*/
class ContractTests {
@Test
fun `should work for http`() {
val contract = ContractDsl.make {
request {
url("/foo")
method("PUT")
headers {
header("foo", "bar")
}
body("foo" to "bar")
}
response {
status(200)
headers {
header("foo2", "bar")
}
body("foo2" to "bar")
}
}
assertDoesNotThrow {
Contract.assertContract(contract)
}
}
@Test
fun `should fail when no method is present`() {
val contract = ContractDsl.make {
request {
url("/foo")
}
response {
status(200)
}
}
assertThrows<IllegalStateException> {
Contract.assertContract(contract)
}.also {
assertThat(it.message).contains("Method is missing for HTTP contract")
}
}
@Test
fun `should fail when no url is present`() {
val contract = ContractDsl.make {
request {
method("GET")
}
response {
status(200)
}
}
assertThrows<IllegalStateException> {
Contract.assertContract(contract)
}.also {
assertThat(it.message).contains("URL is missing for HTTP contract")
}
}
@Test
fun `should fail when no status is present`() {
val contract = ContractDsl.make {
request {
url("/foo")
method("GET")
}
response {
}
}
assertThrows<IllegalStateException> {
Contract.assertContract(contract)
}.also {
assertThat(it.message).contains("Status is missing for HTTP contract")
}
}
@Test
fun `should work for messaging`() {
val contract = ContractDsl.make {
input {
messageFrom("input")
messageBody("foo" to "bar")
messageHeaders {
header("foo", "bar")
}
}
outputMessage {
sentTo("output")
body("foo2" to "bar")
headers {
header("foo2", "bar")
}
}
}
assertDoesNotThrow {
Contract.assertContract(contract)
}
}
@Test
fun `should work for messaging with pattern properties`() {
val contract = ContractDsl.make {
input {
messageFrom("input")
messageBody("foo" to anyNonBlankString())
messageHeaders {
header("foo", anyNumber())
}
}
outputMessage {
sentTo("output")
body("foo2" to anyNonEmptyString())
headers {
header("foo2", anyIpAddress())
}
}
}
assertDoesNotThrow {
Contract.assertContract(contract)
}
}
@Test
fun `should set a description`() {
val contract = ContractDsl.make {
description("""
given:
An input
when:
Sth happens
then:
Output
""")
}
assertDoesNotThrow {
Contract.assertContract(contract)
}.also {
assertThat(contract.description).isEqualTo("""
given:
An input
when:
Sth happens
then:
Output
""")
}
}
@Test
fun `should set a name`() {
val contract = ContractDsl.make {
name("some_special_name")
}
assertDoesNotThrow {
Contract.assertContract(contract)
}.also {
assertThat(contract.name).isEqualTo("some_special_name")
}
}
@Test
fun `should mark a contract ignored`() {
val contract = ContractDsl.make {
ignored()
}
assertDoesNotThrow {
Contract.assertContract(contract)
}.also {
assertThat(contract.ignored).isTrue()
}
}
@Test
fun `should make equals and hashcode work properly for URL`() {
val a: Contract = ContractDsl.make {
request {
method("GET")
url("/1")
}
}
val b: Contract = ContractDsl.make {
request {
method("GET")
url("/1")
}
}
assertDoesNotThrow {
Contract.assertContract(a)
Contract.assertContract(b)
}. also {
assertThat(a).isEqualTo(b)
}
}
@Test
fun `should make equals and hashcode work properly for URL with consumer producer`() {
val a: Contract = ContractDsl.make {
request {
method("GET")
url(value(c("/1"), p("/1")))
}
}
val b: Contract = ContractDsl.make {
request {
method("GET")
url(value(c("/1"), p("/1")))
}
}
assertDoesNotThrow {
Contract.assertContract(a)
Contract.assertContract(b)
}. also {
assertThat(a).isEqualTo(b)
}
}
@Test
fun `should return true when comparing two equal contracts with interpolated string`() {
val index = 1
val a: Contract = ContractDsl.make {
request {
method(PUT())
headers {
contentType(applicationJson())
}
url( "/$index")
}
response {
status(OK())
}
}
val b: Contract = ContractDsl.make {
request {
method(PUT())
headers {
contentType(applicationJson())
}
url("/$index")
}
response {
status(OK())
}
}
assertDoesNotThrow {
Contract.assertContract(a)
Contract.assertContract(b)
}. also {
assertThat(a).isEqualTo(b)
}
}
@Test
fun `should return false when comparing two unequal contracts with interpolated string`() {
var index = 1
val a: Contract = ContractDsl.make {
request {
method(PUT())
headers {
contentType(applicationJson())
}
url( "/$index")
}
response {
status(OK())
}
}
index = 2
val b: Contract = ContractDsl.make {
request {
method(PUT())
headers {
contentType(applicationJson())
}
url("/$index")
}
response {
status(OK())
}
}
assertDoesNotThrow {
Contract.assertContract(a)
Contract.assertContract(b)
}. also {
assertThat(a).isNotEqualTo(b)
}
}
@Test
fun `should return true when comparing two equal complex contracts`() {
val a: Contract = ContractDsl.make {
request {
method(GET())
url("/path")
headers {
header("Accept", value(
consumer(regex("text/.*")),
producer("text/plain")
))
header("X-Custom-Header", value(
consumer(regex("^.*2134.*$")),
producer("121345")
))
}
}
response {
status(OK())
body("id" to ("value" to "132"),
"surname" to "Kowalsky",
"name" to "Jan",
"created" to "2014-02-02 12:23:43"
)
headers {
header("Content-Type", "text/plain")
}
}
}
val b: Contract = ContractDsl.make {
request {
method(GET())
url("/path")
headers {
header("Accept", value(
consumer(regex("text/.*")),
producer("text/plain")
))
header("X-Custom-Header", value(
consumer(regex("^.*2134.*$")),
producer("121345")
))
}
}
response {
status(OK())
body("id" to ("value" to "132"),
"surname" to "Kowalsky",
"name" to "Jan",
"created" to "2014-02-02 12:23:43"
)
headers {
header("Content-Type", "text/plain")
}
}
}
assertDoesNotThrow {
Contract.assertContract(a)
Contract.assertContract(b)
}. also {
assertThat(a).isEqualTo(b)
}
}
@Test
fun `should support bodyMatchers`() {
val contract = ContractDsl.make {
request {
method(GET())
url("/path")
body("id" to ("value" to "132"))
bodyMatchers {
jsonPath("$.id.value", byRegex(anInteger()))
}
}
response {
status(OK())
body("id" to ("value" to "132"),
"surname" to "Kowalsky",
"name" to "Jan",
"created" to "2014-02-02 12:23:43"
)
headers {
contentType(applicationJson())
}
bodyMatchers {
jsonPath("$.created", byTimestamp())
}
}
}
assertDoesNotThrow {
Contract.assertContract(contract)
}. also {
assertThat(contract.request.bodyMatchers.hasMatchers()).isTrue()
assertThat(contract.response.bodyMatchers.hasMatchers()).isTrue()
}
}
}

View File

@@ -163,20 +163,6 @@ class ContractSpec extends Specification {
noExceptionThrown()
}
def 'should generate a value if only regex is passed for client'() {
given:
Request request = new Request()
DslProperty property
when:
request.with {
property = value(consumer(regex("[0-9]{5}")))
}
def value = Integer.valueOf(property.serverValue as String)
then:
value >= 0
value <= 99_999
}
def 'should set a description'() {
given:
// tag::description[]

View File

@@ -21,349 +21,343 @@ import org.junit.Test;
/**
* @author Marcin Grzejszczak
* @author Tim Ysewyn
*/
public class HttpStatusTests {
@Test
public void CONTINUE() {
BDDAssertions.then(new HttpStatus().CONTINUE()).isEqualTo(100);
BDDAssertions.then(HttpStatus.CONTINUE()).isEqualTo(100);
}
@Test
public void SWITCHING_PROTOCOLS() {
BDDAssertions.then(new HttpStatus().SWITCHING_PROTOCOLS()).isEqualTo(101);
BDDAssertions.then(HttpStatus.SWITCHING_PROTOCOLS()).isEqualTo(101);
}
@Test
public void PROCESSING() {
BDDAssertions.then(new HttpStatus().PROCESSING()).isEqualTo(102);
BDDAssertions.then(HttpStatus.PROCESSING()).isEqualTo(102);
}
@Test
public void CHECKPOINT() {
BDDAssertions.then(new HttpStatus().CHECKPOINT()).isEqualTo(103);
BDDAssertions.then(HttpStatus.CHECKPOINT()).isEqualTo(103);
}
@Test
public void OK() {
BDDAssertions.then(new HttpStatus().OK()).isEqualTo(200);
BDDAssertions.then(HttpStatus.OK()).isEqualTo(200);
}
@Test
public void CREATED() {
BDDAssertions.then(new HttpStatus().CREATED()).isEqualTo(201);
BDDAssertions.then(HttpStatus.CREATED()).isEqualTo(201);
}
@Test
public void ACCEPTED() {
BDDAssertions.then(new HttpStatus().ACCEPTED()).isEqualTo(202);
BDDAssertions.then(HttpStatus.ACCEPTED()).isEqualTo(202);
}
@Test
public void NON_AUTHORITATIVE_INFORMATION() {
BDDAssertions.then(new HttpStatus().NON_AUTHORITATIVE_INFORMATION())
.isEqualTo(203);
BDDAssertions.then(HttpStatus.NON_AUTHORITATIVE_INFORMATION()).isEqualTo(203);
}
@Test
public void NO_CONTENT() {
BDDAssertions.then(new HttpStatus().NO_CONTENT()).isEqualTo(204);
BDDAssertions.then(HttpStatus.NO_CONTENT()).isEqualTo(204);
}
@Test
public void RESET_CONTENT() {
BDDAssertions.then(new HttpStatus().RESET_CONTENT()).isEqualTo(205);
BDDAssertions.then(HttpStatus.RESET_CONTENT()).isEqualTo(205);
}
@Test
public void PARTIAL_CONTENT() {
BDDAssertions.then(new HttpStatus().PARTIAL_CONTENT()).isEqualTo(206);
BDDAssertions.then(HttpStatus.PARTIAL_CONTENT()).isEqualTo(206);
}
@Test
public void MULTI_STATUS() {
BDDAssertions.then(new HttpStatus().MULTI_STATUS()).isEqualTo(207);
BDDAssertions.then(HttpStatus.MULTI_STATUS()).isEqualTo(207);
}
@Test
public void ALREADY_REPORTED() {
BDDAssertions.then(new HttpStatus().ALREADY_REPORTED()).isEqualTo(208);
BDDAssertions.then(HttpStatus.ALREADY_REPORTED()).isEqualTo(208);
}
@Test
public void IM_USED() {
BDDAssertions.then(new HttpStatus().IM_USED()).isEqualTo(226);
BDDAssertions.then(HttpStatus.IM_USED()).isEqualTo(226);
}
@Test
public void MULTIPLE_CHOICES() {
BDDAssertions.then(new HttpStatus().MULTIPLE_CHOICES()).isEqualTo(300);
BDDAssertions.then(HttpStatus.MULTIPLE_CHOICES()).isEqualTo(300);
}
@Test
public void MOVED_PERMANENTLY() {
BDDAssertions.then(new HttpStatus().MOVED_PERMANENTLY()).isEqualTo(301);
BDDAssertions.then(HttpStatus.MOVED_PERMANENTLY()).isEqualTo(301);
}
@Test
public void FOUND() {
BDDAssertions.then(new HttpStatus().FOUND()).isEqualTo(302);
BDDAssertions.then(HttpStatus.FOUND()).isEqualTo(302);
}
@Test
public void MOVED_TEMPORARILY() {
BDDAssertions.then(new HttpStatus().MOVED_TEMPORARILY()).isEqualTo(302);
BDDAssertions.then(HttpStatus.MOVED_TEMPORARILY()).isEqualTo(302);
}
@Test
public void SEE_OTHER() {
BDDAssertions.then(new HttpStatus().SEE_OTHER()).isEqualTo(303);
BDDAssertions.then(HttpStatus.SEE_OTHER()).isEqualTo(303);
}
@Test
public void NOT_MODIFIED() {
BDDAssertions.then(new HttpStatus().NOT_MODIFIED()).isEqualTo(304);
BDDAssertions.then(HttpStatus.NOT_MODIFIED()).isEqualTo(304);
}
@Test
public void USE_PROXY() {
BDDAssertions.then(new HttpStatus().USE_PROXY()).isEqualTo(305);
BDDAssertions.then(HttpStatus.USE_PROXY()).isEqualTo(305);
}
@Test
public void TEMPORARY_REDIRECT() {
BDDAssertions.then(new HttpStatus().TEMPORARY_REDIRECT()).isEqualTo(307);
BDDAssertions.then(HttpStatus.TEMPORARY_REDIRECT()).isEqualTo(307);
}
@Test
public void PERMANENT_REDIRECT() {
BDDAssertions.then(new HttpStatus().PERMANENT_REDIRECT()).isEqualTo(308);
BDDAssertions.then(HttpStatus.PERMANENT_REDIRECT()).isEqualTo(308);
}
@Test
public void BAD_REQUEST() {
BDDAssertions.then(new HttpStatus().BAD_REQUEST()).isEqualTo(400);
BDDAssertions.then(HttpStatus.BAD_REQUEST()).isEqualTo(400);
}
@Test
public void UNAUTHORIZED() {
BDDAssertions.then(new HttpStatus().UNAUTHORIZED()).isEqualTo(401);
BDDAssertions.then(HttpStatus.UNAUTHORIZED()).isEqualTo(401);
}
@Test
public void PAYMENT_REQUIRED() {
BDDAssertions.then(new HttpStatus().PAYMENT_REQUIRED()).isEqualTo(402);
BDDAssertions.then(HttpStatus.PAYMENT_REQUIRED()).isEqualTo(402);
}
@Test
public void FORBIDDEN() {
BDDAssertions.then(new HttpStatus().FORBIDDEN()).isEqualTo(403);
BDDAssertions.then(HttpStatus.FORBIDDEN()).isEqualTo(403);
}
@Test
public void NOT_FOUND() {
BDDAssertions.then(new HttpStatus().NOT_FOUND()).isEqualTo(404);
BDDAssertions.then(HttpStatus.NOT_FOUND()).isEqualTo(404);
}
@Test
public void METHOD_NOT_ALLOWED() {
BDDAssertions.then(new HttpStatus().METHOD_NOT_ALLOWED()).isEqualTo(405);
BDDAssertions.then(HttpStatus.METHOD_NOT_ALLOWED()).isEqualTo(405);
}
@Test
public void NOT_ACCEPTABLE() {
BDDAssertions.then(new HttpStatus().NOT_ACCEPTABLE()).isEqualTo(406);
BDDAssertions.then(HttpStatus.NOT_ACCEPTABLE()).isEqualTo(406);
}
@Test
public void PROXY_AUTHENTICATION_REQUIRED() {
BDDAssertions.then(new HttpStatus().PROXY_AUTHENTICATION_REQUIRED())
.isEqualTo(407);
BDDAssertions.then(HttpStatus.PROXY_AUTHENTICATION_REQUIRED()).isEqualTo(407);
}
@Test
public void REQUEST_TIMEOUT() {
BDDAssertions.then(new HttpStatus().REQUEST_TIMEOUT()).isEqualTo(408);
BDDAssertions.then(HttpStatus.REQUEST_TIMEOUT()).isEqualTo(408);
}
@Test
public void CONFLICT() {
BDDAssertions.then(new HttpStatus().CONFLICT()).isEqualTo(409);
BDDAssertions.then(HttpStatus.CONFLICT()).isEqualTo(409);
}
@Test
public void GONE() {
BDDAssertions.then(new HttpStatus().GONE()).isEqualTo(410);
BDDAssertions.then(HttpStatus.GONE()).isEqualTo(410);
}
@Test
public void LENGTH_REQUIRED() {
BDDAssertions.then(new HttpStatus().LENGTH_REQUIRED()).isEqualTo(411);
BDDAssertions.then(HttpStatus.LENGTH_REQUIRED()).isEqualTo(411);
}
@Test
public void PRECONDITION_FAILED() {
BDDAssertions.then(new HttpStatus().PRECONDITION_FAILED()).isEqualTo(412);
BDDAssertions.then(HttpStatus.PRECONDITION_FAILED()).isEqualTo(412);
}
@Test
public void PAYLOAD_TOO_LARGE() {
BDDAssertions.then(new HttpStatus().PAYLOAD_TOO_LARGE()).isEqualTo(413);
BDDAssertions.then(HttpStatus.PAYLOAD_TOO_LARGE()).isEqualTo(413);
}
@Test
public void REQUEST_ENTITY_TOO_LARGE() {
BDDAssertions.then(new HttpStatus().REQUEST_ENTITY_TOO_LARGE()).isEqualTo(413);
BDDAssertions.then(HttpStatus.REQUEST_ENTITY_TOO_LARGE()).isEqualTo(413);
}
@Test
public void URI_TOO_LONG() {
BDDAssertions.then(new HttpStatus().URI_TOO_LONG()).isEqualTo(414);
BDDAssertions.then(HttpStatus.URI_TOO_LONG()).isEqualTo(414);
}
@Test
public void REQUEST_URI_TOO_LONG() {
BDDAssertions.then(new HttpStatus().REQUEST_URI_TOO_LONG()).isEqualTo(414);
BDDAssertions.then(HttpStatus.REQUEST_URI_TOO_LONG()).isEqualTo(414);
}
@Test
public void UNSUPPORTED_MEDIA_TYPE() {
BDDAssertions.then(new HttpStatus().UNSUPPORTED_MEDIA_TYPE()).isEqualTo(415);
BDDAssertions.then(HttpStatus.UNSUPPORTED_MEDIA_TYPE()).isEqualTo(415);
}
@Test
public void REQUESTED_RANGE_NOT_SATISFIABLE() {
BDDAssertions.then(new HttpStatus().REQUESTED_RANGE_NOT_SATISFIABLE())
.isEqualTo(416);
BDDAssertions.then(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE()).isEqualTo(416);
}
@Test
public void EXPECTATION_FAILED() {
BDDAssertions.then(new HttpStatus().EXPECTATION_FAILED()).isEqualTo(417);
BDDAssertions.then(HttpStatus.EXPECTATION_FAILED()).isEqualTo(417);
}
@Test
public void I_AM_A_TEAPOT() {
BDDAssertions.then(new HttpStatus().I_AM_A_TEAPOT()).isEqualTo(418);
BDDAssertions.then(HttpStatus.I_AM_A_TEAPOT()).isEqualTo(418);
}
@Test
public void INSUFFICIENT_SPACE_ON_RESOURCE() {
BDDAssertions.then(new HttpStatus().INSUFFICIENT_SPACE_ON_RESOURCE())
.isEqualTo(419);
BDDAssertions.then(HttpStatus.INSUFFICIENT_SPACE_ON_RESOURCE()).isEqualTo(419);
}
@Test
public void METHOD_FAILURE() {
BDDAssertions.then(new HttpStatus().METHOD_FAILURE()).isEqualTo(420);
BDDAssertions.then(HttpStatus.METHOD_FAILURE()).isEqualTo(420);
}
@Test
public void DESTINATION_LOCKED() {
BDDAssertions.then(new HttpStatus().DESTINATION_LOCKED()).isEqualTo(421);
BDDAssertions.then(HttpStatus.DESTINATION_LOCKED()).isEqualTo(421);
}
@Test
public void UNPROCESSABLE_ENTITY() {
BDDAssertions.then(new HttpStatus().UNPROCESSABLE_ENTITY()).isEqualTo(422);
BDDAssertions.then(HttpStatus.UNPROCESSABLE_ENTITY()).isEqualTo(422);
}
@Test
public void LOCKED() {
BDDAssertions.then(new HttpStatus().LOCKED()).isEqualTo(423);
BDDAssertions.then(HttpStatus.LOCKED()).isEqualTo(423);
}
@Test
public void FAILED_DEPENDENCY() {
BDDAssertions.then(new HttpStatus().FAILED_DEPENDENCY()).isEqualTo(424);
BDDAssertions.then(HttpStatus.FAILED_DEPENDENCY()).isEqualTo(424);
}
@Test
public void UPGRADE_REQUIRED() {
BDDAssertions.then(new HttpStatus().UPGRADE_REQUIRED()).isEqualTo(426);
BDDAssertions.then(HttpStatus.UPGRADE_REQUIRED()).isEqualTo(426);
}
@Test
public void PRECONDITION_REQUIRED() {
BDDAssertions.then(new HttpStatus().PRECONDITION_REQUIRED()).isEqualTo(428);
BDDAssertions.then(HttpStatus.PRECONDITION_REQUIRED()).isEqualTo(428);
}
@Test
public void TOO_MANY_REQUESTS() {
BDDAssertions.then(new HttpStatus().TOO_MANY_REQUESTS()).isEqualTo(429);
BDDAssertions.then(HttpStatus.TOO_MANY_REQUESTS()).isEqualTo(429);
}
@Test
public void REQUEST_HEADER_FIELDS_TOO_LARGE() {
BDDAssertions.then(new HttpStatus().REQUEST_HEADER_FIELDS_TOO_LARGE())
.isEqualTo(431);
BDDAssertions.then(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE()).isEqualTo(431);
}
@Test
public void UNAVAILABLE_FOR_LEGAL_REASONS() {
BDDAssertions.then(new HttpStatus().UNAVAILABLE_FOR_LEGAL_REASONS())
.isEqualTo(451);
BDDAssertions.then(HttpStatus.UNAVAILABLE_FOR_LEGAL_REASONS()).isEqualTo(451);
}
@Test
public void INTERNAL_SERVER_ERROR() {
BDDAssertions.then(new HttpStatus().INTERNAL_SERVER_ERROR()).isEqualTo(500);
BDDAssertions.then(HttpStatus.INTERNAL_SERVER_ERROR()).isEqualTo(500);
}
@Test
public void NOT_IMPLEMENTED() {
BDDAssertions.then(new HttpStatus().NOT_IMPLEMENTED()).isEqualTo(501);
BDDAssertions.then(HttpStatus.NOT_IMPLEMENTED()).isEqualTo(501);
}
@Test
public void BAD_GATEWAY() {
BDDAssertions.then(new HttpStatus().BAD_GATEWAY()).isEqualTo(502);
BDDAssertions.then(HttpStatus.BAD_GATEWAY()).isEqualTo(502);
}
@Test
public void SERVICE_UNAVAILABLE() {
BDDAssertions.then(new HttpStatus().SERVICE_UNAVAILABLE()).isEqualTo(503);
BDDAssertions.then(HttpStatus.SERVICE_UNAVAILABLE()).isEqualTo(503);
}
@Test
public void GATEWAY_TIMEOUT() {
BDDAssertions.then(new HttpStatus().GATEWAY_TIMEOUT()).isEqualTo(504);
BDDAssertions.then(HttpStatus.GATEWAY_TIMEOUT()).isEqualTo(504);
}
@Test
public void HTTP_VERSION_NOT_SUPPORTED() {
BDDAssertions.then(new HttpStatus().HTTP_VERSION_NOT_SUPPORTED()).isEqualTo(505);
BDDAssertions.then(HttpStatus.HTTP_VERSION_NOT_SUPPORTED()).isEqualTo(505);
}
@Test
public void VARIANT_ALSO_NEGOTIATES() {
BDDAssertions.then(new HttpStatus().VARIANT_ALSO_NEGOTIATES()).isEqualTo(506);
BDDAssertions.then(HttpStatus.VARIANT_ALSO_NEGOTIATES()).isEqualTo(506);
}
@Test
public void INSUFFICIENT_STORAGE() {
BDDAssertions.then(new HttpStatus().INSUFFICIENT_STORAGE()).isEqualTo(507);
BDDAssertions.then(HttpStatus.INSUFFICIENT_STORAGE()).isEqualTo(507);
}
@Test
public void LOOP_DETECTED() {
BDDAssertions.then(new HttpStatus().LOOP_DETECTED()).isEqualTo(508);
BDDAssertions.then(HttpStatus.LOOP_DETECTED()).isEqualTo(508);
}
@Test
public void BANDWIDTH_LIMIT_EXCEEDED() {
BDDAssertions.then(new HttpStatus().BANDWIDTH_LIMIT_EXCEEDED()).isEqualTo(509);
BDDAssertions.then(HttpStatus.BANDWIDTH_LIMIT_EXCEEDED()).isEqualTo(509);
}
@Test
public void NOT_EXTENDED() {
BDDAssertions.then(new HttpStatus().NOT_EXTENDED()).isEqualTo(510);
BDDAssertions.then(HttpStatus.NOT_EXTENDED()).isEqualTo(510);
}
@Test
public void NETWORK_AUTHENTICATION_REQUIRED() {
BDDAssertions.then(new HttpStatus().NETWORK_AUTHENTICATION_REQUIRED())
.isEqualTo(511);
BDDAssertions.then(HttpStatus.NETWORK_AUTHENTICATION_REQUIRED()).isEqualTo(511);
}
}

View File

@@ -20,11 +20,9 @@ import spock.lang.Specification
class RegexPatternsSpec extends Specification {
RegexPatterns regexPatterns = new RegexPatterns()
def "should generate a regex for ip address [#textToMatch] that is a match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.ipAddress().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.ipAddress().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'123.123.123.123' || true
@@ -33,7 +31,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex for hostname [#textToMatch] that is a match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.hostname().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.hostname().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'https://asd.com' || true
@@ -46,7 +44,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex for email [#textToMatch] that is a match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.email().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.email().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'asd@asd.com' || true
@@ -57,7 +55,7 @@ class RegexPatternsSpec extends Specification {
// @see https://formvalidation.io/validators/uri/
def "should generate a regex for url [#textToMatch] that is a match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.url().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.url().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'ftp://asd.com:9090/asd/a?a=b' || true
@@ -130,7 +128,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex for httpsUrl [#textToMatch] that is a match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.httpsUrl().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.httpsUrl().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'ftp://asd.com:9090/asd/a?a=b' || false
@@ -203,7 +201,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex for a number [#textToMatch] that is a match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.number().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.number().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'1' || true
@@ -215,7 +213,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex for a positive integer [#textToMatch] that is a match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.positiveInt().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.positiveInt().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'1' || true
@@ -227,7 +225,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex for a double [#textToMatch] that is a match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.aDouble().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.aDouble().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'1' || false
@@ -239,7 +237,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex for a uuid [#textToMatch] that is a match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.uuid().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.uuid().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
UUID.randomUUID().toString() || true
@@ -252,7 +250,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex with date [#textToMatch] in YYYY-MM-DD format that should match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.isoDate().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.isoDate().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
"2014-03-01" || true
@@ -270,7 +268,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex with datetime [#textToMatch] in YYYY-MM-DDTHH:mm:ss format that should match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.isoDateTime().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.isoDateTime().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
"2014-03-01T12:23:45" || true
@@ -295,7 +293,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex with time [#textToMatch] in HH:mm:ss format that should match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.isoTime().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.isoTime().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
"12:23:45" || true
@@ -311,7 +309,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex with iso8601DateTimeWithTimezone [#textToMatch] in YYYY-MM-DDTHH:mm:ss.SSSZZ format that should match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.iso8601WithOffset().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.iso8601WithOffset().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'2014-03-01T12:23:45Z' || true
@@ -324,7 +322,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex for a non blank string [#textToMatch] that should match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.nonBlank().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.nonBlank().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'Not Empty' || true
@@ -338,7 +336,7 @@ class RegexPatternsSpec extends Specification {
def "should generate a regex for a non empty string [#textToMatch] that should match [#shouldMatch]"() {
expect:
shouldMatch == regexPatterns.nonEmpty().matcher(textToMatch).matches()
shouldMatch == RegexPatterns.nonEmpty().matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'Not Empty' || true

View File

@@ -130,4 +130,18 @@ class RequestSpec extends Specification {
value >= 0
value <= 99_999
}
def 'should generate a value if only regex is passed for client'() {
given:
Request request = new Request()
DslProperty property
when:
request.with {
property = value(consumer(regex("[0-9]{5}")))
}
def value = Integer.valueOf(property.serverValue as String)
then:
value >= 0
value <= 99_999
}
}

View File

@@ -86,6 +86,8 @@
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>compileTests</goal>
<goal>removeStubs</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>

View File

@@ -44,8 +44,6 @@ import org.springframework.cloud.contract.spec.internal.RegexPatterns
@PackageScope
class MatchingRulesConverter {
private static final RegexPatterns regexPatterns = new RegexPatterns()
static Category matchingRulesForBody(BodyMatchers bodyMatchers) {
return matchingRulesFor("body", bodyMatchers)
}
@@ -89,15 +87,15 @@ class MatchingRulesConverter {
break
case MatchingType.REGEX:
String pattern = it.value().toString()
if (pattern == regexPatterns.number().pattern()) {
if (pattern == RegexPatterns.number().pattern()) {
category.
addRule(key, new NumberTypeMatcher(NumberTypeMatcher.NumberType.NUMBER))
}
else if (pattern == regexPatterns.anInteger().pattern()) {
else if (pattern == RegexPatterns.anInteger().pattern()) {
category.
addRule(key, new NumberTypeMatcher(NumberTypeMatcher.NumberType.INTEGER))
}
else if (pattern == regexPatterns.aDouble().pattern()) {
else if (pattern == RegexPatterns.aDouble().pattern()) {
category.
addRule(key, new NumberTypeMatcher(NumberTypeMatcher.NumberType.DECIMAL))
}

View File

@@ -50,8 +50,6 @@ import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter
@PackageScope
class MessagingSCContractCreator {
RegexPatterns regexPatterns = new RegexPatterns()
private static final String FULL_BODY = '$'
private static final String DESTINATION_KEY = "sentTo"
private static final List<String> NON_HEADER_META_DATA = [DESTINATION_KEY]
@@ -124,15 +122,15 @@ class MessagingSCContractCreator {
switch (rule.numberType) {
case NumberTypeMatcher.NumberType.NUMBER:
jsonPath(key,
byRegex(regexPatterns.number()))
byRegex(RegexPatterns.number()))
break
case NumberTypeMatcher.NumberType.INTEGER:
jsonPath(key,
byRegex(regexPatterns.anInteger()))
byRegex(RegexPatterns.anInteger()))
break
case NumberTypeMatcher.NumberType.DECIMAL:
jsonPath(key,
byRegex(regexPatterns.aDouble()))
byRegex(RegexPatterns.aDouble()))
break
default:
throw new RuntimeException("Unsupported number type!")

View File

@@ -56,7 +56,6 @@ import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter
class RequestResponseSCContractCreator {
private static final String FULL_BODY = '$'
private static final RegexPatterns regexPatterns = new RegexPatterns()
Collection<Contract> convertFrom(RequestResponsePact pact) {
return pact.interactions.collect { RequestResponseInteraction interaction ->
@@ -147,15 +146,15 @@ class RequestResponseSCContractCreator {
switch (rule.numberType) {
case NumberTypeMatcher.NumberType.NUMBER:
jsonPath(key,
byRegex(regexPatterns.number()))
byRegex(RegexPatterns.number()))
break
case NumberTypeMatcher.NumberType.INTEGER:
jsonPath(key, byRegex(regexPatterns.
jsonPath(key, byRegex(RegexPatterns.
anInteger()))
break
case NumberTypeMatcher.NumberType.DECIMAL:
jsonPath(key,
byRegex(regexPatterns.aDouble()))
byRegex(RegexPatterns.aDouble()))
break
default:
throw new RuntimeException("Unsupported number type!")
@@ -237,17 +236,17 @@ class RequestResponseSCContractCreator {
switch (rule.numberType) {
case NumberTypeMatcher.NumberType.NUMBER:
jsonPath(key,
byRegex(regexPatterns.
byRegex(RegexPatterns.
number()))
break
case NumberTypeMatcher.NumberType.INTEGER:
jsonPath(key,
byRegex(regexPatterns.
byRegex(RegexPatterns.
anInteger()))
break
case NumberTypeMatcher.NumberType.DECIMAL:
jsonPath(key,
byRegex(regexPatterns.
byRegex(RegexPatterns.
aDouble()))
break
default:

View File

@@ -212,25 +212,25 @@
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<!-- Joint compilation -->
<executions>
<execution>
<goals>
<goal>addSources</goal>
<goal>addTestSources</goal>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>compileTests</goal>
<goal>removeStubs</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<!-- Joint compilation -->
<executions>
<execution>
<goals>
<goal>addSources</goal>
<goal>addTestSources</goal>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>compileTests</goal>
<goal>removeStubs</goal>
<goal>removeTestStubs</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>