Allow rtesting to use custom diff func#590
Conversation
Test cases can now specify a custom diff function which can be used to either use custom cmp options, or replace cmp with some other differ. The existing set of cmp options are matched using the DiffReason. Custom funcs should assume additional DiffReasons will be defined in the future. The DefaultDiff func is used if a custom Diff is not defined. Custom funcs may delegate to the default for DiffReasons they choose not to modify. Signed-off-by: Scott Andrews <scott@andrews.me>
testing/diff.go
Outdated
| type DiffReason float64 | ||
|
|
||
| const ( | ||
| DiffReasonRaw DiffReason = iota | ||
| DiffReasonTrackRequest | ||
| DiffReasonDeleteCollectionRef | ||
| DiffReasonStashedValue | ||
| DiffReasonResource | ||
| DiffReasonWebhookResponse | ||
| DiffReasonResourceStatusUpdate | ||
| DiffReasonResourceUpdate | ||
| DiffReasonResourceCreate | ||
| ) |
There was a problem hiding this comment.
I'm unsure this is the best approach to fully decouple the existing behavior without either coupling the public API to cmp, or introducing each as a custom func.
There was a problem hiding this comment.
An alternative approach could be a Differ interface with a default implementation where each "diff reason" maps to a method, e.g. Differ#DiffRaw(actual, expected) string, Differ#DiffTrackRequest(actual, expected) string etc. We'd get a bit of method sprawl, but it may be easier to provide a custom differ without accidentally missing a diff reason. At the same time, maintainers need to take care to always call the right diff method when asserting test case. To some degree that's already the case, what with the different opts / reasons.
type X509CertificateDiffer struct {
rtesting.DefaultDiffer
}
func (d *X509CertificateDiffer) DiffStashedValue(expected, actual interface{}) string {
return cmp.Diff(expected, actual, cmp.AllowUnexported(big.Int{}))
}
var _ rtesting.Differ = X509CertificateDiffer{}There was a problem hiding this comment.
One of the things I like about using dedicated methods is that additional type safety can be introduced, or in the case of stash, additional metadata can be added like the stash key.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #590 +/- ##
==========================================
+ Coverage 58.26% 59.35% +1.09%
==========================================
Files 33 35 +2
Lines 3800 3981 +181
==========================================
+ Hits 2214 2363 +149
- Misses 1492 1522 +30
- Partials 94 96 +2 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
I think this should work.
However, Diff is starting to compete with testing#SubReconcilerTestCase's
Verify and VerifyStashedValue and testing#ReconcilerTestCase's Verify field. Their propositions are muddling a bit, aren't they? Afaik Diff should be able to accomplish everything that Verify* is designed to do.
Maybe we should start deprecating Verify* in favour of Diff.
testing/diff.go
Outdated
| type DiffReason float64 | ||
|
|
||
| const ( | ||
| DiffReasonRaw DiffReason = iota | ||
| DiffReasonTrackRequest | ||
| DiffReasonDeleteCollectionRef | ||
| DiffReasonStashedValue | ||
| DiffReasonResource | ||
| DiffReasonWebhookResponse | ||
| DiffReasonResourceStatusUpdate | ||
| DiffReasonResourceUpdate | ||
| DiffReasonResourceCreate | ||
| ) |
There was a problem hiding this comment.
An alternative approach could be a Differ interface with a default implementation where each "diff reason" maps to a method, e.g. Differ#DiffRaw(actual, expected) string, Differ#DiffTrackRequest(actual, expected) string etc. We'd get a bit of method sprawl, but it may be easier to provide a custom differ without accidentally missing a diff reason. At the same time, maintainers need to take care to always call the right diff method when asserting test case. To some degree that's already the case, what with the different opts / reasons.
type X509CertificateDiffer struct {
rtesting.DefaultDiffer
}
func (d *X509CertificateDiffer) DiffStashedValue(expected, actual interface{}) string {
return cmp.Diff(expected, actual, cmp.AllowUnexported(big.Int{}))
}
var _ rtesting.Differ = X509CertificateDiffer{}Signed-off-by: Scott Andrews <scott@andrews.me>
Signed-off-by: Scott Andrews <scott@andrews.me>
mamachanko
left a comment
There was a problem hiding this comment.
➕1️⃣ for Differ!
LGMT
Test cases can now specify a custom diff function which can be used to either use custom cmp options, or replace cmp with some other differ.
The existing set of cmp options are matched using the DiffReason. Custom funcs should assume additional DiffReasons will be defined in the future. The DefaultDiff func is used if a custom Diff is not defined. Custom funcs may delegate to the default for DiffReasons they choose not to modify.
Refs #589