Skip to content

Commit 7f44c37

Browse files
author
Ronald Holshausen
committedNov 24, 2019
fix: correct the markdown rendering of verification errors #980
1 parent cd1d14d commit 7f44c37

File tree

2 files changed

+169
-20
lines changed

2 files changed

+169
-20
lines changed
 

Diff for: ‎provider/pact-jvm-provider/src/main/kotlin/au/com/dius/pact/provider/reporters/MarkdownReporter.kt

+50-19
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package au.com.dius.pact.provider.reporters
22

3+
import arrow.core.Either
4+
import au.com.dius.pact.core.matchers.BodyTypeMismatch
5+
import au.com.dius.pact.core.matchers.HeaderMismatch
36
import au.com.dius.pact.core.model.BasePact
47
import au.com.dius.pact.core.model.Interaction
58
import au.com.dius.pact.core.model.Pact
69
import au.com.dius.pact.core.model.PactSource
710
import au.com.dius.pact.core.model.UrlPactSource
811
import au.com.dius.pact.core.support.hasProperty
912
import au.com.dius.pact.core.support.property
13+
import au.com.dius.pact.provider.BodyComparisonResult
1014
import au.com.dius.pact.provider.IConsumerInfo
1115
import au.com.dius.pact.provider.IProviderInfo
1216
import java.io.BufferedWriter
@@ -170,7 +174,17 @@ class MarkdownReporter(
170174

171175
override fun headerComparisonFailed(key: String, value: List<String>, comparison: Any) {
172176
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\"**$key**\" with value \"**$value**\" " +
173-
"(<span style=\'color:red\'>FAILED</span>) \n\n```\n$comparison\n```\n\n")
177+
"(<span style=\'color:red\'>FAILED</span>) \n\n```\n")
178+
when (comparison) {
179+
is List<*> -> comparison.forEach {
180+
when (it) {
181+
is HeaderMismatch -> pw!!.write(it.mismatch)
182+
else -> pw!!.write(it.toString())
183+
}
184+
}
185+
else -> pw!!.write(comparison.toString())
186+
}
187+
pw!!.write("\n```\n\n")
174188
}
175189

