1 package pgtype_test
2
3 import (
4 "reflect"
5 "testing"
6
7 "github.com/jackc/pgtype"
8 "github.com/jackc/pgtype/testutil"
9 )
10
11 func TestHstoreTranscode(t *testing.T) {
12 text := func(s string) pgtype.Text {
13 return pgtype.Text{String: s, Status: pgtype.Present}
14 }
15
16 values := []interface{}{
17 &pgtype.Hstore{Map: map[string]pgtype.Text{}, Status: pgtype.Present},
18 &pgtype.Hstore{Map: map[string]pgtype.Text{"foo": text(""), "bar": text(""), "baz": text("123")}, Status: pgtype.Present},
19 &pgtype.Hstore{Map: map[string]pgtype.Text{"foo": text("bar")}, Status: pgtype.Present},
20 &pgtype.Hstore{Map: map[string]pgtype.Text{"foo": text("bar"), "baz": text("quz")}, Status: pgtype.Present},
21 &pgtype.Hstore{Map: map[string]pgtype.Text{"NULL": text("bar")}, Status: pgtype.Present},
22 &pgtype.Hstore{Map: map[string]pgtype.Text{"foo": text("NULL")}, Status: pgtype.Present},
23 &pgtype.Hstore{Map: map[string]pgtype.Text{"": text("bar")}, Status: pgtype.Present},
24 &pgtype.Hstore{
25 Map: map[string]pgtype.Text{"a": text("a"), "b": {Status: pgtype.Null}, "c": text("c"), "d": {Status: pgtype.Null}, "e": text("e")},
26 Status: pgtype.Present,
27 },
28 &pgtype.Hstore{Status: pgtype.Null},
29 }
30
31 specialStrings := []string{
32 `"`,
33 `'`,
34 `\`,
35 `\\`,
36 `=>`,
37 ` `,
38 `\ / / \\ => " ' " '`,
39 }
40 for _, s := range specialStrings {
41
42 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{s + "foo": text("bar")}, Status: pgtype.Present})
43 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{"foo" + s + "bar": text("bar")}, Status: pgtype.Present})
44 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{"foo" + s: text("bar")}, Status: pgtype.Present})
45 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{s: text("bar")}, Status: pgtype.Present})
46
47
48 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{"foo": text(s + "bar")}, Status: pgtype.Present})
49 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{"foo": text("foo" + s + "bar")}, Status: pgtype.Present})
50 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{"foo": text("foo" + s)}, Status: pgtype.Present})
51 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{"foo": text(s)}, Status: pgtype.Present})
52 }
53
54 testutil.TestSuccessfulTranscodeEqFunc(t, "hstore", values, func(ai, bi interface{}) bool {
55 a := ai.(pgtype.Hstore)
56 b := bi.(pgtype.Hstore)
57
58 if len(a.Map) != len(b.Map) || a.Status != b.Status {
59 return false
60 }
61
62 for k := range a.Map {
63 if a.Map[k] != b.Map[k] {
64 return false
65 }
66 }
67
68 return true
69 })
70 }
71
72 func TestHstoreTranscodeNullable(t *testing.T) {
73 text := func(s string, status pgtype.Status) pgtype.Text {
74 return pgtype.Text{String: s, Status: status}
75 }
76
77 values := []interface{}{
78 &pgtype.Hstore{Map: map[string]pgtype.Text{"foo": text("", pgtype.Null)}, Status: pgtype.Present},
79 }
80
81 specialStrings := []string{
82 `"`,
83 `'`,
84 `\`,
85 `\\`,
86 `=>`,
87 ` `,
88 `\ / / \\ => " ' " '`,
89 }
90 for _, s := range specialStrings {
91
92 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{s + "foo": text("", pgtype.Null)}, Status: pgtype.Present})
93 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{"foo" + s + "bar": text("", pgtype.Null)}, Status: pgtype.Present})
94 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{"foo" + s: text("", pgtype.Null)}, Status: pgtype.Present})
95 values = append(values, &pgtype.Hstore{Map: map[string]pgtype.Text{s: text("", pgtype.Null)}, Status: pgtype.Present})
96 }
97
98 testutil.TestSuccessfulTranscodeEqFunc(t, "hstore", values, func(ai, bi interface{}) bool {
99 a := ai.(pgtype.Hstore)
100 b := bi.(pgtype.Hstore)
101
102 if len(a.Map) != len(b.Map) || a.Status != b.Status {
103 return false
104 }
105
106 for k := range a.Map {
107 if a.Map[k] != b.Map[k] {
108 return false
109 }
110 }
111
112 return true
113 })
114 }
115
116 func TestHstoreSet(t *testing.T) {
117 successfulTests := []struct {
118 src map[string]string
119 result pgtype.Hstore
120 }{
121 {src: map[string]string{"foo": "bar"}, result: pgtype.Hstore{Map: map[string]pgtype.Text{"foo": {String: "bar", Status: pgtype.Present}}, Status: pgtype.Present}},
122 }
123
124 for i, tt := range successfulTests {
125 var dst pgtype.Hstore
126 err := dst.Set(tt.src)
127 if err != nil {
128 t.Errorf("%d: %v", i, err)
129 }
130
131 if !reflect.DeepEqual(dst, tt.result) {
132 t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.src, tt.result, dst)
133 }
134 }
135 }
136
137 func TestHstoreSetNullable(t *testing.T) {
138 successfulTests := []struct {
139 src map[string]*string
140 result pgtype.Hstore
141 }{
142 {src: map[string]*string{"foo": nil}, result: pgtype.Hstore{Map: map[string]pgtype.Text{"foo": {Status: pgtype.Null}}, Status: pgtype.Present}},
143 }
144
145 for i, tt := range successfulTests {
146 var dst pgtype.Hstore
147 err := dst.Set(tt.src)
148 if err != nil {
149 t.Errorf("%d: %v", i, err)
150 }
151
152 if !reflect.DeepEqual(dst, tt.result) {
153 t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.src, tt.result, dst)
154 }
155 }
156 }
157
158 func TestHstoreAssignTo(t *testing.T) {
159 var m map[string]string
160
161 simpleTests := []struct {
162 src pgtype.Hstore
163 dst *map[string]string
164 expected map[string]string
165 }{
166 {src: pgtype.Hstore{Map: map[string]pgtype.Text{"foo": {String: "bar", Status: pgtype.Present}}, Status: pgtype.Present}, dst: &m, expected: map[string]string{"foo": "bar"}},
167 {src: pgtype.Hstore{Status: pgtype.Null}, dst: &m, expected: ((map[string]string)(nil))},
168 }
169
170 for i, tt := range simpleTests {
171 err := tt.src.AssignTo(tt.dst)
172 if err != nil {
173 t.Errorf("%d: %v", i, err)
174 }
175
176 if !reflect.DeepEqual(*tt.dst, tt.expected) {
177 t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, *tt.dst)
178 }
179 }
180 }
181
182 func TestHstoreAssignToNullable(t *testing.T) {
183 var m map[string]*string
184 strPtr := func(str string) *string { return &str }
185
186 simpleTests := []struct {
187 src pgtype.Hstore
188 dst *map[string]*string
189 expected map[string]*string
190 }{
191 {src: pgtype.Hstore{Map: map[string]pgtype.Text{"foo": {Status: pgtype.Null}, "bar": {String: "1", Status: pgtype.Present}, "baz": {String: "2", Status: pgtype.Present}}, Status: pgtype.Present}, dst: &m, expected: map[string]*string{"foo": nil, "bar": strPtr("1"), "baz": strPtr("2")}},
192 {src: pgtype.Hstore{Status: pgtype.Null}, dst: &m, expected: ((map[string]*string)(nil))},
193 }
194
195 for i, tt := range simpleTests {
196 err := tt.src.AssignTo(tt.dst)
197 if err != nil {
198 t.Errorf("%d: %v", i, err)
199 }
200
201 if !reflect.DeepEqual(*tt.dst, tt.expected) {
202 t.Errorf("%d: expected %v to assign %v, but result was %v", i, tt.src, tt.expected, *tt.dst)
203 }
204 }
205 }
206
View as plain text