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/pgtype"
9 "github.com/jackc/pgx/v5/pgxtest"
10 "github.com/stretchr/testify/require"
11 )
12
13 type someFmtStringer struct{}
14
15 func (someFmtStringer) String() string {
16 return "some fmt.Stringer"
17 }
18
19 func TestTextCodec(t *testing.T) {
20 for _, pgTypeName := range []string{"text", "varchar"} {
21 pgxtest.RunValueRoundTripTests(context.Background(), t, defaultConnTestRunner, nil, pgTypeName, []pgxtest.ValueRoundTripTest{
22 {
23 pgtype.Text{String: "", Valid: true},
24 new(pgtype.Text),
25 isExpectedEq(pgtype.Text{String: "", Valid: true}),
26 },
27 {
28 pgtype.Text{String: "foo", Valid: true},
29 new(pgtype.Text),
30 isExpectedEq(pgtype.Text{String: "foo", Valid: true}),
31 },
32 {nil, new(pgtype.Text), isExpectedEq(pgtype.Text{})},
33 {"foo", new(string), isExpectedEq("foo")},
34 {someFmtStringer{}, new(string), isExpectedEq("some fmt.Stringer")},
35 })
36 }
37 }
38
39
40
41
42
43
44
45
46
47
48
49 func TestTextCodecName(t *testing.T) {
50 pgxtest.RunValueRoundTripTests(context.Background(), t, defaultConnTestRunner, nil, "name", []pgxtest.ValueRoundTripTest{
51 {
52 pgtype.Text{String: "", Valid: true},
53 new(pgtype.Text),
54 isExpectedEq(pgtype.Text{String: "", Valid: true}),
55 },
56 {
57 pgtype.Text{String: "foo", Valid: true},
58 new(pgtype.Text),
59 isExpectedEq(pgtype.Text{String: "foo", Valid: true}),
60 },
61 {nil, new(pgtype.Text), isExpectedEq(pgtype.Text{})},
62 {"foo", new(string), isExpectedEq("foo")},
63 })
64 }
65
66
67 func TestTextCodecBPChar(t *testing.T) {
68 skipCockroachDB(t, "Server does not properly handle bpchar with multi-byte character")
69
70 pgxtest.RunValueRoundTripTests(context.Background(), t, defaultConnTestRunner, nil, "char(3)", []pgxtest.ValueRoundTripTest{
71 {
72 pgtype.Text{String: "a ", Valid: true},
73 new(pgtype.Text),
74 isExpectedEq(pgtype.Text{String: "a ", Valid: true}),
75 },
76 {nil, new(pgtype.Text), isExpectedEq(pgtype.Text{})},
77 {" ", new(string), isExpectedEq(" ")},
78 {"", new(string), isExpectedEq(" ")},
79 {" 嗨 ", new(string), isExpectedEq(" 嗨 ")},
80 })
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 func TestTextCodecACLItem(t *testing.T) {
97 ctr := defaultConnTestRunner
98 ctr.AfterConnect = func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
99 pgxtest.SkipCockroachDB(t, conn, "Server does not support type aclitem")
100 }
101
102 pgxtest.RunValueRoundTripTests(context.Background(), t, ctr, nil, "aclitem", []pgxtest.ValueRoundTripTest{
103 {
104 pgtype.Text{String: "postgres=arwdDxt/postgres", Valid: true},
105 new(pgtype.Text),
106 isExpectedEq(pgtype.Text{String: "postgres=arwdDxt/postgres", Valid: true}),
107 },
108 {pgtype.Text{}, new(pgtype.Text), isExpectedEq(pgtype.Text{})},
109 {nil, new(pgtype.Text), isExpectedEq(pgtype.Text{})},
110 })
111 }
112
113 func TestTextCodecACLItemRoleWithSpecialCharacters(t *testing.T) {
114 ctr := defaultConnTestRunner
115 ctr.AfterConnect = func(ctx context.Context, t testing.TB, conn *pgx.Conn) {
116 pgxtest.SkipCockroachDB(t, conn, "Server does not support type aclitem")
117
118
119
120 roleWithSpecialCharacters := ` tricky, ' } " \ test user `
121
122 commandTag, err := conn.Exec(ctx, `select * from pg_roles where rolname = $1`, roleWithSpecialCharacters)
123 require.NoError(t, err)
124
125 if commandTag.RowsAffected() == 0 {
126 t.Skipf("Role with special characters does not exist.")
127 }
128 }
129
130 pgxtest.RunValueRoundTripTests(context.Background(), t, ctr, nil, "aclitem", []pgxtest.ValueRoundTripTest{
131 {
132 pgtype.Text{String: `postgres=arwdDxt/" tricky, ' } "" \ test user "`, Valid: true},
133 new(pgtype.Text),
134 isExpectedEq(pgtype.Text{String: `postgres=arwdDxt/" tricky, ' } "" \ test user "`, Valid: true}),
135 },
136 })
137 }
138
139 func TestTextMarshalJSON(t *testing.T) {
140 successfulTests := []struct {
141 source pgtype.Text
142 result string
143 }{
144 {source: pgtype.Text{String: ""}, result: "null"},
145 {source: pgtype.Text{String: "a", Valid: true}, result: "\"a\""},
146 }
147 for i, tt := range successfulTests {
148 r, err := tt.source.MarshalJSON()
149 if err != nil {
150 t.Errorf("%d: %v", i, err)
151 }
152
153 if string(r) != tt.result {
154 t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, string(r))
155 }
156 }
157 }
158
159 func TestTextUnmarshalJSON(t *testing.T) {
160 successfulTests := []struct {
161 source string
162 result pgtype.Text
163 }{
164 {source: "null", result: pgtype.Text{String: ""}},
165 {source: "\"a\"", result: pgtype.Text{String: "a", Valid: true}},
166 }
167 for i, tt := range successfulTests {
168 var r pgtype.Text
169 err := r.UnmarshalJSON([]byte(tt.source))
170 if err != nil {
171 t.Errorf("%d: %v", i, err)
172 }
173
174 if r != tt.result {
175 t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r)
176 }
177 }
178 }
179
View as plain text