Skip to content

Commit

Permalink
feat: allow matchers to be applied to unknown body formats
Browse files Browse the repository at this point in the history
  • Loading branch information
Ronald Holshausen committed Jun 18, 2020
1 parent c171797 commit 8203452
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 8 deletions.
Expand Up @@ -73,7 +73,7 @@ protected void assertException(Throwable e) {
"\tpath: /second\n" +
"\tquery: {}\n" +
"\theaders: {testreqheader=[testreqheadervalue]}\n" +
"\tmatchers: MatchingRules(rules={path=Category(name=path, matchingRules={}), header=Category(name=header, matchingRules={})})\n" +
"\tmatchers: MatchingRules(rules={path=Category(name=path, matchingRules={}), header=Category(name=header, matchingRules={}), body=Category(name=body, matchingRules={})})\n" +
"\tgenerators: Generators(categories={})\n" +
"\tbody: EMPTY"));

Expand Down
@@ -1,7 +1,6 @@
package au.com.dius.pact.core.matchers

import au.com.dius.pact.core.model.ContentType
import au.com.dius.pact.core.model.OptionalBody
import au.com.dius.pact.core.model.matchingrules.ContentTypeMatcher
import au.com.dius.pact.core.model.matchingrules.DateMatcher
import au.com.dius.pact.core.model.matchingrules.IncludeMatcher
Expand Down
Expand Up @@ -71,10 +71,7 @@ object Matching : KLogging() {
expected.body.isNull() -> emptyList()
actual.body.isMissing() -> listOf(BodyMismatch(expected.body.unwrap(), null,
"Expected body '${expected.body.unwrap()}' but was missing"))
expected.body.unwrap().contentEquals(actual.body.unwrap()) -> emptyList()
else -> listOf(BodyMismatch(expected.body.unwrap(), actual.body.unwrap(),
"Actual body '${actual.body.valueAsString()}' is not equal to the expected body " +
"'${expected.body.valueAsString()}'"))
else -> matchBodyContents(expected, actual)
}
}
} else {
Expand All @@ -83,6 +80,17 @@ object Matching : KLogging() {
}
}

fun matchBodyContents(expected: HttpPart, actual: HttpPart): List<BodyMismatch> {
val matcher = expected.matchingRules.rulesForCategory("body").matchingRules["$"]
return when {
matcher != null -> domatch(matcher, listOf("$"), expected.body.unwrap(), actual.body.unwrap(), BodyMismatchFactory)
expected.body.unwrap().contentEquals(actual.body.unwrap()) -> emptyList()
else -> listOf(BodyMismatch(expected.body.unwrap(), actual.body.unwrap(),
"Actual body '${actual.body.valueAsString()}' is not equal to the expected body " +
"'${expected.body.valueAsString()}'"))
}
}

fun matchPath(expected: Request, actual: Request): PathMismatch? {
val replacedActual = actual.path.replaceFirst(pathFilter, "")
val matchers = expected.matchingRules
Expand Down
Expand Up @@ -3,6 +3,9 @@ package au.com.dius.pact.core.matchers
import au.com.dius.pact.core.model.OptionalBody
import au.com.dius.pact.core.model.PactReaderKt
import au.com.dius.pact.core.model.Request
import au.com.dius.pact.core.model.Response
import au.com.dius.pact.core.model.matchingrules.ContentTypeMatcher
import au.com.dius.pact.core.model.matchingrules.MatchingRulesImpl
import spock.lang.Specification

class MatchingSpec extends Specification {
Expand Down Expand Up @@ -92,4 +95,38 @@ class MatchingSpec extends Specification {
Matching.compareMessageMetadata([A: 'B', contentType: 'D'], [A: 'B'], null).empty
}

def 'Body Matching - compares the bytes of the body'() {
expect:
Matching.INSTANCE.matchBody(expected, actual, false).empty

where:

expected = new Response(200, [:], OptionalBody.body([1, 2, 3, 4] as byte[]))
actual = new Response(200, [:], OptionalBody.body([1, 2, 3, 4] as byte[]))
}

def 'Body Matching - compares the bytes of the body with text'() {
expect:
Matching.INSTANCE.matchBody(expected, actual, false).empty

where:

expected = new Response(200, [:], OptionalBody.body('hello'.bytes))
actual = new Response(200, [:], OptionalBody.body('hello'.bytes))
}

def 'Body Matching - compares the body with aby defined matcher'() {
given:
def matchingRulesImpl = new MatchingRulesImpl()
matchingRulesImpl.addCategory('body').addRule('$', new ContentTypeMatcher('image/jpeg'))
def expected = new Response(200, ['Content-Type': ['image/jpeg']], OptionalBody.body('hello'.bytes),
matchingRulesImpl)
def actual = new Response(200, [:], OptionalBody.body(MatchingSpec.getResourceAsStream('/RAT.JPG').bytes))

when:
def result = Matching.INSTANCE.matchBody(expected, actual, false)

then:
result.empty
}
}
Binary file added core/matchers/src/test/resources/RAT.JPG
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Expand Up @@ -366,7 +366,8 @@ object DefaultPactReader : PactReader, KLogging() {
return when (source) {
is InputStream -> JsonParser.parseReader(InputStreamReader(source)).asObject() to InputStreamPactSource
is Reader -> JsonParser.parseReader(source).asObject() to ReaderPactSource
is File -> source.bufferedReader().use { JsonParser.parseReader(it).asObject() } to FileSource<Interaction>(source)
is File -> source.bufferedReader().use {
JsonParser.parseReader(it).asObject() } to FileSource<Interaction>(source)
else -> throw IllegalArgumentException("loadPactFromFile expects either an InputStream, Reader or File. " +
"Got a ${source.javaClass.name} instead")
}
Expand Down
Expand Up @@ -68,7 +68,11 @@ data class BrokerUrlSource @JvmOverloads constructor(
override fun description() = if (tag == null) "Pact Broker $url" else "Pact Broker $url (Tag $tag)"

companion object {
fun fromResult(result: PactBrokerResult, options: Map<String, Any> = emptyMap(), tag: String? = null): BrokerUrlSource {
fun fromResult(
result: PactBrokerResult,
options: Map<String, Any> = emptyMap(),
tag: String? = null
): BrokerUrlSource {
return BrokerUrlSource(
result.source,
result.pactBrokerUrl,
Expand Down

0 comments on commit 8203452

Please sign in to comment.