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  }