testext

package
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Mar 7, 2024 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CustomDuration

type CustomDuration time.Duration

CustomDuration is a standard Duration alias that uses duration strings for JSON transport as opposed to epoch nanos.

func (CustomDuration) MarshalJSON

func (duration CustomDuration) MarshalJSON() ([]byte, error)

func (*CustomDuration) UnmarshalJSON

func (duration *CustomDuration) UnmarshalJSON(jsonBytes []byte) error

type EventError added in v0.1.4

type EventError struct {
	Message        string
	Error          string
	Code           int
	Status         int
	StatusCode     int
	HTTPStatusCode int
}

EventError captures the various ways you can bind the error message and its status codes

type FailAlwaysErrorRequest added in v0.1.4

type FailAlwaysErrorRequest struct {
	Error         EventError
	RequestValue  string
	ResponseValue string
}

type FailAlwaysErrorResponse added in v0.1.4

type FailAlwaysErrorResponse struct {
}

type FailAlwaysRequest added in v0.1.4

type FailAlwaysRequest struct {
	RequestValue string
}

type FailAlwaysResponse added in v0.1.4

type FailAlwaysResponse struct {
	ResponseValue string
}

type FreeAddress

type FreeAddress struct {
	// Host is the hostname portion of the address to generate.
	Host string
	// Port is the port number to increment each time.
	Port uint16
	// contains filtered or unexported fields
}

FreeAddress helps you generate unique "host:port" strings for each of your tests. You start at a given port and each call to Next() will give you a new host:port one higher than the previous.

func NewFreeAddress

func NewFreeAddress(host string, startPort uint16) FreeAddress

NewFreeAddress returns a "host:port" generator for the given host that begins at the current port.

func (*FreeAddress) Next

func (next *FreeAddress) Next() string

Next increments the base port and returns the unique host:port. For instance, the first call might return "localhost:9001" and the subsequent one will return "localhost:9002".

type MarshalToObject

type MarshalToObject struct {
	// Home is supposed to be a home email address.
	Home string
	// Work is supposed to be a home email address.
	Work string
}

MarshalToObject is a struct that implements MarshalJSON/UnmarshalJSON in order to remap the structure of this from {Home:"", Work:""} to {H:"", W:""}. Ideally, you should just do this using struct attributes - it will work better.

This is NOT supported in non-Go language clients because we have no way to convey to the request builder code the correct structure it should submit. I include this so that we can have a test codifying that this behavior is not supported. If you want different fields, use `json:""` tags.

func (MarshalToObject) MarshalJSON

func (m MarshalToObject) MarshalJSON() ([]byte, error)

func (*MarshalToObject) UnmarshalJSON

func (m *MarshalToObject) UnmarshalJSON(jsonBytes []byte) error

type MarshalToString

type MarshalToString struct {
	// Home is supposed to be a home email address.
	Home string
	// Work is supposed to be a home email address.
	Work string
}

MarshalToString implements MarshalJSON/UnmarshalJSON to show that you can convert a struct type into some primitive like a string and have that work in your clients. Instead of using the standard object-based JSON this would normally marshal to, this uses a string formatted like "Home,Work".

This SHOULD be supported by external clients like JS/Dart/etc.

func (MarshalToString) MarshalJSON

func (m MarshalToString) MarshalJSON() ([]byte, error)

func (*MarshalToString) UnmarshalJSON

func (m *MarshalToString) UnmarshalJSON(jsonBytes []byte) error

type OtherRequest

type OtherRequest struct {
	// UniqueThing is just a field that doesn't exist in any other testing response. This ensures
	// that we can use events to decode the values like 'Text' which are present while ignoring those
	// that are not... quietly.
	UniqueThing bool
	// Text is the result of the previous call's invocation.
	Text string
}

OtherRequest is a basic payload that partially matches the schema of SampleResponse so when we invoke service methods through the event gateway, we can make sure that we can get the Text value while ignoring everything else from the original payload.

type OtherResponse

type OtherResponse OtherRequest

OtherResponse is a single-value output.

type OtherService

type OtherService interface {
	// SpaceOut takes your input text and puts spaces in between all the letters.
	SpaceOut(context.Context, *OtherRequest) (*OtherResponse, error)

	// RPCExample invokes the TriggerUpperCase() function on the SampleService to get work done.
	// This will make sure that we can do cross-service communication.
	RPCExample(context.Context, *OtherRequest) (*OtherResponse, error)

	// ListenWell can listen for successful responses across multiple services.
	//
	// ON OtherService.SpaceOut
	// ON SampleService.TriggerUpperCase
	ListenWell(context.Context, *OtherRequest) (*OtherResponse, error)

	// ChainOne allows us to test the cascading of events to create more complex flows. When this
	// finishes it will trigger ChainTwo which will, in turn, trigger ChainThree and ChainFour.
	ChainOne(ctx context.Context, request *OtherRequest) (*OtherResponse, error)

	// ChainTwo is used to test that methods invoked via the event gateway can trigger even more events.
	//
	// ON OtherService.ChainOne
	ChainTwo(ctx context.Context, request *OtherRequest) (*OtherResponse, error)

	// ChainThree is used to test that methods invoked via the event gateway can trigger even more events.
	//
	// ON OtherService.ChainTwo
	ChainThree(ctx context.Context, request *OtherRequest) (*OtherResponse, error)

	// ChainFour is used to test that methods invoked via the event gateway can trigger even more events.
	//
	// ON OtherService.ChainTwo
	ChainFour(ctx context.Context, request *OtherRequest) (*OtherResponse, error)

	// ChainFail fires after ChainOne, but should always return an error. This will prevent ChainFailAfter
	// from ever actually running.
	//
	// ON OtherService.ChainOne
	ChainFail(ctx context.Context, request *OtherRequest) (*OtherResponse, error)

	// ChainFailAfter is dependent on a successful call to ChainFail... which always fails. So this NEVER runs.
	//
	// ON OtherService.ChainFail
	ChainFailAfter(ctx context.Context, request *OtherRequest) (*OtherResponse, error)
}

OtherService primarily exists to show that we can send event signals between services.

type OtherServiceHandler

type OtherServiceHandler struct {
	Sequence      *Sequence
	SampleService SampleService
}

func (OtherServiceHandler) ChainFail

func (OtherServiceHandler) ChainFailAfter

func (svc OtherServiceHandler) ChainFailAfter(_ context.Context, req *OtherRequest) (*OtherResponse, error)

func (OtherServiceHandler) ChainFour

func (OtherServiceHandler) ChainOne

func (OtherServiceHandler) ChainThree

func (svc OtherServiceHandler) ChainThree(_ context.Context, req *OtherRequest) (*OtherResponse, error)

func (OtherServiceHandler) ChainTwo

func (OtherServiceHandler) ListenWell

func (svc OtherServiceHandler) ListenWell(_ context.Context, req *OtherRequest) (*OtherResponse, error)

func (OtherServiceHandler) RPCExample

func (svc OtherServiceHandler) RPCExample(ctx context.Context, req *OtherRequest) (*OtherResponse, error)

func (OtherServiceHandler) SpaceOut

type SampleComplexRequest

type SampleComplexRequest struct {
	InUser    SampleUser
	InFlag    bool
	InFloat   float64
	InTime    time.Time
	InTimePtr *time.Time
}

type SampleComplexResponse

type SampleComplexResponse struct {
	OutFlag    bool
	OutFloat   float64
	OutUser    *SampleUser
	OutTime    time.Time
	OutTimePtr *time.Time
}

type SampleDownloadRequest

type SampleDownloadRequest struct {
	Format string
}

type SampleDownloadResponse

type SampleDownloadResponse struct {
	services.StreamResponse
}

type SampleRedirectRequest

type SampleRedirectRequest struct{}

type SampleRedirectResponse

type SampleRedirectResponse struct {
	URI string
	services.StreamResponse
}

func (SampleRedirectResponse) Redirect

func (res SampleRedirectResponse) Redirect() string

type SampleRequest

type SampleRequest struct {
	ID   string
	Text string
}

type SampleResponse

type SampleResponse SampleRequest

type SampleSecurityRequest

type SampleSecurityRequest struct {
	ID   string
	User SampleUser
}

type SampleSecurityResponse

type SampleSecurityResponse struct {
	Roles []string
}

type SampleService

type SampleService interface {
	// Defaults simply utilizes all of the framework's default behaviors.
	Defaults(context.Context, *SampleRequest) (*SampleResponse, error)

	// ComplexValues flexes our ability to encode/decode non-flat structs.
	ComplexValues(context.Context, *SampleComplexRequest) (*SampleComplexResponse, error)

	// ComplexValuesPath flexes our ability to encode/decode non-flat structs while
	// specifying them via path and query string.
	//
	// GET /complex/values/{InUser.ID}/{InUser.Name}/woot
	ComplexValuesPath(context.Context, *SampleComplexRequest) (*SampleComplexResponse, error)

	// Fail4XX always returns a non-nil 400-series error.
	Fail4XX(context.Context, *SampleRequest) (*SampleResponse, error)

	// Fail5XX always returns a non-nil 500-series error.
	Fail5XX(context.Context, *SampleRequest) (*SampleResponse, error)

	// CustomRoute performs a service operation where you override default behavior
	// by providing routing-related Doc Options.
	//
	// HTTP 202
	// GET /custom/route/1/{ID}/{Text}
	CustomRoute(context.Context, *SampleRequest) (*SampleResponse, error)

	// CustomRouteQuery performs a service operation where you override default behavior
	// by providing routing-related Doc Options. The input data relies on the path
	//
	// HTTP 202
	// GET /custom/route/2/{ID}
	CustomRouteQuery(context.Context, *SampleRequest) (*SampleResponse, error)

	// CustomRouteBody performs a service operation where you override default behavior
	// by providing routing-related Doc Options, but rely on body encoding rather than path.
	//
	// HTTP 201
	// PUT /custom/route/3/{ID}
	CustomRouteBody(context.Context, *SampleRequest) (*SampleResponse, error)

	// OmitMe exists in the service, but should be excluded from the public API.
	//
	// HTTP OMIT
	OmitMe(ctx context.Context, request *SampleRequest) (*SampleResponse, error)

	// Download results in a raw stream of data rather than relying on auto-encoding
	// the response value.
	//
	// GET /download
	Download(context.Context, *SampleDownloadRequest) (*SampleDownloadResponse, error)

	// DownloadResumable results in a raw stream of data rather than relying on auto-encoding
	// the response value. The stream includes Content-Range info as though you could resume
	// your stream/download progress later.
	//
	// GET /download/resumable
	DownloadResumable(context.Context, *SampleDownloadRequest) (*SampleDownloadResponse, error)

	// Redirect results in a 307-style redirect to the Download endpoint.
	//
	// GET /redirect
	Redirect(context.Context, *SampleRedirectRequest) (*SampleRedirectResponse, error)

	// Authorization regurgitates the "Authorization" metadata/header.
	Authorization(context.Context, *SampleRequest) (*SampleResponse, error)

	// Sleep successfully responds, but it will sleep for 5 seconds before doing so. Use this
	// for test cases where you want to try out timeouts.
	Sleep(context.Context, *SampleRequest) (*SampleResponse, error)

	// TriggerUpperCase ensures that events still fire as "SampleService.TriggerUpperCase" even though
	// we are going to set a different HTTP path.
	//
	// GET /Upper/Case/WootyAndTheBlowfish
	TriggerUpperCase(context.Context, *SampleRequest) (*SampleResponse, error)
	TriggerLowerCase(context.Context, *SampleRequest) (*SampleResponse, error)
	TriggerFailure(context.Context, *SampleRequest) (*SampleResponse, error)

	// ListenerA fires on only one of the triggers.
	//
	// GET /ListenerA/Woot
	// ON SampleService.TriggerUpperCase
	ListenerA(context.Context, *SampleRequest) (*SampleResponse, error)

	// ListenerB fires on multiple triggers... including another event-based endpoint. We also
	// listen for the TriggerFailure event which should never fire properly.
	//
	// HTTP OMIT
	// ON SampleService.TriggerUpperCase
	// ON SampleService.TriggerLowerCase
	// ON SampleService.TriggerFailure
	// ON SampleService.ListenerA
	// ON OtherService.SpaceOut
	ListenerB(context.Context, *SampleRequest) (*SampleResponse, error)

	// FailAlways will return an error no matter what. It's only goal in life is to trigger OnFailAlways.
	FailAlways(ctx context.Context, request *FailAlwaysRequest) (*FailAlwaysResponse, error)

	// OnFailAlways should trigger after FailAlways inevitably shits the bed.
	//
	// ON SampleService.FailAlways:Error
	OnFailAlways(ctx context.Context, request *FailAlwaysErrorRequest) (*FailAlwaysErrorResponse, error)

	// SecureWithRoles lets us test role based security by looking at the 'roles' doc option.
	//
	// ROLES admin.write,user.{ID}.write ,   user.{User.ID}.admin, junk.{NotReal}.crap
	SecureWithRoles(context.Context, *SampleSecurityRequest) (*SampleSecurityResponse, error)

	// Panic um... panics. It never succeeds. It always behaves like me when I'm on a high place looking down.
	Panic(context.Context, *SampleRequest) (*SampleResponse, error)
}

