Skip to content

assert: avoid panics in mixed-type ordered comparisons - #1963

Open
LeulTew wants to merge 1 commit into
stretchr:masterfrom
LeulTew:leultew-testify-contribution-gauntlet
Open

LeulTew wants to merge 1 commit into
stretchr:masterfrom
LeulTew:leultew-testify-contribution-gauntlet

Conversation

@LeulTew

@LeulTew LeulTew commented Sep 18, 2026

Copy link
Copy Markdown

Summary

Report a failed ordered comparison instead of panicking when a time.Time or byte slice is compared with an incompatible value of the same reflection kind.

Changes

Implementation and validation

Check both operands against the existing time.Time and []byte conversion rules before converting either one. This preserves named-convertible types and routes unsupported pairs through the existing assertion-failure path; it does not add type coercions or change the API.

Regression coverage exercises all four Less/Greater variants in both operand orders, named types, typed-nil slices, formatted failure messages, Helper, and require's FailNow. Valid named/base time and byte-slice controls preserve existing comparison behavior.

The exact base panics for both time.Time versus an unrelated struct and []byte versus []int; the new tests pass with the fix. Separate real-testing.T probes confirm that assert variants still report failure and continue, while require variants report failure and stop, including formatted and method wrappers.

On Linux/amd64 with Go 1.27.1 and GCC 13.3, these commands passed:

go test -mod=readonly -p 1 -parallel 1 ./... -count=1
go test -mod=readonly -race -p 1 -parallel 1 ./... -count=1
go vet -mod=readonly -p 1 ./...
go build -mod=readonly -p 1 ./...

The Linux test copy was verified against the exact base plus the three changed files before and after execution. With the same Go 1.27.1 SDK, CI's gofmt -l . check produced no output on either base or patched source, the changed-file gofmt -d output was empty, and the configured README Go-block formatter (go run ./_readme-gofmt/main.go) passed. Whitespace checks also passed.

Motivation

Unsupported ordered comparisons already report assertion failures, but these pairs panic in one operand order and fail normally in the other. This bug fix makes their failure behavior consistent without allowing incompatible values to pass an assertion.

Minimal reproduction

This test should report an assertion failure, not panic in reflect.Value.Convert:

package example_test

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestIncompatibleComparison(t *testing.T) {
	assert.Less(t, []byte{1}, []int{2})
}

Comparing time.Time{} with an unrelated struct has the same problem. Both remain failed assertions after the fix.

Related issues

No linked issue.

Validation limits: Code generation and the complete CI Go/platform matrix were not run. Windows checks encountered baseline symlink-privilege and race-compiler limits; the full module's normal and race suites passed on Linux without changing those tests.

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