Skip to content

accept async functions with testing.TB variant instead of Gomega#224

Merged
nunnatsa merged 1 commit intonunnatsa:mainfrom
pohly:assertion-wrappers
Feb 4, 2026
Merged

accept async functions with testing.TB variant instead of Gomega#224
nunnatsa merged 1 commit intonunnatsa:mainfrom
pohly:assertion-wrappers

Conversation

@pohly
Copy link
Copy Markdown
Contributor

@pohly pohly commented Dec 17, 2025

Description

In Kubernetes' ktesting package the following assertion is valid:

    tCtx.Eventually(func(tCtx TContext) { /* maybe fail via tCtx */ }).Should(Succeed())

That works because tCtx.Eventually wraps the function such that failures reported via tCtx.Error/Errorf/Fatal/Fatalf are visible to the matcher.

Without this change, the "Success matcher only support a single error value, or function with Gomega as its first parameter" warning is triggered.

Instead of building in specific support for ktesting, the approach is to check for a first parameter which has any (not necessarily all!) of the testing.TB methods for reporting failures. That is considered a valid alternative to Gomega.

There's now a potential false negative in the linter when passing such a function directly to gomega.Eventually/Consistently. That'll fail at runtime because gomega cannot call it, so such a false negative isn't too bad (fails reliably and obviously).

The warning message doesn't get changed because it would be confusing for most users to call out some vague alternative (vague because the linter has no details) that most users won't be able to use.

Fixes # (issue)

kubernetes/kubernetes#135664 (comment)

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • Added test case and related test data

Checklist:

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • I ran make goimports
  • I ran golangci-lint

@nunnatsa

@coveralls
Copy link
Copy Markdown
Collaborator

coveralls commented Dec 17, 2025

Pull Request Test Coverage Report for Build 21637444724

Details

  • 30 of 30 (100.0%) changed or added relevant lines in 3 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage increased (+0.07%) to 87.973%

Files with Coverage Reduction New Missed Lines %
internal/gomegainfo/gomegainfo.go 1 70.0%
Totals Coverage Status
Change from base Build 21126119649: 0.07%
Covered Lines: 2582
Relevant Lines: 2935

💛 - Coveralls

Copy link
Copy Markdown
Owner

@nunnatsa nunnatsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @pohly for the PR. I totally missed it! sorry for that...

Added one comment inline.

Comment on lines +45 to +74
// implementsTB checks if the argument type implements any of the methods in testing.TB which
// can be used to report test failures. Such a type is a potential alternative to a Gomega
// parameter in some Gomega wrappers.
func implementsTB(t gotypes.Type) bool {
for _, interfaceType := range tbInterfaces {
if gotypes.Implements(t, interfaceType) {
return true
}
}
return false
}

var tbInterfaces = []*gotypes.Interface{
tbInterface("Error", false),
}

func tbInterface(name string, printf bool) *gotypes.Interface {
var params []*gotypes.Var
if printf {
params = append(params, gotypes.NewVar(0, nil, "", gotypes.Typ[gotypes.String]))
}
params = append(params, gotypes.NewVar(0, nil, "", gotypes.NewSlice(gotypes.Universe.Lookup("any").Type())))
signature := gotypes.NewSignatureType(nil, nil, nil,
gotypes.NewTuple(params...),
gotypes.NewTuple(),
true,
)
method := gotypes.NewFunc(0, nil, name, signature)
return gotypes.NewInterfaceType([]*gotypes.Func{method}, nil)
}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about moving this code to the internal/typecheck pakcage?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. I used the opportunity to add the alternative error reporting functions and a unit test.

@pohly pohly force-pushed the assertion-wrappers branch 2 times, most recently from c1bf483 to 4d95fcc Compare February 2, 2026 18:48
Comment thread internal/typecheck/interfaces_test.go
In Kubernetes' ktesting package the following assertion is valid:

    tCtx.Eventually(func(tCtx TContext) { /* maybe fail via tCtx */ }).Should(Succeed())

That works because tCtx.Eventually wraps the function such that failures
reported via tCtx.Error/Errorf/Fatal/Fatalf are visible to the matcher.

Without this change, the "Success matcher only support a single error value, or
function with Gomega as its first parameter" warning is triggered.

Instead of building in specific support for ktesting, the approach is to check
for a first parameter which has any (not necessarily all!) of the testing.TB
methods for reporting failures. That is considered a valid alternative to
a Gomega instance.

There's now a potential false negative in the linter when passing such a
function directly to gomega.Eventually/Consistently. That'll fail at runtime
because gomega cannot call it, so such a false negative isn't too bad (fails
reliably and obviously).

The warning message doesn't get changed because it would be confusing for most
users to call out some vague alternative (vague because the linter has no
details) that most users won't be able to use.
@pohly pohly force-pushed the assertion-wrappers branch from 4d95fcc to fcfeb70 Compare February 3, 2026 15:59
@nunnatsa nunnatsa merged commit c325ce8 into nunnatsa:main Feb 4, 2026
2 checks passed
pohly added a commit to pohly/kubernetes that referenced this pull request Mar 9, 2026
Among other updates and features this brings
nunnatsa/ginkgolinter#224 into Kubernetes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants