testutil

package
v0.5.8 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package testutil runs Popcorn Web applications from isolated copies of the registered runtime configuration.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Exchange

func Exchange(t pwtest.TestingT, handler http.Handler, request pwtest.Request) pwtest.Response

Exchange runs one request through handler on a real net/http server and returns what it answered.

It is the net/http half of the backend-neutral seam. The fasthttp half has the same name and the same signature apart from the handler type, so a test written against it says the same thing on either transport and only the import line moves.

The server is real and the connection is not: an in-memory pipe carries it, so the test pays a full request parse and response serialization — which is where half the behaviour worth testing lives — without paying a socket. That is also what makes it a fair pair with the other half, which runs the same way.

Each call starts and keeps a server for the rest of the test; a test making several requests against one handler builds a Harness once instead.

Types

type Config

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

Config is an isolated copy of all registered framework and application configuration values. Its three operations are methods, so a test reads config.Update rather than naming this package twice on one line.

func (*Config) Get added in v0.5.1

func (c *Config) Get[T any]() T

Get returns one typed value from a copied configuration. It is the one entry with nothing to infer the type from, so the call site writes it: config.Get[pw.ServerConfig](). A nil configuration answers the zero value.

func (*Config) Set added in v0.5.1

func (c *Config) Set[T any](value T)

Set replaces one typed value in a copied configuration.

func (*Config) Update added in v0.5.1

func (c *Config) Update[T any](edit func(*T))

Update edits one typed value in a copied configuration, inferring the type from the edit's parameter.

type Harness added in v0.5.2

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

Harness is one running server and one client, shared by every exchange of a test.

Exchange starts a fresh server, listener and goroutine per call and keeps all of them alive until the test ends, so a test driving one handler with N requests held N listeners and paid N startups. A harness starts the server once, and its client reuses connections — which is also what lets a sequence of exchanges meet keep-alive the way a browser would.

func NewHarness added in v0.5.2

func NewHarness(t pwtest.TestingT, handler http.Handler) *Harness

NewHarness starts a real net/http server for handler and returns the harness that drives it. The server is shut down by t.Cleanup.

func (*Harness) Exchange added in v0.5.2

func (h *Harness) Exchange(request pwtest.Request) pwtest.Response

Exchange runs one request through the harness's server and returns what it answered.

type IdPInfo

type IdPInfo struct {
	Issuer       string
	ClientID     string
	ClientSecret string
}

IdPInfo is what a test needs to point an application at the identity provider TestRun started for it.

type IdPOption

type IdPOption func(*idpSettings) error

IdPOption configures the identity provider started by WithIdentityProvider.

func WithIdPBinding

func WithIdPBinding(bind func(*Config, IdPInfo)) IdPOption

WithIdPBinding writes the issuer and generated client credentials into the copied configuration. It runs after customize, so it wins over a placeholder the test left there.

func WithIdPClient

func WithIdPClient(redirectURIs ...string) IdPOption

WithIdPClient registers a client whose redirect URIs are matched exactly. The default client accepts any loopback callback, which is what a test server on a reserved port needs.

func WithIdPConfig

func WithIdPConfig(path string) IdPOption

WithIdPConfig reads the roster from a devidp.toml file.

func WithIdPRoster

func WithIdPRoster(source string) IdPOption

WithIdPRoster reads the roster from devidp.toml content held in the test.

func WithIdPScopes

func WithIdPScopes(scopes ...string) IdPOption

WithIdPScopes adds scope tokens beyond openid, profile, and email.

func WithIdPUsers

func WithIdPUsers(users ...devidp.User) IdPOption

WithIdPUsers builds the roster from Go values.

func WithLoginUser

func WithLoginUser(subject string) IdPOption

WithLoginUser pre-selects the subject the provider signs in as, so authorization redirects straight back to the application with a code.

type RunOption

type RunOption func(*runSettings) error

RunOption configures TestRun resources.

