tests

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2023 License: MIT Imports: 13 Imported by: 1

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultInputPriority = -1
View Source
var DefaultMockPriority = -2
View Source
var DefaultOutputPriority = 1
View Source
var DefaultPreparePriority = -3
View Source
var InitGinData = func() *GinData {
	data := &GinData{}
	return data
}

Meant to be used with tests.NewGinTester. You can create your own if you'd like, just ensure the data type that is returned conforms to GinDataInterface

Functions

func RemoveInterfacePointer added in v1.1.0

func RemoveInterfacePointer[T any](pointerInterface interface{}) interface{}

Exposed interface pointer removal that requires the type to be passed into a generic function so a default value can be created in the zero case.

func SimpleCookie added in v1.0.0

func SimpleCookie(name, value string) *http.Cookie

Types

type ErrorIO added in v1.0.0

type ErrorIO struct {
	ReadErr  error
	CloseErr error
}

Helper to handle bad read errors

func NewDefaultErrorIO added in v1.0.0

func NewDefaultErrorIO() *ErrorIO

func (*ErrorIO) Close added in v1.0.0

func (e *ErrorIO) Close() error

func (*ErrorIO) Read added in v1.0.0

func (e *ErrorIO) Read(p []byte) (n int, err error)

type GinData

type GinData struct {
	Ctx      *gin.Context
	Engine   *gin.Engine
	Recorder *httptest.ResponseRecorder
}

Simple GIN context intialization

func (*GinData) GetCtx

func (d *GinData) GetCtx() *gin.Context

func (*GinData) GetEngine

func (d *GinData) GetEngine() *gin.Engine

func (*GinData) GetRecorder

func (d *GinData) GetRecorder() *httptest.ResponseRecorder

func (*GinData) PrepareForTest

func (d *GinData) PrepareForTest()

type GinDataInterface

type GinDataInterface interface {

	// Fetch the test context
	GetCtx() *gin.Context

	// Fetch the test engine
	GetEngine() *gin.Engine

	// Fetch the test response recorder
	GetRecorder() *httptest.ResponseRecorder

	/*
		Initialize the context, engine, and recorder. Is automatically
		called by the tester if using the NewGinTester() function.
	*/
	PrepareForTest()
}

type GinValidateOptions

type GinValidateOptions struct {
	Code    int
	Body    interface{}
	Cookies []*http.Cookie
}

type TestConfig

type TestConfig[C, M, D any] struct {
	Options *TestOptions[C, M, D]
	// contains filtered or unexported fields
}

Individual test to be run by a tester. This is the interface which all children test types must conform to.

func (*TestConfig[C, M, D]) Register added in v1.1.0

func (tc *TestConfig[C, M, D]) Register(tester *Tester[C, M, D]) *TestConfig[C, M, D]

Helper function for adding a test to a tester. Makes it easier to do this inline

type TestOptions

type TestOptions[C, M, D any] struct {
	// contains filtered or unexported fields
}

The TestOptions object is responsible providing binding to all the useful test options available. It implemented method chaining in order to make for a more simple interface for creating options.

Each chained option should return a completely new TestOptions struct so as to allow easy bifrucation of test setup.

func NewOptions added in v1.1.0

func NewOptions[C, M, D any]() *TestOptions[C, M, D]

func (*TestOptions[C, M, D]) Append added in v0.2.0

func (to *TestOptions[C, M, D]) Append(
	otherTestOptions ...*TestOptions[C, M, D],
) *TestOptions[C, M, D]

Append creates a new TestOptions object with all the options provided combined.

func (*TestOptions[C, M, D]) Checkout added in v0.2.0

func (to *TestOptions[C, M, D]) Checkout(
	tag string,
) *TestOptions[C, M, D]

Checkout the most recent entry of the tag in the options. Return all options prior to that tag, including that tag. If the tag is not found, this will panic.

func (*TestOptions[C, M, D]) Copy

