go.mercari.io/datastore@v1.8.2/prop_test.go (about) 1 package datastore 2 3 import ( 4 "context" 5 "testing" 6 ) 7 8 func TestSaveStruct_Basic(t *testing.T) { 9 ctx := context.Background() 10 11 type Data struct { 12 Str string 13 } 14 15 ps, err := SaveStruct(ctx, &Data{"Test"}) 16 if err != nil { 17 t.Fatal(err) 18 } 19 20 if v := len(ps); v != 1 { 21 t.Fatalf("unexpected: %v", v) 22 } 23 24 p := ps[0] 25 if v := p.Name; v != "Str" { 26 t.Fatalf("unexpected: %v", v) 27 } 28 if v, ok := p.Value.(string); !ok { 29 t.Fatalf("unexpected: %v", ok) 30 } else if v != "Test" { 31 t.Fatalf("unexpected: %v", v) 32 } 33 } 34 35 func TestSaveStruct_Object(t *testing.T) { 36 ctx := context.Background() 37 38 type Data struct { 39 Str string 40 } 41 42 ps, err := SaveStruct(ctx, &Data{Str: "Str"}) 43 if err != nil { 44 t.Fatal(err) 45 } 46 47 if v := len(ps); v != 1 { 48 t.Fatalf("unexpected: %v", v) 49 } 50 p := ps[0] 51 if v := p.Name; v != "Str" { 52 t.Fatalf("unexpected: %v", v) 53 } 54 if v := p.Value.(string); v != "Str" { 55 t.Fatalf("unexpected: %v", v) 56 } 57 } 58 59 func TestSaveStruct_ObjectPropertyRename(t *testing.T) { 60 ctx := context.Background() 61 62 type Data struct { 63 Str string `datastore:"modified"` 64 } 65 66 ps, err := SaveStruct(ctx, &Data{Str: "Str"}) 67 if err != nil { 68 t.Fatal(err) 69 } 70 71 if v := len(ps); v != 1 { 72 t.Fatalf("unexpected: %v", v) 73 } 74 p := ps[0] 75 if v := p.Name; v != "modified" { 76 t.Fatalf("unexpected: %v", v) 77 } 78 if v := p.Value.(string); v != "Str" { 79 t.Fatalf("unexpected: %v", v) 80 } 81 } 82 83 func TestSaveStruct_EmbedStruct(t *testing.T) { 84 ctx := context.Background() 85 86 type Embed struct { 87 Inner string 88 } 89 90 type Data struct { 91 Embed 92 93 Str string 94 } 95 96 ps, err := SaveStruct(ctx, &Data{ 97 Embed: Embed{ 98 Inner: "Inner", 99 }, 100 Str: "Str", 101 }) 102 if err != nil { 103 t.Fatal(err) 104 } 105 106 if v := len(ps); v != 2 { 107 t.Fatalf("unexpected: %v", v) 108 } 109 { 110 p := ps[0] 111 if v := p.Name; v != "Inner" { 112 t.Fatalf("unexpected: %v", v) 113 } 114 if v := p.Value.(string); v != "Inner" { 115 t.Fatalf("unexpected: %v", v) 116 } 117 } 118 { 119 p := ps[1] 120 if v := p.Name; v != "Str" { 121 t.Fatalf("unexpected: %v", v) 122 } 123 if v := p.Value.(string); v != "Str" { 124 t.Fatalf("unexpected: %v", v) 125 } 126 } 127 } 128 129 func TestSaveStruct_WithEmbedPtrStruct(t *testing.T) { 130 ctx := context.Background() 131 132 type Inner struct { 133 A string 134 B string 135 } 136 137 type Data struct { 138 *Inner 139 } 140 141 { 142 ps, err := SaveStruct(ctx, &Data{Inner: &Inner{A: "A", B: "B"}}) 143 if err != nil { 144 t.Fatal(err) 145 } 146 if v := len(ps); v != 2 { 147 t.Errorf("unexpected: %v", v) 148 } 149 150 obj := &Data{} 151 err = LoadStruct(ctx, obj, ps) 152 if err != nil { 153 t.Fatal(err) 154 } 155 if v := obj.Inner; v == nil { 156 t.Errorf("unexpected: %v", v) 157 } 158 } 159 { 160 ps, err := SaveStruct(ctx, &Data{}) 161 if err != nil { 162 t.Fatal(err) 163 } 164 if v := len(ps); v != 0 { 165 t.Errorf("unexpected: %v", v) 166 } 167 obj := &Data{} 168 err = LoadStruct(ctx, obj, ps) 169 if err != nil { 170 t.Fatal(err) 171 } 172 if v := obj.Inner; v != nil { 173 t.Errorf("unexpected: %v", v) 174 } 175 } 176 } 177 178 func TestSaveStruct_WithPtrStruct(t *testing.T) { 179 // TODO Why this test is failed? 180 t.SkipNow() 181 182 ctx := context.Background() 183 184 type Inner struct { 185 A string 186 B string 187 } 188 189 type Data struct { 190 Inner *Inner `datastore:",flatten"` 191 } 192 193 { 194 ps, err := SaveStruct(ctx, &Data{Inner: &Inner{A: "A", B: "B"}}) 195 if err != nil { 196 t.Fatal(err) 197 } 198 if v := len(ps); v != 2 { 199 t.Errorf("unexpected: %v", v) 200 } 201 202 obj := &Data{} 203 err = LoadStruct(ctx, obj, ps) 204 if err != nil { 205 t.Fatal(err) 206 } 207 if v := obj.Inner; v == nil { 208 t.Errorf("unexpected: %v", v) 209 } 210 } 211 { 212 ps, err := SaveStruct(ctx, &Data{}) 213 if err != nil { 214 t.Fatal(err) 215 } 216 if v := len(ps); v != 0 { 217 t.Errorf("unexpected: %v", v) 218 } 219 obj := &Data{} 220 err = LoadStruct(ctx, obj, ps) 221 if err != nil { 222 t.Fatal(err) 223 } 224 if v := obj.Inner; v != nil { 225 t.Errorf("unexpected: %v", v) 226 } 227 } 228 } 229 230 func TestSaveStruct_ObjectHasObjectSlice(t *testing.T) { 231 ctx := context.Background() 232 233 type Inner struct { 234 A string 235 B string 236 } 237 238 type Data struct { 239 Slice []Inner 240 } 241 242 ps, err := SaveStruct(ctx, &Data{ 243 Slice: []Inner{ 244 {A: "A1", B: "B1"}, 245 {A: "A2", B: "B2"}, 246 {A: "A3", B: "B3"}, 247 }, 248 }) 249 if err != nil { 250 t.Fatal(err) 251 } 252 253 if v := len(ps); v != 1 { 254 t.Fatalf("unexpected: %v", v) 255 } 256 p := ps[0] 257 if v := p.Name; v != "Slice" { 258 t.Fatalf("unexpected: %v", v) 259 } 260 es := p.Value.([]interface{}) 261 if v := len(es); v != 3 { 262 t.Fatalf("unexpected: %v", v) 263 } 264 265 expects := []struct { 266 Name string 267 Value string 268 }{ 269 {"A", "A1"}, 270 {"B", "B1"}, 271 {"A", "A2"}, 272 {"B", "B2"}, 273 {"A", "A3"}, 274 {"B", "B3"}, 275 } 276 277 for idx, entity := range es { 278 e := entity.(*Entity) 279 if v := len(e.Properties); v != 2 { 280 t.Fatalf("unexpected: %v", v) 281 } 282 for pIdx, p := range e.Properties { 283 expect := expects[idx*len(e.Properties)+pIdx] 284 if v := p.Name; v != expect.Name { 285 t.Errorf("unexpected: %v", v) 286 } 287 if v := p.Value.(string); v != expect.Value { 288 t.Errorf("unexpected: %v", v) 289 } 290 } 291 } 292 } 293 294 func TestLoadStruct_Basic(t *testing.T) { 295 ctx := context.Background() 296 297 type Data struct { 298 Str string 299 } 300 301 var ps PropertyList 302 ps = append(ps, Property{ 303 Name: "Str", 304 Value: "Test", 305 }) 306 obj := &Data{} 307 err := LoadStruct(ctx, obj, ps) 308 if err != nil { 309 t.Fatal(err) 310 } 311 312 if v := obj.Str; v != "Test" { 313 t.Fatalf("unexpected: %v", v) 314 } 315 } 316 317 func TestLoadStruct_IgnoreMismatchProperty(t *testing.T) { 318 ctx := context.Background() 319 320 type Data1 struct { 321 A string 322 B string 323 } 324 type Data2 struct { 325 A string 326 } 327 328 ps, err := SaveStruct(ctx, &Data1{}) 329 if err != nil { 330 t.Fatal(err) 331 } 332 333 err = LoadStruct(ctx, &Data2{}, ps) 334 if err != nil { 335 t.Fatal(err) 336 } 337 } 338 339 func TestLoadStruct_CheckMismatchProperty(t *testing.T) { 340 ctx := context.Background() 341 342 SuppressErrFieldMismatch = false 343 defer func() { 344 SuppressErrFieldMismatch = true 345 }() 346 347 type Data1 struct { 348 A string 349 B string 350 } 351 type Data2 struct { 352 A string 353 } 354 355 ps, err := SaveStruct(ctx, &Data1{}) 356 if err != nil { 357 t.Fatal(err) 358 } 359 360 err = LoadStruct(ctx, &Data2{}, ps) 361 if err == nil { 362 t.Fatal(err) 363 } else if _, ok := err.(*ErrFieldMismatch); ok { 364 // ok! 365 } else { 366 t.Fatal(err) 367 } 368 }