forked from TrueCloudLab/restic
214 lines
5 KiB
Go
214 lines
5 KiB
Go
|
// Copyright 2015 Google Inc. All rights reserved.
|
||
|
// Use of this source code is governed by the Apache 2.0
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package search
|
||
|
|
||
|
import (
|
||
|
"reflect"
|
||
|
"testing"
|
||
|
)
|
||
|
|
||
|
func TestLoadingStruct(t *testing.T) {
|
||
|
testCases := []struct {
|
||
|
desc string
|
||
|
fields []Field
|
||
|
meta *DocumentMetadata
|
||
|
want interface{}
|
||
|
wantErr bool
|
||
|
}{
|
||
|
{
|
||
|
desc: "Basic struct",
|
||
|
fields: []Field{
|
||
|
{Name: "Name", Value: "Gopher"},
|
||
|
{Name: "Legs", Value: float64(4)},
|
||
|
},
|
||
|
want: &struct {
|
||
|
Name string
|
||
|
Legs float64
|
||
|
}{"Gopher", 4},
|
||
|
},
|
||
|
{
|
||
|
desc: "Struct with tags",
|
||
|
fields: []Field{
|
||
|
{Name: "Name", Value: "Gopher"},
|
||
|
{Name: "about", Value: "Likes slide rules."},
|
||
|
},
|
||
|
meta: &DocumentMetadata{Facets: []Facet{
|
||
|
{Name: "Legs", Value: float64(4)},
|
||
|
{Name: "Fur", Value: Atom("furry")},
|
||
|
}},
|
||
|
want: &struct {
|
||
|
Name string
|
||
|
Info string `search:"about"`
|
||
|
Legs float64 `search:",facet"`
|
||
|
Fuzz Atom `search:"Fur,facet"`
|
||
|
}{"Gopher", "Likes slide rules.", 4, Atom("furry")},
|
||
|
},
|
||
|
{
|
||
|
desc: "Bad field from tag",
|
||
|
want: &struct {
|
||
|
AlphaBeta string `search:"αβ"`
|
||
|
}{},
|
||
|
wantErr: true,
|
||
|
},
|
||
|
{
|
||
|
desc: "Ignore missing field",
|
||
|
fields: []Field{
|
||
|
{Name: "Meaning", Value: float64(42)},
|
||
|
},
|
||
|
want: &struct{}{},
|
||
|
wantErr: true,
|
||
|
},
|
||
|
{
|
||
|
desc: "Ignore unsettable field",
|
||
|
fields: []Field{
|
||
|
{Name: "meaning", Value: float64(42)},
|
||
|
},
|
||
|
want: &struct{ meaning float64 }{}, // field not populated.
|
||
|
wantErr: true,
|
||
|
},
|
||
|
{
|
||
|
desc: "Error on missing facet",
|
||
|
meta: &DocumentMetadata{Facets: []Facet{
|
||
|
{Name: "Set", Value: Atom("yes")},
|
||
|
{Name: "Missing", Value: Atom("no")},
|
||
|
}},
|
||
|
want: &struct {
|
||
|
Set Atom `search:",facet"`
|
||
|
}{Atom("yes")},
|
||
|
wantErr: true,
|
||
|
},
|
||
|
{
|
||
|
desc: "Error on unsettable facet",
|
||
|
meta: &DocumentMetadata{Facets: []Facet{
|
||
|
{Name: "Set", Value: Atom("yes")},
|
||
|
{Name: "unset", Value: Atom("no")},
|
||
|
}},
|
||
|
want: &struct {
|
||
|
Set Atom `search:",facet"`
|
||
|
}{Atom("yes")},
|
||
|
wantErr: true,
|
||
|
},
|
||
|
{
|
||
|
desc: "Error setting ignored field",
|
||
|
fields: []Field{
|
||
|
{Name: "Set", Value: "yes"},
|
||
|
{Name: "Ignored", Value: "no"},
|
||
|
},
|
||
|
want: &struct {
|
||
|
Set string
|
||
|
Ignored string `search:"-"`
|
||
|
}{Set: "yes"},
|
||
|
wantErr: true,
|
||
|
},
|
||
|
{
|
||
|
desc: "Error setting ignored facet",
|
||
|
meta: &DocumentMetadata{Facets: []Facet{
|
||
|
{Name: "Set", Value: Atom("yes")},
|
||
|
{Name: "Ignored", Value: Atom("no")},
|
||
|
}},
|
||
|
want: &struct {
|
||
|
Set Atom `search:",facet"`
|
||
|
Ignored Atom `search:"-,facet"`
|
||
|
}{Set: Atom("yes")},
|
||
|
wantErr: true,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, tt := range testCases {
|
||
|
// Make a pointer to an empty version of what want points to.
|
||
|
dst := reflect.New(reflect.TypeOf(tt.want).Elem()).Interface()
|
||
|
err := loadStructWithMeta(dst, tt.fields, tt.meta)
|
||
|
if err != nil != tt.wantErr {
|
||
|
t.Errorf("%s: got err %v; want err %t", tt.desc, err, tt.wantErr)
|
||
|
continue
|
||
|
}
|
||
|
if !reflect.DeepEqual(dst, tt.want) {
|
||
|
t.Errorf("%s: doesn't match\ngot: %v\nwant: %v", tt.desc, dst, tt.want)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestSavingStruct(t *testing.T) {
|
||
|
testCases := []struct {
|
||
|
desc string
|
||
|
doc interface{}
|
||
|
wantFields []Field
|
||
|
wantFacets []Facet
|
||
|
}{
|
||
|
{
|
||
|
desc: "Basic struct",
|
||
|
doc: &struct {
|
||
|
Name string
|
||
|
Legs float64
|
||
|
}{"Gopher", 4},
|
||
|
wantFields: []Field{
|
||
|
{Name: "Name", Value: "Gopher"},
|
||
|
{Name: "Legs", Value: float64(4)},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
desc: "Struct with tags",
|
||
|
doc: &struct {
|
||
|
Name string
|
||
|
Info string `search:"about"`
|
||
|
Legs float64 `search:",facet"`
|
||
|
Fuzz Atom `search:"Fur,facet"`
|
||
|
}{"Gopher", "Likes slide rules.", 4, Atom("furry")},
|
||
|
wantFields: []Field{
|
||
|
{Name: "Name", Value: "Gopher"},
|
||
|
{Name: "about", Value: "Likes slide rules."},
|
||
|
},
|
||
|
wantFacets: []Facet{
|
||
|
{Name: "Legs", Value: float64(4)},
|
||
|
{Name: "Fur", Value: Atom("furry")},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
desc: "Ignore unexported struct fields",
|
||
|
doc: &struct {
|
||
|
Name string
|
||
|
info string
|
||
|
Legs float64 `search:",facet"`
|
||
|
fuzz Atom `search:",facet"`
|
||
|
}{"Gopher", "Likes slide rules.", 4, Atom("furry")},
|
||
|
wantFields: []Field{
|
||
|
{Name: "Name", Value: "Gopher"},
|
||
|
},
|
||
|
wantFacets: []Facet{
|
||
|
{Name: "Legs", Value: float64(4)},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
desc: "Ignore fields marked -",
|
||
|
doc: &struct {
|
||
|
Name string
|
||
|
Info string `search:"-"`
|
||
|
Legs float64 `search:",facet"`
|
||
|
Fuzz Atom `search:"-,facet"`
|
||
|
}{"Gopher", "Likes slide rules.", 4, Atom("furry")},
|
||
|
wantFields: []Field{
|
||
|
{Name: "Name", Value: "Gopher"},
|
||
|
},
|
||
|
wantFacets: []Facet{
|
||
|
{Name: "Legs", Value: float64(4)},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, tt := range testCases {
|
||
|
fields, meta, err := saveStructWithMeta(tt.doc)
|
||
|
if err != nil {
|
||
|
t.Errorf("%s: got err %v; want nil", tt.desc, err)
|
||
|
continue
|
||
|
}
|
||
|
if !reflect.DeepEqual(fields, tt.wantFields) {
|
||
|
t.Errorf("%s: fields don't match\ngot: %v\nwant: %v", tt.desc, fields, tt.wantFields)
|
||
|
}
|
||
|
if facets := meta.Facets; !reflect.DeepEqual(facets, tt.wantFacets) {
|
||
|
t.Errorf("%s: facets don't match\ngot: %v\nwant: %v", tt.desc, facets, tt.wantFacets)
|
||
|
}
|
||
|
}
|
||
|
}
|