sqltest

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2026 License: Apache-2.0 Imports: 10 Imported by: 1

Documentation

Overview

Package sqltest is the scripted database/sql driver a consumer's hermetic tests run over: a connector whose connections consume scripted responses in call order and record every statement, prepare, and transaction call they receive. It supports prepare, so prepare-based verification has a harness, and it accepts any argument value unconverted, so tests see the exact Go values a runner bound. It is public because every consumer's unit tier runs over it, the library's own packages included.

It is strict where a real driver is, so a test cannot pass on a path production would reject: a statement with no response scripted for it fails (ErrUnscripted), an argument count that does not match the statement's $N placeholders fails (ErrArguments), and a scripted response that does not fit its call (rows for an exec, an affected count for a query, a row of the wrong width or containing a non-driver.Value) fails (ErrScript). The one leniency it keeps is the argument set: a real driver rejects a value it cannot encode, and this one records it.

Open returns the pool and its Recorder; Dialect is the stub dialect whose MapError wraps every error in a MappedError, so a test proves with one errors.As that an error passed through MapError.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUnscripted = errors.New("sqltest: unscripted call")
	ErrScript     = errors.New("sqltest: response does not fit the call")
	ErrArguments  = errors.New("sqltest: argument count does not match the placeholders")
)

The driver's own failures, each the counterpart of a failure a real driver or engine raises: a statement no response was scripted for is a statement the test did not expect to run; a response whose shape does not fit the call is a script defect; an argument count that does not match the statement's placeholders is what the engine rejects at bind time.

Functions

This section is empty.

Types

type Call

type Call struct {
	Op        Op
	SQL       string
	Args      []any
	TxOptions driver.TxOptions
}

Call is one recorded driver call. SQL and Args are set for exec, query, and prepare; TxOptions for begin.

type Dialect

type Dialect struct{}

Dialect is the stub dialect: $N placeholders and a MapError that wraps every non-nil error in a *MappedError, so a test proves an error crossed the mapping boundary with one errors.As.

func (Dialect) MapError

func (Dialect) MapError(err error) error

MapError wraps err in a *MappedError; nil stays nil. An already mapped error is returned as is, so double mapping is visible as absence of nesting rather than a crash.

func (Dialect) Name

func (Dialect) Name() string

func (Dialect) Placeholder

func (Dialect) Placeholder(n int) string

type MappedError

type MappedError struct{ Err error }

MappedError marks an error that passed through Dialect.MapError.

func (*MappedError) Error

func (e *MappedError) Error() string

func (*MappedError) Unwrap

func (e *MappedError) Unwrap() error

type Op

type Op string

Op names a recorded driver call.

const (
	OpExec     Op = "exec"
	OpQuery    Op = "query"
	OpPrepare  Op = "prepare"
	OpBegin    Op = "begin"
	OpCommit   Op = "commit"
	OpRollback Op = "rollback"
)

type Recorder

type Recorder struct {

	// FailPrepare, when set, decides whether a prepare of the given text
	// fails; nil means every prepare succeeds.
	FailPrepare func(query string) error
	// FailBegin, FailCommit, FailRollback, FailPing inject failures into the
	// transaction and ping calls.
	FailBegin, FailCommit, FailRollback, FailPing error
	// contains filtered or unexported fields
}

Recorder is the shared state behind every connection a connector hands out: the response queue, the call log, and the failure switches.

func Open

func Open(t testing.TB, responses ...Response) (*sql.DB, *Recorder)

Open returns a pool over a fresh Recorder, closed when the test ends.

func (*Recorder) Calls

func (r *Recorder) Calls() []Call

Calls returns a copy of the call log in order.

func (*Recorder) Ops

func (r *Recorder) Ops() []Op

Ops returns the sequence of operations recorded.

func (*Recorder) Pending

func (r *Recorder) Pending() int

Pending reports how many scripted responses remain unconsumed; a test asserts zero to prove every scripted call happened.

func (*Recorder) Queue

func (r *Recorder) Queue(responses ...Response)

Queue appends responses for later exec and query calls.

func (*Recorder) RowsLeaked

func (r *Recorder) RowsLeaked() int

RowsLeaked reports row sets opened and never closed.

func (*Recorder) SQL

func (r *Recorder) SQL(op Op) []string

SQL returns the statement texts recorded for op, in order.

type Response

type Response struct {
	Err      error
	Affected int64
	Columns  []string
	Rows     [][]driver.Value
}

Response scripts the outcome of the next exec or query call: an error, or the affected count (exec) or the columns and rows (query). An exec response has no columns or rows and a query response no affected count; every row is as wide as Columns and contains driver.Value types only, as a real driver returns them. Prepare, begin, commit, and rollback do not consume responses; their failures are set on the Recorder directly.

Jump to

Keyboard shortcuts

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