assert

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2025 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package assert provides the underlying implementation for the Should assertion library. It contains the core assertion logic, which is then exposed through the top-level `should` package. This package handles value comparisons, error formatting, and detailed difference reporting.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AnyMatch added in v0.2.0

func AnyMatch[T any](t testing.TB, actual []T, predicate func(T) bool, opts ...Option)

AnyMatch reports a test failure if no element in the slice matches the predicate function.

This assertion allows custom matching logic by providing a predicate function that will be called for each element in the slice. The test passes if any element makes the predicate return true.

Example:

type User struct { Age int }

users := []User{{Age: 16}, {Age: 21}}
should.AnyMatch(t, users, func(user User) bool {
	return user.Age > 18
})

numbers := []int{1, 3, 5, 8}
should.AnyMatch(t, numbers, func(n int) bool {
	return n%2 == 0
}, should.WithMessage("No even numbers found"))

func BeEmpty

func BeEmpty(t testing.TB, actual any, opts ...Option)

BeEmpty reports a test failure if the value is not empty.

This assertion works with strings, slices, arrays, maps, channels, and pointers. For strings, empty means zero length. For slices/arrays/maps/channels, empty means zero length. For pointers, empty means nil. Provides detailed error messages showing the type, length, and content of non-empty values.

Example:

should.BeEmpty(t, "")

should.BeEmpty(t, []int{}, should.WithMessage("List should be empty"))

should.BeEmpty(t, map[string]int{})

Only works with strings, slices, arrays, maps, channels, or pointers.

func BeEqual

func BeEqual[T any](t testing.TB, actual, expected T, opts ...Option)

BeEqual reports a test failure if the two values are not deeply equal.

Uses reflect.DeepEqual for comparison. For primitive types (string, int, float, bool, etc.), it shows a simple message. For complex objects (structs, slices, maps), it shows field-by-field differences.

Example:

should.BeEqual(t, "hello", "hello")

should.BeEqual(t, 42, 42)

should.BeEqual(t, user, expectedUser, should.WithMessage("User objects should match"))

Works with any comparable types. Uses deep comparison for complex objects.

func BeError added in v0.2.0

func BeError(t testing.TB, err error, opts ...Option)

BeError reports a test failure if the provided error is nil.

This assertion is useful to ensure that a function call actually produced an error when one is expected. It provides clear failure messages showing when an error was expected but not returned. It supports optional custom error messages through Option.

Example:

should.BeError(t, err)
should.BeError(t, err, should.WithMessage("Expected a validation error"))

func BeErrorAs added in v0.2.0

func BeErrorAs(t testing.TB, err error, target interface{}, opts ...Option)

BeErrorAs reports a test failure if the provided error does not match the target type using errors.As.

This assertion is useful when you need to verify that an error can be unwrapped into a specific type, such as a custom error struct. It supports optional custom error messages through Option.

Example:

var pathErr *os.PathError
should.BeErrorAs(t, err, &pathErr)
should.BeErrorAs(t, err, &MyCustomError{}, should.WithMessage("Expected custom error type"))

func BeErrorIs added in v0.2.0

func BeErrorIs(t testing.TB, err error, target error, opts ...Option)

BeErrorIs reports a test failure if the provided error is not equal to the target error using errors.Is.

This assertion is useful to check if an error matches a specific sentinel value, such as io.EOF or custom exported error variables. It supports optional custom error messages through Option.

Example:

should.BeErrorIs(t, err, io.EOF)
should.BeErrorIs(t, err, ErrUnauthorized, should.WithMessage("Expected unauthorized error"))

func BeFalse

func BeFalse(t testing.TB, actual bool, opts ...Option)

BeFalse reports a test failure if the value is not false.

This assertion only works with boolean values and will fail immediately if the value is not a boolean type.

Example:

should.BeFalse(t, false)

should.BeFalse(t, user.IsDeleted, should.WithMessage("User should not be deleted"))

func BeGreaterOrEqualTo

func BeGreaterOrEqualTo[T Ordered](t testing.TB, actual T, expected T, opts ...Option)

BeGreaterOrEqualTo reports a test failure if the value is not greater than or equal to the expected threshold.

This assertion works with all numeric types and provides detailed error messages when the assertion fails. It supports optional custom error messages through Option.

Example:

should.BeGreaterOrEqualTo(t, 10, 10)

should.BeGreaterOrEqualTo(t, user.Score, 0, should.WithMessage("Score cannot be negative"))

should.BeGreaterOrEqualTo(t, 3.14, 3.14)

