github.com/jackc/pgx/v5@v5.5.5/pgtype/jsonb_test.go (about) 1 package pgtype_test 2 3 import ( 4 "context" 5 "testing" 6 7 pgx "github.com/jackc/pgx/v5" 8 "github.com/jackc/pgx/v5/pgxtest" 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestJSONBTranscode(t *testing.T) { 13 type jsonStruct struct { 14 Name string `json:"name"` 15 Age int `json:"age"` 16 } 17 18 pgxtest.RunValueRoundTripTests(context.Background(), t, defaultConnTestRunner, nil, "jsonb", []pgxtest.ValueRoundTripTest{ 19 {nil, new(*jsonStruct), isExpectedEq((*jsonStruct)(nil))}, 20 {map[string]any(nil), new(*string), isExpectedEq((*string)(nil))}, 21 {map[string]any(nil), new([]byte), isExpectedEqBytes([]byte(nil))}, 22 {[]byte(nil), new([]byte), isExpectedEqBytes([]byte(nil))}, 23 {nil, new([]byte), isExpectedEqBytes([]byte(nil))}, 24 }) 25 26 pgxtest.RunValueRoundTripTests(context.Background(), t, defaultConnTestRunner, pgxtest.KnownOIDQueryExecModes, "jsonb", []pgxtest.ValueRoundTripTest{ 27 {[]byte("{}"), new([]byte), isExpectedEqBytes([]byte("{}"))}, 28 {[]byte("null"), new([]byte), isExpectedEqBytes([]byte("null"))}, 29 {[]byte("42"), new([]byte), isExpectedEqBytes([]byte("42"))}, 30 {[]byte(`"hello"`), new([]byte), isExpectedEqBytes([]byte(`"hello"`))}, 31 {[]byte(`"hello"`), new(string), isExpectedEq(`"hello"`)}, 32 {map[string]any{"foo": "bar"}, new(map[string]any), isExpectedEqMap(map[string]any{"foo": "bar"})}, 33 {jsonStruct{Name: "Adam", Age: 10}, new(jsonStruct), isExpectedEq(jsonStruct{Name: "Adam", Age: 10})}, 34 }) 35 } 36 37 func TestJSONBCodecUnmarshalSQLNull(t *testing.T) { 38 defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, t testing.TB, conn *pgx.Conn) { 39 // Slices are nilified 40 slice := []string{"foo", "bar", "baz"} 41 err := conn.QueryRow(ctx, "select null::jsonb").Scan(&slice) 42 require.NoError(t, err) 43 require.Nil(t, slice) 44 45 // Maps are nilified 46 m := map[string]any{"foo": "bar"} 47 err = conn.QueryRow(ctx, "select null::jsonb").Scan(&m) 48 require.NoError(t, err) 49 require.Nil(t, m) 50 51 m = map[string]interface{}{"foo": "bar"} 52 err = conn.QueryRow(ctx, "select null::jsonb").Scan(&m) 53 require.NoError(t, err) 54 require.Nil(t, m) 55 56 // Pointer to pointer are nilified 57 n := 42 58 p := &n 59 err = conn.QueryRow(ctx, "select null::jsonb").Scan(&p) 60 require.NoError(t, err) 61 require.Nil(t, p) 62 63 // A string cannot scan a NULL. 64 str := "foobar" 65 err = conn.QueryRow(ctx, "select null::jsonb").Scan(&str) 66 require.EqualError(t, err, "can't scan into dest[0]: cannot scan NULL into *string") 67 68 // A non-string cannot scan a NULL. 69 err = conn.QueryRow(ctx, "select null::jsonb").Scan(&n) 70 require.EqualError(t, err, "can't scan into dest[0]: cannot scan NULL into *int") 71 }) 72 } 73 74 // https://github.com/jackc/pgx/issues/1681 75 func TestJSONBCodecEncodeJSONMarshalerThatCanBeWrapped(t *testing.T) { 76 defaultConnTestRunner.RunTest(context.Background(), t, func(ctx context.Context, t testing.TB, conn *pgx.Conn) { 77 var jsonStr string 78 err := conn.QueryRow(context.Background(), "select $1::jsonb", &ParentIssue1681{}).Scan(&jsonStr) 79 require.NoError(t, err) 80 require.Equal(t, `{"custom": "thing"}`, jsonStr) // Note that unlike json, jsonb reformats the JSON string. 81 }) 82 }