SampleService is a mix of different options, parameter setups, and responses so that we can run integration tests using our code-generated clients. Each method is nothing special, but they each do something a little differently than the rest to flex different parts of the framework.

PREFIX /v2

type SampleServiceHandler

type SampleServiceHandler struct {
	Sequence *Sequence
}

func (SampleServiceHandler) Authorization

func (s SampleServiceHandler) Authorization(ctx context.Context, req *SampleRequest) (*SampleResponse, error)

func (SampleServiceHandler) ComplexValues

func (SampleServiceHandler) ComplexValuesPath

func (SampleServiceHandler) CustomRoute

func (SampleServiceHandler) CustomRouteBody

func (s SampleServiceHandler) CustomRouteBody(_ context.Context, req *SampleRequest) (*SampleResponse, error)

func (SampleServiceHandler) CustomRouteQuery

func (s SampleServiceHandler) CustomRouteQuery(_ context.Context, req *SampleRequest) (*SampleResponse, error)

func (SampleServiceHandler) Defaults

func (SampleServiceHandler) Download

func (SampleServiceHandler) DownloadResumable

func (SampleServiceHandler) Fail4XX

func (SampleServiceHandler) Fail5XX

func (SampleServiceHandler) FailAlways added in v0.1.4

func (SampleServiceHandler) ListenerA

func (SampleServiceHandler) ListenerB

func (SampleServiceHandler) OmitMe

func (SampleServiceHandler) OnFailAlways added in v0.1.4

func (SampleServiceHandler) Panic

func (SampleServiceHandler) Redirect

func (SampleServiceHandler) SecureWithRoles

func (SampleServiceHandler) Sleep

func (SampleServiceHandler) TriggerFailure

func (s SampleServiceHandler) TriggerFailure(_ context.Context, req *SampleRequest) (*SampleResponse, error)

func (SampleServiceHandler) TriggerLowerCase

func (s SampleServiceHandler) TriggerLowerCase(_ context.Context, req *SampleRequest) (*SampleResponse, error)

func (SampleServiceHandler) TriggerUpperCase

func (s SampleServiceHandler) TriggerUpperCase(_ context.Context, req *SampleRequest) (*SampleResponse, error)

type SampleUser

type SampleUser struct {
	// ID is a string value that will likely have no whitespace.
	ID string
	// Name is a string value that will likely have spaces.
	Name string
	// Age is a numeric value that we should support.
	Age int
	// Attention is a duration to ensure that we use epoch nanos as the format, NOT the string.
	Attention time.Duration
	// AttentionString is a custom duration alias that overrides MarshalJSON/UnmarshalJSON to use strings for transport.
	AttentionString CustomDuration
	// PhoneNumber exercises the notion that clients should refer to this field as Digits, not PhoneNumber.
	PhoneNumber string `json:"Digits"`
	// MarshalToString makes sure that we can use strings as an alternate JSON format for structs.
	MarshalToString MarshalToString
	// MarshalToString makes sure that we can use custom marshaling of struct values.
	// This is NOT globally supported in all client languages - just Go for now.
	MarshalToObject MarshalToObject
}

SampleUser contains an array of different fields that we support sending to/from clients in all of our supported languages.

type Sequence

type Sequence struct {
	// contains filtered or unexported fields
}

Sequence is a convenient way to capture a series of values in a specified order that you can use to determine if code was fired in a specific sequence/order.

func (*Sequence) Append

func (seq *Sequence) Append(value string)

Append writes the next value for the piece of code that executed.

func (*Sequence) Reset

func (seq *Sequence) Reset()

Reset erases all current values in the sequence, allowing you to re-use this sequence multiple times within the same test case.

func (*Sequence) ResetWithWorkers

func (seq *Sequence) ResetWithWorkers(waitGroupCount int)

ResetWithWorkers erases all current values in the sequence and update the underlying wait group to expect this many 'Done()' invocations. This allows you to re-use this sequence multiple times within the same test case.

func (*Sequence) Value

func (seq *Sequence) Value(index int) string

Value returns the value at the specific index. If you haven't appended that much yet, then this will return "".

func (*Sequence) Values

func (seq *Sequence) Values() []string

Values returns all the values that you collected during the test case.

func (*Sequence) WaitGroup

func (seq *Sequence) WaitGroup() *sync.WaitGroup

WaitGroup returns the wait group that helps synchronize the async routines filling this sequence.

Directories

Path Synopsis
Code generated by Frodo - DO NOT EDIT.
Code generated by Frodo - DO NOT EDIT.

Jump to

Keyboard shortcuts

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