Skip to content

Commit

Permalink
refactor: update MarkdownReporter to accumulate all events and genera…
Browse files Browse the repository at this point in the history
…te the report at the end #1128
  • Loading branch information
Ronald Holshausen committed Oct 4, 2020
1 parent 358a76d commit e3a43e1
Showing 1 changed file with 128 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,15 @@ import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter
import java.io.PrintWriter
import java.io.StringWriter
import java.time.ZonedDateTime

data class Event(
val type: String,
val contents: String,
val data: List<Any?>
)

/**
* Pact verifier reporter that displays the results of the verification in a markdown document
*/
Expand All @@ -38,21 +45,25 @@ class MarkdownReporter(
override lateinit var reportFile: File
override lateinit var verifier: IProviderVerifier

private lateinit var provider: IProviderInfo
private val events = mutableListOf<Event>()

init {
if (reportDir == null) {
reportDir = File(System.getProperty("user.dir"))
}
reportFile = File(reportDir, "$name$ext")
}

private var pw: PrintWriter? = null

override fun initialise(provider: IProviderInfo) {
pw?.close()
this.provider = provider
reportDir!!.mkdirs()
reportFile = File(reportDir, provider.name + ext)
pw = PrintWriter(BufferedWriter(FileWriter(reportFile, true)))
pw!!.write("""
}

override fun finaliseReport() {
val pw = PrintWriter(BufferedWriter(FileWriter(reportFile, false)))
pw.write("""
# ${provider.name}
| Description | Value |
Expand All @@ -61,33 +72,34 @@ class MarkdownReporter(
| Pact Version | ${BasePact.lookupVersion()} |
""".trimIndent())
}

override fun finaliseReport() {
pw?.close()
for (event in events) {
pw.write(event.contents)
}
pw.close()
}

override fun reportVerificationForConsumer(consumer: IConsumerInfo, provider: IProviderInfo, tag: String?) {
val report = StringBuilder("## Verifying a pact between _${consumer.name}_")
val output = StringBuilder("## Verifying a pact between _${consumer.name}_")
if (!consumer.name.contains(provider.name)) {
report.append(" and _${provider.name}_")
output.append(" and _${provider.name}_")
}
if (tag != null) {
report.append(" for tag $tag")
output.append(" for tag $tag")
}
if (consumer.pending) {
report.append(" [PENDING]")
output.append(" [PENDING]")
}
report.append("\n\n")
pw!!.write(report.toString())
output.append("\n\n")
events.add(Event("reportVerificationForConsumer", output.toString(), listOf(consumer, provider, tag)))
}

override fun verifyConsumerFromUrl(pactUrl: UrlPactSource, consumer: IConsumerInfo) {
pw!!.write("From `${pactUrl.description()}`<br/>\n")
events.add(Event("verifyConsumerFromUrl", "From `${pactUrl.description()}`<br/>\n", listOf(pactUrl, consumer)))
}

override fun verifyConsumerFromFile(pactFile: PactSource, consumer: IConsumerInfo) {
pw!!.write("From `${pactFile.description()}`<br/>\n")
events.add(Event("verifyConsumerFromFile", "From `${pactFile.description()}`<br/>\n", listOf(pactFile, consumer)))
}

override fun pactLoadFailureForConsumer(consumer: IConsumerInfo, message: String) { }
Expand All @@ -97,16 +109,16 @@ class MarkdownReporter(
override fun warnPactFileHasNoInteractions(pact: Pact<Interaction>) { }

override fun interactionDescription(interaction: Interaction) {
pw!!.write("${interaction.description} \n")
events.add(Event("interactionDescription", "${interaction.description} \n", listOf(interaction)))
}

override fun stateForInteraction(state: String, provider: IProviderInfo, consumer: IConsumerInfo, isSetup: Boolean) {
pw!!.write("Given **$state** \n")
events.add(Event("stateForInteraction", "Given **$state** \n", listOf(state, provider, consumer, isSetup)))
}

override fun warnStateChangeIgnored(state: String, provider: IProviderInfo, consumer: IConsumerInfo) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;<span style=\'color: yellow\'>WARNING: State Change ignored as " +
"there is no stateChange URL</span> \n")
events.add(Event("warnStateChangeIgnored", "&nbsp;&nbsp;&nbsp;&nbsp;<span style=\'color: yellow\'>WARNING: State Change ignored as " +
"there is no stateChange URL</span> \n", listOf(state, provider, consumer)))
}

override fun stateChangeRequestFailedWithException(
Expand All @@ -115,15 +127,21 @@ class MarkdownReporter(
e: Exception,
printStackTrace: Boolean
) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;<span style='color: red'>State Change Request Failed - ${e.message}" +
val sw = StringWriter()
val pw = PrintWriter(sw)
pw.write("&nbsp;&nbsp;&nbsp;&nbsp;<span style='color: red'>State Change Request Failed - ${e.message}" +
"</span>\n\n```\n")
e.printStackTrace(pw!!)
pw!!.write("\n```\n\n")
e.printStackTrace(pw)
pw.write("\n```\n\n")
pw.close()

events.add(Event("stateChangeRequestFailedWithException", sw.toString(), listOf(state, isSetup, e, printStackTrace)))
}

override fun stateChangeRequestFailed(state: String, provider: IProviderInfo, isSetup: Boolean, httpStatus: String) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;<span style='color: red'>State Change Request Failed - $httpStatus" +
"</span> \n")
events.add(Event("stateChangeRequestFailedWithException",
"&nbsp;&nbsp;&nbsp;&nbsp;<span style='color: red'>State Change Request Failed - $httpStatus" +
"</span> \n", listOf(state, provider, isSetup, httpStatus)))
}

override fun warnStateChangeIgnoredDueToInvalidUrl(
Expand All @@ -132,8 +150,10 @@ class MarkdownReporter(
isSetup: Boolean,
stateChangeHandler: Any
) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;<span style=\'color: yellow\'>WARNING: State Change ignored as " +
"there is no stateChange URL, received `$stateChangeHandler`</span> \n")
events.add(Event("warnStateChangeIgnoredDueToInvalidUrl",
"&nbsp;&nbsp;&nbsp;&nbsp;<span style=\'color: yellow\'>WARNING: State Change ignored as " +
"there is no stateChange URL, received `$stateChangeHandler`</span> \n",
listOf(state, provider, isSetup, stateChangeHandler)))
}

override fun requestFailed(
Expand All @@ -143,80 +163,102 @@ class MarkdownReporter(
e: Exception,
printStackTrace: Boolean
) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;<span style='color: red'>Request Failed - ${e.message}</span>\n\n```\n")
e.printStackTrace(pw!!)
pw!!.write("\n```\n\n")
val sw = StringWriter()
val pw = PrintWriter(sw)
pw.write("&nbsp;&nbsp;&nbsp;&nbsp;<span style='color: red'>Request Failed - ${e.message}</span>\n\n```\n")
e.printStackTrace(pw)
pw.write("\n```\n\n")
pw.close()

events.add(Event("requestFailed", sw.toString(), listOf(provider, interaction, interactionMessage, e,
printStackTrace)))
}

override fun returnsAResponseWhich() {
pw!!.write("&nbsp;&nbsp;returns a response which \n")
events.add(Event("returnsAResponseWhich", "&nbsp;&nbsp;returns a response which \n", listOf()))
}

override fun statusComparisonOk(status: Int) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;has status code **$status** " +
"(<span style='color:green'>OK</span>) \n")
events.add(Event("statusComparisonOk", "&nbsp;&nbsp;&nbsp;&nbsp;has status code **$status** " +
"(<span style='color:green'>OK</span>) \n", listOf(status)))
}

override fun statusComparisonFailed(status: Int, comparison: Any) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;has status code **$status** " +
val sw = StringWriter()
val pw = PrintWriter(sw)
pw.write("&nbsp;&nbsp;&nbsp;&nbsp;has status code **$status** " +
"(<span style='color:red'>FAILED</span>)\n\n```\n")
if (comparison.hasProperty("message")) {
pw!!.write(comparison.property("message")?.get(comparison).toString())
pw.write(comparison.property("message")?.get(comparison).toString())
} else {
pw!!.write(comparison.toString())
pw.write(comparison.toString())
}
pw!!.write("\n```\n\n")
pw.write("\n```\n\n")
pw.close()

events.add(Event("statusComparisonFailed", pw.toString(), listOf(status, comparison)))
}

override fun includesHeaders() {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;includes headers \n")
events.add(Event("includesHeaders", "&nbsp;&nbsp;&nbsp;&nbsp;includes headers \n", listOf()))
}

override fun headerComparisonOk(key: String, value: List<String>) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"**$key**\" with value \"**$value**\" " +
"(<span style=\'color:green\'>OK</span>) \n")
events.add(Event("headerComparisonOk",
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"**$key**\" with value \"**$value**\" " +
"(<span style=\'color:green\'>OK</span>) \n", listOf(key, value)))
}

override fun headerComparisonFailed(key: String, value: List<String>, comparison: Any) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"**$key**\" with value \"**$value**\" " +
val sw = StringWriter()
val pw = PrintWriter(sw)
pw.write("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"**$key**\" with value \"**$value**\" " +
"(<span style=\'color:red\'>FAILED</span>) \n\n```\n")
when (comparison) {
is List<*> -> comparison.forEach {
when (it) {
is HeaderMismatch -> pw!!.write(it.mismatch)
else -> pw!!.write(it.toString())
is HeaderMismatch -> pw.write(it.mismatch)
else -> pw.write(it.toString())
}
}
else -> pw!!.write(comparison.toString())
else -> pw.write(comparison.toString())
}
pw!!.write("\n```\n\n")
pw.write("\n```\n\n")
pw.close()

events.add(Event("headerComparisonFailed", pw.toString(), listOf(key, value, comparison)))
}

override fun bodyComparisonOk() {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;has a matching body (<span style='color:green'>OK</span>) \n")
events.add(Event("bodyComparisonOk",
"&nbsp;&nbsp;&nbsp;&nbsp;has a matching body (<span style='color:green'>OK</span>) \n", listOf()))
}

override fun bodyComparisonFailed(comparison: Any) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;has a matching body (<span style='color:red'>FAILED</span>) \n\n")
val sw = StringWriter()
val pw = PrintWriter(sw)
pw.write("&nbsp;&nbsp;&nbsp;&nbsp;has a matching body (<span style='color:red'>FAILED</span>) \n\n")

when (comparison) {
is Err<*> -> {
comparison as Err<BodyTypeMismatch>
pw!!.write("```\n${comparison.error.description()}\n```\n")
pw.write("```\n${comparison.error.description()}\n```\n")
}
is Ok<*> -> {
comparison as Ok<BodyComparisonResult>
pw!!.write("| Path | Failure |\n")
pw!!.write("| ---- | ------- |\n")
pw.write("| Path | Failure |\n")
pw.write("| ---- | ------- |\n")
comparison.value.mismatches.forEach { entry ->
pw!!.write("|`${entry.key}`|${entry.value.joinToString("\n") { it.description() }}|\n")
pw.write("|`${entry.key}`|${entry.value.joinToString("\n") { it.description() }}|\n")
}
pw!!.write("\n\nDiff:\n\n")
renderDiff(pw!!, comparison.value.diff)
pw!!.write("\n\n")
pw.write("\n\nDiff:\n\n")
renderDiff(pw, comparison.value.diff)
pw.write("\n\n")
}
else -> pw!!.write("```\n${comparison}\n```\n")
else -> pw.write("```\n${comparison}\n```\n")
}
pw.close()
events.add(Event("bodyComparisonFailed", pw.toString(), listOf(comparison)))
}

private fun renderDiff(pw: PrintWriter, diff: Any?) {
Expand All @@ -232,53 +274,70 @@ class MarkdownReporter(
override fun errorHasNoAnnotatedMethodsFoundForInteraction(interaction: Interaction) { }

override fun verificationFailed(interaction: Interaction, e: Exception, printStackTrace: Boolean) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;<span style='color: red'>Verification Failed - ${e.message}</span>\n\n```\n")
val sw = StringWriter()
val pw = PrintWriter(sw)
pw.write("&nbsp;&nbsp;&nbsp;&nbsp;<span style='color: red'>Verification Failed - ${e.message}</span>\n\n```\n")
e.printStackTrace(pw)
pw!!.write("\n```\n\n")
pw.write("\n```\n\n")
pw.close()
events.add(Event("verificationFailed", pw.toString(), listOf(interaction, e, printStackTrace)))
}

override fun generatesAMessageWhich() {
pw!!.write("&nbsp;&nbsp;generates a message which \n")
events.add(Event("generatesAMessageWhich", "&nbsp;&nbsp;generates a message which \n", listOf()))
}

override fun displayFailures(failures: Map<String, Any>) { }

override fun displayFailures(failures: List<VerificationResult.Failed>) { }

override fun metadataComparisonFailed(key: String, value: Any?, comparison: Any) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"**$key**\" with value \"**$value**\" " +
val sw = StringWriter()
val pw = PrintWriter(sw)
pw.write("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"**$key**\" with value \"**$value**\" " +
"(<span style=\'color:red\'>FAILED</span>) \n")
pw!!.write("\n```\n$comparison\n```\n\n")
pw.write("\n```\n$comparison\n```\n\n")
pw.close()
events.add(Event("metadataComparisonFailed", pw.toString(), listOf(key, value, comparison)))
}

override fun includesMetadata() {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;includes metadata \n")
events.add(Event("includesMetadata", "&nbsp;&nbsp;&nbsp;&nbsp;includes metadata \n", listOf()))
}

override fun metadataComparisonOk(key: String, value: Any?) {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"**$key**\" with value \"**$value**\" " +
"(<span style=\'color:green\'>OK</span>) \n")
events.add(Event("metadataComparisonOk",
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"**$key**\" with value \"**$value**\" " +
"(<span style=\'color:green\'>OK</span>) \n", listOf(key, value)))
}

override fun metadataComparisonOk() {
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;has matching metadata (<span style='color:green'>OK</span>)\n")
events.add(Event("metadataComparisonOk",
"&nbsp;&nbsp;&nbsp;&nbsp;has matching metadata (<span style='color:green'>OK</span>)\n", listOf()))
}

override fun reportVerificationNoticesForConsumer(
consumer: IConsumerInfo,
provider: IProviderInfo,
notices: List<VerificationNotice>
) {
pw!!.write("Notices:\n")
notices.forEachIndexed { i, notice -> pw!!.write("${i + 1}. ${notice.text}\n") }
pw!!.write("\n")
val sw = StringWriter()
val pw = PrintWriter(sw)
pw.write("Notices:\n")
notices.forEachIndexed { i, notice -> pw.write("${i + 1}. ${notice.text}\n") }
pw.write("\n")
pw.close()
events.add(Event("reportVerificationNoticesForConsumer", pw.toString(), listOf(consumer, provider, notices)))
}

override fun warnPublishResultsSkippedBecauseFiltered() {
pw!!.write("NOTE: Skipping publishing of verification results as the interactions have been filtered\n")
events.add(Event("warnPublishResultsSkippedBecauseFiltered",
"NOTE: Skipping publishing of verification results as the interactions have been filtered\n", listOf()))
}

override fun warnPublishResultsSkippedBecauseDisabled(envVar: String) {
pw!!.write("NOTE: Skipping publishing of verification results as it has been disabled ($envVar is not 'true')\n")
events.add(Event("warnPublishResultsSkippedBecauseDisabled",
"NOTE: Skipping publishing of verification results as it has been disabled ($envVar is not 'true')\n",
listOf(envVar)))
}
}

0 comments on commit e3a43e1

Please sign in to comment.