Only works with numeric types. Both values must be of the same type.

func BeGreaterThan

func BeGreaterThan[T Ordered](t testing.TB, actual T, expected T, opts ...Option)

BeGreaterThan reports a test failure if the value is not greater than the expected threshold.

This assertion works with all numeric types and provides detailed error messages showing the actual value, threshold, difference, and helpful hints. It supports optional custom error messages through Option.

Example:

should.BeGreaterThan(t, 10, 5)

should.BeGreaterThan(t, user.Age, 18, should.WithMessage("User must be adult"))

should.BeGreaterThan(t, 3.14, 2.71)

Only works with numeric types. Both values must be of the same type.

func BeInRange

func BeInRange[T Ordered](t testing.TB, actual T, minValue T, maxValue T, opts ...Option)

BeInRange reports a test failure if the value is not within the specified range (inclusive).

This assertion works with all numeric types and provides detailed error messages when the assertion fails, indicating whether the value is above or below the range and by how much.

Example:

should.BeInRange(t, 25, 18, 65)

should.BeInRange(t, 99.5, 0.0, 100.0)

should.BeInRange(t, 200, 200, 299, should.WithMessage("HTTP status should be 2xx"))

Only works with numeric types. All values must be of the same type.

func BeLessOrEqualTo

func BeLessOrEqualTo[T Ordered](t testing.TB, actual T, expected T, opts ...Option)

BeLessOrEqualTo reports a test failure if the value is not less than or equal to the expected threshold.

This assertion works with all numeric types and provides detailed error messages when the assertion fails. It supports optional custom error messages through Option.

Example:

should.BeLessOrEqualTo(t, 5, 10)

should.BeLessOrEqualTo(t, user.Age, 65, should.WithMessage("User must be under retirement age"))

should.BeLessOrEqualTo(t, 3.14, 3.14)

Only works with numeric types. Both values must be of the same type.

func BeLessThan

func BeLessThan[T Ordered](t testing.TB, actual T, expected T, opts ...Option)

BeLessThan reports a test failure if the value is not less than the expected threshold.

This assertion works with all numeric types and provides detailed error messages showing the actual value, threshold, difference, and helpful hints. It supports optional custom error messages through Option.

Example:

should.BeLessThan(t, 5, 10)

should.BeLessThan(t, user.Age, 65, should.WithMessage("User must be under retirement age"))

should.BeLessThan(t, 2.71, 3.14)

Only works with numeric types. Both values must be of the same type.

func BeNil

func BeNil(t testing.TB, actual any, opts ...Option)

BeNil reports a test failure if the value is not nil.

This assertion works with pointers, interfaces, channels, functions, slices, and maps. It uses Go's reflection to check if the value is nil.

Example:

var ptr *int
should.BeNil(t, ptr)

var slice []int
should.BeNil(t, slice, should.WithMessage("Slice should be nil"))

Only works with nillable types (pointers, interfaces, channels, functions, slices, maps).

func BeOfType

func BeOfType(t testing.TB, actual, expected any, opts ...Option)

BeOfType reports a test failure if the value is not of the expected type.

This assertion checks if the type of the actual value matches the type of the expected value (using an instance of the expected type).

Example:

type MyType struct{}
var v MyType
should.BeOfType(t, MyType{}, v)

func BeOneOf

func BeOneOf[T any](t testing.TB, actual T, options []T, opts ...Option)

BeOneOf reports a test failure if the value is not one of the provided options.

This assertion checks if the actual value is present in the slice of allowed options. It uses deep comparison to check for equality.

Example:

status := "pending"
allowedStatus := []string{"active", "inactive"}
should.BeOneOf(t, status, allowedStatus)

func BeSameTime added in v0.2.0

func BeSameTime(t testing.TB, actual, expected time.Time, opts ...Option)

BeSameTime reports a test failure if two `time.Time` values do not represent the same time.

By default, the comparison is timezone-sensitive and nanosecond-precise. You can customize the behavior with functional options:

- should.WithIgnoreTimezone(): compares the instants regardless of the timezone/location

- should.WithTruncate(unit): truncates both times to the specified precision before comparison

Example:

should.BeSameTime(t, time1, time2)

should.BeSameTime(
    t,
    actual,
    expected,
    should.WithIgnoreTimezone(),
    should.WithTruncate(time.Second),
)

func BeSorted added in v0.2.0

func BeSorted[T Sortable](t testing.TB, actual []T, opts ...Option)

BeSorted reports a test failure if the slice is not sorted in ascending order.

