Skip to content

Model testify, gotest.tools, and goconvey assertions as trusted functions#420

Open
TvdW wants to merge 3 commits into
uber-go:mainfrom
TvdW:model-test-libraries
Open

Model testify, gotest.tools, and goconvey assertions as trusted functions#420
TvdW wants to merge 3 commits into
uber-go:mainfrom
TvdW:model-test-libraries

Conversation

@TvdW

@TvdW TvdW commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

This PR adds three more test libraries to the hooks, in an attempt to further reduce false positives around test suites.

Claude-assisted, human-reviewed.

No diff on stdlib expected because it doesn't use any of these 😉

TvdW added 3 commits June 17, 2026 15:19
Trusted function matching previously required the call to be a selector
expression (`assert.Error(...)`), so functions of dot-imported packages
(`Error(...)` with `import . "..."`) were never matched. Resolve the
called identifier for both call forms via
`asthelper.FuncIdentFromCallExpr` in both `matchCall` and
`generateComparators`. Soundness is unchanged: the identifier must
still resolve to a function object whose package path matches the
trusted signature, so local functions and function values never match.
…ions

Extend the SplitBlockOn hook with more assertion functions whose success
implies nilability facts about their arguments:

- testify `ErrorContains(f)`/`EqualError(f)` (function and method
  forms): these can only pass with a non-nil error, same as `Error`.
- gotest.tools assert (both /v3 and the legacy v1/v2 import path):
  `NilError`, `Error`, and `ErrorContains`, plus `Assert` via a new
  `boolOrErrorExpr` action handling its bool and error argument forms.
- goconvey `So(actual, assertion, ...)`: a new `soExpr` action resolves
  the assertion argument to its package-level object and models the
  nilability-relevant `Should*` assertions. The idiomatic dot-imported
  call form relies on the dot-import matching from the previous commit.

Also hoist the argIndex bounds check from the individual actions into
SplitBlockOn, and document that the failure branch of a split is modeled
as terminating execution.
`if assert.NoError(t, err) { <use> }` is a common pattern with testify's
non-fatal `assert` package, but narrowing previously only applied to
statement-position assertion calls (via SplitBlockOn), so NilAway
reported false positives inside such guarded branches.

Model these through the ReplaceConditional mechanism, following the
existing `errors.As` pattern: the conditional is replaced with
`<call> && <implied expr>` (e.g., `assert.NoError(t, err) && err == nil`),
where the implied expression is the same one `_splitBlockOn` derives for
the call in statement position, so the per-assertion semantics are
defined in a single place.
@TvdW TvdW force-pushed the model-test-libraries branch from c385155 to 6c573fd Compare June 17, 2026 19:19
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.

1 participant