github.com/thiagoyeds/go-cloud@v0.26.0/docstore/driver/document_test.go (about) 1 // Copyright 2019 The Go Cloud Development Kit Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package driver 16 17 import ( 18 "fmt" 19 "sort" 20 "strings" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 "gocloud.dev/gcerrors" 25 ) 26 27 type S struct { 28 I int 29 M map[string]interface{} 30 } 31 32 func TestNewDocument(t *testing.T) { 33 for _, test := range []struct { 34 in interface{} 35 wantErr bool 36 wantMap bool 37 }{ 38 {in: nil, wantErr: true}, 39 {in: map[string]interface{}{}, wantMap: true}, 40 {in: map[string]interface{}(nil), wantErr: true}, 41 {in: S{}, wantErr: true}, 42 {in: &S{}, wantMap: false}, 43 {in: (*S)(nil), wantErr: true}, 44 {in: map[string]bool{}, wantErr: true}, 45 } { 46 got, err := NewDocument(test.in) 47 if err != nil { 48 if !test.wantErr { 49 t.Errorf("%#v: got %v, did not want error", test.in, err) 50 } 51 if c := gcerrors.Code(err); c != gcerrors.InvalidArgument { 52 t.Errorf("%#v: got error code %s, want InvalidArgument", test.in, c) 53 } 54 continue 55 } 56 if test.wantErr { 57 t.Errorf("%#v: got nil, want error", test.in) 58 continue 59 } 60 if g := (got.m != nil); g != test.wantMap { 61 t.Errorf("%#v: got map: %t, want map: %t", test.in, g, test.wantMap) 62 } 63 } 64 } 65 66 func TestGet(t *testing.T) { 67 in := map[string]interface{}{ 68 "S": &S{ 69 I: 2, 70 M: map[string]interface{}{ 71 "J": 3, 72 "T": &S{I: 4}, 73 }, 74 }, 75 } 76 doc, err := NewDocument(in) 77 if err != nil { 78 t.Fatal(err) 79 } 80 81 for _, test := range []struct { 82 fp string 83 want interface{} 84 }{ 85 {"S.I", 2}, 86 {"S.i", 2}, 87 {"S.M.J", 3}, 88 {"S.m.J", 3}, 89 {"S.M.T.I", 4}, 90 {"S.m.T.i", 4}, 91 } { 92 fp := strings.Split(test.fp, ".") 93 got, err := doc.Get(fp) 94 if err != nil { 95 t.Fatal(err) 96 } 97 if !cmp.Equal(got, test.want) { 98 t.Errorf("%s: got %v, want %v", got, test.fp, test.want) 99 } 100 } 101 } 102 103 func TestSet(t *testing.T) { 104 in := map[string]interface{}{ 105 "S": &S{ 106 I: 2, 107 M: map[string]interface{}{ 108 "J": 3, 109 "T": &S{I: 4}, 110 }, 111 }, 112 } 113 doc, err := NewDocument(in) 114 if err != nil { 115 t.Fatal(err) 116 } 117 for _, test := range []struct { 118 fp string 119 val interface{} 120 }{ 121 {"S.I", -1}, 122 {"S.i", -2}, 123 {"S.M.J", -3}, 124 {"S.m.J", -4}, 125 {"S.M.T.I", -5}, 126 {"S.m.T.i", -6}, 127 {"new.field", -7}, 128 } { 129 fp := strings.Split(test.fp, ".") 130 if err := doc.Set(fp, test.val); err != nil { 131 t.Fatalf("%q: %v", test.fp, err) 132 } 133 got, err := doc.Get(fp) 134 if err != nil { 135 t.Fatalf("%s: %v", test.fp, err) 136 } 137 if !cmp.Equal(got, test.val) { 138 t.Errorf("got %v, want %v", got, test.val) 139 } 140 } 141 } 142 143 func TestGetField(t *testing.T) { 144 type S struct { 145 A int `docstore:"a"` 146 B interface{} `docstore:"b"` 147 } 148 149 want := 1 150 for _, in := range []interface{}{ 151 map[string]interface{}{"a": want, "b": nil}, 152 &S{A: want, B: nil}, 153 } { 154 t.Run(fmt.Sprint(in), func(t *testing.T) { 155 doc, err := NewDocument(in) 156 if err != nil { 157 t.Fatal(err) 158 } 159 got, err := doc.GetField("a") 160 if err != nil { 161 t.Fatal(err) 162 } 163 if got != want { 164 t.Errorf("got %v, want %v", got, want) 165 } 166 167 got, err = doc.GetField("b") 168 if err != nil { 169 t.Fatal(err) 170 } 171 if got != nil { 172 t.Errorf("got %v, want nil", got) 173 } 174 175 _, err = doc.GetField("c") 176 if gcerrors.Code(err) != gcerrors.NotFound { 177 t.Fatalf("got %v, want NotFound", err) 178 } 179 }) 180 } 181 } 182 183 func TestFieldNames(t *testing.T) { 184 type E struct { 185 C int 186 } 187 type S struct { 188 A int `docstore:"a"` 189 B int 190 E 191 } 192 193 for _, test := range []struct { 194 in interface{} 195 want []string 196 }{ 197 { 198 map[string]interface{}{"a": 1, "b": map[string]interface{}{"c": 2}}, 199 []string{"a", "b"}, 200 }, 201 { 202 &S{}, 203 []string{"B", "C", "a"}, 204 }, 205 } { 206 doc, err := NewDocument(test.in) 207 if err != nil { 208 t.Fatal(err) 209 } 210 got := doc.FieldNames() 211 sort.Strings(got) 212 if !cmp.Equal(got, test.want) { 213 t.Errorf("%v: got %v, want %v", test.in, got, test.want) 214 } 215 } 216 } 217 218 func TestHasField(t *testing.T) { 219 type withRev struct { 220 Rev interface{} 221 } 222 type withoutRev struct { 223 W withRev 224 } 225 226 for _, tc := range []struct { 227 in interface{} 228 want bool 229 }{ 230 { 231 in: &withRev{}, 232 want: true, 233 }, 234 { 235 in: &withoutRev{}, 236 want: false, 237 }, 238 { 239 in: map[string]interface{}{"Rev": nil}, 240 want: true, 241 }, 242 { 243 in: map[string]interface{}{}, 244 want: false, 245 }, 246 } { 247 doc, err := NewDocument(tc.in) 248 if err != nil { 249 t.Fatal(err) 250 } 251 on := doc.HasField("Rev") 252 if on != tc.want { 253 t.Errorf("%v: got %v want %v", tc.in, on, tc.want) 254 } 255 } 256 } 257 258 func TestHasFieldFold(t *testing.T) { 259 type withRev struct { 260 Rev interface{} 261 } 262 type withoutRev struct { 263 W withRev 264 } 265 266 for _, tc := range []struct { 267 in interface{} 268 want bool 269 }{ 270 { 271 in: &withRev{}, 272 want: true, 273 }, 274 { 275 in: &withoutRev{}, 276 want: false, 277 }, 278 } { 279 doc, err := NewDocument(tc.in) 280 if err != nil { 281 t.Fatal(err) 282 } 283 for _, f := range []string{"Rev", "rev", "REV"} { 284 on := doc.HasFieldFold(f) 285 if on != tc.want { 286 t.Errorf("%v: got %v want %v", tc.in, on, tc.want) 287 } 288 } 289 } 290 }