This assertion works with slices of any ordered type (integers, floats, strings). For arrays, convert to slice using slice syntax: myArray[:]. Provides detailed error messages showing order violations with indices and values.

Example:

should.BeSorted(t, []int{1, 2, 3, 4, 5})

should.BeSorted(t, []string{"a", "b", "c"})

should.BeSorted(t, myArray[:]) // for arrays

Only works with slices of ordered types (cmp.Ordered constraint).

func BeTrue

func BeTrue(t testing.TB, actual bool, opts ...Option)

BeTrue reports a test failure if the value is not true.

This assertion only works with boolean values and will fail immediately if the value is not a boolean type.

Example:

should.BeTrue(t, true)

should.BeTrue(t, user.IsActive, should.WithMessage("User must be active"))

func BeWithin added in v0.2.0

func BeWithin[T Float](t testing.TB, actual T, expected T, tolerance T, opts ...Option)

BeWithin reports a test failure if the actual value is not within the given tolerance of the expected value.

This assertion works with both float32 and float64 types and provides detailed error messages when the assertion fails. It is especially useful for testing floating-point numbers where exact equality is unreliable due to precision issues.

An optional custom error message can be provided using WithMessage.

Example:

should.BeWithin(t, 3.14159, 3.14, 0.002)

should.BeWithin(t, 3.142, 3.14, 0.001, should.WithMessage("Pi approximation is outside the allowed range"))

func Contain

func Contain(t testing.TB, actual any, expected any, opts ...Option)

Contain reports a test failure if the slice or array does not contain the expected value.

This assertion provides intelligent error messages based on the type of collection: - For []string: Shows similar elements and typo detection - For numeric slices ([]int, []float64, etc.): Shows insertion context and sorted position - For other types: Shows formatted collection with clear error messages Supports all slice and array types.

Example:

should.Contain(t, users, "user3")

should.Contain(t, []int{1, 2, 3}, 2)

should.Contain(t, []float64{1.1, 2.2}, 1.5, should.WithMessage("Expected value missing"))

should.Contain(t, []string{"apple", "banana"}, "apple")

If the input is not a slice or array, the test fails immediately.

func ContainKey

func ContainKey[K comparable, V any](t testing.TB, actual map[K]V, expectedKey K, opts ...Option)

ContainKey reports a test failure if the map does not contain the expected key.

This assertion works with maps of any key type and provides intelligent error messages: - For string keys: Shows similar keys and typo detection - For numeric keys: Shows similar keys with numeric differences - For other types: Shows formatted keys with clear error messages Supports all map types.

Example:

userMap := map[string]int{"name": 1, "age": 2}
should.ContainKey(t, userMap, "email")

should.ContainKey(t, map[int]string{1: "one", 2: "two"}, 3, should.WithMessage("Key must exist"))

func ContainSubstring

func ContainSubstring(t testing.TB, actual string, substring string, opts ...Option)

ContainSubstring reports a test failure if the string does not contain the expected substring.

This assertion checks if the actual string contains the expected substring. It provides a detailed error message showing the expected and actual strings, with intelligent formatting for very long strings, and includes a note if case mismatch is detected.

Example:

should.ContainSubstring(t, "Hello, world!", "world")

should.ContainSubstring(t, "Hello, World", "WORLD", should.WithIgnoreCase())

should.ContainSubstring(t, longText, "keyword", should.WithMessage("Expected keyword to be present"))

Note: The assertion is case-sensitive by default. Use should.WithIgnoreCase() to ignore case.

func ContainValue

func ContainValue[K comparable, V any](t testing.TB, actual map[K]V, expectedValue V, opts ...Option)

ContainValue reports a test failure if the map does not contain the expected value.

This assertion works with maps of any value type and provides intelligent error messages: - For string values: Shows similar values and typo detection - For numeric values: Shows similar values with numeric differences - For other types: Shows formatted values with clear error messages Supports all map types.

Example:

userMap := map[string]int{"name": 1, "age": 2}
should.ContainValue(t, userMap, 3)

should.ContainValue(t, map[int]string{1: "one", 2: "two"}, "three", should.WithMessage("Value must exist"))

func EndWith

func EndWith(t testing.TB, actual string, expected string, opts ...Option)

EndWith reports a test failure if the string does not end with the expected substring.

This assertion checks if the actual string ends with the expected substring. It provides a detailed error message showing the expected and actual strings, along with a note if the case mismatch is detected.

Example:

should.EndWith(t, "Hello, world!", "world")

should.EndWith(t, "Hello, world", "WORLD", should.WithIgnoreCase())