func (to *TestOptions[C, M, D]) Copy() *TestOptions[C, M, D]

Helper copy function

func (*TestOptions[C, M, D]) CreateFunctionTest

func (to *TestOptions[C, M, D]) CreateFunctionTest(function interface{}, testName string) *TestConfig[C, M, D]

Create a new test which automatically fetches the function given at runtime.

func (*TestOptions[C, M, D]) CreateMethodTest

func (to *TestOptions[C, M, D]) CreateMethodTest(method, testName string) *TestConfig[C, M, D]

Create a new test which automatically fetches the named component method at runtime.

func (*TestOptions[C, M, D]) CreateTest added in v0.2.0

func (to *TestOptions[C, M, D]) CreateTest(
	testName string,
	getTestFunction func(state *TestState[C, M, D]) interface{},
) *TestConfig[C, M, D]

Create a new test based on the given function. By doing things this way, private methods can be tested as well by accessing them from the state at runtime.

func (*TestOptions[C, M, D]) Gin_Body added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_Body(
	f func(state *TestState[C, M, D]) []interface{},
) *TestOptions[C, M, D]

Write a value to the test request body. You can omit the args to method and url to leave them empty. For most tests, that will be sufficient.

func (*TestOptions[C, M, D]) Gin_BodyValue added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_BodyValue(
	value interface{},
) *TestOptions[C, M, D]

Write a specific body value to the test. If you need to write this value based on the options, use WriteGinBody() instead. You can omit the args to method and url to leave them empty. For most tests, that will be sufficient.

func (to *TestOptions[C, M, D]) Gin_Cookie(
	cookieFunction func(state *TestState[C, M, D]) *http.Cookie,
) *TestOptions[C, M, D]

Write a header to the request being made.

func (*TestOptions[C, M, D]) Gin_CookieValue added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_CookieValue(
	cookie *http.Cookie,
) *TestOptions[C, M, D]

Write a header to the request being made.

func (*TestOptions[C, M, D]) Gin_CookieValues added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_CookieValues(
	cookies []*http.Cookie,
) *TestOptions[C, M, D]

Write header values to the request being made.

func (*TestOptions[C, M, D]) Gin_Cookies added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_Cookies(
	cookiesFunction func(state *TestState[C, M, D]) []*http.Cookie,
) *TestOptions[C, M, D]

Write header values to the request being made.

func (*TestOptions[C, M, D]) Gin_Header added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_Header(
	key string, valueFunction func(state *TestState[C, M, D]) string,
) *TestOptions[C, M, D]

Write a header to the request being made.

func (*TestOptions[C, M, D]) Gin_HeaderValue added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_HeaderValue(
	key, value string,
) *TestOptions[C, M, D]

Write a header to the request being made.

func (*TestOptions[C, M, D]) Gin_HeaderValues added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_HeaderValues(
	headers map[string]string,
) *TestOptions[C, M, D]

Write header values to the request being made.

func (*TestOptions[C, M, D]) Gin_Headers added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_Headers(
	headersFunction func(state *TestState[C, M, D]) map[string]string,
) *TestOptions[C, M, D]

Write header values to the request being made.

func (*TestOptions[C, M, D]) Gin_SetCtx added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_SetCtx(
	key string, valueFunction func(state *TestState[C, M, D]) interface{},
) *TestOptions[C, M, D]

Sets a gin ctx key to a calculated value based on the state

func (*TestOptions[C, M, D]) Gin_SetCtxValue added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_SetCtxValue(
	key string, value interface{},
) *TestOptions[C, M, D]

Sets a specific value of the gin context prior to execution

func (*TestOptions[C, M, D]) Gin_SetMethodAndURL added in v1.0.0

func (to *TestOptions[C, M, D]) Gin_SetMethodAndURL(
	method, url string,
) *TestOptions[C, M, D]

func (*TestOptions[C, M, D]) Gin_Validate

