Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

This is the go-openapi fork of the testify testing package. The main goal is to remove external dependencies while maintaining a clean, focused API for testing in Go. This fork strips out unnecessary features (mocks, suite) and internalizes dependencies (go-spew, difflib) to ensure `github.com/go-openapi/testify/v2` is the only import needed.

## Key Architecture

### Core Packages
- **assert**: Provides non-fatal test assertions (tests continue after failures)
- **require**: Provides fatal test assertions (tests stop immediately on failure via `FailNow()`)
- Both packages share similar APIs, but `require` wraps `assert` functions to make them fatal

### Code Generation
- The codebase uses code generation extensively via `_codegen/main.go`
- Generated files include:
- `assert/assertion_format.go` - Format string variants of assertions
- `assert/assertion_forward.go` - Forwarded assertion methods
- `require/require.go` - Require variants of all assert functions
- `require/require_forward.go` - Forwarded require methods

### Dependency Isolation Strategy
- **internal/spew**: Internalized copy of go-spew for pretty-printing values
- **internal/difflib**: Internalized copy of go-difflib for generating diffs
- **assert/yaml**: Stub package that panics by default if YAML assertions are used
- **enable/yaml**: Optional module that activates YAML support via init() when imported

The "enable" pattern allows YAML functionality to be opt-in: import `_ "github.com/go-openapi/testify/v2/enable/yaml"` to activate YAML assertions without forcing a dependency on all users.

## Development Commands

### Running Tests
```bash
# Run all tests
go test ./...

# Run tests in a specific package
go test ./assert
go test ./require

# Run a single test
go test ./assert -run TestEqual

# Run tests with verbose output
go test -v ./...
```

### Code Generation
When modifying assertion functions in `assert/assertions.go`, regenerate derived code:
```bash
# Generate all code
go generate ./...

# This runs the codegen tool which:
# 1. Parses assert/assertions.go for TestingT functions
# 2. Generates format variants (e.g., Equalf from Equal)
# 3. Generates require variants (fatal versions)
# 4. Generates forwarded assertion methods
```

The code generator looks for functions with signature `func(TestingT, ...) bool` in the assert package and creates corresponding variants.

### Build and Verify
```bash
# Tidy dependencies
go mod tidy

# Build code generator
cd _codegen && go build

# Format code
go fmt ./...
```

## Important Constraints

### API Stability
The following assertions are guaranteed stable (used by go-openapi/go-swagger):
- Condition, Contains, Empty, Equal, EqualError, EqualValues, Error, ErrorContains, ErrorIs
- Fail, FailNow, False, Greater, Implements, InDelta, IsType, JSONEq, Len
- Nil, NoError, NotContains, NotEmpty, NotEqual, NotNil, NotPanics, NotZero
- Panics, PanicsWithValue, Subset, True, YAMLEq, Zero

Other APIs may change without notice as the project evolves.

### Zero External Dependencies
Do not add external dependencies to the main module. If new functionality requires a dependency:
1. Consider internalizing it (copy into `internal/` with proper licensing)
2. Or create an "enable" package that users import to activate the feature

### YAML Support Pattern
When using YAML assertions (YAMLEq, YAMLEqf):
- Tests must import: `_ "github.com/go-openapi/testify/v2/enable/yaml"`
- Without this import, YAML assertions will panic with helpful error message
- This pattern keeps gopkg.in/yaml.v3 as an optional dependency

## Module Information

- Module path: `github.com/go-openapi/testify/v2`
- Go version: 1.24.0
- v2.0.0 is retracted (see go.mod)
- License: Apache-2.0 (forked from MIT-licensed stretchr/testify)

## Testing Philosophy