should.EndWith(t, "Hello, world!", "world", should.WithMessage("Expected string to end with 'world'"))

Note: The assertion is case-sensitive by default. Use should.WithIgnoreCase() to ignore case.

func HaveLength

func HaveLength(t testing.TB, actual any, expected int, opts ...Option)

HaveLength reports a test failure if the collection does not have the expected length.

This assertion works with strings, slices, arrays, and maps. It provides a detailed error message showing the expected and actual lengths, along with the difference.

Example:

should.HaveLength(t, []int{1, 2, 3}, 3)
should.HaveLength(t, "hello", 5)

func NotBeEmpty

func NotBeEmpty(t testing.TB, actual any, opts ...Option)

NotBeEmpty reports a test failure if the value is empty.

This assertion works with strings, slices, arrays, maps, channels, and pointers. For strings, non-empty means length > 0. For slices/arrays/maps/channels, non-empty means length > 0. For pointers, non-empty means not nil. Provides detailed error messages for empty values.

Example:

should.NotBeEmpty(t, "hello")

should.NotBeEmpty(t, []int{1, 2, 3}, should.WithMessage("List must have items"))

should.NotBeEmpty(t, &user)

Only works with strings, slices, arrays, maps, channels, or pointers.

func NotBeEqual

func NotBeEqual[T any](t testing.TB, actual, expected T, opts ...Option)

NotBeEqual reports a test failure if the two values are deeply equal.

This assertion uses Go's reflect.DeepEqual for comparison and provides detailed error messages showing exactly what differs between the values. For complex objects, it shows field-by-field differences to help identify the specific mismatches.

Example:

should.NotBeEqual(t, "hello", "world")

should.NotBeEqual(t, 42, 43)

should.NotBeEqual(t, user, expectedUser, should.WithMessage("User objects should not match"))

func NotBeError added in v0.2.0

func NotBeError(t testing.TB, err error, opts ...Option)

NotBeError - no error required

Verifies that err is nil, ensuring successful operation. Supports optional custom error messages via Option.

Example:

should.NotBeError(t, err)

_, err = os.Open("/nonexistent/file.txt")
should.NotBeError(t, err, should.WithMessage("File should exist and be readable"))

func NotBeNil

func NotBeNil(t testing.TB, actual any, opts ...Option)

NotBeNil reports a test failure if the value is nil.

This assertion works with pointers, interfaces, channels, functions, slices, and maps. It uses Go's reflection to check if the value is not nil.

Example:

user := &User{Name: "John"}
should.NotBeNil(t, user, should.WithMessage("User must not be nil"))

should.NotBeNil(t, make([]int, 0))

Only works with nillable types (pointers, interfaces, channels, functions, slices, maps).

func NotContain

func NotContain(t testing.TB, actual any, expected any, opts ...Option)

NotContain reports a test failure if the slice or array contains the expected value.

This assertion works with slices and arrays of any type and provides detailed error messages showing where the unexpected element was found.

Example:

should.NotContain(t, users, "bannedUser")

should.NotContain(t, []int{1, 2, 3}, 4)

should.NotContain(t, []string{"apple", "banana"}, "orange", should.WithMessage("Should not have orange"))

If the input is not a slice or array, the test fails immediately.

func NotContainDuplicates

func NotContainDuplicates(t testing.TB, actual any, opts ...Option)

NotContainDuplicates reports a test failure if the slice or array contains duplicate values.

This assertion works with slices and arrays of any type and provides detailed error messages showing where the duplicate values were found.

Example:

should.NotContainDuplicates(t, []int{1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4})

should.NotContainDuplicates(t, []string{"John", "John"})

If the input is not a slice or array, the test fails immediately.

func NotContainKey

func NotContainKey[K comparable, V any](t testing.TB, actual map[K]V, expectedKey K, opts ...Option)

NotContainKey reports a test failure if the map contains the expected key.

This assertion works with maps of any key type and provides detailed error messages showing where the key was found, including the map type, size, and context around the found key. Supports all map types.

Example:

userMap := map[string]int{"name": 1, "age": 2}
should.NotContainKey(t, userMap, "age") // This will fail

should.NotContainKey(t, map[int]string{1: "one", 2: "two"}, 3, should.WithMessage("Key should not exist"))

func NotContainValue

func NotContainValue[K comparable, V any](t testing.TB, actual map[K]V, expectedValue V, opts ...Option)

NotContainValue reports a test failure if the map contains the expected value.

