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
18 changes: 9 additions & 9 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ codegen/
7. `r.Equal(...)` - fatal forward method
8. `r.Equalf(..., "msg")` - fatal forward format variant

With 76 assertion functions, this generates 608 functions automatically.
With 127 assertion functions, this generates 840 functions automatically.

### Dependency Isolation Strategy
- **internal/spew**: Internalized copy of go-spew for pretty-printing values
Expand Down Expand Up @@ -141,7 +141,7 @@ cd codegen && go run . -output-packages assert,require -include-doc

# Preview documentation site locally
cd hack/doc-site/hugo
./gendoc.sh
go run gendoc.go
# Visit http://localhost:1313/testify/

# The Hugo site auto-reloads on changes to docs/doc-site/
Expand Down Expand Up @@ -278,7 +278,7 @@ The codegen also generates domain-organized documentation for a Hugo static site
**Hugo static site setup:**
Located in `hack/doc-site/hugo/`:
- **hugo.yaml** - Main Hugo configuration
- **gendoc.sh** - Development server script
- **gendoc.go** - Development server script
- **themes/hugo-relearn** - Documentation theme
- Mounts generated content from `docs/doc-site/`

Expand All @@ -289,7 +289,7 @@ go generate ./...

# Then start the Hugo dev server
cd hack/doc-site/hugo
./gendoc.sh
go run gendoc.go