Keep tests simple and focused. The assert package provides detailed failure messages automatically, so test code should be minimal and readable. Use `require` when a test cannot continue meaningfully after a failure, and `assert` when subsequent checks might provide additional context.
87 changes: 74 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,46 @@ However, at `go-openapi` we would like to address the well-known issues in `test
testify-style mocks are thus not going to be supported anytime soon.
* extra convoluted stuff in the like of `InDeltaSlice`

## Generics adoption

### Context from the original repository

Several attempts have been made to introduce generics in the original stretchr/testify repository:

* **github.com/stretchr/testify#1308** - Comprehensive refactor replacing `interface{}` with generic type parameters across assertions (Draft, v2.0.0 milestone)
* **github.com/stretchr/testify#1805** - Proposal for generic `IsOfType[T]()` to avoid dummy value instantiation in type checks
* **github.com/stretchr/testify#1685** - Iterator support (`iter.Seq`) for Contains/ElementsMatch assertions (Go 1.23+)
* **github.com/stretchr/testify#1147** - General discussion about generics adoption (marked "Not Planned")

### Challenges identified

The original repository's exploration of generics revealed several design challenges:

1. **Type inference limitations**: Go's type inference struggles with complex generic signatures, often requiring explicit type parameters that burden the API (e.g., `Contains[int, int](arr1, arr2)`)

2. **Overly broad type constraints**: PR #1308's approach used constraints like `ConvertibleToFloat64` that accepted more types than intended, weakening type safety

3. **Loss of flexibility**: Testify currently compares non-comparable types (slices, maps) via `reflect.DeepEqual`. Generic constraints would eliminate this capability, as Go generics require comparable or explicitly constrained types

4. **Breaking changes**: Any comprehensive generics adoption requires a major version bump and Go 1.18+ minimum version

5. **Inconsistent design patterns**: Different assertions would need different constraint strategies, making a uniform approach difficult

### Approach in this fork

This fork targets **go1.24** and can leverage generics without backward compatibility concerns.

The approach will be **selective and pragmatic** rather than comprehensive:

* **Targeted improvements** where generics provide clear value without compromising existing functionality
* **Focus on eliminating anti-patterns** like dummy value instantiation in `IsType` (see #1805)
* **Preserve reflection-based flexibility** for comparing complex types rather than forcing everything through generic constraints
* **Careful constraint design** to ensure type safety without being overly restrictive or permissive

The goal is to enhance type safety and developer experience where it matters most, while maintaining the flexibility that makes testify useful for real-world testing scenarios.

**Status**: Design and exploration phase. Contributions and proposals welcome.

## Usage at go-openapi

At this moment, we have identified the following usage in our tools. This API shall remain stable.
Expand Down Expand Up @@ -150,25 +190,46 @@ distributed with this fork, including internalized libraries.

## PRs from the original repo

### Already merged or incorporated

The following proposed contributions to the original repo have been merged or incorporated with
some adaptations into this fork:

* github.com/stretchr/testify#1513
* github.com/stretchr/testify#1772
* github.com/stretchr/testify#1797
* github.com/stretchr/testify#1356
* github.com/stretchr/testify#1513 - JSONEqBytes for byte slice JSON comparison
* github.com/stretchr/testify#1772 - YAML library migration to maintained fork (go.yaml.in/yaml)
* github.com/stretchr/testify#1797 - Codegen package consolidation and licensing
* github.com/stretchr/testify#1356 - panic(nil) handling for Go 1.21+

### Planned merges

#### Critical safety fixes (high priority)

* github.com/stretchr/testify#1825 - Fix panic when using EqualValues with uncomparable types
* github.com/stretchr/testify#1818 - Fix panic on invalid regex in Regexp/NotRegexp assertions

#### Leveraging internalized dependencies (go-spew, difflib)

These improvements apply to the internalized and modernized copies of dependencies in this fork:

* github.com/stretchr/testify#1829 - Fix time.Time rendering in diffs (internalized go-spew)
* github.com/stretchr/testify#1822 - Deterministic map ordering in diffs (internalized go-spew)
* github.com/stretchr/testify#1816 - Fix panic on unexported struct key in map (internalized go-spew - may need deeper fix)

#### UX improvements

* github.com/stretchr/testify#1223 - Display uint values in decimal instead of hex in diffs

### Under consideration

### Other noticeable contributions, not merged
#### Colorized output

These would probably need some rework/fix or adaptation, but the proposed idea is worthwhile, IMHO.
Several PRs propose colorized terminal output with different approaches and dependencies.
If implemented, this would be provided as an optional `enable/color` module:

* github.com/stretchr/testify#1460 (ci)
* github.com/stretchr/testify#1467 (colorized output)
* github.com/stretchr/testify#1480 (colorized output)
* github.com/stretchr/testify/pull#1232 (colorized output)
* github.com/stretchr/testify#994 (colorized output)
* github.com/stretchr/testify#1495 (bug fix)
* github.com/stretchr/testify#1223 (layout bug fix)
* github.com/stretchr/testify#1467 - Colorized output with terminal detection (most mature implementation)
* github.com/stretchr/testify#1480 - Colorized diffs via TESTIFY_COLORED_DIFF env var
* github.com/stretchr/testify#1232 - Colorized output for expected/actual/errors
* github.com/stretchr/testify#994 - Colorize expected vs actual values

## Contributing

Expand Down
Loading
Loading