mirror of
https://github.com/jackc/pgx.git
synced 2025-05-25 00:40:04 +00:00
Initial extraction of pgxtest
- Introduce ConnTestRunner - RunWithQueryExecModes
This commit is contained in:
parent
e392908c72
commit
e18d76b798
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"github.com/jackc/pgx/v5/pgconn"
|
"github.com/jackc/pgx/v5/pgconn"
|
||||||
|
"github.com/jackc/pgx/v5/pgxtest"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -15,7 +16,7 @@ import (
|
|||||||
func TestConnSendBatch(t *testing.T) {
|
func TestConnSendBatch(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
skipCockroachDB(t, conn, "Server serial type is incompatible with test")
|
skipCockroachDB(t, conn, "Server serial type is incompatible with test")
|
||||||
|
|
||||||
sql := `create temporary table ledger(
|
sql := `create temporary table ledger(
|
||||||
@ -149,7 +150,7 @@ func TestConnSendBatch(t *testing.T) {
|
|||||||
func TestConnSendBatchMany(t *testing.T) {
|
func TestConnSendBatchMany(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
sql := `create temporary table ledger(
|
sql := `create temporary table ledger(
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
description varchar not null,
|
description varchar not null,
|
||||||
@ -194,7 +195,7 @@ func TestConnSendBatchWithPreparedStatement(t *testing.T) {
|
|||||||
pgx.QueryExecModeExec,
|
pgx.QueryExecModeExec,
|
||||||
// Don't test simple mode with prepared statements.
|
// Don't test simple mode with prepared statements.
|
||||||
}
|
}
|
||||||
testWithQueryExecModes(t, modes, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, modes, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
skipCockroachDB(t, conn, "Server issues incorrect ParameterDescription (https://github.com/cockroachdb/cockroach/issues/60907)")
|
skipCockroachDB(t, conn, "Server issues incorrect ParameterDescription (https://github.com/cockroachdb/cockroach/issues/60907)")
|
||||||
_, err := conn.Prepare(context.Background(), "ps1", "select n from generate_series(0,$1::int) n")
|
_, err := conn.Prepare(context.Background(), "ps1", "select n from generate_series(0,$1::int) n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -300,7 +301,7 @@ func TestConnSendBatchWithPreparedStatementAndStatementCacheDisabled(t *testing.
|
|||||||
func TestConnSendBatchCloseRowsPartiallyRead(t *testing.T) {
|
func TestConnSendBatchCloseRowsPartiallyRead(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
|
|
||||||
batch := &pgx.Batch{}
|
batch := &pgx.Batch{}
|
||||||
batch.Queue("select n from generate_series(0,5) n")
|
batch.Queue("select n from generate_series(0,5) n")
|
||||||
@ -359,7 +360,7 @@ func TestConnSendBatchCloseRowsPartiallyRead(t *testing.T) {
|
|||||||
func TestConnSendBatchQueryError(t *testing.T) {
|
func TestConnSendBatchQueryError(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
|
|
||||||
batch := &pgx.Batch{}
|
batch := &pgx.Batch{}
|
||||||
batch.Queue("select n from generate_series(0,5) n where 100/(5-n) > 0")
|
batch.Queue("select n from generate_series(0,5) n where 100/(5-n) > 0")
|
||||||
@ -397,7 +398,7 @@ func TestConnSendBatchQueryError(t *testing.T) {
|
|||||||
func TestConnSendBatchQuerySyntaxError(t *testing.T) {
|
func TestConnSendBatchQuerySyntaxError(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
|
|
||||||
batch := &pgx.Batch{}
|
batch := &pgx.Batch{}
|
||||||
batch.Queue("select 1 1")
|
batch.Queue("select 1 1")
|
||||||
@ -421,7 +422,7 @@ func TestConnSendBatchQuerySyntaxError(t *testing.T) {
|
|||||||
func TestConnSendBatchQueryRowInsert(t *testing.T) {
|
func TestConnSendBatchQueryRowInsert(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
|
|
||||||
sql := `create temporary table ledger(
|
sql := `create temporary table ledger(
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
@ -458,7 +459,7 @@ func TestConnSendBatchQueryRowInsert(t *testing.T) {
|
|||||||
func TestConnSendBatchQueryPartialReadInsert(t *testing.T) {
|
func TestConnSendBatchQueryPartialReadInsert(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
|
|
||||||
sql := `create temporary table ledger(
|
sql := `create temporary table ledger(
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
@ -495,7 +496,7 @@ func TestConnSendBatchQueryPartialReadInsert(t *testing.T) {
|
|||||||
func TestTxSendBatch(t *testing.T) {
|
func TestTxSendBatch(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
|
|
||||||
sql := `create temporary table ledger1(
|
sql := `create temporary table ledger1(
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
@ -562,7 +563,7 @@ func TestTxSendBatch(t *testing.T) {
|
|||||||
func TestTxSendBatchRollback(t *testing.T) {
|
func TestTxSendBatchRollback(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
|
|
||||||
sql := `create temporary table ledger1(
|
sql := `create temporary table ledger1(
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
@ -597,7 +598,7 @@ func TestTxSendBatchRollback(t *testing.T) {
|
|||||||
func TestConnBeginBatchDeferredError(t *testing.T) {
|
func TestConnBeginBatchDeferredError(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
|
|
||||||
skipCockroachDB(t, conn, "Server does not support deferred constraint (https://github.com/cockroachdb/cockroach/issues/31632)")
|
skipCockroachDB(t, conn, "Server does not support deferred constraint (https://github.com/cockroachdb/cockroach/issues/31632)")
|
||||||
|
|
||||||
|
23
conn_test.go
23
conn_test.go
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"github.com/jackc/pgx/v5/pgconn"
|
"github.com/jackc/pgx/v5/pgconn"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
"github.com/jackc/pgx/v5/pgxtest"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -198,7 +199,7 @@ func TestParseConfigExtractsDefaultQueryExecMode(t *testing.T) {
|
|||||||
func TestExec(t *testing.T) {
|
func TestExec(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
if results := mustExec(t, conn, "create temporary table foo(id integer primary key);"); results.String() != "CREATE TABLE" {
|
if results := mustExec(t, conn, "create temporary table foo(id integer primary key);"); results.String() != "CREATE TABLE" {
|
||||||
t.Error("Unexpected results from Exec")
|
t.Error("Unexpected results from Exec")
|
||||||
}
|
}
|
||||||
@ -232,7 +233,7 @@ func TestExec(t *testing.T) {
|
|||||||
func TestExecFailure(t *testing.T) {
|
func TestExecFailure(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
if _, err := conn.Exec(context.Background(), "selct;"); err == nil {
|
if _, err := conn.Exec(context.Background(), "selct;"); err == nil {
|
||||||
t.Fatal("Expected SQL syntax error")
|
t.Fatal("Expected SQL syntax error")
|
||||||
}
|
}
|
||||||
@ -248,7 +249,7 @@ func TestExecFailure(t *testing.T) {
|
|||||||
func TestExecFailureWithArguments(t *testing.T) {
|
func TestExecFailureWithArguments(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
_, err := conn.Exec(context.Background(), "selct $1;", 1)
|
_, err := conn.Exec(context.Background(), "selct $1;", 1)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Expected SQL syntax error")
|
t.Fatal("Expected SQL syntax error")
|
||||||
@ -263,7 +264,7 @@ func TestExecFailureWithArguments(t *testing.T) {
|
|||||||
func TestExecContextWithoutCancelation(t *testing.T) {
|
func TestExecContextWithoutCancelation(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
defer cancelFunc()
|
defer cancelFunc()
|
||||||
|
|
||||||
@ -281,7 +282,7 @@ func TestExecContextWithoutCancelation(t *testing.T) {
|
|||||||
func TestExecContextFailureWithoutCancelation(t *testing.T) {
|
func TestExecContextFailureWithoutCancelation(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
defer cancelFunc()
|
defer cancelFunc()
|
||||||
|
|
||||||
@ -303,7 +304,7 @@ func TestExecContextFailureWithoutCancelation(t *testing.T) {
|
|||||||
func TestExecContextFailureWithoutCancelationWithArguments(t *testing.T) {
|
func TestExecContextFailureWithoutCancelationWithArguments(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
defer cancelFunc()
|
defer cancelFunc()
|
||||||
|
|
||||||
@ -680,7 +681,7 @@ func TestFatalTxError(t *testing.T) {
|
|||||||
func TestInsertBoolArray(t *testing.T) {
|
func TestInsertBoolArray(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
if results := mustExec(t, conn, "create temporary table foo(spice bool[]);"); results.String() != "CREATE TABLE" {
|
if results := mustExec(t, conn, "create temporary table foo(spice bool[]);"); results.String() != "CREATE TABLE" {
|
||||||
t.Error("Unexpected results from Exec")
|
t.Error("Unexpected results from Exec")
|
||||||
}
|
}
|
||||||
@ -695,7 +696,7 @@ func TestInsertBoolArray(t *testing.T) {
|
|||||||
func TestInsertTimestampArray(t *testing.T) {
|
func TestInsertTimestampArray(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
if results := mustExec(t, conn, "create temporary table foo(spice timestamp[]);"); results.String() != "CREATE TABLE" {
|
if results := mustExec(t, conn, "create temporary table foo(spice timestamp[]);"); results.String() != "CREATE TABLE" {
|
||||||
t.Error("Unexpected results from Exec")
|
t.Error("Unexpected results from Exec")
|
||||||
}
|
}
|
||||||
@ -819,7 +820,7 @@ func TestConnInitTypeMap(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUnregisteredTypeUsableAsStringArgumentAndBaseResult(t *testing.T) {
|
func TestUnregisteredTypeUsableAsStringArgumentAndBaseResult(t *testing.T) {
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
skipCockroachDB(t, conn, "Server does support domain types (https://github.com/cockroachdb/cockroach/issues/27796)")
|
skipCockroachDB(t, conn, "Server does support domain types (https://github.com/cockroachdb/cockroach/issues/27796)")
|
||||||
|
|
||||||
var n uint64
|
var n uint64
|
||||||
@ -835,7 +836,7 @@ func TestUnregisteredTypeUsableAsStringArgumentAndBaseResult(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDomainType(t *testing.T) {
|
func TestDomainType(t *testing.T) {
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
skipCockroachDB(t, conn, "Server does support domain types (https://github.com/cockroachdb/cockroach/issues/27796)")
|
skipCockroachDB(t, conn, "Server does support domain types (https://github.com/cockroachdb/cockroach/issues/27796)")
|
||||||
|
|
||||||
// Domain type uint64 is a PostgreSQL domain of underlying type numeric.
|
// Domain type uint64 is a PostgreSQL domain of underlying type numeric.
|
||||||
@ -1006,7 +1007,7 @@ func TestStmtCacheInvalidationTx(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestInsertDurationInterval(t *testing.T) {
|
func TestInsertDurationInterval(t *testing.T) {
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
_, err := conn.Exec(context.Background(), "create temporary table t(duration INTERVAL(0) NOT NULL)")
|
_, err := conn.Exec(context.Background(), "create temporary table t(duration INTERVAL(0) NOT NULL)")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
@ -9,40 +9,18 @@ import (
|
|||||||
|
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"github.com/jackc/pgx/v5/pgconn"
|
"github.com/jackc/pgx/v5/pgconn"
|
||||||
|
"github.com/jackc/pgx/v5/pgxtest"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testWithAllQueryExecModes(t *testing.T, f func(t *testing.T, conn *pgx.Conn)) {
|
var defaultConnTestRunner pgxtest.ConnTestRunner
|
||||||
modes := []pgx.QueryExecMode{
|
|
||||||
pgx.QueryExecModeCacheStatement,
|
|
||||||
pgx.QueryExecModeCacheDescribe,
|
|
||||||
pgx.QueryExecModeDescribeExec,
|
|
||||||
pgx.QueryExecModeExec,
|
|
||||||
pgx.QueryExecModeSimpleProtocol,
|
|
||||||
}
|
|
||||||
testWithQueryExecModes(t, modes, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testWithQueryExecModes(t *testing.T, modes []pgx.QueryExecMode, f func(t *testing.T, conn *pgx.Conn)) {
|
func init() {
|
||||||
for _, mode := range modes {
|
defaultConnTestRunner = pgxtest.DefaultConnTestRunner()
|
||||||
t.Run(mode.String(),
|
defaultConnTestRunner.CreateConfig = func(ctx context.Context, t testing.TB) *pgx.ConnConfig {
|
||||||
func(t *testing.T) {
|
|
||||||
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
config, err := pgx.ParseConfig(os.Getenv("PGX_TEST_DATABASE"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
return config
|
||||||
config.DefaultQueryExecMode = mode
|
|
||||||
conn, err := pgx.ConnectConfig(context.Background(), config)
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer func() {
|
|
||||||
err := conn.Close(context.Background())
|
|
||||||
require.NoError(t, err)
|
|
||||||
}()
|
|
||||||
|
|
||||||
f(t, conn)
|
|
||||||
|
|
||||||
ensureConnValid(t, conn)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +62,7 @@ func mustExec(t testing.TB, conn *pgx.Conn, sql string, arguments ...interface{}
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do a simple query to ensure the connection is still usable
|
// Do a simple query to ensure the connection is still usable
|
||||||
func ensureConnValid(t *testing.T, conn *pgx.Conn) {
|
func ensureConnValid(t testing.TB, conn *pgx.Conn) {
|
||||||
var sum, rowCount int32
|
var sum, rowCount int32
|
||||||
|
|
||||||
rows, err := conn.Query(context.Background(), "select generate_series(1,$1)", 10)
|
rows, err := conn.Query(context.Background(), "select generate_series(1,$1)", 10)
|
||||||
|
88
pgxtest/pgxtest.go
Normal file
88
pgxtest/pgxtest.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// Package pgxtest provides utilities for testing pgx and packages that integrate with pgx.
|
||||||
|
package pgxtest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/jackc/pgx/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ConnTestRunner controls how a *pgx.Conn is created and closed by tests. All fields are required. Use DefaultConnTestRunner to get a
|
||||||
|
// ConnTestRunner with reasonable default values.
|
||||||
|
type ConnTestRunner struct {
|
||||||
|
// CreateConfig returns a *pgx.ConnConfig suitable for use with pgx.ConnectConfig.
|
||||||
|
CreateConfig func(ctx context.Context, t testing.TB) *pgx.ConnConfig
|
||||||
|
|
||||||
|
// AfterConnect is called after conn is established. It allows for arbitrary connection setup before a test begins.
|
||||||
|
AfterConnect func(ctx context.Context, t testing.TB, conn *pgx.Conn)
|
||||||
|
|
||||||
|
// AfterTest is called after the test is run. It allows for validating the state of the connection before it is closed.
|
||||||
|
AfterTest func(ctx context.Context, t testing.TB, conn *pgx.Conn)
|
||||||
|
|
||||||
|
// CloseConn closes conn.
|
||||||
|
CloseConn func(ctx context.Context, t testing.TB, conn *pgx.Conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultConnTestRunner returns a new ConnTestRunner with all fields set to reasonable default values.
|
||||||
|
func DefaultConnTestRunner() ConnTestRunner {
|
||||||
|
return ConnTestRunner{
|
||||||
|
CreateConfig: func(ctx context.Context, t testing.TB) *pgx.ConnConfig {
|
||||||
|
config, err := pgx.ParseConfig("")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ParseConfig failed: %v", err)
|
||||||
|
}
|
||||||
|
return config
|
||||||
|
},
|
||||||
|
AfterConnect: func(ctx context.Context, t testing.TB, conn *pgx.Conn) {},
|
||||||
|
AfterTest: func(ctx context.Context, t testing.TB, conn *pgx.Conn) {},
|
||||||
|
CloseConn: func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
|
err := conn.Close(ctx)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Close failed: %v", err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctr *ConnTestRunner) RunTest(ctx context.Context, t testing.TB, f func(ctx context.Context, t testing.TB, conn *pgx.Conn)) {
|
||||||
|
config := ctr.CreateConfig(ctx, t)
|
||||||
|
conn, err := pgx.ConnectConfig(ctx, config)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ConnectConfig failed: %v", err)
|
||||||
|
}
|
||||||
|
defer ctr.CloseConn(ctx, t, conn)
|
||||||
|
|
||||||
|
ctr.AfterConnect(ctx, t, conn)
|
||||||
|
f(ctx, t, conn)
|
||||||
|
ctr.AfterTest(ctx, t, conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RunWithQueryExecModes runs a f in a new test for each element of modes with a new connection created using connector.
|
||||||
|
// If modes is nil all pgx.QueryExecModes are tested.
|
||||||
|
func RunWithQueryExecModes(ctx context.Context, t *testing.T, ctr ConnTestRunner, modes []pgx.QueryExecMode, f func(ctx context.Context, t testing.TB, conn *pgx.Conn)) {
|
||||||
|
if modes == nil {
|
||||||
|
modes = []pgx.QueryExecMode{
|
||||||
|
pgx.QueryExecModeCacheStatement,
|
||||||
|
pgx.QueryExecModeCacheDescribe,
|
||||||
|
pgx.QueryExecModeDescribeExec,
|
||||||
|
pgx.QueryExecModeExec,
|
||||||
|
pgx.QueryExecModeSimpleProtocol,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, mode := range modes {
|
||||||
|
ctrWithMode := ctr
|
||||||
|
ctrWithMode.CreateConfig = func(ctx context.Context, t testing.TB) *pgx.ConnConfig {
|
||||||
|
config := ctr.CreateConfig(ctx, t)
|
||||||
|
config.DefaultQueryExecMode = mode
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run(mode.String(),
|
||||||
|
func(t *testing.T) {
|
||||||
|
ctrWithMode.RunTest(ctx, t, f)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"github.com/jackc/pgx/v5/pgconn"
|
"github.com/jackc/pgx/v5/pgconn"
|
||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
|
"github.com/jackc/pgx/v5/pgxtest"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -1866,7 +1867,7 @@ func TestQueryErrorWithDisabledStatementCache(t *testing.T) {
|
|||||||
func TestConnQueryFunc(t *testing.T) {
|
func TestConnQueryFunc(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
var actualResults []interface{}
|
var actualResults []interface{}
|
||||||
|
|
||||||
var a, b int
|
var a, b int
|
||||||
@ -1895,7 +1896,7 @@ func TestConnQueryFunc(t *testing.T) {
|
|||||||
func TestConnQueryFuncScanError(t *testing.T) {
|
func TestConnQueryFuncScanError(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
var actualResults []interface{}
|
var actualResults []interface{}
|
||||||
|
|
||||||
var a, b int
|
var a, b int
|
||||||
@ -1917,7 +1918,7 @@ func TestConnQueryFuncScanError(t *testing.T) {
|
|||||||
func TestConnQueryFuncAbort(t *testing.T) {
|
func TestConnQueryFuncAbort(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
var a, b int
|
var a, b int
|
||||||
ct, err := conn.QueryFunc(
|
ct, err := conn.QueryFunc(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
|
"github.com/jackc/pgx/v5/pgxtest"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -18,7 +19,7 @@ import (
|
|||||||
func TestDateTranscode(t *testing.T) {
|
func TestDateTranscode(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
dates := []time.Time{
|
dates := []time.Time{
|
||||||
time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC),
|
time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
time.Date(1000, 1, 1, 0, 0, 0, 0, time.UTC),
|
time.Date(1000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
@ -57,7 +58,7 @@ func TestDateTranscode(t *testing.T) {
|
|||||||
func TestTimestampTzTranscode(t *testing.T) {
|
func TestTimestampTzTranscode(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
inputTime := time.Date(2013, 1, 2, 3, 4, 5, 6000, time.Local)
|
inputTime := time.Date(2013, 1, 2, 3, 4, 5, 6000, time.Local)
|
||||||
|
|
||||||
var outputTime time.Time
|
var outputTime time.Time
|
||||||
@ -77,7 +78,7 @@ func TestTimestampTzTranscode(t *testing.T) {
|
|||||||
func TestJSONAndJSONBTranscode(t *testing.T) {
|
func TestJSONAndJSONBTranscode(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
for _, typename := range []string{"json", "jsonb"} {
|
for _, typename := range []string{"json", "jsonb"} {
|
||||||
if _, ok := conn.TypeMap().TypeForName(typename); !ok {
|
if _, ok := conn.TypeMap().TypeForName(typename); !ok {
|
||||||
continue // No JSON/JSONB type -- must be running against old PostgreSQL
|
continue // No JSON/JSONB type -- must be running against old PostgreSQL
|
||||||
@ -109,7 +110,7 @@ func TestJSONAndJSONBTranscodeExtendedOnly(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testJSONString(t *testing.T, conn *pgx.Conn, typename string) {
|
func testJSONString(t testing.TB, conn *pgx.Conn, typename string) {
|
||||||
input := `{"key": "value"}`
|
input := `{"key": "value"}`
|
||||||
expectedOutput := map[string]string{"key": "value"}
|
expectedOutput := map[string]string{"key": "value"}
|
||||||
var output map[string]string
|
var output map[string]string
|
||||||
@ -125,7 +126,7 @@ func testJSONString(t *testing.T, conn *pgx.Conn, typename string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testJSONStringPointer(t *testing.T, conn *pgx.Conn, typename string) {
|
func testJSONStringPointer(t testing.TB, conn *pgx.Conn, typename string) {
|
||||||
input := `{"key": "value"}`
|
input := `{"key": "value"}`
|
||||||
expectedOutput := map[string]string{"key": "value"}
|
expectedOutput := map[string]string{"key": "value"}
|
||||||
var output map[string]string
|
var output map[string]string
|
||||||
@ -233,7 +234,7 @@ func testJSONStruct(t *testing.T, conn *pgx.Conn, typename string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustParseCIDR(t *testing.T, s string) *net.IPNet {
|
func mustParseCIDR(t testing.TB, s string) *net.IPNet {
|
||||||
_, ipnet, err := net.ParseCIDR(s)
|
_, ipnet, err := net.ParseCIDR(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -245,7 +246,7 @@ func mustParseCIDR(t *testing.T, s string) *net.IPNet {
|
|||||||
func TestInetCIDRTranscodeIPNet(t *testing.T) {
|
func TestInetCIDRTranscodeIPNet(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
value *net.IPNet
|
value *net.IPNet
|
||||||
@ -296,7 +297,7 @@ func TestInetCIDRTranscodeIPNet(t *testing.T) {
|
|||||||
func TestInetCIDRTranscodeIP(t *testing.T) {
|
func TestInetCIDRTranscodeIP(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
value net.IP
|
value net.IP
|
||||||
@ -360,7 +361,7 @@ func TestInetCIDRTranscodeIP(t *testing.T) {
|
|||||||
func TestInetCIDRArrayTranscodeIPNet(t *testing.T) {
|
func TestInetCIDRArrayTranscodeIPNet(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
value []*net.IPNet
|
value []*net.IPNet
|
||||||
@ -423,7 +424,7 @@ func TestInetCIDRArrayTranscodeIPNet(t *testing.T) {
|
|||||||
func TestInetCIDRArrayTranscodeIP(t *testing.T) {
|
func TestInetCIDRArrayTranscodeIP(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
value []net.IP
|
value []net.IP
|
||||||
@ -509,7 +510,7 @@ func TestInetCIDRArrayTranscodeIP(t *testing.T) {
|
|||||||
func TestInetCIDRTranscodeWithJustIP(t *testing.T) {
|
func TestInetCIDRTranscodeWithJustIP(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
value string
|
value string
|
||||||
@ -555,16 +556,16 @@ func TestInetCIDRTranscodeWithJustIP(t *testing.T) {
|
|||||||
func TestArrayDecoding(t *testing.T) {
|
func TestArrayDecoding(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
sql string
|
sql string
|
||||||
query interface{}
|
query interface{}
|
||||||
scan interface{}
|
scan interface{}
|
||||||
assert func(*testing.T, interface{}, interface{})
|
assert func(testing.TB, interface{}, interface{})
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"select $1::bool[]", []bool{true, false, true}, &[]bool{},
|
"select $1::bool[]", []bool{true, false, true}, &[]bool{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t testing.TB, query, scan interface{}) {
|
||||||
if !reflect.DeepEqual(query, *(scan.(*[]bool))) {
|
if !reflect.DeepEqual(query, *(scan.(*[]bool))) {
|
||||||
t.Errorf("failed to encode bool[]")
|
t.Errorf("failed to encode bool[]")
|
||||||
}
|
}
|
||||||
@ -572,7 +573,7 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"select $1::smallint[]", []int16{2, 4, 484, 32767}, &[]int16{},
|
"select $1::smallint[]", []int16{2, 4, 484, 32767}, &[]int16{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t testing.TB, query, scan interface{}) {
|
||||||
if !reflect.DeepEqual(query, *(scan.(*[]int16))) {
|
if !reflect.DeepEqual(query, *(scan.(*[]int16))) {
|
||||||
t.Errorf("failed to encode smallint[]")
|
t.Errorf("failed to encode smallint[]")
|
||||||
}
|
}
|
||||||
@ -580,7 +581,7 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"select $1::smallint[]", []uint16{2, 4, 484, 32767}, &[]uint16{},
|
"select $1::smallint[]", []uint16{2, 4, 484, 32767}, &[]uint16{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t testing.TB, query, scan interface{}) {
|
||||||
if !reflect.DeepEqual(query, *(scan.(*[]uint16))) {
|
if !reflect.DeepEqual(query, *(scan.(*[]uint16))) {
|
||||||
t.Errorf("failed to encode smallint[]")
|
t.Errorf("failed to encode smallint[]")
|
||||||
}
|
}
|
||||||
@ -588,7 +589,7 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"select $1::int[]", []int32{2, 4, 484}, &[]int32{},
|
"select $1::int[]", []int32{2, 4, 484}, &[]int32{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t testing.TB, query, scan interface{}) {
|
||||||
if !reflect.DeepEqual(query, *(scan.(*[]int32))) {
|
if !reflect.DeepEqual(query, *(scan.(*[]int32))) {
|
||||||
t.Errorf("failed to encode int[]")
|
t.Errorf("failed to encode int[]")
|
||||||
}
|
}
|
||||||
@ -596,7 +597,7 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"select $1::int[]", []uint32{2, 4, 484, 2147483647}, &[]uint32{},
|
"select $1::int[]", []uint32{2, 4, 484, 2147483647}, &[]uint32{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t testing.TB, query, scan interface{}) {
|
||||||
if !reflect.DeepEqual(query, *(scan.(*[]uint32))) {
|
if !reflect.DeepEqual(query, *(scan.(*[]uint32))) {
|
||||||
t.Errorf("failed to encode int[]")
|
t.Errorf("failed to encode int[]")
|
||||||
}
|
}
|
||||||
@ -604,7 +605,7 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"select $1::bigint[]", []int64{2, 4, 484, 9223372036854775807}, &[]int64{},
|
"select $1::bigint[]", []int64{2, 4, 484, 9223372036854775807}, &[]int64{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t testing.TB, query, scan interface{}) {
|
||||||
if !reflect.DeepEqual(query, *(scan.(*[]int64))) {
|
if !reflect.DeepEqual(query, *(scan.(*[]int64))) {
|
||||||
t.Errorf("failed to encode bigint[]")
|
t.Errorf("failed to encode bigint[]")
|
||||||
}
|
}
|
||||||
@ -612,7 +613,7 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"select $1::bigint[]", []uint64{2, 4, 484, 9223372036854775807}, &[]uint64{},
|
"select $1::bigint[]", []uint64{2, 4, 484, 9223372036854775807}, &[]uint64{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t testing.TB, query, scan interface{}) {
|
||||||
if !reflect.DeepEqual(query, *(scan.(*[]uint64))) {
|
if !reflect.DeepEqual(query, *(scan.(*[]uint64))) {
|
||||||
t.Errorf("failed to encode bigint[]")
|
t.Errorf("failed to encode bigint[]")
|
||||||
}
|
}
|
||||||
@ -620,7 +621,7 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"select $1::text[]", []string{"it's", "over", "9000!"}, &[]string{},
|
"select $1::text[]", []string{"it's", "over", "9000!"}, &[]string{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t testing.TB, query, scan interface{}) {
|
||||||
if !reflect.DeepEqual(query, *(scan.(*[]string))) {
|
if !reflect.DeepEqual(query, *(scan.(*[]string))) {
|
||||||
t.Errorf("failed to encode text[]")
|
t.Errorf("failed to encode text[]")
|
||||||
}
|
}
|
||||||
@ -628,7 +629,7 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"select $1::timestamptz[]", []time.Time{time.Unix(323232, 0), time.Unix(3239949334, 00)}, &[]time.Time{},
|
"select $1::timestamptz[]", []time.Time{time.Unix(323232, 0), time.Unix(3239949334, 00)}, &[]time.Time{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t testing.TB, query, scan interface{}) {
|
||||||
queryTimeSlice := query.([]time.Time)
|
queryTimeSlice := query.([]time.Time)
|
||||||
scanTimeSlice := *(scan.(*[]time.Time))
|
scanTimeSlice := *(scan.(*[]time.Time))
|
||||||
require.Equal(t, len(queryTimeSlice), len(scanTimeSlice))
|
require.Equal(t, len(queryTimeSlice), len(scanTimeSlice))
|
||||||
@ -639,7 +640,7 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"select $1::bytea[]", [][]byte{{0, 1, 2, 3}, {4, 5, 6, 7}}, &[][]byte{},
|
"select $1::bytea[]", [][]byte{{0, 1, 2, 3}, {4, 5, 6, 7}}, &[][]byte{},
|
||||||
func(t *testing.T, query, scan interface{}) {
|
func(t testing.TB, query, scan interface{}) {
|
||||||
queryBytesSliceSlice := query.([][]byte)
|
queryBytesSliceSlice := query.([][]byte)
|
||||||
scanBytesSliceSlice := *(scan.(*[][]byte))
|
scanBytesSliceSlice := *(scan.(*[][]byte))
|
||||||
if len(queryBytesSliceSlice) != len(scanBytesSliceSlice) {
|
if len(queryBytesSliceSlice) != len(scanBytesSliceSlice) {
|
||||||
@ -671,7 +672,7 @@ func TestArrayDecoding(t *testing.T) {
|
|||||||
func TestEmptyArrayDecoding(t *testing.T) {
|
func TestEmptyArrayDecoding(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
var val []string
|
var val []string
|
||||||
|
|
||||||
err := conn.QueryRow(context.Background(), "select array[]::text[]").Scan(&val)
|
err := conn.QueryRow(context.Background(), "select array[]::text[]").Scan(&val)
|
||||||
@ -716,7 +717,7 @@ func TestEmptyArrayDecoding(t *testing.T) {
|
|||||||
func TestPointerPointer(t *testing.T) {
|
func TestPointerPointer(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
skipCockroachDB(t, conn, "Server auto converts ints to bigint and test relies on exact types")
|
skipCockroachDB(t, conn, "Server auto converts ints to bigint and test relies on exact types")
|
||||||
|
|
||||||
type allTypes struct {
|
type allTypes struct {
|
||||||
@ -802,7 +803,7 @@ func TestPointerPointer(t *testing.T) {
|
|||||||
func TestPointerPointerNonZero(t *testing.T) {
|
func TestPointerPointerNonZero(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
f := "foo"
|
f := "foo"
|
||||||
dest := &f
|
dest := &f
|
||||||
|
|
||||||
@ -819,7 +820,7 @@ func TestPointerPointerNonZero(t *testing.T) {
|
|||||||
func TestEncodeTypeRename(t *testing.T) {
|
func TestEncodeTypeRename(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
type _int int
|
type _int int
|
||||||
inInt := _int(1)
|
inInt := _int(1)
|
||||||
var outInt _int
|
var outInt _int
|
||||||
@ -979,7 +980,7 @@ func TestEncodeTypeRename(t *testing.T) {
|
|||||||
func TestRowsScanNilThenScanValue(t *testing.T) {
|
func TestRowsScanNilThenScanValue(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testWithAllQueryExecModes(t, func(t *testing.T, conn *pgx.Conn) {
|
pgxtest.RunWithQueryExecModes(context.Background(), t, defaultConnTestRunner, nil, func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
|
||||||
sql := `select null as a, null as b
|
sql := `select null as a, null as b
|
||||||
union
|
union
|
||||||
select 1, 2
|
select 1, 2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user