Skip to content

Commit

Permalink
feat(DSL): check varargs for NULL values #1679
Browse files Browse the repository at this point in the history
  • Loading branch information
rholshausen committed Mar 29, 2023
1 parent 0a06556 commit 1721cb0
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ dependencies {
testImplementation 'net.bytebuddy:byte-buddy:1.12.7'
testImplementation 'com.github.tomakehurst:wiremock-jre8:2.34.0'
testImplementation 'org.junit.vintage:junit-vintage-engine:5.9.2'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2'
}

// Align versions of all Kotlin components
Expand Down
1 change: 1 addition & 0 deletions consumer/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ dependencies {
testRuntimeOnly 'org.objenesis:objenesis:3.2'
testImplementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4.2'
testImplementation 'io.grpc:grpc-protobuf:1.43.2'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
}
Original file line number Diff line number Diff line change
Expand Up @@ -236,21 +236,24 @@ open class PactDslJsonBody : DslPart {
* @param name attribute name
* @param value boolean value
*/
fun booleanValue(name: String, vararg values: Boolean): PactDslJsonBody {
fun booleanValue(name: String, vararg values: Boolean?): PactDslJsonBody {
require(values.isNotEmpty()) {
"At least one example value is required"
}
require(values.none { it == null }) {
"Example values can not be null"
}
if (body is JsonValue.Object && values.size > 1) {
throw IllegalArgumentException("You provided multiple example values (${values.size}) but only one was expected")
} else if (body is JsonValue.Array && body.size() < values.size) {
throw IllegalArgumentException("You provided ${values.size} example values but ${body.size()} was expected")
}

when (val body = body) {
is JsonValue.Object -> body.add(name, if (values[0]) JsonValue.True else JsonValue.False)
is JsonValue.Object -> body.add(name, if (values[0]!!) JsonValue.True else JsonValue.False)
is JsonValue.Array -> {
values.padTo(body.size()).forEachIndexed { i, value ->
body[i].asObject()!!.add(name, if (value) JsonValue.True else JsonValue.False)
body[i].asObject()!!.add(name, if (value!!) JsonValue.True else JsonValue.False)
}
}
else -> {}
Expand Down Expand Up @@ -310,9 +313,12 @@ open class PactDslJsonBody : DslPart {
* Attributes that can be any string
* @param names attribute names
*/
fun stringTypes(vararg names: String): PactDslJsonBody {
fun stringTypes(vararg names: String?): PactDslJsonBody {
require(names.none { it == null }) {
"Attribute names can not be null"
}
for (name in names) {
stringType(name)
stringType(name!!)
}
return this
}
Expand All @@ -322,10 +328,13 @@ open class PactDslJsonBody : DslPart {
* @param name attribute name
* @param example example value to use for generated bodies
*/
fun stringType(name: String, vararg examples: String): PactDslJsonBody {
fun stringType(name: String, vararg examples: String?): PactDslJsonBody {
require(examples.isNotEmpty()) {
"At least one example value is required"
}
require(examples.none { it == null }) {
"Example values can not be null"
}
if (body is JsonValue.Object && examples.size > 1) {
throw IllegalArgumentException(
"You provided multiple example values (${examples.size}) but only one was expected"
Expand All @@ -335,10 +344,10 @@ open class PactDslJsonBody : DslPart {
}

when (val body = body) {
is JsonValue.Object -> body.add(name, JsonValue.StringValue(examples[0].toCharArray()))
is JsonValue.Object -> body.add(name, JsonValue.StringValue(examples[0]!!.toCharArray()))
is JsonValue.Array -> {
examples.padTo(body.size()).forEachIndexed { i, value ->
body[i].asObject()!!.add(name, JsonValue.StringValue(value.toCharArray()))
body[i].asObject()!!.add(name, JsonValue.StringValue(value!!.toCharArray()))
}
}
else -> {}
Expand All @@ -362,9 +371,15 @@ open class PactDslJsonBody : DslPart {
* Attributes that can be any number
* @param names attribute names
*/
fun numberTypes(vararg names: String): PactDslJsonBody {
fun numberTypes(vararg names: String?): PactDslJsonBody {
require(names.isNotEmpty()) {
"At least one attribute name is required"
}
require(names.none { it == null }) {
"Attribute names can not be null"
}
for (name in names) {
numberType(name)
numberType(name!!)
}
return this
}
Expand All @@ -374,21 +389,24 @@ open class PactDslJsonBody : DslPart {
* @param name attribute name
* @param number example number to use for generated bodies
*/
fun numberType(name: String, vararg numbers: Number): PactDslJsonBody {
fun numberType(name: String, vararg numbers: Number?): PactDslJsonBody {
require(numbers.isNotEmpty()) {
"At least one example value is required"
}
require(numbers.none { it == null }) {
"Example values can not be null"
}
if (body is JsonValue.Object && numbers.size > 1) {
throw IllegalArgumentException("You provided multiple example values (${numbers.size}) but only one was expected")
} else if (body is JsonValue.Array && body.size() < numbers.size) {
throw IllegalArgumentException("You provided ${numbers.size} example values but ${body.size()} was expected")
}

when (val body = body) {
is JsonValue.Object -> body.add(name, JsonValue.Decimal(numbers[0].toString().toCharArray()))
is JsonValue.Object -> body.add(name, JsonValue.Decimal(numbers[0]!!.toString().toCharArray()))
is JsonValue.Array -> {
numbers.padTo(body.size()).forEachIndexed { i, value ->
body[i].asObject()!!.add(name, JsonValue.Decimal(value.toString().toCharArray()))
body[i].asObject()!!.add(name, JsonValue.Decimal(value!!.toString().toCharArray()))
}
}
else -> {}
Expand All @@ -405,16 +423,22 @@ open class PactDslJsonBody : DslPart {
*/
fun integerType(name: String): PactDslJsonBody {
generators.addGenerator(Category.BODY, matcherKey(name!!, rootPath), RandomIntGenerator(0, Int.MAX_VALUE))
return integerType(name, 100)
return integerType(name, 100 as Int)
}

/**
* Attributes that must be an integer
* @param names attribute names
*/
fun integerTypes(vararg names: String): PactDslJsonBody {
fun integerTypes(vararg names: String?): PactDslJsonBody {
require(names.isNotEmpty()) {
"At least one attribute name is required"
}
require(names.none { it == null }) {
"Attribute names can not be null"
}
for (name in names) {
integerType(name)
integerType(name!!)
}
return this
}
Expand All @@ -424,21 +448,24 @@ open class PactDslJsonBody : DslPart {
* @param name attribute name
* @param number example integer value to use for generated bodies
*/
fun integerType(name: String, vararg numbers: Long): PactDslJsonBody {
fun integerType(name: String, vararg numbers: Long?): PactDslJsonBody {
require(numbers.isNotEmpty()) {
"At least one example value is required"
}
require(numbers.none { it == null }) {
"Example values can not be null"
}
if (body is JsonValue.Object && numbers.size > 1) {
throw IllegalArgumentException("You provided multiple example values (${numbers.size}) but only one was expected")
} else if (body is JsonValue.Array && body.size() < numbers.size) {
throw IllegalArgumentException("You provided ${numbers.size} example values but ${body.size()} was expected")
}

when (val body = body) {
is JsonValue.Object -> body.add(name, JsonValue.Integer(numbers[0].toString().toCharArray()))
is JsonValue.Object -> body.add(name, JsonValue.Integer(numbers[0]!!.toString().toCharArray()))
is JsonValue.Array -> {
numbers.padTo(body.size()).forEachIndexed { i, value ->
body[i].asObject()!!.add(name, JsonValue.Integer(value.toString().toCharArray()))
body[i].asObject()!!.add(name, JsonValue.Integer(value!!.toString().toCharArray()))
}
}
else -> {}
Expand All @@ -454,21 +481,24 @@ open class PactDslJsonBody : DslPart {
* @param name attribute name
* @param number example integer value to use for generated bodies
*/
fun integerType(name: String, vararg numbers: Int): PactDslJsonBody {
fun integerType(name: String, vararg numbers: Int?): PactDslJsonBody {
require(numbers.isNotEmpty()) {
"At least one example value is required"
}
require(numbers.none { it == null }) {
"Example values can not be null"
}
if (body is JsonValue.Object && numbers.size > 1) {
throw IllegalArgumentException("You provided multiple example values (${numbers.size}) but only one was expected")
} else if (body is JsonValue.Array && body.size() < numbers.size) {
throw IllegalArgumentException("You provided ${numbers.size} example values but ${body.size()} was expected")
}

when (val body = body) {
is JsonValue.Object -> body.add(name, JsonValue.Integer(numbers[0].toString().toCharArray()))
is JsonValue.Object -> body.add(name, JsonValue.Integer(numbers[0]!!.toString().toCharArray()))
is JsonValue.Array -> {
numbers.padTo(body.size()).forEachIndexed { i, value ->
body[i].asObject()!!.add(name, JsonValue.Integer(value.toString().toCharArray()))
body[i].asObject()!!.add(name, JsonValue.Integer(value!!.toString().toCharArray()))
}
}
else -> {}
Expand All @@ -492,9 +522,15 @@ open class PactDslJsonBody : DslPart {
* Attributes that must be a decimal values (have significant digits after the decimal point)
* @param names attribute names
*/
fun decimalTypes(vararg names: String): PactDslJsonBody {
fun decimalTypes(vararg names: String?): PactDslJsonBody {
require(names.isNotEmpty()) {
"At least one attribute name is required"
}
require(names.none { it == null }) {
"Attribute names can not be null"
}
for (name in names) {
decimalType(name)
decimalType(name!!)
}
return this
}
Expand All @@ -504,21 +540,24 @@ open class PactDslJsonBody : DslPart {
* @param name attribute name
* @param number example decimalType value
*/
fun decimalType(name: String, vararg numbers: BigDecimal): PactDslJsonBody {
fun decimalType(name: String, vararg numbers: BigDecimal?): PactDslJsonBody {
require(numbers.isNotEmpty()) {
"At least one example value is required"
}
require(numbers.none { it == null }) {
"Example values can not be null"
}
if (body is JsonValue.Object && numbers.size > 1) {
throw IllegalArgumentException("You provided multiple example values (${numbers.size}) but only one was expected")
} else if (body is JsonValue.Array && body.size() < numbers.size) {
throw IllegalArgumentException("You provided ${numbers.size} example values but ${body.size()} was expected")
}

when (val body = body) {
is JsonValue.Object -> body.add(name, JsonValue.Decimal(numbers[0].toString().toCharArray()))
is JsonValue.Object -> body.add(name, JsonValue.Decimal(numbers[0]!!.toString().toCharArray()))
is JsonValue.Array -> {
numbers.padTo(body.size()).forEachIndexed { i, value ->
body[i].asObject()!!.add(name, JsonValue.Decimal(value.toString().toCharArray()))
body[i].asObject()!!.add(name, JsonValue.Decimal(value!!.toString().toCharArray()))
}
}
else -> {}
Expand All @@ -534,21 +573,24 @@ open class PactDslJsonBody : DslPart {
* @param name attribute name
* @param number example decimalType value
*/
fun decimalType(name: String, vararg numbers: Double): PactDslJsonBody {
fun decimalType(name: String, vararg numbers: Double?): PactDslJsonBody {
require(numbers.isNotEmpty()) {
"At least one example value is required"
}
require(numbers.none { it == null }) {
"Example values can not be null"
}
if (body is JsonValue.Object && numbers.size > 1) {
throw IllegalArgumentException("You provided multiple example values (${numbers.size}) but only one was expected")
} else if (body is JsonValue.Array && body.size() < numbers.size) {
throw IllegalArgumentException("You provided ${numbers.size} example values but ${body.size()} was expected")
}

when (val body = body) {
is JsonValue.Object -> body.add(name, JsonValue.Decimal(numbers[0].toString().toCharArray()))
is JsonValue.Object -> body.add(name, JsonValue.Decimal(numbers[0]!!.toString().toCharArray()))
is JsonValue.Array -> {
numbers.padTo(body.size()).forEachIndexed { i, value ->
body[i].asObject()!!.add(name, JsonValue.Decimal(value.toString().toCharArray()))
body[i].asObject()!!.add(name, JsonValue.Decimal(value!!.toString().toCharArray()))
}
}
else -> {}
Expand Down Expand Up @@ -651,9 +693,15 @@ open class PactDslJsonBody : DslPart {
* Attributes that must be a boolean
* @param names attribute names
*/
fun booleanTypes(vararg names: String): PactDslJsonBody {
fun booleanTypes(vararg names: String?): PactDslJsonBody {
require(names.isNotEmpty()) {
"At least one attribute name is required"
}
require(names.none { it == null }) {
"Attribute names can not be null"
}
for (name in names) {
booleanType(name)
booleanType(name!!)
}
return this
}
Expand All @@ -664,10 +712,13 @@ open class PactDslJsonBody : DslPart {
* @param example example boolean to use for generated bodies
*/
@JvmOverloads
fun booleanType(name: String, vararg examples: Boolean = booleanArrayOf(true)): PactDslJsonBody {
fun booleanType(name: String, vararg examples: Boolean? = arrayOf(true)): PactDslJsonBody {
require(examples.isNotEmpty()) {
"At least one example value is required"
}
require(examples.none { it == null }) {
"Example values can not be null"
}
if (body is JsonValue.Object && examples.size > 1) {
throw IllegalArgumentException(
"You provided multiple example values (${examples.size}) but only one was expected"
Expand All @@ -677,10 +728,10 @@ open class PactDslJsonBody : DslPart {
}

when (val body = body) {
is JsonValue.Object -> body.add(name, if (examples[0]) JsonValue.True else JsonValue.False)
is JsonValue.Object -> body.add(name, if (examples[0]!!) JsonValue.True else JsonValue.False)
is JsonValue.Array -> {
examples.padTo(body.size()).forEachIndexed { i, value ->
body[i].asObject()!!.add(name, if (value) JsonValue.True else JsonValue.False)
body[i].asObject()!!.add(name, if (value!!) JsonValue.True else JsonValue.False)
}
}
else -> {}
Expand All @@ -698,10 +749,13 @@ open class PactDslJsonBody : DslPart {
* @param value example value to use for generated bodies
*/
@Suppress("ThrowsCount")
fun stringMatcher(name: String, regex: String, vararg values: String): PactDslJsonBody {
fun stringMatcher(name: String, regex: String, vararg values: String?): PactDslJsonBody {
require(values.isNotEmpty()) {
"At least one example value is required"
}
require(values.none { it == null }) {
"Example values can not be null"
}
if (body is JsonValue.Object && values.size > 1) {
throw IllegalArgumentException("You provided multiple example values (${values.size}) but only one was expected")
} else if (body is JsonValue.Array && body.size() < values.size) {
Expand All @@ -711,14 +765,14 @@ open class PactDslJsonBody : DslPart {
val re = Regex(regex)
when (val body = body) {
is JsonValue.Object -> {
if (!values[0].matches(re)) {
if (!values[0]!!.matches(re)) {
throw InvalidMatcherException("Example \"${values[0]}\" does not match regular expression \"$regex\"")
}
body.add(name, JsonValue.StringValue(values[0].toCharArray()))
body.add(name, JsonValue.StringValue(values[0]!!.toCharArray()))
}
is JsonValue.Array -> {
values.padTo(body.size()).forEachIndexed { i, value ->
if (!value.matches(re)) {
if (!value!!.matches(re)) {
throw InvalidMatcherException("Example \"$value\" does not match regular expression \"$regex\"")
}
body[i].asObject()!!.add(name, JsonValue.StringValue(value.toCharArray()))
Expand Down
Loading

0 comments on commit 1721cb0

Please sign in to comment.