sqlkittest

package module
v0.0.0-...-591bdfc Latest Latest
Warning

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

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

Documentation

Overview

Package sqlkittest proves that an sqlkit.Executor behaves like every other.

It holds the executor conformance suite, a tiny fixture schema per dialect that exercises rendering, the development runner and verification without any domain, and the container helpers that provision the databases the suite runs against.

It is its own module so that sqlkit itself never depends on testcontainers.

Index

Constants

View Source
const (
	// PostgresImage is the PostgreSQL image the suites run against.
	PostgresImage = "postgres:17.6-alpine"
	// MySQLImage is the MySQL image the suites run against. It is 8.0 or later
	// because an identifier column needs the utf8mb4_0900_as_cs collation.
	MySQLImage = "mysql:8.4.6"
)

Pinned images. A moving tag would let a remote image update change what a conformance suite means overnight, on a Tuesday, for no reason anybody could find.

Variables

View Source
var FixtureExpectation = sqlkit.SchemaExpectation{
	"widgets": {
		Columns:           []string{"id", "owner", "payload", "at", "score"},
		IdentifierColumns: []string{"id", "owner"},
		Indexes:           []string{"widgets_owner_idx"},
	},
	"parts": {
		Columns:           []string{"id", "widget_id"},
		IdentifierColumns: []string{"id", "widget_id"},
	},
}

FixtureExpectation is what the fixture requires of the live schema.

View Source
var FixtureTables = []string{"widgets", "parts"}

FixtureTables are the fixture's tables, unprefixed, in creation order.

Functions

func FixtureSchema

func FixtureSchema(dialect sqlkit.Dialect) (string, bool)

FixtureSchema returns the fixture's schema document for a dialect, carrying sqlkit.PrefixToken wherever a table prefix goes. It reports false for a dialect it has no document for.

func RunExecutorSuite

func RunExecutorSuite(t *testing.T, factory Factory)

RunExecutorSuite proves that an executor behaves like every other: how it runs statements and releases rows, who begins and who commits, what nesting means, what a failure leaves behind, and that values survive the round trip identically on every driver and dialect.

func RunTestMySQL

func RunTestMySQL(t *testing.T, opts ...TestOption) string

RunTestMySQL starts a MySQL container and returns a DSN for it.

The DSN asks for three things a portable store needs and MySQL does not do by default:

  • parsed times in UTC, because timestamps are stored as UTC at microsecond precision and a driver left to its own devices hands back a string in whatever zone the session happens to carry;
  • clientFoundRows, because MySQL otherwise reports how many rows a write changed rather than how many it matched, and a conditional update that matched its row but wrote the same values would look like a conflict;
  • multiStatements, so a published schema can be applied in one go.

func RunTestPostgres

func RunTestPostgres(t *testing.T, opts ...TestOption) string

RunTestPostgres starts a PostgreSQL container and returns a DSN for it.

The container lives as long as the test: termination is registered with t.Cleanup the instant the container starts, before anything that could fail, so a failing migration cannot leak it.

func RunTestSQLite

func RunTestSQLite(t *testing.T, opts ...TestOption) string

RunTestSQLite returns a DSN for a fresh SQLite database file, named after the database, in the test's own temporary directory.

There is no container: SQLite runs in the process. That is exactly why it is in the matrix — it makes a conformance suite cheap enough to run on every commit, which is what keeps the other six combinations honest.

Foreign keys are switched on explicitly, because SQLite leaves them off by default.

Types

type Factory

type Factory func(t *testing.T) Harness

Factory builds a harness. It is called once per case and may register cleanup with t. The suite creates and drops its own prefixed fixture schema in the harness's database, so one database serves every case.

type Harness

type Harness struct {
	// Executor is the executor under test. It must also implement
	// [sqlkit.Execer] and [sqlkit.Querier].
	Executor sqlkit.Executor
	// CallerTx begins a transaction the way a host's own code would, and
	// returns a context carrying it — through the executor package's
	// ContextWithTx — plus a function that commits or rolls it back. It is how
	// the suite checks that an executor joins a transaction it did not begin
	// and leaves its disposition alone.
	CallerTx func(ctx context.Context) (scoped context.Context, done func(commit bool) error)
}

Harness is what the executor suite needs from one executor on one database.

type TestOption

type TestOption func(*testConfig)

TestOption varies how a test database is provisioned.

func WithDatabase

func WithDatabase(name string) TestOption

WithDatabase overrides the database name, which defaults to "sqlkit". For SQLite it names the database file.

func WithImage

func WithImage(image string) TestOption

WithImage overrides the pinned image, for testing against another version.

func WithStartupTimeout

func WithStartupTimeout(timeout time.Duration) TestOption

WithStartupTimeout overrides how long the helper waits for readiness.

Jump to

Keyboard shortcuts

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