-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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 <[email protected]>
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 <[email protected]>
Signed-off-by: Scott Andrews <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
➕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