176190
override fun bodyComparisonOk() {
@@ -179,25 +193,42 @@ class MarkdownReporter(
179193

180194
override fun bodyComparisonFailed(comparison: Any) {
181195
pw!!.write("&nbsp;&nbsp;&nbsp;&nbsp;has a matching body (<span style='color:red'>FAILED</span>) \n\n")
182-
pw!!.write("| Path | Failure |\n")
183-
pw!!.write("| ---- | ------- |\n")
184-
185-
val property = comparison.property("comparison")?.get(comparison)
186-
when {
187-
comparison is String -> pw!!.write("|\$|$comparison|\n")
188-
property is Map<*, *> -> pw!!.write(property.map {
189-
val mismatches = (it.value as List<Map<String, Any>>).joinToString("; ") { mismatch ->
190-
mismatch["mismatch"].toString()
196+
197+
// val property = comparison.property("comparison")?.get(comparison)
198+
// when {
199+
// comparison is String -> pw!!.write("|\$|$comparison|\n")
200+
// property is Map<*, *> -> pw!!.write(property.map {
201+
// val mismatches = (it.value as List<Map<String, Any>>).joinToString("; ") { mismatch ->
202+
// mismatch["mismatch"].toString()
203+
// }
204+
// "|${it.key}|$mismatches|"
205+
// }.joinToString("\n"))
206+
// else -> pw!!.write("|\$|$property|")
207+
// }
208+
// pw!!.write("\n\n")
209+
// if (comparison.hasProperty("diff")) {
210+
// pw!!.write("Diff:\n\n")
211+
// renderDiff(pw!!, comparison.property("diff")?.get(comparison))
212+
// pw!!.write("\n\n")
213+
// }
214+
215+
when (comparison) {
216+
is Either.Left<*> -> {
217+
comparison as Either.Left<BodyTypeMismatch>
218+
pw!!.write("```\n${comparison.a.description()}\n```\n")
219+
}
220+
is Either.Right<*> -> {
221+
comparison as Either.Right<BodyComparisonResult>
222+
pw!!.write("| Path | Failure |\n")
223+
pw!!.write("| ---- | ------- |\n")
224+
comparison.b.mismatches.forEach { entry ->
225+
pw!!.write("|`${entry.key}`|${entry.value.joinToString("\n") { it.description() }}|\n")
191226
}
192-
"|${it.key}|$mismatches|"
193-
}.joinToString("\n"))
194-
else -> pw!!.write("|\$|$property|")
195-
}
196-
pw!!.write("\n\n")
197-
if (comparison.hasProperty("diff")) {
198-
pw!!.write("Diff:\n\n")
199-
renderDiff(pw!!, comparison.property("diff")?.get(comparison))
200-
pw!!.write("\n\n")
227+
pw!!.write("\n\nDiff:\n\n")
228+
renderDiff(pw!!, comparison.b.diff)
229+
pw!!.write("\n\n")
230+
}
231+
else -> pw!!.write("```\n${comparison}\n```\n")
201232
}
202233
}
203234

Diff for: ‎provider/pact-jvm-provider/src/test/groovy/au/com/dius/pact/provider/reporters/MarkdownReporterSpec.groovy

+119-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
package au.com.dius.pact.provider.reporters
22

3+
import arrow.core.Either
4+
import au.com.dius.pact.core.matchers.BodyMismatch
5+
import au.com.dius.pact.core.matchers.HeaderMismatch
36
import au.com.dius.pact.core.model.Request
47
import au.com.dius.pact.core.model.RequestResponseInteraction
58
import au.com.dius.pact.core.model.Response
9+
import au.com.dius.pact.provider.BodyComparisonResult
610
import au.com.dius.pact.provider.ConsumerInfo
711
import au.com.dius.pact.provider.ProviderInfo
12+
import com.google.gson.JsonParser
813
import spock.lang.Specification
914

10-
@SuppressWarnings('UnnecessaryObjectReferences')
15+
@SuppressWarnings(['UnnecessaryObjectReferences', 'LineLength'])
1116
class MarkdownReporterSpec extends Specification {
1217

1318
private File reportDir
@@ -80,4 +85,117 @@ class MarkdownReporterSpec extends Specification {
8085
results.contains('## Verifying a pact between _Consumer_ and _provider1_\n\nInteraction 1 ')
8186
}
8287

88+
@SuppressWarnings(['MethodSize', 'TrailingWhitespace'])
89+
def 'generates the correct markdown for validation failures'() {
90+
given:
91+
def reporter = new MarkdownReporter('test', reportDir)
92+
def provider1 = new ProviderInfo(name: 'provider1')
93+
def consumer = new ConsumerInfo(name: 'Consumer')
94+
def interaction1 = new RequestResponseInteraction('Interaction 1', [], new Request(), new Response())
95+
96+
when:
97+
reporter.initialise(provider1)
98+
reporter.reportVerificationForConsumer(consumer, provider1, null)
99+
reporter.interactionDescription(interaction1)
100+
reporter.statusComparisonFailed(200, 'expected status of 201 but was 200')
101+
reporter.headerComparisonFailed('HEADER-X', ['Y'], [
102+
new HeaderMismatch('HEADER-X', 'Y', '', "Expected a header 'HEADER-X' but was missing")
103+
])
104+
reporter.bodyComparisonFailed(
105+
new Either.Right(new BodyComparisonResult([
106+
'$.0': [
107+
new BodyMismatch(
108+
JsonParser.parseString('{"doesNotExist":"Test","documentId":0}'),
109+
JsonParser.parseString('{"documentId":0,"documentCategoryId":5,"documentCategoryCode":null,"contentLength":0,"tags":null}'),
110+
'Expected doesNotExist="Test" but was missing', '$.0', '''{
111+
- "doesNotExist": "Test",
112+
- "documentId": 0
113+
+ "documentId": 0,
114+
+ "documentCategoryId": 5,
115+
+ "documentCategoryCode": null,
116+
+ "contentLength": 0,
117+
+ "tags": null
118+
}''')],
119+
'$.1': [
120+
new BodyMismatch(JsonParser.parseString('{"doesNotExist":"Test","documentId":0}'),
121+
JsonParser.parseString('{"documentId":1,"documentCategoryId":5,"documentCategoryCode":null,"contentLength":0,"tags":null}'),
122+
'Expected doesNotExist="Test" but was missing', '$.1', '''{
123+
- "doesNotExist": "Test",
124+
- "documentId": 0
125+
+ "documentId": 1,
126+
+ "documentCategoryId": 5,
127+
+ "documentCategoryCode": null,
128+
+ "contentLength": 0,
129+
+ "tags": null
130+
}''')]
131+
], [
132+
' {',
133+
'- " doesNotExist ": " Test ",',
134+
'- " documentId ": 0',
135+
'+ " documentId ": 0,',
136+
'+ " documentCategoryId ": 5,',
137+
'+ " documentCategoryCode ": null,',
138+
'+ " contentLength ": 0,',
139+
'+ " tags ": null',
140+
'+ },',
141+
'+ {',
142+
'+ " documentId ": 1,',
143+
'+ " documentCategoryId ": 5,',
144+
'+ " documentCategoryCode ": null,',
145+
'+ " contentLength ": 0,',
146+
'+ " tags ": null',
147+
' }'
148+
]))
149+
)
150+
reporter.finaliseReport()
151+
152+
def results = new File(reportDir, 'provider1.md').text
153+
154+
then:
155+
results.contains(
156+
'''|&nbsp;&nbsp;&nbsp;&nbsp;has status code **200** (<span style='color:red'>FAILED</span>)
157+
|
158+
|```
159+
|expected status of 201 but was 200
160+
|```'''.stripMargin()
161+
)
162+
results.contains(
163+
'''|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"**HEADER-X**" with value "**[Y]**" (<span style='color:red'>FAILED</span>)
164+
|
165+
|```
166+
|Expected a header 'HEADER-X' but was missing
167+
|```'''.stripMargin()
168+
)
169+
results.contains(
170+
'''|&nbsp;&nbsp;&nbsp;&nbsp;has a matching body (<span style='color:red'>FAILED</span>)
171+
|
172+
|| Path | Failure |
173+
|| ---- | ------- |
174+
||`$.0`|Expected doesNotExist="Test" but was missing|
175+
||`$.1`|Expected doesNotExist="Test" but was missing|
176+
|
177+
|
178+
|Diff:
179+
|
180+
|```diff
181+
| {
182+
|- " doesNotExist ": " Test ",
183+
|- " documentId ": 0
184+
|+ " documentId ": 0,
185+
|+ " documentCategoryId ": 5,
186+
|+ " documentCategoryCode ": null,
187+
|+ " contentLength ": 0,
188+
|+ " tags ": null
189+
|+ },
190+
|+ {
191+
|+ " documentId ": 1,
192+
|+ " documentCategoryId ": 5,
193+
|+ " documentCategoryCode ": null,
194+
|+ " contentLength ": 0,
195+
|+ " tags ": null
196+
| }
197+
|```'''.stripMargin()
198+
)
199+
}
200+
83201
}

0 commit comments

Comments
 (0)
Please sign in to comment.