func (to *TestOptions[C, M, D]) Gin_Validate(
	f func(*TestState[C, M, D]) GinValidateOptions,
) *TestOptions[C, M, D]

Shorthand to validate any portion of the gin response. As long as the input to each field is something other than the default value, that field will be checked

func (*TestOptions[C, M, D]) Gin_ValidateBody

func (to *TestOptions[C, M, D]) Gin_ValidateBody(
	f func(*TestState[C, M, D]) interface{},
) *TestOptions[C, M, D]

Ensures the body of the recorder matches the data passed in.

func (*TestOptions[C, M, D]) Gin_ValidateBodyValue added in v1.1.0

func (to *TestOptions[C, M, D]) Gin_ValidateBodyValue(
	expectedBody interface{},
) *TestOptions[C, M, D]

Ensures the body of the recorder matches the data passed in.

func (*TestOptions[C, M, D]) Gin_ValidateCode

func (to *TestOptions[C, M, D]) Gin_ValidateCode(
	f func(*TestState[C, M, D]) int,
) *TestOptions[C, M, D]

Ensures the http code that's written to the recorder matches

func (*TestOptions[C, M, D]) Gin_ValidateCodeValue added in v1.1.0

func (to *TestOptions[C, M, D]) Gin_ValidateCodeValue(
	code int,
) *TestOptions[C, M, D]

Ensures the http code that's written to the recorder matches

func (*TestOptions[C, M, D]) Gin_ValidateCookieValues added in v1.1.0

func (to *TestOptions[C, M, D]) Gin_ValidateCookieValues(
	expectedCookies []*http.Cookie,
) *TestOptions[C, M, D]

Ensures the cookies that are written to the recorder match.

func (*TestOptions[C, M, D]) Gin_ValidateCookies

func (to *TestOptions[C, M, D]) Gin_ValidateCookies(
	f func(*TestState[C, M, D]) []*http.Cookie,
) *TestOptions[C, M, D]

Ensures the cookies that are written to the recorder match.

func (*TestOptions[C, M, D]) Gin_ValidateValues added in v1.1.0

func (to *TestOptions[C, M, D]) Gin_ValidateValues(
	ginValidateOptions GinValidateOptions,
) *TestOptions[C, M, D]

Shorthand to validate any portion of the gin response. As long as the input to each field is something other than the default value, that field will be checked

func (*TestOptions[C, M, D]) Mock added in v1.0.0

func (to *TestOptions[C, M, D]) Mock(
	f interface{},
) *TestOptions[C, M, D]

Function to automatically handle a mock chain. Use the autogenerated functions from the components command places at the bottom of your component definition file, prefixed with "mock_" to use this.

ex. mock_component().METHOD(args...).Return(response...) (or similar)

Default Priority = -2

func (*TestOptions[C, M, D]) NewOption

func (to *TestOptions[C, M, D]) NewOption(
	priority int,
	applyFunction func(state *TestState[C, M, D]),
) *TestOptions[C, M, D]

General use case for adding an option. If there is any arbitrary thing you need to do, and the premade functions do not allow you to do it, you can add a generic option to allow you to do anything. It sends the whole state of the test into the "applyFunction" for you to modify as you please.

func (*TestOptions[C, M, D]) Prepare added in v1.1.0

func (to *TestOptions[C, M, D]) Prepare(
	f func(),
) *TestOptions[C, M, D]

Adjust data prior to runtime without care for test state Default Priority = -3

func (*TestOptions[C, M, D]) PrepareData

func (to *TestOptions[C, M, D]) PrepareData(
	f func(data *D),
) *TestOptions[C, M, D]

Adjust data prior to runtime without care for mocks or component state Default Priority = -3

func (*TestOptions[C, M, D]) PrepareState

func (to *TestOptions[C, M, D]) PrepareState(
	f func(state *TestState[C, M, D]),
) *TestOptions[C, M, D]

