run.qontract.core.pattern.TabularPattern.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of qontract-core Show documentation
Show all versions of qontract-core Show documentation
A Contract Testing Tool that leverages Gherkin to describe APIs in a human readable and machine enforceable manner
package run.qontract.core.pattern
import io.cucumber.messages.Messages
import run.qontract.core.*
import run.qontract.core.utilities.mapZip
import run.qontract.core.utilities.stringToPatternMap
import run.qontract.core.utilities.withNullPattern
import run.qontract.core.value.*
fun toTabularPattern(jsonContent: String, typeAlias: String? = null): TabularPattern = toTabularPattern(stringToPatternMap(jsonContent), typeAlias)
fun toTabularPattern(map: Map, typeAlias: String? = null): TabularPattern {
val missingKeyStrategy = when ("...") {
in map -> ignoreUnexpectedKeys
else -> ::validateUnexpectedKeys
}
return TabularPattern(map.minus("..."), missingKeyStrategy, typeAlias)
}
data class TabularPattern(override val pattern: Map, private val unexpectedKeyCheck: UnexpectedKeyCheck = ::validateUnexpectedKeys, override val typeAlias: String? = null) : Pattern {
override fun matches(sampleData: Value?, resolver: Resolver): Result {
if(sampleData !is JSONObjectValue)
return mismatchResult("JSON object", sampleData)
val resolverWithNullType = withNullPattern(resolver)
val missingKey = resolverWithNullType.findMissingKey(pattern, sampleData.jsonObject, unexpectedKeyCheck)
if(missingKey != null)
return missingKeyToResult(missingKey, "key")
mapZip(pattern, sampleData.jsonObject).forEach { (key, patternValue, sampleValue) ->
when (val result = resolverWithNullType.matchesPattern(key, patternValue, sampleValue)) {
is Result.Failure -> return result.breadCrumb(key)
}
}
return Result.Success()
}
override fun listOf(valueList: List, resolver: Resolver): Value = JSONArrayValue(valueList)
override fun generate(resolver: Resolver): JSONObjectValue {
val resolverWithNullType = withNullPattern(resolver)
return JSONObjectValue(pattern.mapKeys { entry -> withoutOptionality(entry.key) }.mapValues { (key, pattern) ->
attempt(breadCrumb = key) { resolverWithNullType.generate(key, pattern) }
})
}
override fun newBasedOn(row: Row, resolver: Resolver): List {
val resolverWithNullType = withNullPattern(resolver)
return forEachKeyCombinationIn(pattern, row) { pattern ->
newBasedOn(pattern, row, resolverWithNullType)
}.map { toTabularPattern(it) }
}
override fun parse(value: String, resolver: Resolver): Value = parsedJSON(value)
override fun encompasses(otherPattern: Pattern, thisResolver: Resolver, otherResolver: Resolver, typeStack: TypeStack): Result {
val thisResolverWithNullType = withNullPattern(thisResolver)
val otherResolverWithNullType = withNullPattern(otherResolver)
return when (otherPattern) {
is ExactValuePattern -> otherPattern.fitsWithin(listOf(this), otherResolverWithNullType, thisResolverWithNullType, typeStack)
!is TabularPattern -> Result.Failure("Expected tabular json type, got ${otherPattern.typeName}")
else -> mapEncompassesMap(pattern, otherPattern.pattern, thisResolverWithNullType, otherResolverWithNullType, typeStack)
}
}
override val typeName: String = "json object"
}
fun newBasedOn(patternMap: Map, row: Row, resolver: Resolver): List