gh-245: Created new DslProperty creation methods (#247)

Added:
- iso8601WithOffset which handles iso8601 date time with timezone date validation
- nonBlankString which handles string that aren't "" and also just whitespace
- nonEmptyString which handles "" strings
- anyOf(String...) which handles enumerated style attributes for validation

fixes #245

changed the name of iso8601DatetimeWithTimezone to anyIso8601WithOffset per code review suggestions
This commit is contained in:
Peter Frank
2017-03-20 10:02:40 -07:00
committed by Marcin Grzejszczak
parent 77f42a6f98
commit ebf09dfda3
5 changed files with 113 additions and 10 deletions

View File

@@ -83,6 +83,23 @@ abstract class PatternValueDslProperty<T extends DslProperty> {
return createAndValidateProperty(RegexPatterns.ANY_TIME, "12:2$d:3$d")
}
T anyIso8601WithOffset() {
int d = this.random.nextInt(8) + 1
return createAndValidateProperty(RegexPatterns.ISO8601_WITH_OFFSET, "201$d-0$d-1${d}T12:23:34.123Z")
}
T anyNonBlankString() {
return createAndValidateProperty(RegexPatterns.NON_BLANK, randomString(20))
}
T anyNonEmptyString() {
return createAndValidateProperty(RegexPatterns.NON_EMPTY, randomString(20))
}
T anyOf(String... values){
return createAndValidateProperty(RegexPatterns.anyOf(values), values[0])
}
private static String randomString(int length) {
char[] characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()
Random random = new Random()

View File

@@ -44,6 +44,13 @@ class RegexPatterns {
protected static final Pattern ANY_DATE = Pattern.compile('(\\d\\d\\d\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])')
protected static final Pattern ANY_DATE_TIME = Pattern.compile('([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])')
protected static final Pattern ANY_TIME = Pattern.compile('(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])')
protected static final Pattern NON_EMPTY = Pattern.compile(/.+/)
protected static final Pattern NON_BLANK = Pattern.compile(/.*(\S+|\R).*|!^\R*$/)
protected static final Pattern ISO8601_WITH_OFFSET = Pattern.compile(/([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.\d{3})?(Z|[+-][01]\d:[0-5]\d)/)
protected static Pattern anyOf(String... values){
return Pattern.compile(values.collect({"^$it\$"}).join("|"))
}
String onlyAlphaUnicode() {
return ONLY_ALPHA_UNICODE.pattern()
@@ -89,6 +96,18 @@ class RegexPatterns {
return ANY_TIME.pattern()
}
String iso8601WithOffset() {
return ISO8601_WITH_OFFSET.pattern()
}
String nonEmpty() {
return NON_EMPTY.pattern()
}
String nonBlank() {
return NON_BLANK.pattern()
}
// end::regexps[]
static String multipartParam(Object name, Object value) {

View File

@@ -146,4 +146,47 @@ class RegexPatternsSpec extends Specification {
"23:60:45" || false
"23:59:60" || false
}
def "should generate a regex with iso8601DateTimeWithTimezone [#textToMatch] in YYYY-MM-DDTHH:mm:ss.SSSZZ format that should match [#shouldMatch]"(){
expect:
shouldMatch == Pattern.compile(regexPatterns.iso8601WithOffset()).matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'2014-03-01T12:23:45Z' || true
'2014-03-01T12:23:45+01:00' || true
'2014-03-01T12:23:45.123Z' || true
'2014-03-01T12:23:45.123+01:00' || true
'2014-03-01T12:23:45' || false
'2014-03-01T12:23:45.123' || false
}
def "should generate a regex for a non blank string [#textToMatch] that should match [#shouldMatch]"(){
expect:
shouldMatch == Pattern.compile(regexPatterns.nonBlank()).matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'Not Empty' || true
'' || false
' ' || false
}
def "should generate a regex for a non empty string [#textToMatch] that should match [#shouldMatch]"() {
expect:
shouldMatch == Pattern.compile(regexPatterns.nonEmpty()).matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'Not Empty' || true
'' || false
' ' || true
}
def "should generate a regex for an enumerated value [#textToMatch] that should match [#shouldMatch]"(){
expect:
shouldMatch == RegexPatterns.anyOf('foo', 'bar').matcher(textToMatch).matches()
where:
textToMatch || shouldMatch
'foo' || true
'bar' || true
'baz' || false
}
}

View File

@@ -997,7 +997,11 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
uuid: $(anyUuid()),
date: $(anyDate()),
dateTime: $(anyDateTime()),
time: $(anyTime())
time: $(anyTime()),
iso8601WithOffset: $(anyIso8601WithOffset()),
nonBlankString: $(anyNonBlankString()),
nonEmptyString: $(anyNonEmptyString()),
anyOf: $(anyOf('foo', 'bar'))
])
headers {
contentType(applicationJson())
@@ -1016,7 +1020,11 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
uuid: $(anyUuid()),
date: $(anyDate()),
dateTime: $(anyDateTime()),
time: $(anyTime())
time: $(anyTime()),
iso8601WithOffset: $(anyIso8601WithOffset()),
nonBlankString: $(anyNonBlankString()),
nonEmptyString: $(anyNonEmptyString()),
anyOf: $(anyOf('foo', 'bar'))
])
headers {
contentType(applicationJson())
@@ -1040,13 +1048,17 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
test.contains('assertThatJson(parsedJson).field("date").matches("(\\\\d\\\\d\\\\d\\\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])")')
test.contains('assertThatJson(parsedJson).field("dateTime").matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])")')
test.contains('assertThatJson(parsedJson).field("time").matches("(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])")')
test.contains('assertThatJson(parsedJson).field("iso8601WithOffset").matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\\\.\\\\d{3})?(Z|[+-][01]\\\\d:[0-5]\\\\d)")')
test.contains('assertThatJson(parsedJson).field("nonBlankString").matches(".*(\\\\S+|\\\\R).*|!^\\\\R*' + endOfLineRegexSymbol + '")')
test.contains('assertThatJson(parsedJson).field("nonEmptyString").matches(".+")')
test.contains('assertThatJson(parsedJson).field("anyOf").matches("^foo' + endOfLineRegexSymbol + '|^bar' + endOfLineRegexSymbol + '")')
!test.contains('cursor')
and:
SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString())
where:
methodBuilderName | methodBuilder
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
"JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) }
methodBuilderName | methodBuilder | endOfLineRegexSymbol
"JaxRsClientSpockMethodRequestProcessingBodyBuilder"| { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$'
"JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | '$'
}
private String stripped(String string) {

View File

@@ -1898,7 +1898,11 @@ World.'''"""
uuid: $(anyUuid()),
date: $(anyDate()),
dateTime: $(anyDateTime()),
time: $(anyTime())
time: $(anyTime()),
iso8601WithOffset: $(anyIso8601WithOffset()),
nonBlankString: $(anyNonBlankString()),
nonEmptyString: $(anyNonEmptyString()),
anyOf: $(anyOf('foo', 'bar'))
])
headers {
contentType(applicationJson())
@@ -1917,7 +1921,11 @@ World.'''"""
uuid: $(anyUuid()),
date: $(anyDate()),
dateTime: $(anyDateTime()),
time: $(anyTime())
time: $(anyTime()),
iso8601WithOffset: $(anyIso8601WithOffset()),
nonBlankString: $(anyNonBlankString()),
nonEmptyString: $(anyNonEmptyString()),
anyOf: $(anyOf('foo', 'bar'))
])
headers {
contentType(applicationJson())
@@ -1941,13 +1949,17 @@ World.'''"""
test.contains('assertThatJson(parsedJson).field("date").matches("(\\\\d\\\\d\\\\d\\\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])')
test.contains('assertThatJson(parsedJson).field("dateTime").matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])')
test.contains('assertThatJson(parsedJson).field("time").matches("(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])")')
test.contains('assertThatJson(parsedJson).field("iso8601WithOffset").matches("([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\\\\.\\\\d{3})?(Z|[+-][01]\\\\d:[0-5]\\\\d)")')
test.contains('assertThatJson(parsedJson).field("nonBlankString").matches(".*(\\\\S+|\\\\R).*|!^\\\\R*' + endOfLineRegExSymbol + '")')
test.contains('assertThatJson(parsedJson).field("nonEmptyString").matches(".+")')
test.contains('assertThatJson(parsedJson).field("anyOf").matches("^foo' + endOfLineRegExSymbol + '|^bar' + endOfLineRegExSymbol + '")')
!test.contains('cursor')
and:
SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString())
where:
methodBuilderName | methodBuilder
"MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) }
methodBuilderName | methodBuilder | endOfLineRegExSymbol
"MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '\\$'
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '$'
}