assert

package
v0.72.0 Latest Latest
Warning

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

Go to latest
Published: Apr 11, 2022 License: Apache-2.0 Imports: 8 Imported by: 0

README

testcase/assert

This package meant to provide a small and dependency lightweight implementation for common assertion related requirements.

Example:

assert.Should(tb).True(true)
assert.Must(tb).Equal(expected, actual, "error message")
assert.Must(tb).NotEqual(true, false, "exp")
assert.Must(tb).Contain([]int{1, 2, 3}, 3, "exp")
assert.Must(tb).Contain([]int{1, 2, 3}, []int{1, 2}, "exp")
assert.Must(tb).Contain(map[string]int{"The Answer": 42, "oth": 13}, map[string]int{"The Answer": 42}, "exp")

For more examples, check out the example_test.go file.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AnyOf added in v0.60.0

type AnyOf struct {
	TB testing.TB
	Fn func(...interface{})
	// contains filtered or unexported fields
}

AnyOf is an assertion helper that allows you run AnyOf.Test assertion blocks, that can fail, as lone at least one of them succeeds. common usage use-cases:

  • list of interface, where test order, or the underlying structure's implementation is irrelevant for the behavior.
  • list of big structures, where not all field value relevant, only a subset, like a structure it wraps under a field.
  • list of structures with fields that has dynamic state values, which is irrelevant for the given test.
  • structure that can have various state scenario, and you want to check all of them, and you expect to find one match with the input.
  • fan out scenario, where you need to check in parallel that at least one of the worker received the event.
Example (FanOutPublishing)
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

type ExamplePublisherEvent struct{ V int }
type ExamplePublisher struct{}

func (ExamplePublisher) Publish(event ExamplePublisherEvent)         {}
func (ExamplePublisher) Subscribe(func(event ExamplePublisherEvent)) {}
func (ExamplePublisher) Wait()                                       {}
func (ExamplePublisher) Close() error                                { return nil }

func main() {
	var tb testing.TB
	publisher := ExamplePublisher{}
	anyOf := &assert.AnyOf{TB: tb, Fn: tb.Fatal}
	for i := 0; i < 42; i++ {
		publisher.Subscribe(func(event ExamplePublisherEvent) {
			anyOf.Test(func(it assert.It) {
				it.Must.Equal(42, event.V)
			})
		})
	}
	publisher.Publish(ExamplePublisherEvent{V: 42})
	publisher.Wait()
	assert.Must(tb).Nil(publisher.Close())
	anyOf.Finish()
}
Output:

Example (ListOfCompositedStructuresWhereOnlyTheEmbededValueIsRelevant)
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	type BigStruct struct {
		ID            string // not relevant for the test
		A, B, C, D, E int    // not relevant data as well
		WrappedStruct struct {
			A, B, C int // relevant data for the test
		}
	}
	anyOf := assert.AnyOf{TB: tb, Fn: tb.Fatal}
	for _, v := range []BigStruct{} {
		anyOf.Test(func(it assert.It) {
			it.Must.Equal(42, v.WrappedStruct.A)
			it.Must.Equal(1, v.WrappedStruct.B)
			it.Must.Equal(2, v.WrappedStruct.C)
		})
	}
	anyOf.Finish()
}
Output:

Example (ListOfInterface)
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	type ExampleInterface interface {
		Foo() int
		Bar() bool
		Baz() string
	}
	anyOf := assert.AnyOf{TB: tb, Fn: tb.Fatal}
	for _, v := range []ExampleInterface{} {
		anyOf.Test(func(it assert.It) {
			it.Must.True(v.Bar())
		})
	}
	anyOf.Finish()
}
Output:

Example (ListOfStructuresWithIrrelevantValues)
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	type StructWithDynamicValues struct {
		IrrelevantStateValue int // not relevant data for the test
		ImportantValue       int
	}
	anyOf := assert.AnyOf{TB: tb, Fn: tb.Fatal}
	for _, v := range []StructWithDynamicValues{} {
		anyOf.Test(func(it assert.It) {
			it.Must.Equal(42, v.ImportantValue)
		})
	}
	anyOf.Finish()
}
Output:

Example (StructWithManyAcceptableState)
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	type ExampleStruct struct {
		Type    string
		A, B, C int
	}
	var es ExampleStruct
	anyOf := assert.AnyOf{TB: tb, Fn: tb.Fatal}
	anyOf.Test(func(it assert.It) {
		it.Must.Equal(`foo`, es.Type)
		it.Must.Equal(1, es.A)
		it.Must.Equal(2, es.B)
		it.Must.Equal(3, es.C)
	})
	anyOf.Test(func(it assert.It) {
		it.Must.Equal(`foo`, es.Type)
		it.Must.Equal(3, es.A)
		it.Must.Equal(2, es.B)
		it.Must.Equal(1, es.C)
	})
	anyOf.Test(func(it assert.It) {
		it.Must.Equal(`bar`, es.Type)
		it.Must.Equal(11, es.A)
		it.Must.Equal(12, es.B)
		it.Must.Equal(13, es.C)
	})
	anyOf.Test(func(it assert.It) {
		it.Must.Equal(`baz`, es.Type)
		it.Must.Equal(21, es.A)
		it.Must.Equal(22, es.B)
		it.Must.Equal(23, es.C)
	})
	anyOf.Finish()
}
Output:

func (*AnyOf) Finish added in v0.60.0

func (ao *AnyOf) Finish(msg ...interface{})

Finish will check if any of the assertion succeeded.

func (*AnyOf) Test added in v0.60.0

func (ao *AnyOf) Test(blk func(it It))

Test will test a block of assertion that must succeed in order to make AnyOf pass. You can have as much AnyOf.Test calls as you need, but if any of them pass with success, the rest will be skipped. Using Test is safe for concurrently.

type Asserter

type Asserter struct {
	TB testing.TB
	Fn func(args ...interface{})
}

func Must

func Must(tb testing.TB) Asserter
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	// create an assertion helper which will fail the testing context with .Fatal(...) in case of a failed assert.
	assert.Must(tb).True(true)
}
Output:

func Should

func Should(tb testing.TB) Asserter
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	// create an assertion helper which will fail the testing context with .Error(...) in case of a failed assert.
	assert.Should(tb).True(true)
}
Output:

func (Asserter) AnyOf added in v0.60.0

func (a Asserter) AnyOf(blk func(a *AnyOf), msg ...interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	var list []interface {
		Foo() int
		Bar() bool
		Baz() string
	}
	assert.Must(tb).AnyOf(func(anyOf *assert.AnyOf) {
		for _, testingCase := range list {
			anyOf.Test(func(it assert.It) {
				it.Must.True(testingCase.Bar())
			})
		}
	})
}
Output:

func (Asserter) Contain

func (a Asserter) Contain(src, has interface{}, msg ...interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).Contain([]int{1, 2, 3}, 3, "optional assertion explanation")
	assert.Must(tb).Contain([]int{1, 2, 3}, []int{1, 2}, "optional assertion explanation")
	assert.Must(tb).Contain(map[string]int{"The Answer": 42, "oth": 13}, map[string]int{"The Answer": 42}, "optional assertion explanation")
}
Output:

func (Asserter) ContainExactly

func (a Asserter) ContainExactly(expected, actual interface{}, msg ...interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).ContainExactly([]int{1, 2, 3}, []int{2, 3, 1}, "optional assertion explanation")  // true
	assert.Must(tb).ContainExactly([]int{1, 2, 3}, []int{1, 42, 2}, "optional assertion explanation") // false
}
Output:

func (Asserter) Empty added in v0.61.0

func (a Asserter) Empty(v interface{}, msg ...interface{})

Empty gets whether the specified value is considered empty.

Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB

	assert.Must(tb).Empty([]int{})   // pass
	assert.Must(tb).Empty([]int{42}) // fail

	assert.Must(tb).Empty([42]int{})   // pass
	assert.Must(tb).Empty([42]int{42}) // fail

	assert.Must(tb).Empty(map[int]int{})       // pass
	assert.Must(tb).Empty(map[int]int{42: 24}) // fail

	assert.Must(tb).Empty("")   // pass
	assert.Must(tb).Empty("42") // fail
}
Output:

func (Asserter) Equal

func (a Asserter) Equal(expected, actually interface{}, msg ...interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).Equal(true, true, "optional assertion explanation")
}
Output:

func (Asserter) ErrorIs added in v0.68.0

func (a Asserter) ErrorIs(expected, actual error, msg ...interface{})

ErrorIs allows you to assert an error value by an expectation. if the implementation of the test subject later changes, and for example, it starts to use wrapping, this should not be an issue as the err's error chain is also matched against the expectation.

Example
package main

import (
	"errors"
	"fmt"
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB

	actualErr := errors.New("boom")
	assert.Must(tb).ErrorIs(errors.New("boom"), actualErr)                                  // passes for equality
	assert.Must(tb).ErrorIs(errors.New("boom"), fmt.Errorf("wrapped error: %w", actualErr)) // passes for wrapped errors
}
Output:

func (Asserter) False added in v0.61.0

func (a Asserter) False(v bool, msg ...interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).False(false, "optional assertion explanation")
}
Output:

func (Asserter) Nil

func (a Asserter) Nil(v interface{}, msg ...interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).Nil(nil, "optional assertion explanation")
}
Output:

func (Asserter) NotContain

func (a Asserter) NotContain(source, oth interface{}, msg ...interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).NotContain([]int{1, 2, 3}, 42, "optional assertion explanation")
	assert.Must(tb).NotContain([]int{1, 2, 3}, []int{42}, "optional assertion explanation")
	assert.Must(tb).NotContain(map[string]int{"The Answer": 42, "oth": 13}, map[string]int{"The Answer": 13}, "optional assertion explanation")
}
Output:

func (Asserter) NotEmpty added in v0.61.0

func (a Asserter) NotEmpty(v interface{}, msg ...interface{})

NotEmpty gets whether the specified value is considered empty.

Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB

	assert.Must(tb).NotEmpty([]int{42}, "optional assertion explanation")

	assert.Must(tb).NotEmpty([]int{})   // fail
	assert.Must(tb).NotEmpty([]int{42}) // pass

	assert.Must(tb).NotEmpty([42]int{})   // fail
	assert.Must(tb).NotEmpty([42]int{42}) // pass

	assert.Must(tb).NotEmpty(map[int]int{})       // fail
	assert.Must(tb).NotEmpty(map[int]int{42: 24}) // pass

	assert.Must(tb).NotEmpty("")   // fail
	assert.Must(tb).NotEmpty("42") // pass
}
Output:

func (Asserter) NotEqual added in v0.58.0

func (a Asserter) NotEqual(v, oth interface{}, msg ...interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).NotEqual(true, false, "optional assertion explanation")
}
Output:

func (Asserter) NotNil

func (a Asserter) NotNil(v interface{}, msg ...interface{})
Example
package main

import (
	"errors"
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).NotNil(errors.New("42"), "optional assertion explanation")
}
Output:

func (Asserter) NotPanic

func (a Asserter) NotPanic(blk func(), msg ...interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).NotPanic(func() { /* no boom */ }, "optional assertion explanation")
}
Output:

func (Asserter) Panic

func (a Asserter) Panic(blk func(), msg ...interface{}) (panicValue interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).Panic(func() { panic("boom") }, "optional assertion explanation")
}
Output:

func (Asserter) True

func (a Asserter) True(v bool, msg ...interface{})
Example
package main

import (
	"testing"

	"github.com/adamluzsi/testcase/assert"
)

func main() {
	var tb testing.TB
	assert.Must(tb).True(true, "optional assertion explanation")
}
Output:

type It added in v0.60.0

type It struct {
	testing.TB
	// Must Asserter will use FailNow on a failed assertion.
	// This will make test exit early on.
	Must Asserter
	// Should Asserter's will allow to continue the test scenario,
	// but mark test failed on a failed assertion.
	Should Asserter
}

func MakeIt added in v0.63.0

func MakeIt(tb testing.TB) It

Jump to

Keyboard shortcuts

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