func WithIdentityProvider

func WithIdentityProvider(options ...IdPOption) RunOption

WithIdentityProvider starts a development OpenID Provider before the application server, so a test can drive an OIDC login without a browser and without external credentials.

Exactly one roster source is required: WithIdPConfig, WithIdPRoster, or WithIdPUsers.

func WithMigrations

func WithMigrations(directory string) RunOption

WithMigrations installs the migrated schema from a migration directory.

The schema is installed by replaying a snapshot rather than by running every migration, so the cost is paid once per test binary and an in-memory database works on both the host and the TinyGo execution path.

func WithMigrationsFS

func WithMigrationsFS(sources fs.FS) RunOption

WithMigrationsFS installs the migrated schema from an embedded migration tree.

func WithSeed

func WithSeed(files ...string) RunOption

WithSeed loads dataset files into the copied database after the migration schema is installed and before the HTTP server starts.

Each name is a path relative to the seed directory; the .yaml extension may be omitted. Datasets are applied in the given order.

func WithSeedDir

func WithSeedDir(directory string) RunOption

WithSeedDir overrides the dataset directory, which defaults to testdata/seed relative to the test package directory.

func WithTransaction

func WithTransaction(enabled bool) RunOption

WithTransaction runs every request of this test server inside one transaction that is rolled back when the test finishes, so tests sharing one database stay independent and may run in parallel. Framework transactions started by the application nest into it as savepoints, which requires a driver with savepoint support.

type Server

type Server struct {
	URL    string
	Port   int
	Config *Config
	DB     *sql.DB
	// contains filtered or unexported fields
}

Server is a running application created by TestRun.

func TestRun

func TestRun(t TestingT, handler http.Handler, customize func(*Config), options ...RunOption) *Server

TestRun copies every registered configuration, defaults the copied server port to -1, applies customize, initializes copied runtime resources, and starts the application. Port -1 selects an available loopback port.

func (*Server) AssertDB

func (server *Server) AssertDB(t TestingT, files ...string)

AssertDB compares the running server's database against expected datasets.

A mismatch is reported through Errorf with a plain-text per-table diff and the test continues.

Under WithTransaction it reads inside the test transaction, so writes made by requests are visible before any commit. Otherwise only committed state is visible, and a request whose transaction is still open has not been compared yet.

func (*Server) Client

func (server *Server) Client() *http.Client

Client returns an HTTP client configured for the test server.

func (*Server) Close

func (server *Server) Close()

Close stops the server, rolls back a WithTransaction transaction, and releases its copied runtime resources.

func (*Server) Context

func (server *Server) Context() context.Context

Context returns a context carrying the same runtime resources the server installs on requests, including the WithTransaction transaction. Use it to prepare or assert data inside the test transaction.

func (*Server) IdP

func (server *Server) IdP() *devidp.Server

IdP returns the running provider, or nil when the test did not start one.

func (*Server) IdPInfo

func (server *Server) IdPInfo() IdPInfo

IdPInfo returns the issuer and generated client credentials.

func (*Server) LoginAs

func (server *Server) LoginAs(t TestingT, subject string)

LoginAs changes the pre-selected subject for the next authorization.

func (*Server) Seed

func (server *Server) Seed(t TestingT, files ...string)

Seed loads dataset files into the running server's database.

Use it to reset state between phases of one test. A failure stops the test.

Under WithTransaction it seeds inside the test transaction, so the rows are visible to requests and disappear with the rollback. Otherwise it seeds through the pool and the rows are committed.

type TestingT

type TestingT interface {
	Helper()
	Cleanup(func())
	Fatalf(string, ...any)
	Errorf(string, ...any)
}

TestingT is the subset of testing.T used by TestRun.

It stays an interface so this shipped package never imports testing. Fatalf reports setup failure that invalidates the test; Errorf reports an assertion failure that lets the test continue.

Jump to

Keyboard shortcuts

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