golang.org/x/build@v0.0.0-20240506185731-218518f32b70/internal/datastore/fake/client_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package fake 6 7 import ( 8 "bytes" 9 "context" 10 "encoding/gob" 11 "testing" 12 "time" 13 14 "cloud.google.com/go/datastore" 15 "github.com/google/go-cmp/cmp" 16 ) 17 18 type author struct { 19 Name string 20 } 21 22 func TestClientGet(t *testing.T) { 23 cases := []struct { 24 desc string 25 db map[string]map[string][]byte 26 key *datastore.Key 27 dst interface{} 28 want *author 29 wantErr bool 30 }{ 31 { 32 desc: "correct key", 33 db: map[string]map[string][]byte{ 34 "Author": {datastore.NameKey("Author", "The Trial", nil).Encode(): gobEncode(t, &author{Name: "Kafka"})}, 35 }, 36 key: datastore.NameKey("Author", "The Trial", nil), 37 dst: new(author), 38 want: &author{Name: "Kafka"}, 39 }, 40 { 41 desc: "incorrect key errors", 42 db: map[string]map[string][]byte{ 43 "Author": {datastore.NameKey("Author", "The Trial", nil).Encode(): gobEncode(t, &author{Name: "Kafka"})}, 44 }, 45 key: datastore.NameKey("Author", "The Go Programming Language", nil), 46 dst: new(author), 47 wantErr: true, 48 }, 49 { 50 desc: "nil dst errors", 51 db: map[string]map[string][]byte{ 52 "Author": {datastore.NameKey("Author", "The Trial", nil).Encode(): gobEncode(t, &author{Name: "Kafka"})}, 53 }, 54 key: datastore.NameKey("Author", "The Go Programming Language", nil), 55 wantErr: true, 56 }, 57 { 58 desc: "incorrect dst type errors", 59 db: map[string]map[string][]byte{ 60 "Author": {datastore.NameKey("Author", "The Trial", nil).Encode(): gobEncode(t, &author{Name: "Kafka"})}, 61 }, 62 key: datastore.NameKey("Author", "The Go Programming Language", nil), 63 dst: &time.Time{}, 64 wantErr: true, 65 }, 66 { 67 desc: "non-pointer dst errors", 68 db: map[string]map[string][]byte{ 69 "Author": {datastore.NameKey("Author", "The Trial", nil).Encode(): gobEncode(t, &author{Name: "Kafka"})}, 70 }, 71 key: datastore.NameKey("Author", "The Go Programming Language", nil), 72 dst: author{}, 73 wantErr: true, 74 }, 75 { 76 desc: "nil key", 77 db: map[string]map[string][]byte{ 78 "Author": {datastore.NameKey("Author", "The Trial", nil).Encode(): gobEncode(t, &author{Name: "Kafka"})}, 79 }, 80 key: nil, 81 dst: new(author), 82 wantErr: true, 83 }, 84 { 85 desc: "nil dst errors", 86 db: map[string]map[string][]byte{ 87 "Author": {datastore.NameKey("Author", "The Trial", nil).Encode(): gobEncode(t, &author{Name: "Kafka"})}, 88 }, 89 key: datastore.NameKey("Author", "The Go Programming Language", nil), 90 dst: nil, 91 wantErr: true, 92 }, 93 { 94 desc: "empty db errors", 95 key: datastore.NameKey("Author", "The Go Programming Language", nil), 96 dst: nil, 97 wantErr: true, 98 }, 99 } 100 for _, c := range cases { 101 t.Run(c.desc, func(t *testing.T) { 102 cl := &Client{db: c.db} 103 104 if err := cl.Get(context.Background(), c.key, c.dst); (err != nil) != c.wantErr { 105 t.Fatalf("cl.Get(_, %v, %v) = %q, wantErr: %v", c.key, c.dst, err, c.wantErr) 106 } 107 if c.wantErr { 108 return 109 } 110 if diff := cmp.Diff(c.want, c.dst); diff != "" { 111 t.Errorf("author mismatch (-want +got):\n%s", diff) 112 } 113 }) 114 } 115 } 116 117 func TestClientGetAll(t *testing.T) { 118 cases := []struct { 119 desc string 120 db map[string]map[string][]byte 121 query *datastore.Query 122 want []*author 123 wantKeys []*datastore.Key 124 wantErr bool 125 }{ 126 { 127 desc: "all of a Kind", 128 db: map[string]map[string][]byte{ 129 "Author": {datastore.NameKey("Author", "The Trial", nil).Encode(): gobEncode(t, &author{Name: "Kafka"})}, 130 }, 131 query: datastore.NewQuery("Author"), 132 wantKeys: []*datastore.Key{datastore.NameKey("Author", "The Trial", nil)}, 133 want: []*author{{Name: "Kafka"}}, 134 }, 135 { 136 desc: "all of a non-existent kind", 137 db: map[string]map[string][]byte{ 138 "Author": {datastore.NameKey("Author", "The Trial", nil).Encode(): gobEncode(t, &author{Name: "Kafka"})}, 139 }, 140 query: datastore.NewQuery("Book"), 141 wantErr: false, 142 }, 143 } 144 for _, c := range cases { 145 t.Run(c.desc, func(t *testing.T) { 146 cl := &Client{db: c.db} 147 148 var got []*author 149 keys, err := cl.GetAll(context.Background(), c.query, &got) 150 if (err != nil) != c.wantErr { 151 t.Fatalf("cl.Getall(_, %v, %v) = %q, wantErr: %v", c.query, got, err, c.wantErr) 152 } 153 if diff := cmp.Diff(c.want, got); diff != "" { 154 t.Errorf("authors mismatch (-want +got):\n%s", diff) 155 } 156 if diff := cmp.Diff(c.wantKeys, keys); diff != "" { 157 t.Errorf("keys mismatch (-want +got):\n%s", diff) 158 } 159 }) 160 } 161 } 162 163 func TestClientPut(t *testing.T) { 164 cl := &Client{} 165 src := &author{Name: "Kafka"} 166 key := datastore.NameKey("Author", "The Trial", nil) 167 168 gotKey, err := cl.Put(context.Background(), key, src) 169 if err != nil { 170 t.Fatalf("cl.Put(_, %v, %v) = %v, %q, wanted no error", gotKey, key, src, err) 171 } 172 got := new(author) 173 gobDecode(t, cl.db["Author"][key.Encode()], got) 174 175 if diff := cmp.Diff(src, got); diff != "" { 176 t.Errorf("author mismatch (-want +got):\n%s", diff) 177 } 178 if diff := cmp.Diff(key, gotKey); diff != "" { 179 t.Errorf("keys mismatch (-want +got):\n%s", diff) 180 } 181 } 182 183 // gobEncode encodes src with gob, returning the encoded byte slice. 184 // It will report errors on the provided testing.T. 185 func gobEncode(t *testing.T, src interface{}) []byte { 186 t.Helper() 187 dst := bytes.Buffer{} 188 e := gob.NewEncoder(&dst) 189 if err := e.Encode(src); err != nil { 190 t.Errorf("e.Encode(%v) = %q, wanted no error", src, err) 191 return nil 192 } 193 return dst.Bytes() 194 } 195 196 // gobDecode decodes v into dst with gob. It will report errors on the 197 // provided testing.T. 198 func gobDecode(t *testing.T, v []byte, dst interface{}) { 199 t.Helper() 200 d := gob.NewDecoder(bytes.NewReader(v)) 201 if err := d.Decode(dst); err != nil { 202 t.Errorf("d.Decode(%v) = %q, wanted no error", dst, err) 203 } 204 }