Adjust state prior to other options Default Priority = -3

func (*TestOptions[C, M, D]) SetInput

func (to *TestOptions[C, M, D]) SetInput(
	argIndex int,
	f func(state *TestState[C, M, D]) interface{},
) *TestOptions[C, M, D]

Specify a value of a particular arg based on the component and/or the test data. Default Priority = -1

func (*TestOptions[C, M, D]) SetInputByValue

func (to *TestOptions[C, M, D]) SetInputByValue(
	argIndex int,
	value interface{},
) *TestOptions[C, M, D]

Directly specify a value of a particular arg. Default Priority = -1

func (*TestOptions[C, M, D]) SetInputByValue_Pointer added in v1.1.0

func (to *TestOptions[C, M, D]) SetInputByValue_Pointer(
	argIndex int,
	value interface{},
) *TestOptions[C, M, D]

Directly specify a value of a particular arg. Default Priority = -1

func (*TestOptions[C, M, D]) SetInputs

func (to *TestOptions[C, M, D]) SetInputs(
	f func(state *TestState[C, M, D]) []interface{},
) *TestOptions[C, M, D]

Specify a value of all args at once based on the component and/or the test data. Default Priority = -1

func (*TestOptions[C, M, D]) SetInputsByValue

func (to *TestOptions[C, M, D]) SetInputsByValue(
	values ...interface{},
) *TestOptions[C, M, D]

Directly specify a value of all args at once. Default Priority = -1

func (*TestOptions[C, M, D]) SetInputsByValue_Pointer added in v1.1.0

func (to *TestOptions[C, M, D]) SetInputsByValue_Pointer(
	values ...interface{},
) *TestOptions[C, M, D]

Directly specify a value of all args at once. Default Priority = -1

func (*TestOptions[C, M, D]) Tag added in v0.2.0

func (to *TestOptions[C, M, D]) Tag(
	tag string,
) *TestOptions[C, M, D]

Create a tag which allows options to be "checked-out" later. This allows more simple control over options when writing iterative tests on each other.

func (*TestOptions[C, M, D]) Validate added in v1.1.0

func (to *TestOptions[C, M, D]) Validate(
	f func(state *TestState[C, M, D]) error,
) *TestOptions[C, M, D]

func (*TestOptions[C, M, D]) ValidateOutput

func (to *TestOptions[C, M, D]) ValidateOutput(
	argIndex int,
	f func(state *TestState[C, M, D]) interface{},
) *TestOptions[C, M, D]

Specify a value of a particular arg based on the component and/or the test data. Default Priority = 1

func (*TestOptions[C, M, D]) ValidateOutputValue

func (to *TestOptions[C, M, D]) ValidateOutputValue(
	argIndex int,
	expectedValue interface{},
) *TestOptions[C, M, D]

Directly check a value of a particular output. Default Priority = 1

func (*TestOptions[C, M, D]) ValidateOutputValue_Pointer added in v1.1.0

func (to *TestOptions[C, M, D]) ValidateOutputValue_Pointer(
	argIndex int,
	expectedValue *interface{},
) *TestOptions[C, M, D]

Directly check a value of a particular output. Default Priority = 1

func (*TestOptions[C, M, D]) ValidateOutputValues

func (to *TestOptions[C, M, D]) ValidateOutputValues(
	expectedValues ...interface{},
) *TestOptions[C, M, D]

Directly check all values of all outputs at once. Default Priority = 1

func (*TestOptions[C, M, D]) ValidateOutputValues_Pointer added in v1.1.0

func (to *TestOptions[C, M, D]) ValidateOutputValues_Pointer(
	expectedValues ...interface{},
) *TestOptions[C, M, D]

Directly check all values of all outputs at once. Default Priority = 1

func (*TestOptions[C, M, D]) ValidateOutputs

func (to *TestOptions[C, M, D]) ValidateOutputs(
	f func(state *TestState[C, M, D]) []interface{},
) *TestOptions[C, M, D]