# Visit http://localhost:1313/testify/
```
Expand Down Expand Up @@ -489,10 +489,10 @@ func TestParseTestExamples(t *testing.T) {
- Drop-in replacement for stretchr/testify

**The Math:**
- 76 assertion functions × 8 variants = 608 functions
- Old model: Manually maintain 608 functions across multiple packages
- New model: Write 76 functions once, generate the rest
- Result: 87% reduction in manual code maintenance
- 127 assertion functions × 4-8 variants = 840 functions
- Old model: Manually maintain 840 functions across multiple packages
- New model: Write 127 functions once, generate the rest
- Result: 85% reduction in manual code maintenance

### Technical Innovations

Expand Down Expand Up @@ -555,7 +555,7 @@ hack/doc-site/hugo/ # Note: Temporary location
├── hugo.yaml # Main Hugo configuration
├── testify.yaml # Generated config with version info
├── testify.yaml.template # Template for testify.yaml
├── gendoc.sh # Development server launcher
├── gendoc.go # Development server launcher
├── README.md, TODO.md # Documentation and planning
├── themes/
│ └── hugo-relearn/ # Documentation theme
Expand Down
28 changes: 28 additions & 0 deletions .github/wordlist.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
API
APIs
BDD
BSON
CI
CIDR
CLI
CLIs
CodeFactor
CodeQL
CSV
DCO
DockerHub
Expand All @@ -22,15 +25,20 @@ IDs
IP
IPs
ISBN
ISC
JSON
JUnit
Kubernetes
LOC
Markdown
NaN
OAI
OAuth
OpenAPI
PHPUnit
PR
PRs
PyTest
README
SSN
TCP
Expand Down Expand Up @@ -64,17 +72,23 @@ bitmask
bson
bytesize
cancelled
cgo
ci
cidr
cli
clis
codebase
codecov
codegen
colorizer
colorizers
config
configs
csv
customizable
dependabot
dereference
dereferencing
deserialize
deserialized
deserializer
Expand All @@ -87,6 +101,7 @@ flattener
fuzzying
gc
github
globals
go-openapi
godoc
golang
Expand All @@ -102,6 +117,7 @@ https
hugo
i.e.
id
impactful
implementor
implementors
initialism
Expand All @@ -116,6 +132,7 @@ json
jsonschema
k8s
kubernetes
lifecycle
linter
linters
listA
Expand All @@ -128,6 +145,7 @@ marshaling
middleware
middlewares
mixin
monorepo
multipart
mutex
oai
Expand All @@ -136,33 +154,42 @@ oauth2
openapi
param
params
prepend
prepended
rebase
rebased
roadmap
redeclare
repo
repos
roundtrip
roundtripper
schema
schemas
semver
serialize
serialized
serializer
sexualized
spdx
ssn
stdlib
struct
structs
submodule
subpackage
substring
swagger
testify's
tls
toolchain
ui
ulid
uncategorized
unmarshal
unmarshaled
unmarshaling
unexported
untyped
uri
url
Expand All @@ -177,4 +204,5 @@ validators
waitFor
workspace
workspaces
xunit
yaml
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at ivan+abuse@flanders.co.nz. All
reported by contacting the project team at <ivan+abuse@flanders.co.nz>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Testify/v2

<!-- Badges: s[roadmap]tatus -->
[![Tests][test-badge]][test-url] [![Coverage][cov-badge]][cov-url] [![CI vuln scan][vuln-scan-badge]][vuln-scan-url] [![CodeQL][codeql-badge]][codeql-url]
[![Tests][test-badge]][test-url] [![Coverage][cov-badge]][cov-url] [![CI vulnerability scan][vuln-scan-badge]][vuln-scan-url] [![CodeQL][codeql-badge]][codeql-url]
<!-- Badges: release & docker images -->
<!-- Badges: code quality -->
<!-- Badges: license & compliance -->
Expand Down
115 changes: 115 additions & 0 deletions assert/assert_adhoc_example_8_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// SPDX-FileCopyrightText: Copyright 2025 go-swagger maintainers
// SPDX-License-Identifier: Apache-2.0

package assert_test

import (
"context"
"errors"
"fmt"
"sync/atomic"
"testing"
"time"

"github.com/go-openapi/testify/v2/assert"
)

// ExampleEventually_asyncReady demonstrates polling a condition that becomes true
// after a few attempts, simulating an asynchronous operation completing.
func ExampleEventually_asyncReady() {
t := new(testing.T) // normally provided by test

// Simulate an async operation that completes after a short delay.
var ready atomic.Bool
go func() {
time.Sleep(30 * time.Millisecond)
ready.Store(true)
}()

result := assert.Eventually(t, ready.Load, 200*time.Millisecond, 10*time.Millisecond)

fmt.Printf("eventually ready: %t", result)

// Output: eventually ready: true
}

// ExampleEventually_healthCheck demonstrates [Eventually] with a
// func(context.Context) error condition, polling until the operation
// succeeds (returns nil).
func ExampleEventually_healthCheck() {
t := new(testing.T) // normally provided by test

// Simulate a service that becomes healthy after a few attempts.
var attempts atomic.Int32
healthCheck := func(_ context.Context) error {
if attempts.Add(1) < 3 {
return errors.New("service not ready")
}

return nil
}

result := assert.Eventually(t, healthCheck, 200*time.Millisecond, 10*time.Millisecond)

fmt.Printf("eventually healthy: %t", result)

// Output: eventually healthy: true
}

// ExampleNever_noSpuriousEvents demonstrates asserting that a condition never becomes true
// during the observation period.
func ExampleNever_noSpuriousEvents() {
t := new(testing.T) // normally provided by test

// A channel that should remain empty during the test.
events := make(chan struct{}, 1)

result := assert.Never(t, func() bool {
select {
case <-events:
return true // event received = condition becomes true = Never fails
default:
return false
}
}, 100*time.Millisecond, 10*time.Millisecond)

fmt.Printf("never received: %t", result)

// Output: never received: true
}

// ExampleConsistently_invariant demonstrates asserting that a condition remains true
// throughout the entire observation period.
func ExampleConsistently_invariant() {
t := new(testing.T) // normally provided by test

// A counter that stays within bounds during the test.
var counter atomic.Int32
counter.Store(5)

result := assert.Consistently(t, func() bool {
return counter.Load() < 10
}, 100*time.Millisecond, 10*time.Millisecond)

fmt.Printf("consistently under limit: %t", result)

// Output: consistently under limit: true
}

// ExampleConsistently_alwaysHealthy demonstrates [Consistently] with a
// func(context.Context) error condition, asserting that the operation
// always succeeds (returns nil) throughout the observation period.
func ExampleConsistently_alwaysHealthy() {
t := new(testing.T) // normally provided by test

// Simulate a service that stays healthy.
healthCheck := func(_ context.Context) error {
return nil // always healthy
}

result := assert.Consistently(t, healthCheck, 100*time.Millisecond, 10*time.Millisecond)

fmt.Printf("consistently healthy: %t", result)

// Output: consistently healthy: true
}
Loading
Loading