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  }