Specify a value of all args at once based on the component and/or the test data. Default Priority = 1

func (*TestOptions[C, M, D]) WithPriority

func (to *TestOptions[C, M, D]) WithPriority(priority int) *TestOptions[C, M, D]

Adjusts the priority of the last option in the TestOptions. If no options exist currently, will panic so that the method chaining archetype can be preserved. Priorities < 0 are run before the test runs Priorities > 0 are run after test runs Priority = 0 is reserved for state cleanup before checking outputs Lower value priority occurs first.

type TestState

type TestState[C, M, D any] struct {
	Assertions *assert.Assertions

	Component C
	Mocks     *M
	Data      *D

	Input  []interface{}
	Output []interface{}
}

The internal test state. Is automatically updated as options are called.

type Tester

type Tester[C, M, D any] struct {

	// Global options for this tester
	Options *TestOptions[C, M, D]

	// Whether or not the tester should run tests in parallel
	Parallel bool
	// contains filtered or unexported fields
}

A tester is the base unit that handles mock testing for a component. Type P is the component params Type C is the component type Type M is the mocks type Type D is the data type

func NewFunctionTester

func NewFunctionTester[D any](
	initDataFunction func() *D,
) *Tester[interface{}, interface{}, D]

Create a new Tester for a function or a group of functions. This does not require any components or mocks to run as it is intended to be used on individual functions. The rest of the tester suite can still be used in this case, although the inferred generic types for the C (Component) and M (Mocks) fields will both simply be interfaces. You should ignore those fields in the Options.

func NewGinTester

func NewGinTester[C, M, D any](
	buildMocksFunction func(*testing.T) (C, *M),
	initDataFunction func() *D,
) *Tester[C, M, D]

Create a new Tester for methods requiring a gin test context. The Data structure must conform to the interface tests.GinDataInterface or else your test will panic. You may compose the tests.GinData into your data object to get this automatically. Preparation step will automatically occur at priority -100.

func NewTester

func NewTester[C, M, D any](
	buildMocksFunction func(*testing.T) (C, *M),
	initDataFunction func() *D,
) *Tester[C, M, D]

Create a new Tester with a specified Component, Mocks, and Data structure. Use tests.NullDataInitialization as the initDataFunction if you do not need to use the provided data object to facilitate your tester.

func NewTesterWithInit added in v1.1.0

func NewTesterWithInit[C, M any](
	buildMocksFunction func(*testing.T) (C, *M),
	initDataFunction func(),
) *Tester[C, M, interface{}]

Create a new Tester with a specified Component and Mocks structure. Requires a specification of a default initialization function.

func NewTesterWithoutData

func NewTesterWithoutData[C, M any](
	buildMocksFunction func(*testing.T) (C, *M),
) *Tester[C, M, interface{}]

Create a new Tester with a specified Component and Mocks structure. No initialization step is called for this kind of tester. The inferred type for the data is interface{}, but it will always be set to nil for tests created this way.

func (*Tester[C, M, D]) AddTests

func (tester *Tester[C, M, D]) AddTests(
	tests ...*TestConfig[C, M, D],
) *Tester[C, M, D]

Add tests that run a method of the parent component

func (*Tester[C, M, D]) NewOptions added in v1.0.0

func (tester *Tester[C, M, D]) NewOptions() *TestOptions[C, M, D]

Create a new options for this tester without any of the existing options included. Makes it slightly easier to branch

func (*Tester[C, M, D]) Test

func (tester *Tester[C, M, D]) Test(t *testing.T)

Runs all the currently appended tests in the order in which they were appended.

func (*Tester[C, M, D]) WithGroupID

func (tester *Tester[C, M, D]) WithGroupID(
	groupID string,
) *Tester[C, M, D]

Attach a group id to the tester so that all tests under this tester automatically have a prefix attached to them.

Jump to

Keyboard shortcuts

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