This assertion works with maps of any value type and provides detailed error messages showing where the value was found, including the map type, size, and context around the found value. Supports all map types.

Example:

userMap := map[string]int{"name": 1, "age": 2}
should.NotContainValue(t, userMap, 2) // This will fail

should.NotContainValue(t, map[int]string{1: "one", 2: "two"}, "three", should.WithMessage("Value should not exist"))

func NotPanic

func NotPanic(t testing.TB, fn func(), opts ...Option)

NotPanic reports a test failure if the given function panics.

This assertion executes the provided function and expects it to complete normally without panicking. If a panic occurs, it captures the panic value and includes it in the error message. Supports optional custom error messages through Option.

Example:

should.NotPanic(t, func() {
	result := add(1, 2)
	_ = result
})

should.NotPanic(t, func() {
	user.Save()
}, should.WithMessage("Save operation should not panic"))

Note: Stack trace is not available when should.WithStackTrace() is not used

The function parameter must not be nil.

func Panic

func Panic(t testing.TB, fn func(), opts ...Option)

Panic reports a test failure if the given function does not panic.

This assertion executes the provided function and expects it to panic. It captures and recovers from the panic to prevent the test from crashing. Supports optional custom error messages through Option.

Example:

should.Panic(t, func() {
	panic("expected panic")
})

should.Panic(t, func() {
	divide(1, 0)
}, should.WithMessage("Division by zero should panic"))

The function parameter must not be nil.

func StartWith

func StartWith(t testing.TB, actual string, expected string, opts ...Option)

StartWith reports a test failure if the string does not start with the expected substring.

This assertion checks if the actual string starts with the expected substring. It provides a detailed error message showing the expected and actual strings, along with a note if the case mismatch is detected.

Example:

should.StartWith(t, "Hello, world!", "hello")

should.StartWith(t, "Hello, world!", "hello", should.WithIgnoreCase())

should.StartWith(t, "Hello, world!", "world", should.WithMessage("Expected string to start with 'world'"))

Note: The assertion is case-sensitive by default. Use should.WithIgnoreCase() to ignore case.

Types

type Config

type Config struct {
	Message    string
	IgnoreCase bool
	StackTrace bool
	Time       TimeOptions
}

Config provides configuration options for assertions. It allows for custom error messages and future extensibility.

type Float added in v0.2.0

type Float interface {
	~float32 | ~float64
}

Float is a constraint that permits either float32 or float64 types.

type Option

type Option interface {
	Apply(config *Config)
}

Option is a functional option for configuring assertions.

func WithIgnoreCase

func WithIgnoreCase() Option

WithIgnoreCase creates an option for ignoring case in comparisons.

func WithIgnoreTimezone added in v0.2.0

func WithIgnoreTimezone() Option

WithIgnoreTimezone creates an option for ignoring timezone when comparing times. When enabled, comparisons use calendar components (year, month, day, hour, minute, second[, ns]) and do not consider the Location/offset.

func WithMessage

func WithMessage(msg string) Option

WithMessage creates an option for setting a custom error message.

The message is treated as a plain string literal. Use this when you want to display a fixed message without formatting or placeholders.

Example usage:

should.BeGreaterThan(t, userAge, 18, should.WithMessage("User must be adult"))

See also: WithMessagef for messages that include formatting placeholders.

func WithMessagef added in v0.2.0

func WithMessagef(msg string, args ...any) Option

WithMessagef creates an option for setting a custom error message with formatting.

The message supports placeholders, similar to fmt.Sprintf, and takes optional arguments to replace them. Use this when you need dynamic content in the message.

Example usage:

should.BeLessOrEqualTo(t, score, 100, should.WithMessagef("Score cannot exceed %d", 100))

func WithStackTrace

func WithStackTrace() Option

WithStackTrace creates an option for including stack traces on NotPanic assertions.

func WithTruncate added in v0.2.0

func WithTruncate(unit time.Duration) Option

WithTruncate truncates the actual and expected times to the specified unit before comparing.

This is useful for asserting that two times are the same up to a certain level of precision, ignoring differences in smaller units.

type Ordered

type Ordered interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
		~float32 | ~float64
}

Ordered is a type constraint for types that can be ordered. It includes all integer and floating-point types.

type Sortable added in v0.2.0

type Sortable interface {
	cmp.Ordered
}

Sortable is a type constraint for types that can be sorted. It uses Go's cmp.Ordered constraint for type-safe sorting operations.

type TimeOptions added in v0.2.0

type TimeOptions struct {
	IgnoreTimezone bool
	TruncateUnit   time.Duration
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL