Skip to content

feat: add fail-now checker - #302

Open
mmorel-35 wants to merge 2 commits into
Antonboom:masterfrom
mmorel-35:issue-144
Open

feat: add fail-now checker#302
mmorel-35 wants to merge 2 commits into
Antonboom:masterfrom
mmorel-35:issue-144

Conversation

@mmorel-35

@mmorel-35 mmorel-35 commented Mar 15, 2026

Copy link
Copy Markdown
Contributor

assert.Fail, assert.FailNow (and their f/require variants) are thin wrappers over standard testing.T methods. This checker detects their use and auto-fixes to the direct stdlib equivalents.

Checker: fail-now

  • Enabled by default: true
  • Autofix: true (when the call result is discarded and the target method exists on the t type)

Fix mapping

Detected Fixed
assert.Fail(t, "msg") t.Error("msg")
assert.Fail(t, "fail", "msg") t.Error("msg")
assert.Fail(t, "fail", "fmt %s", arg) t.Errorf("fmt %s", arg)
assert.Failf(t, "fail", "fmt %s", arg) t.Errorf("fmt %s", arg)
assert.FailNow(t, "msg") t.Fatal("msg")
assert.FailNow(t, "fail", "fmt %s", arg) t.Fatalf("fmt %s", arg)
assert.FailNowf(t, "fail", "fmt %s", arg) t.Fatalf("fmt %s", arg)
s.FailNow("msg") (suite receiver) s.T().Fatal("msg")

When msgAndArgs are present in non-f variants, failureMessage is dropped and msgAndArgs become the replacement arguments (matching testify's own messageFromMsgAndArgs convention). Suite method calls are fixed via receiver.T() when the receiver implements TestifySuite.

Fix safety constraints

  • Expression context: the autofix is only emitted when the call result is definitely discarded (ExprStmt/GoStmt/DeferStmt). In expression contexts (e.g. _ = assert.Fail(...), if assert.Fail(...) {}), the diagnostic is reported but no fix is suggested, to avoid producing uncompilable code.
  • Method availability: the fix is gated on the static type of the t argument having the target method (checked via types.LookupFieldOrMethod). If t only implements assert.TestingT (which only requires Errorf), the non-f fix is withheld.
  • Assertion objects: calls on non-suite method receivers (e.g. assertObj.Fail(...) where assertObj is *assert.Assertions) are ignored entirely — no diagnostic is emitted since there is no accessible testing.T to suggest.

Implementation

  • internal/checkers/fail_now.go — checker (implemented as AdvancedChecker using insp.WithStack for parent-node context) + fix logic
  • internal/checkers/checkers_registry.go — registered in the advanced-checker section, enabled by default
  • internal/testgen/gen_fail_now.go — test generator with errored + golden templates covering all arg variants, suite method calls, expression-context no-fix cases, and ignored assertion-object calls
  • analyzer/testdata/src/go-require-http-handlers/ — updated test + golden to reflect that assert.FailNow and s.FailNow in HTTP handlers are now also fixed by this checker

Closes #144

Comment thread internal/checkers/fail_now.go
Copilot AI added a commit to mmorel-35/testifylint that referenced this pull request May 28, 2026
mmorel-35 pushed a commit to mmorel-35/testifylint that referenced this pull request May 28, 2026
@Antonboom Antonboom added the llm-based LLM shit label Jun 22, 2026
Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
@mmorel-35
mmorel-35 force-pushed the issue-144 branch 2 times, most recently from b5176b7 to 5b9af9b Compare July 10, 2026 10:46
…replacements

Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

llm-based LLM shit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fail-now: suggest t.Fatalf instead of weird assertions

3 participants