From 4c735746e88b63044e4c2f9d41c8bff8382acf54 Mon Sep 17 00:00:00 2001 From: MTRNord Date: Sat, 10 Mar 2018 15:34:26 +0100 Subject: [PATCH] [CircleCI-Service] Apply changes that got requested by t3chguy Signed-off-by: MTRNord --- .../go-neb/services/circleci/circleci.go | 74 +- .../go-neb/services/circleci/types.go | 4 +- .../go-neb/services/circleci/util.go | 61 - vendor/src/github.com/fatih/structs/LICENSE | 21 - vendor/src/github.com/fatih/structs/README.md | 163 -- vendor/src/github.com/fatih/structs/field.go | 141 -- .../github.com/fatih/structs/field_test.go | 397 ----- .../src/github.com/fatih/structs/structs.go | 586 ------- .../fatih/structs/structs_example_test.go | 351 ---- .../github.com/fatih/structs/structs_test.go | 1453 ----------------- vendor/src/github.com/fatih/structs/tags.go | 32 - .../src/github.com/fatih/structs/tags_test.go | 46 - 12 files changed, 42 insertions(+), 3287 deletions(-) delete mode 100644 src/github.com/matrix-org/go-neb/services/circleci/util.go delete mode 100644 vendor/src/github.com/fatih/structs/LICENSE delete mode 100644 vendor/src/github.com/fatih/structs/README.md delete mode 100644 vendor/src/github.com/fatih/structs/field.go delete mode 100644 vendor/src/github.com/fatih/structs/field_test.go delete mode 100644 vendor/src/github.com/fatih/structs/structs.go delete mode 100644 vendor/src/github.com/fatih/structs/structs_example_test.go delete mode 100644 vendor/src/github.com/fatih/structs/structs_test.go delete mode 100644 vendor/src/github.com/fatih/structs/tags.go delete mode 100644 vendor/src/github.com/fatih/structs/tags_test.go diff --git a/src/github.com/matrix-org/go-neb/services/circleci/circleci.go b/src/github.com/matrix-org/go-neb/services/circleci/circleci.go index a96d7ad..4bb234c 100644 --- a/src/github.com/matrix-org/go-neb/services/circleci/circleci.go +++ b/src/github.com/matrix-org/go-neb/services/circleci/circleci.go @@ -12,10 +12,7 @@ import ( "github.com/matrix-org/go-neb/database" "github.com/matrix-org/go-neb/types" "github.com/matrix-org/gomatrix" - "io/ioutil" "strconv" - "github.com/fatih/structs" - "time" ) // ServiceType of the CircleCI service. @@ -29,8 +26,6 @@ const DefaultTemplate = (`%{repository_slug}#%{build_num} (%{branch} - %{commit} // Matches 'owner/repo' var ownerRepoRegex = regexp.MustCompile(`^([A-z0-9-_.]+)/([A-z0-9-_.]+)$`) -var httpClient = &http.Client{} - // Service contains the Config fields for the CircleCI service. // // This service will send notifications into a Matrix room when CircleCI sends @@ -92,7 +87,7 @@ type Service struct { } // Converts a webhook notification into a map of template var name to value -func notifToTemplate(n WebhookNotification) map[string]string { +func notifToTemplate(n webhookNotification) map[string]string { t := make(map[string]string) //Get Payload to variable p := n.Payload @@ -106,7 +101,7 @@ func notifToTemplate(n WebhookNotification) map[string]string { shaLength = 10 } t["commit"] = p.VcsRevision[:shaLength] // shortened commit SHA - t["author"] = p.CommitterName // author: commit author name + t["author"] = p.CommitterName // author: commit author name // commit_message: commit message of build // commit_subject: first line of the commit message t["commit_message"] = p.Body @@ -117,25 +112,47 @@ func notifToTemplate(n WebhookNotification) map[string]string { } t["message"] = p.Outcome // message: CircleCI message to the build - if !p.StartTime.IsZero() && !p.StopTime.IsZero() { - t["duration"] = p.StopTime.Sub(p.StartTime).String() - t["elapsed_time"] = t["duration"] + if !p.StartTime.IsZero() && !p.StopTime.IsZero() { + t["duration"] = p.StopTime.Sub(p.StartTime).String() + t["elapsed_time"] = t["duration"] } t["build_url"] = p.BuildURL - // Make the full struct data into the Map without manual mapping - rawT := structs.Map(p) - for key, value := range rawT { - switch value := value.(type) { - case string: - t[CamelCaseToUnderscore(key)] = value - case int: - t[CamelCaseToUnderscore(key)] = strconv.Itoa(value) - case time.Time: - t[CamelCaseToUnderscore(key)] = value.String() - } + //Map json fields + t["vcs_url"] = p.VcsURL + t["build_num"] = strconv.Itoa(p.BuildNum) + t["branch"] = p.Branch + t["vcs_revision"] = p.VcsRevision + t["committer_name"] = p.CommitterName + t["committer_email"] = p.CommitterEmail + t["subject"] = p.Subject + t["body"] = p.Body + t["why"] = p.Why + switch value := p.DontBuild.(type) { + case string: + t["dont_build"] = value + case int: + t["dont_build"] = strconv.Itoa(value) + case bool: + t["dont_build"] = strconv.FormatBool(value) + } + t["queued_at"] = p.QueuedAt.String() + t["start_time"] = p.StartTime.String() + t["stop_time"] = p.StopTime.String() + t["build_time_millis"] = strconv.Itoa(p.BuildTimeMillis) + t["username"] = p.Username + t["reponame"] = p.Reponame + t["lifecycle"] = p.Lifecycle + t["outcome"] = p.Outcome + t["status"] = p.Status + switch value := p.RetryOf.(type) { + case string: + t["retry_of"] = value + case int: + t["retry_of"] = strconv.Itoa(value) } + //TODO: Figure out how to map the Steps Slice/Array return t } @@ -163,19 +180,8 @@ func outputForTemplate(circleciTmpl string, tmpl map[string]string) (out string) // // See https://circleci.com/docs/1.0/configuration/#notify for more information. func (s *Service) OnReceiveWebhook(w http.ResponseWriter, req *http.Request, cli *gomatrix.Client) { - body, err := ioutil.ReadAll(req.Body) - if err != nil { - log.WithFields(log.Fields{ - "Body": req.Body, - log.ErrorKey: err, - }).Warn("Failed to Read Body") - w.WriteHeader(403) - return - } - //fmt.Printf("%s\n", body) - - var notif WebhookNotification - if err := json.Unmarshal(body, ¬if); err != nil { + var notif webhookNotification + if err := json.NewDecoder(req.Body).Decode(¬if); err != nil { log.WithError(err).Error("CircleCI webhook received an invalid JSON body") w.WriteHeader(400) return diff --git a/src/github.com/matrix-org/go-neb/services/circleci/types.go b/src/github.com/matrix-org/go-neb/services/circleci/types.go index c58a124..a775706 100644 --- a/src/github.com/matrix-org/go-neb/services/circleci/types.go +++ b/src/github.com/matrix-org/go-neb/services/circleci/types.go @@ -3,7 +3,7 @@ package circleci import "time" // WebhookNotification is the response of a webhook notification by circleCI -type WebhookNotification struct { +type webhookNotification struct { Payload struct { VcsURL string `json:"vcs_url,omitempty"` BuildURL string `json:"build_url,omitempty"` @@ -41,4 +41,4 @@ type WebhookNotification struct { } `json:"actions,omitempty"` } `json:"steps,omitempty"` } `json:"payload"` -} \ No newline at end of file +} diff --git a/src/github.com/matrix-org/go-neb/services/circleci/util.go b/src/github.com/matrix-org/go-neb/services/circleci/util.go deleted file mode 100644 index d21e2c7..0000000 --- a/src/github.com/matrix-org/go-neb/services/circleci/util.go +++ /dev/null @@ -1,61 +0,0 @@ -package circleci - -import ( - "unicode" - "unicode/utf8" -) - -type buffer struct { - r []byte - runeBytes [utf8.UTFMax]byte -} - -func (b *buffer) write(r rune) { - if r < utf8.RuneSelf { - b.r = append(b.r, byte(r)) - return - } - n := utf8.EncodeRune(b.runeBytes[0:], r) - b.r = append(b.r, b.runeBytes[0:n]...) -} - -func (b *buffer) indent() { - if len(b.r) > 0 { - b.r = append(b.r, '_') - } -} - -func CamelCaseToUnderscore(s string) string { - b := buffer{ - r: make([]byte, 0, len(s)), - } - var m rune - var w bool - for _, ch := range s { - if unicode.IsUpper(ch) { - if m != 0 { - if !w { - b.indent() - w = true - } - b.write(m) - } - m = unicode.ToLower(ch) - } else { - if m != 0 { - b.indent() - b.write(m) - m = 0 - w = false - } - b.write(ch) - } - } - if m != 0 { - if !w { - b.indent() - } - b.write(m) - } - return string(b.r) -} \ No newline at end of file diff --git a/vendor/src/github.com/fatih/structs/LICENSE b/vendor/src/github.com/fatih/structs/LICENSE deleted file mode 100644 index 34504e4..0000000 --- a/vendor/src/github.com/fatih/structs/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Fatih Arslan - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/vendor/src/github.com/fatih/structs/README.md b/vendor/src/github.com/fatih/structs/README.md deleted file mode 100644 index 44e0100..0000000 --- a/vendor/src/github.com/fatih/structs/README.md +++ /dev/null @@ -1,163 +0,0 @@ -# Structs [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/structs) [![Build Status](http://img.shields.io/travis/fatih/structs.svg?style=flat-square)](https://travis-ci.org/fatih/structs) [![Coverage Status](http://img.shields.io/coveralls/fatih/structs.svg?style=flat-square)](https://coveralls.io/r/fatih/structs) - -Structs contains various utilities to work with Go (Golang) structs. It was -initially used by me to convert a struct into a `map[string]interface{}`. With -time I've added other utilities for structs. It's basically a high level -package based on primitives from the reflect package. Feel free to add new -functions or improve the existing code. - -## Install - -```bash -go get github.com/fatih/structs -``` - -## Usage and Examples - -Just like the standard lib `strings`, `bytes` and co packages, `structs` has -many global functions to manipulate or organize your struct data. Lets define -and declare a struct: - -```go -type Server struct { - Name string `json:"name,omitempty"` - ID int - Enabled bool - users []string // not exported - http.Server // embedded -} - -server := &Server{ - Name: "gopher", - ID: 123456, - Enabled: true, -} -``` - -```go -// Convert a struct to a map[string]interface{} -// => {"Name":"gopher", "ID":123456, "Enabled":true} -m := structs.Map(server) - -// Convert the values of a struct to a []interface{} -// => ["gopher", 123456, true] -v := structs.Values(server) - -// Convert the names of a struct to a []string -// (see "Names methods" for more info about fields) -n := structs.Names(server) - -// Convert the values of a struct to a []*Field -// (see "Field methods" for more info about fields) -f := structs.Fields(server) - -// Return the struct name => "Server" -n := structs.Name(server) - -// Check if any field of a struct is initialized or not. -h := structs.HasZero(server) - -// Check if all fields of a struct is initialized or not. -z := structs.IsZero(server) - -// Check if server is a struct or a pointer to struct -i := structs.IsStruct(server) -``` - -### Struct methods - -The structs functions can be also used as independent methods by creating a new -`*structs.Struct`. This is handy if you want to have more control over the -structs (such as retrieving a single Field). - -```go -// Create a new struct type: -s := structs.New(server) - -m := s.Map() // Get a map[string]interface{} -v := s.Values() // Get a []interface{} -f := s.Fields() // Get a []*Field -n := s.Names() // Get a []string -f := s.Field(name) // Get a *Field based on the given field name -f, ok := s.FieldOk(name) // Get a *Field based on the given field name -n := s.Name() // Get the struct name -h := s.HasZero() // Check if any field is initialized -z := s.IsZero() // Check if all fields are initialized -``` - -### Field methods - -We can easily examine a single Field for more detail. Below you can see how we -get and interact with various field methods: - - -```go -s := structs.New(server) - -// Get the Field struct for the "Name" field -name := s.Field("Name") - -// Get the underlying value, value => "gopher" -value := name.Value().(string) - -// Set the field's value -name.Set("another gopher") - -// Get the field's kind, kind => "string" -name.Kind() - -// Check if the field is exported or not -if name.IsExported() { - fmt.Println("Name field is exported") -} - -// Check if the value is a zero value, such as "" for string, 0 for int -if !name.IsZero() { - fmt.Println("Name is initialized") -} - -// Check if the field is an anonymous (embedded) field -if !name.IsEmbedded() { - fmt.Println("Name is not an embedded field") -} - -// Get the Field's tag value for tag name "json", tag value => "name,omitempty" -tagValue := name.Tag("json") -``` - -Nested structs are supported too: - -```go -addrField := s.Field("Server").Field("Addr") - -// Get the value for addr -a := addrField.Value().(string) - -// Or get all fields -httpServer := s.Field("Server").Fields() -``` - -We can also get a slice of Fields from the Struct type to iterate over all -fields. This is handy if you wish to examine all fields: - -```go -s := structs.New(server) - -for _, f := range s.Fields() { - fmt.Printf("field name: %+v\n", f.Name()) - - if f.IsExported() { - fmt.Printf("value : %+v\n", f.Value()) - fmt.Printf("is zero : %+v\n", f.IsZero()) - } -} -``` - -## Credits - - * [Fatih Arslan](https://github.com/fatih) - * [Cihangir Savas](https://github.com/cihangir) - -## License - -The MIT License (MIT) - see LICENSE.md for more details diff --git a/vendor/src/github.com/fatih/structs/field.go b/vendor/src/github.com/fatih/structs/field.go deleted file mode 100644 index e697832..0000000 --- a/vendor/src/github.com/fatih/structs/field.go +++ /dev/null @@ -1,141 +0,0 @@ -package structs - -import ( - "errors" - "fmt" - "reflect" -) - -var ( - errNotExported = errors.New("field is not exported") - errNotSettable = errors.New("field is not settable") -) - -// Field represents a single struct field that encapsulates high level -// functions around the field. -type Field struct { - value reflect.Value - field reflect.StructField - defaultTag string -} - -// Tag returns the value associated with key in the tag string. If there is no -// such key in the tag, Tag returns the empty string. -func (f *Field) Tag(key string) string { - return f.field.Tag.Get(key) -} - -// Value returns the underlying value of the field. It panics if the field -// is not exported. -func (f *Field) Value() interface{} { - return f.value.Interface() -} - -// IsEmbedded returns true if the given field is an anonymous field (embedded) -func (f *Field) IsEmbedded() bool { - return f.field.Anonymous -} - -// IsExported returns true if the given field is exported. -func (f *Field) IsExported() bool { - return f.field.PkgPath == "" -} - -// IsZero returns true if the given field is not initialized (has a zero value). -// It panics if the field is not exported. -func (f *Field) IsZero() bool { - zero := reflect.Zero(f.value.Type()).Interface() - current := f.Value() - - return reflect.DeepEqual(current, zero) -} - -// Name returns the name of the given field -func (f *Field) Name() string { - return f.field.Name -} - -// Kind returns the fields kind, such as "string", "map", "bool", etc .. -func (f *Field) Kind() reflect.Kind { - return f.value.Kind() -} - -// Set sets the field to given value v. It returns an error if the field is not -// settable (not addressable or not exported) or if the given value's type -// doesn't match the fields type. -func (f *Field) Set(val interface{}) error { - // we can't set unexported fields, so be sure this field is exported - if !f.IsExported() { - return errNotExported - } - - // do we get here? not sure... - if !f.value.CanSet() { - return errNotSettable - } - - given := reflect.ValueOf(val) - - if f.value.Kind() != given.Kind() { - return fmt.Errorf("wrong kind. got: %s want: %s", given.Kind(), f.value.Kind()) - } - - f.value.Set(given) - return nil -} - -// Zero sets the field to its zero value. It returns an error if the field is not -// settable (not addressable or not exported). -func (f *Field) Zero() error { - zero := reflect.Zero(f.value.Type()).Interface() - return f.Set(zero) -} - -// Fields returns a slice of Fields. This is particular handy to get the fields -// of a nested struct . A struct tag with the content of "-" ignores the -// checking of that particular field. Example: -// -// // Field is ignored by this package. -// Field *http.Request `structs:"-"` -// -// It panics if field is not exported or if field's kind is not struct -func (f *Field) Fields() []*Field { - return getFields(f.value, f.defaultTag) -} - -// Field returns the field from a nested struct. It panics if the nested struct -// is not exported or if the field was not found. -func (f *Field) Field(name string) *Field { - field, ok := f.FieldOk(name) - if !ok { - panic("field not found") - } - - return field -} - -// FieldOk returns the field from a nested struct. The boolean returns whether -// the field was found (true) or not (false). -func (f *Field) FieldOk(name string) (*Field, bool) { - value := &f.value - // value must be settable so we need to make sure it holds the address of the - // variable and not a copy, so we can pass the pointer to strctVal instead of a - // copy (which is not assigned to any variable, hence not settable). - // see "https://blog.golang.org/laws-of-reflection#TOC_8." - if f.value.Kind() != reflect.Ptr { - a := f.value.Addr() - value = &a - } - v := strctVal(value.Interface()) - t := v.Type() - - field, ok := t.FieldByName(name) - if !ok { - return nil, false - } - - return &Field{ - field: field, - value: v.FieldByName(name), - }, true -} diff --git a/vendor/src/github.com/fatih/structs/field_test.go b/vendor/src/github.com/fatih/structs/field_test.go deleted file mode 100644 index de9dc3b..0000000 --- a/vendor/src/github.com/fatih/structs/field_test.go +++ /dev/null @@ -1,397 +0,0 @@ -package structs - -import ( - "reflect" - "testing" -) - -// A test struct that defines all cases -type Foo struct { - A string - B int `structs:"y"` - C bool `json:"c"` - d string // not exported - E *Baz - x string `xml:"x"` // not exported, with tag - Y []string - Z map[string]interface{} - *Bar // embedded -} - -type Baz struct { - A string - B int -} - -type Bar struct { - E string - F int - g []string -} - -func newStruct() *Struct { - b := &Bar{ - E: "example", - F: 2, - g: []string{"zeynep", "fatih"}, - } - - // B and x is not initialized for testing - f := &Foo{ - A: "gopher", - C: true, - d: "small", - E: nil, - Y: []string{"example"}, - Z: nil, - } - f.Bar = b - - return New(f) -} - -func TestField_Set(t *testing.T) { - s := newStruct() - - f := s.Field("A") - err := f.Set("fatih") - if err != nil { - t.Error(err) - } - - if f.Value().(string) != "fatih" { - t.Errorf("Setted value is wrong: %s want: %s", f.Value().(string), "fatih") - } - - f = s.Field("Y") - err = f.Set([]string{"override", "with", "this"}) - if err != nil { - t.Error(err) - } - - sliceLen := len(f.Value().([]string)) - if sliceLen != 3 { - t.Errorf("Setted values slice length is wrong: %d, want: %d", sliceLen, 3) - } - - f = s.Field("C") - err = f.Set(false) - if err != nil { - t.Error(err) - } - - if f.Value().(bool) { - t.Errorf("Setted value is wrong: %t want: %t", f.Value().(bool), false) - } - - // let's pass a different type - f = s.Field("A") - err = f.Set(123) // Field A is of type string, but we are going to pass an integer - if err == nil { - t.Error("Setting a field's value with a different type than the field's type should return an error") - } - - // old value should be still there :) - if f.Value().(string) != "fatih" { - t.Errorf("Setted value is wrong: %s want: %s", f.Value().(string), "fatih") - } - - // let's access an unexported field, which should give an error - f = s.Field("d") - err = f.Set("large") - if err != errNotExported { - t.Error(err) - } - - // let's set a pointer to struct - b := &Bar{ - E: "gopher", - F: 2, - } - - f = s.Field("Bar") - err = f.Set(b) - if err != nil { - t.Error(err) - } - - baz := &Baz{ - A: "helloWorld", - B: 42, - } - - f = s.Field("E") - err = f.Set(baz) - if err != nil { - t.Error(err) - } - - ba := s.Field("E").Value().(*Baz) - - if ba.A != "helloWorld" { - t.Errorf("could not set baz. Got: %s Want: helloWorld", ba.A) - } -} - -func TestField_NotSettable(t *testing.T) { - a := map[int]Baz{ - 4: Baz{ - A: "value", - }, - } - - s := New(a[4]) - - if err := s.Field("A").Set("newValue"); err != errNotSettable { - t.Errorf("Trying to set non-settable field should error with %q. Got %q instead.", errNotSettable, err) - } -} - -func TestField_Zero(t *testing.T) { - s := newStruct() - - f := s.Field("A") - err := f.Zero() - if err != nil { - t.Error(err) - } - - if f.Value().(string) != "" { - t.Errorf("Zeroed value is wrong: %s want: %s", f.Value().(string), "") - } - - f = s.Field("Y") - err = f.Zero() - if err != nil { - t.Error(err) - } - - sliceLen := len(f.Value().([]string)) - if sliceLen != 0 { - t.Errorf("Zeroed values slice length is wrong: %d, want: %d", sliceLen, 0) - } - - f = s.Field("C") - err = f.Zero() - if err != nil { - t.Error(err) - } - - if f.Value().(bool) { - t.Errorf("Zeroed value is wrong: %t want: %t", f.Value().(bool), false) - } - - // let's access an unexported field, which should give an error - f = s.Field("d") - err = f.Zero() - if err != errNotExported { - t.Error(err) - } - - f = s.Field("Bar") - err = f.Zero() - if err != nil { - t.Error(err) - } - - f = s.Field("E") - err = f.Zero() - if err != nil { - t.Error(err) - } - - v := s.Field("E").value - if !v.IsNil() { - t.Errorf("could not set baz. Got: %s Want: ", v.Interface()) - } -} - -func TestField(t *testing.T) { - s := newStruct() - - defer func() { - err := recover() - if err == nil { - t.Error("Retrieveing a non existing field from the struct should panic") - } - }() - - _ = s.Field("no-field") -} - -func TestField_Kind(t *testing.T) { - s := newStruct() - - f := s.Field("A") - if f.Kind() != reflect.String { - t.Errorf("Field A has wrong kind: %s want: %s", f.Kind(), reflect.String) - } - - f = s.Field("B") - if f.Kind() != reflect.Int { - t.Errorf("Field B has wrong kind: %s want: %s", f.Kind(), reflect.Int) - } - - // unexported - f = s.Field("d") - if f.Kind() != reflect.String { - t.Errorf("Field d has wrong kind: %s want: %s", f.Kind(), reflect.String) - } -} - -func TestField_Tag(t *testing.T) { - s := newStruct() - - v := s.Field("B").Tag("json") - if v != "" { - t.Errorf("Field's tag value of a non existing tag should return empty, got: %s", v) - } - - v = s.Field("C").Tag("json") - if v != "c" { - t.Errorf("Field's tag value of the existing field C should return 'c', got: %s", v) - } - - v = s.Field("d").Tag("json") - if v != "" { - t.Errorf("Field's tag value of a non exported field should return empty, got: %s", v) - } - - v = s.Field("x").Tag("xml") - if v != "x" { - t.Errorf("Field's tag value of a non exported field with a tag should return 'x', got: %s", v) - } - - v = s.Field("A").Tag("json") - if v != "" { - t.Errorf("Field's tag value of a existing field without a tag should return empty, got: %s", v) - } -} - -func TestField_Value(t *testing.T) { - s := newStruct() - - v := s.Field("A").Value() - val, ok := v.(string) - if !ok { - t.Errorf("Field's value of a A should be string") - } - - if val != "gopher" { - t.Errorf("Field's value of a existing tag should return 'gopher', got: %s", val) - } - - defer func() { - err := recover() - if err == nil { - t.Error("Value of a non exported field from the field should panic") - } - }() - - // should panic - _ = s.Field("d").Value() -} - -func TestField_IsEmbedded(t *testing.T) { - s := newStruct() - - if !s.Field("Bar").IsEmbedded() { - t.Errorf("Fields 'Bar' field is an embedded field") - } - - if s.Field("d").IsEmbedded() { - t.Errorf("Fields 'd' field is not an embedded field") - } -} - -func TestField_IsExported(t *testing.T) { - s := newStruct() - - if !s.Field("Bar").IsExported() { - t.Errorf("Fields 'Bar' field is an exported field") - } - - if !s.Field("A").IsExported() { - t.Errorf("Fields 'A' field is an exported field") - } - - if s.Field("d").IsExported() { - t.Errorf("Fields 'd' field is not an exported field") - } -} - -func TestField_IsZero(t *testing.T) { - s := newStruct() - - if s.Field("A").IsZero() { - t.Errorf("Fields 'A' field is an initialized field") - } - - if !s.Field("B").IsZero() { - t.Errorf("Fields 'B' field is not an initialized field") - } -} - -func TestField_Name(t *testing.T) { - s := newStruct() - - if s.Field("A").Name() != "A" { - t.Errorf("Fields 'A' field should have the name 'A'") - } -} - -func TestField_Field(t *testing.T) { - s := newStruct() - - e := s.Field("Bar").Field("E") - - val, ok := e.Value().(string) - if !ok { - t.Error("The value of the field 'e' inside 'Bar' struct should be string") - } - - if val != "example" { - t.Errorf("The value of 'e' should be 'example, got: %s", val) - } - - defer func() { - err := recover() - if err == nil { - t.Error("Field of a non existing nested struct should panic") - } - }() - - _ = s.Field("Bar").Field("e") -} - -func TestField_Fields(t *testing.T) { - s := newStruct() - fields := s.Field("Bar").Fields() - - if len(fields) != 3 { - t.Errorf("We expect 3 fields in embedded struct, was: %d", len(fields)) - } -} - -func TestField_FieldOk(t *testing.T) { - s := newStruct() - - b, ok := s.FieldOk("Bar") - if !ok { - t.Error("The field 'Bar' should exists.") - } - - e, ok := b.FieldOk("E") - if !ok { - t.Error("The field 'E' should exists.") - } - - val, ok := e.Value().(string) - if !ok { - t.Error("The value of the field 'e' inside 'Bar' struct should be string") - } - - if val != "example" { - t.Errorf("The value of 'e' should be 'example, got: %s", val) - } -} diff --git a/vendor/src/github.com/fatih/structs/structs.go b/vendor/src/github.com/fatih/structs/structs.go deleted file mode 100644 index be3816a..0000000 --- a/vendor/src/github.com/fatih/structs/structs.go +++ /dev/null @@ -1,586 +0,0 @@ -// Package structs contains various utilities functions to work with structs. -package structs - -import ( - "fmt" - - "reflect" -) - -var ( - // DefaultTagName is the default tag name for struct fields which provides - // a more granular to tweak certain structs. Lookup the necessary functions - // for more info. - DefaultTagName = "structs" // struct's field default tag name -) - -// Struct encapsulates a struct type to provide several high level functions -// around the struct. -type Struct struct { - raw interface{} - value reflect.Value - TagName string -} - -// New returns a new *Struct with the struct s. It panics if the s's kind is -// not struct. -func New(s interface{}) *Struct { - return &Struct{ - raw: s, - value: strctVal(s), - TagName: DefaultTagName, - } -} - -// Map converts the given struct to a map[string]interface{}, where the keys -// of the map are the field names and the values of the map the associated -// values of the fields. The default key string is the struct field name but -// can be changed in the struct field's tag value. The "structs" key in the -// struct's field tag value is the key name. Example: -// -// // Field appears in map as key "myName". -// Name string `structs:"myName"` -// -// A tag value with the content of "-" ignores that particular field. Example: -// -// // Field is ignored by this package. -// Field bool `structs:"-"` -// -// A tag value with the content of "string" uses the stringer to get the value. Example: -// -// // The value will be output of Animal's String() func. -// // Map will panic if Animal does not implement String(). -// Field *Animal `structs:"field,string"` -// -// A tag value with the option of "flatten" used in a struct field is to flatten its fields -// in the output map. Example: -// -// // The FieldStruct's fields will be flattened into the output map. -// FieldStruct time.Time `structs:",flatten"` -// -// A tag value with the option of "omitnested" stops iterating further if the type -// is a struct. Example: -// -// // Field is not processed further by this package. -// Field time.Time `structs:"myName,omitnested"` -// Field *http.Request `structs:",omitnested"` -// -// A tag value with the option of "omitempty" ignores that particular field if -// the field value is empty. Example: -// -// // Field appears in map as key "myName", but the field is -// // skipped if empty. -// Field string `structs:"myName,omitempty"` -// -// // Field appears in map as key "Field" (the default), but -// // the field is skipped if empty. -// Field string `structs:",omitempty"` -// -// Note that only exported fields of a struct can be accessed, non exported -// fields will be neglected. -func (s *Struct) Map() map[string]interface{} { - out := make(map[string]interface{}) - s.FillMap(out) - return out -} - -// FillMap is the same as Map. Instead of returning the output, it fills the -// given map. -func (s *Struct) FillMap(out map[string]interface{}) { - if out == nil { - return - } - - fields := s.structFields() - - for _, field := range fields { - name := field.Name - val := s.value.FieldByName(name) - isSubStruct := false - var finalVal interface{} - - tagName, tagOpts := parseTag(field.Tag.Get(s.TagName)) - if tagName != "" { - name = tagName - } - - // if the value is a zero value and the field is marked as omitempty do - // not include - if tagOpts.Has("omitempty") { - zero := reflect.Zero(val.Type()).Interface() - current := val.Interface() - - if reflect.DeepEqual(current, zero) { - continue - } - } - - if !tagOpts.Has("omitnested") { - finalVal = s.nested(val) - - v := reflect.ValueOf(val.Interface()) - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - - switch v.Kind() { - case reflect.Map, reflect.Struct: - isSubStruct = true - } - } else { - finalVal = val.Interface() - } - - if tagOpts.Has("string") { - s, ok := val.Interface().(fmt.Stringer) - if ok { - out[name] = s.String() - } - continue - } - - if isSubStruct && (tagOpts.Has("flatten")) { - for k := range finalVal.(map[string]interface{}) { - out[k] = finalVal.(map[string]interface{})[k] - } - } else { - out[name] = finalVal - } - } -} - -// Values converts the given s struct's field values to a []interface{}. A -// struct tag with the content of "-" ignores the that particular field. -// Example: -// -// // Field is ignored by this package. -// Field int `structs:"-"` -// -// A value with the option of "omitnested" stops iterating further if the type -// is a struct. Example: -// -// // Fields is not processed further by this package. -// Field time.Time `structs:",omitnested"` -// Field *http.Request `structs:",omitnested"` -// -// A tag value with the option of "omitempty" ignores that particular field and -// is not added to the values if the field value is empty. Example: -// -// // Field is skipped if empty -// Field string `structs:",omitempty"` -// -// Note that only exported fields of a struct can be accessed, non exported -// fields will be neglected. -func (s *Struct) Values() []interface{} { - fields := s.structFields() - - var t []interface{} - - for _, field := range fields { - val := s.value.FieldByName(field.Name) - - _, tagOpts := parseTag(field.Tag.Get(s.TagName)) - - // if the value is a zero value and the field is marked as omitempty do - // not include - if tagOpts.Has("omitempty") { - zero := reflect.Zero(val.Type()).Interface() - current := val.Interface() - - if reflect.DeepEqual(current, zero) { - continue - } - } - - if tagOpts.Has("string") { - s, ok := val.Interface().(fmt.Stringer) - if ok { - t = append(t, s.String()) - } - continue - } - - if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") { - // look out for embedded structs, and convert them to a - // []interface{} to be added to the final values slice - for _, embeddedVal := range Values(val.Interface()) { - t = append(t, embeddedVal) - } - } else { - t = append(t, val.Interface()) - } - } - - return t -} - -// Fields returns a slice of Fields. A struct tag with the content of "-" -// ignores the checking of that particular field. Example: -// -// // Field is ignored by this package. -// Field bool `structs:"-"` -// -// It panics if s's kind is not struct. -func (s *Struct) Fields() []*Field { - return getFields(s.value, s.TagName) -} - -// Names returns a slice of field names. A struct tag with the content of "-" -// ignores the checking of that particular field. Example: -// -// // Field is ignored by this package. -// Field bool `structs:"-"` -// -// It panics if s's kind is not struct. -func (s *Struct) Names() []string { - fields := getFields(s.value, s.TagName) - - names := make([]string, len(fields)) - - for i, field := range fields { - names[i] = field.Name() - } - - return names -} - -func getFields(v reflect.Value, tagName string) []*Field { - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - - t := v.Type() - - var fields []*Field - - for i := 0; i < t.NumField(); i++ { - field := t.Field(i) - - if tag := field.Tag.Get(tagName); tag == "-" { - continue - } - - f := &Field{ - field: field, - value: v.FieldByName(field.Name), - } - - fields = append(fields, f) - - } - - return fields -} - -// Field returns a new Field struct that provides several high level functions -// around a single struct field entity. It panics if the field is not found. -func (s *Struct) Field(name string) *Field { - f, ok := s.FieldOk(name) - if !ok { - panic("field not found") - } - - return f -} - -// FieldOk returns a new Field struct that provides several high level functions -// around a single struct field entity. The boolean returns true if the field -// was found. -func (s *Struct) FieldOk(name string) (*Field, bool) { - t := s.value.Type() - - field, ok := t.FieldByName(name) - if !ok { - return nil, false - } - - return &Field{ - field: field, - value: s.value.FieldByName(name), - defaultTag: s.TagName, - }, true -} - -// IsZero returns true if all fields in a struct is a zero value (not -// initialized) A struct tag with the content of "-" ignores the checking of -// that particular field. Example: -// -// // Field is ignored by this package. -// Field bool `structs:"-"` -// -// A value with the option of "omitnested" stops iterating further if the type -// is a struct. Example: -// -// // Field is not processed further by this package. -// Field time.Time `structs:"myName,omitnested"` -// Field *http.Request `structs:",omitnested"` -// -// Note that only exported fields of a struct can be accessed, non exported -// fields will be neglected. It panics if s's kind is not struct. -func (s *Struct) IsZero() bool { - fields := s.structFields() - - for _, field := range fields { - val := s.value.FieldByName(field.Name) - - _, tagOpts := parseTag(field.Tag.Get(s.TagName)) - - if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") { - ok := IsZero(val.Interface()) - if !ok { - return false - } - - continue - } - - // zero value of the given field, such as "" for string, 0 for int - zero := reflect.Zero(val.Type()).Interface() - - // current value of the given field - current := val.Interface() - - if !reflect.DeepEqual(current, zero) { - return false - } - } - - return true -} - -// HasZero returns true if a field in a struct is not initialized (zero value). -// A struct tag with the content of "-" ignores the checking of that particular -// field. Example: -// -// // Field is ignored by this package. -// Field bool `structs:"-"` -// -// A value with the option of "omitnested" stops iterating further if the type -// is a struct. Example: -// -// // Field is not processed further by this package. -// Field time.Time `structs:"myName,omitnested"` -// Field *http.Request `structs:",omitnested"` -// -// Note that only exported fields of a struct can be accessed, non exported -// fields will be neglected. It panics if s's kind is not struct. -func (s *Struct) HasZero() bool { - fields := s.structFields() - - for _, field := range fields { - val := s.value.FieldByName(field.Name) - - _, tagOpts := parseTag(field.Tag.Get(s.TagName)) - - if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") { - ok := HasZero(val.Interface()) - if ok { - return true - } - - continue - } - - // zero value of the given field, such as "" for string, 0 for int - zero := reflect.Zero(val.Type()).Interface() - - // current value of the given field - current := val.Interface() - - if reflect.DeepEqual(current, zero) { - return true - } - } - - return false -} - -// Name returns the structs's type name within its package. For more info refer -// to Name() function. -func (s *Struct) Name() string { - return s.value.Type().Name() -} - -// structFields returns the exported struct fields for a given s struct. This -// is a convenient helper method to avoid duplicate code in some of the -// functions. -func (s *Struct) structFields() []reflect.StructField { - t := s.value.Type() - - var f []reflect.StructField - - for i := 0; i < t.NumField(); i++ { - field := t.Field(i) - // we can't access the value of unexported fields - if field.PkgPath != "" { - continue - } - - // don't check if it's omitted - if tag := field.Tag.Get(s.TagName); tag == "-" { - continue - } - - f = append(f, field) - } - - return f -} - -func strctVal(s interface{}) reflect.Value { - v := reflect.ValueOf(s) - - // if pointer get the underlying element≤ - for v.Kind() == reflect.Ptr { - v = v.Elem() - } - - if v.Kind() != reflect.Struct { - panic("not struct") - } - - return v -} - -// Map converts the given struct to a map[string]interface{}. For more info -// refer to Struct types Map() method. It panics if s's kind is not struct. -func Map(s interface{}) map[string]interface{} { - return New(s).Map() -} - -// FillMap is the same as Map. Instead of returning the output, it fills the -// given map. -func FillMap(s interface{}, out map[string]interface{}) { - New(s).FillMap(out) -} - -// Values converts the given struct to a []interface{}. For more info refer to -// Struct types Values() method. It panics if s's kind is not struct. -func Values(s interface{}) []interface{} { - return New(s).Values() -} - -// Fields returns a slice of *Field. For more info refer to Struct types -// Fields() method. It panics if s's kind is not struct. -func Fields(s interface{}) []*Field { - return New(s).Fields() -} - -// Names returns a slice of field names. For more info refer to Struct types -// Names() method. It panics if s's kind is not struct. -func Names(s interface{}) []string { - return New(s).Names() -} - -// IsZero returns true if all fields is equal to a zero value. For more info -// refer to Struct types IsZero() method. It panics if s's kind is not struct. -func IsZero(s interface{}) bool { - return New(s).IsZero() -} - -// HasZero returns true if any field is equal to a zero value. For more info -// refer to Struct types HasZero() method. It panics if s's kind is not struct. -func HasZero(s interface{}) bool { - return New(s).HasZero() -} - -// IsStruct returns true if the given variable is a struct or a pointer to -// struct. -func IsStruct(s interface{}) bool { - v := reflect.ValueOf(s) - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - - // uninitialized zero value of a struct - if v.Kind() == reflect.Invalid { - return false - } - - return v.Kind() == reflect.Struct -} - -// Name returns the structs's type name within its package. It returns an -// empty string for unnamed types. It panics if s's kind is not struct. -func Name(s interface{}) string { - return New(s).Name() -} - -// nested retrieves recursively all types for the given value and returns the -// nested value. -func (s *Struct) nested(val reflect.Value) interface{} { - var finalVal interface{} - - v := reflect.ValueOf(val.Interface()) - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - - switch v.Kind() { - case reflect.Struct: - n := New(val.Interface()) - n.TagName = s.TagName - m := n.Map() - - // do not add the converted value if there are no exported fields, ie: - // time.Time - if len(m) == 0 { - finalVal = val.Interface() - } else { - finalVal = m - } - case reflect.Map: - // get the element type of the map - mapElem := val.Type() - switch val.Type().Kind() { - case reflect.Ptr, reflect.Array, reflect.Map, - reflect.Slice, reflect.Chan: - mapElem = val.Type().Elem() - if mapElem.Kind() == reflect.Ptr { - mapElem = mapElem.Elem() - } - } - - // only iterate over struct types, ie: map[string]StructType, - // map[string][]StructType, - if mapElem.Kind() == reflect.Struct || - (mapElem.Kind() == reflect.Slice && - mapElem.Elem().Kind() == reflect.Struct) { - m := make(map[string]interface{}, val.Len()) - for _, k := range val.MapKeys() { - m[k.String()] = s.nested(val.MapIndex(k)) - } - finalVal = m - break - } - - // TODO(arslan): should this be optional? - finalVal = val.Interface() - case reflect.Slice, reflect.Array: - if val.Type().Kind() == reflect.Interface { - finalVal = val.Interface() - break - } - - // TODO(arslan): should this be optional? - // do not iterate of non struct types, just pass the value. Ie: []int, - // []string, co... We only iterate further if it's a struct. - // i.e []foo or []*foo - if val.Type().Elem().Kind() != reflect.Struct && - !(val.Type().Elem().Kind() == reflect.Ptr && - val.Type().Elem().Elem().Kind() == reflect.Struct) { - finalVal = val.Interface() - break - } - - slices := make([]interface{}, val.Len(), val.Len()) - for x := 0; x < val.Len(); x++ { - slices[x] = s.nested(val.Index(x)) - } - finalVal = slices - default: - finalVal = val.Interface() - } - - return finalVal -} diff --git a/vendor/src/github.com/fatih/structs/structs_example_test.go b/vendor/src/github.com/fatih/structs/structs_example_test.go deleted file mode 100644 index 329c130..0000000 --- a/vendor/src/github.com/fatih/structs/structs_example_test.go +++ /dev/null @@ -1,351 +0,0 @@ -package structs - -import ( - "fmt" - "time" -) - -func ExampleNew() { - type Server struct { - Name string - ID int32 - Enabled bool - } - - server := &Server{ - Name: "Arslan", - ID: 123456, - Enabled: true, - } - - s := New(server) - - fmt.Printf("Name : %v\n", s.Name()) - fmt.Printf("Values : %v\n", s.Values()) - fmt.Printf("Value of ID : %v\n", s.Field("ID").Value()) - // Output: - // Name : Server - // Values : [Arslan 123456 true] - // Value of ID : 123456 - -} - -func ExampleMap() { - type Server struct { - Name string - ID int32 - Enabled bool - } - - s := &Server{ - Name: "Arslan", - ID: 123456, - Enabled: true, - } - - m := Map(s) - - fmt.Printf("%#v\n", m["Name"]) - fmt.Printf("%#v\n", m["ID"]) - fmt.Printf("%#v\n", m["Enabled"]) - // Output: - // "Arslan" - // 123456 - // true - -} - -func ExampleMap_tags() { - // Custom tags can change the map keys instead of using the fields name - type Server struct { - Name string `structs:"server_name"` - ID int32 `structs:"server_id"` - Enabled bool `structs:"enabled"` - } - - s := &Server{ - Name: "Zeynep", - ID: 789012, - } - - m := Map(s) - - // access them by the custom tags defined above - fmt.Printf("%#v\n", m["server_name"]) - fmt.Printf("%#v\n", m["server_id"]) - fmt.Printf("%#v\n", m["enabled"]) - // Output: - // "Zeynep" - // 789012 - // false - -} - -func ExampleMap_omitNested() { - // By default field with struct types are processed too. We can stop - // processing them via "omitnested" tag option. - type Server struct { - Name string `structs:"server_name"` - ID int32 `structs:"server_id"` - Time time.Time `structs:"time,omitnested"` // do not convert to map[string]interface{} - } - - const shortForm = "2006-Jan-02" - t, _ := time.Parse("2006-Jan-02", "2013-Feb-03") - - s := &Server{ - Name: "Zeynep", - ID: 789012, - Time: t, - } - - m := Map(s) - - // access them by the custom tags defined above - fmt.Printf("%v\n", m["server_name"]) - fmt.Printf("%v\n", m["server_id"]) - fmt.Printf("%v\n", m["time"].(time.Time)) - // Output: - // Zeynep - // 789012 - // 2013-02-03 00:00:00 +0000 UTC -} - -func ExampleMap_omitEmpty() { - // By default field with struct types of zero values are processed too. We - // can stop processing them via "omitempty" tag option. - type Server struct { - Name string `structs:",omitempty"` - ID int32 `structs:"server_id,omitempty"` - Location string - } - - // Only add location - s := &Server{ - Location: "Tokyo", - } - - m := Map(s) - - // map contains only the Location field - fmt.Printf("%v\n", m) - // Output: - // map[Location:Tokyo] -} - -func ExampleValues() { - type Server struct { - Name string - ID int32 - Enabled bool - } - - s := &Server{ - Name: "Fatih", - ID: 135790, - Enabled: false, - } - - m := Values(s) - - fmt.Printf("Values: %+v\n", m) - // Output: - // Values: [Fatih 135790 false] -} - -func ExampleValues_omitEmpty() { - // By default field with struct types of zero values are processed too. We - // can stop processing them via "omitempty" tag option. - type Server struct { - Name string `structs:",omitempty"` - ID int32 `structs:"server_id,omitempty"` - Location string - } - - // Only add location - s := &Server{ - Location: "Ankara", - } - - m := Values(s) - - // values contains only the Location field - fmt.Printf("Values: %+v\n", m) - // Output: - // Values: [Ankara] -} - -func ExampleValues_tags() { - type Location struct { - City string - Country string - } - - type Server struct { - Name string - ID int32 - Enabled bool - Location Location `structs:"-"` // values from location are not included anymore - } - - s := &Server{ - Name: "Fatih", - ID: 135790, - Enabled: false, - Location: Location{City: "Ankara", Country: "Turkey"}, - } - - // Let get all values from the struct s. Note that we don't include values - // from the Location field - m := Values(s) - - fmt.Printf("Values: %+v\n", m) - // Output: - // Values: [Fatih 135790 false] -} - -func ExampleFields() { - type Access struct { - Name string - LastAccessed time.Time - Number int - } - - s := &Access{ - Name: "Fatih", - LastAccessed: time.Now(), - Number: 1234567, - } - - fields := Fields(s) - - for i, field := range fields { - fmt.Printf("[%d] %+v\n", i, field.Name()) - } - - // Output: - // [0] Name - // [1] LastAccessed - // [2] Number -} - -func ExampleFields_nested() { - type Person struct { - Name string - Number int - } - - type Access struct { - Person Person - HasPermission bool - LastAccessed time.Time - } - - s := &Access{ - Person: Person{Name: "fatih", Number: 1234567}, - LastAccessed: time.Now(), - HasPermission: true, - } - - // Let's get all fields from the struct s. - fields := Fields(s) - - for _, field := range fields { - if field.Name() == "Person" { - fmt.Printf("Access.Person.Name: %+v\n", field.Field("Name").Value()) - } - } - - // Output: - // Access.Person.Name: fatih -} - -func ExampleField() { - type Person struct { - Name string - Number int - } - - type Access struct { - Person Person - HasPermission bool - LastAccessed time.Time - } - - access := &Access{ - Person: Person{Name: "fatih", Number: 1234567}, - LastAccessed: time.Now(), - HasPermission: true, - } - - // Create a new Struct type - s := New(access) - - // Get the Field type for "Person" field - p := s.Field("Person") - - // Get the underlying "Name field" and print the value of it - name := p.Field("Name") - - fmt.Printf("Value of Person.Access.Name: %+v\n", name.Value()) - - // Output: - // Value of Person.Access.Name: fatih - -} - -func ExampleIsZero() { - type Server struct { - Name string - ID int32 - Enabled bool - } - - // Nothing is initalized - a := &Server{} - isZeroA := IsZero(a) - - // Name and Enabled is initialized, but not ID - b := &Server{ - Name: "Golang", - Enabled: true, - } - isZeroB := IsZero(b) - - fmt.Printf("%#v\n", isZeroA) - fmt.Printf("%#v\n", isZeroB) - // Output: - // true - // false -} - -func ExampleHasZero() { - // Let's define an Access struct. Note that the "Enabled" field is not - // going to be checked because we added the "structs" tag to the field. - type Access struct { - Name string - LastAccessed time.Time - Number int - Enabled bool `structs:"-"` - } - - // Name and Number is not initialized. - a := &Access{ - LastAccessed: time.Now(), - } - hasZeroA := HasZero(a) - - // Name and Number is initialized. - b := &Access{ - Name: "Fatih", - LastAccessed: time.Now(), - Number: 12345, - } - hasZeroB := HasZero(b) - - fmt.Printf("%#v\n", hasZeroA) - fmt.Printf("%#v\n", hasZeroB) - // Output: - // true - // false -} diff --git a/vendor/src/github.com/fatih/structs/structs_test.go b/vendor/src/github.com/fatih/structs/structs_test.go deleted file mode 100644 index 96a5284..0000000 --- a/vendor/src/github.com/fatih/structs/structs_test.go +++ /dev/null @@ -1,1453 +0,0 @@ -package structs - -import ( - "fmt" - "reflect" - "testing" - "time" -) - -func TestMapNonStruct(t *testing.T) { - foo := []string{"foo"} - - defer func() { - err := recover() - if err == nil { - t.Error("Passing a non struct into Map should panic") - } - }() - - // this should panic. We are going to recover and and test it - _ = Map(foo) -} - -func TestStructIndexes(t *testing.T) { - type C struct { - something int - Props map[string]interface{} - } - - defer func() { - err := recover() - if err != nil { - fmt.Printf("err %+v\n", err) - t.Error("Using mixed indexes should not panic") - } - }() - - // They should not panic - _ = Map(&C{}) - _ = Fields(&C{}) - _ = Values(&C{}) - _ = IsZero(&C{}) - _ = HasZero(&C{}) -} - -func TestMap(t *testing.T) { - var T = struct { - A string - B int - C bool - }{ - A: "a-value", - B: 2, - C: true, - } - - a := Map(T) - - if typ := reflect.TypeOf(a).Kind(); typ != reflect.Map { - t.Errorf("Map should return a map type, got: %v", typ) - } - - // we have three fields - if len(a) != 3 { - t.Errorf("Map should return a map of len 3, got: %d", len(a)) - } - - inMap := func(val interface{}) bool { - for _, v := range a { - if reflect.DeepEqual(v, val) { - return true - } - } - - return false - } - - for _, val := range []interface{}{"a-value", 2, true} { - if !inMap(val) { - t.Errorf("Map should have the value %v", val) - } - } - -} - -func TestMap_Tag(t *testing.T) { - var T = struct { - A string `structs:"x"` - B int `structs:"y"` - C bool `structs:"z"` - }{ - A: "a-value", - B: 2, - C: true, - } - - a := Map(T) - - inMap := func(key interface{}) bool { - for k := range a { - if reflect.DeepEqual(k, key) { - return true - } - } - return false - } - - for _, key := range []string{"x", "y", "z"} { - if !inMap(key) { - t.Errorf("Map should have the key %v", key) - } - } - -} - -func TestMap_CustomTag(t *testing.T) { - var T = struct { - A string `json:"x"` - B int `json:"y"` - C bool `json:"z"` - D struct { - E string `json:"jkl"` - } `json:"nested"` - }{ - A: "a-value", - B: 2, - C: true, - } - T.D.E = "e-value" - - s := New(T) - s.TagName = "json" - - a := s.Map() - - inMap := func(key interface{}) bool { - for k := range a { - if reflect.DeepEqual(k, key) { - return true - } - } - return false - } - - for _, key := range []string{"x", "y", "z"} { - if !inMap(key) { - t.Errorf("Map should have the key %v", key) - } - } - - nested, ok := a["nested"].(map[string]interface{}) - if !ok { - t.Fatalf("Map should contain the D field that is tagged as 'nested'") - } - - e, ok := nested["jkl"].(string) - if !ok { - t.Fatalf("Map should contain the D.E field that is tagged as 'jkl'") - } - - if e != "e-value" { - t.Errorf("D.E field should be equal to 'e-value', got: '%v'", e) - } - -} - -func TestMap_MultipleCustomTag(t *testing.T) { - var A = struct { - X string `aa:"ax"` - }{"a_value"} - - aStruct := New(A) - aStruct.TagName = "aa" - - var B = struct { - X string `bb:"bx"` - }{"b_value"} - - bStruct := New(B) - bStruct.TagName = "bb" - - a, b := aStruct.Map(), bStruct.Map() - if !reflect.DeepEqual(a, map[string]interface{}{"ax": "a_value"}) { - t.Error("Map should have field ax with value a_value") - } - - if !reflect.DeepEqual(b, map[string]interface{}{"bx": "b_value"}) { - t.Error("Map should have field bx with value b_value") - } -} - -func TestMap_OmitEmpty(t *testing.T) { - type A struct { - Name string - Value string `structs:",omitempty"` - Time time.Time `structs:",omitempty"` - } - a := A{} - - m := Map(a) - - _, ok := m["Value"].(map[string]interface{}) - if ok { - t.Error("Map should not contain the Value field that is tagged as omitempty") - } - - _, ok = m["Time"].(map[string]interface{}) - if ok { - t.Error("Map should not contain the Time field that is tagged as omitempty") - } -} - -func TestMap_OmitNested(t *testing.T) { - type A struct { - Name string - Value string - Time time.Time `structs:",omitnested"` - } - a := A{Time: time.Now()} - - type B struct { - Desc string - A A - } - b := &B{A: a} - - m := Map(b) - - in, ok := m["A"].(map[string]interface{}) - if !ok { - t.Error("Map nested structs is not available in the map") - } - - // should not happen - if _, ok := in["Time"].(map[string]interface{}); ok { - t.Error("Map nested struct should omit recursiving parsing of Time") - } - - if _, ok := in["Time"].(time.Time); !ok { - t.Error("Map nested struct should stop parsing of Time at is current value") - } -} - -func TestMap_Nested(t *testing.T) { - type A struct { - Name string - } - a := &A{Name: "example"} - - type B struct { - A *A - } - b := &B{A: a} - - m := Map(b) - - if typ := reflect.TypeOf(m).Kind(); typ != reflect.Map { - t.Errorf("Map should return a map type, got: %v", typ) - } - - in, ok := m["A"].(map[string]interface{}) - if !ok { - t.Error("Map nested structs is not available in the map") - } - - if name := in["Name"].(string); name != "example" { - t.Errorf("Map nested struct's name field should give example, got: %s", name) - } -} - -func TestMap_NestedMapWithStructValues(t *testing.T) { - type A struct { - Name string - } - - type B struct { - A map[string]*A - } - - a := &A{Name: "example"} - - b := &B{ - A: map[string]*A{ - "example_key": a, - }, - } - - m := Map(b) - - if typ := reflect.TypeOf(m).Kind(); typ != reflect.Map { - t.Errorf("Map should return a map type, got: %v", typ) - } - - in, ok := m["A"].(map[string]interface{}) - if !ok { - t.Errorf("Nested type of map should be of type map[string]interface{}, have %T", m["A"]) - } - - example := in["example_key"].(map[string]interface{}) - if name := example["Name"].(string); name != "example" { - t.Errorf("Map nested struct's name field should give example, got: %s", name) - } -} - -func TestMap_NestedMapWithStringValues(t *testing.T) { - type B struct { - Foo map[string]string - } - - type A struct { - B *B - } - - b := &B{ - Foo: map[string]string{ - "example_key": "example", - }, - } - - a := &A{B: b} - - m := Map(a) - - if typ := reflect.TypeOf(m).Kind(); typ != reflect.Map { - t.Errorf("Map should return a map type, got: %v", typ) - } - - in, ok := m["B"].(map[string]interface{}) - if !ok { - t.Errorf("Nested type of map should be of type map[string]interface{}, have %T", m["B"]) - } - - foo := in["Foo"].(map[string]string) - if name := foo["example_key"]; name != "example" { - t.Errorf("Map nested struct's name field should give example, got: %s", name) - } -} -func TestMap_NestedMapWithInterfaceValues(t *testing.T) { - type B struct { - Foo map[string]interface{} - } - - type A struct { - B *B - } - - b := &B{ - Foo: map[string]interface{}{ - "example_key": "example", - }, - } - - a := &A{B: b} - - m := Map(a) - - if typ := reflect.TypeOf(m).Kind(); typ != reflect.Map { - t.Errorf("Map should return a map type, got: %v", typ) - } - - in, ok := m["B"].(map[string]interface{}) - if !ok { - t.Errorf("Nested type of map should be of type map[string]interface{}, have %T", m["B"]) - } - - foo := in["Foo"].(map[string]interface{}) - if name := foo["example_key"]; name != "example" { - t.Errorf("Map nested struct's name field should give example, got: %s", name) - } -} - -func TestMap_NestedMapWithSliceIntValues(t *testing.T) { - type B struct { - Foo map[string][]int - } - - type A struct { - B *B - } - - b := &B{ - Foo: map[string][]int{ - "example_key": []int{80}, - }, - } - - a := &A{B: b} - - m := Map(a) - - if typ := reflect.TypeOf(m).Kind(); typ != reflect.Map { - t.Errorf("Map should return a map type, got: %v", typ) - } - - in, ok := m["B"].(map[string]interface{}) - if !ok { - t.Errorf("Nested type of map should be of type map[string]interface{}, have %T", m["B"]) - } - - foo := in["Foo"].(map[string][]int) - if name := foo["example_key"]; name[0] != 80 { - t.Errorf("Map nested struct's name field should give example, got: %v", name) - } -} - -func TestMap_NestedMapWithSliceStructValues(t *testing.T) { - type address struct { - Country string `structs:"country"` - } - - type B struct { - Foo map[string][]address - } - - type A struct { - B *B - } - - b := &B{ - Foo: map[string][]address{ - "example_key": []address{ - {Country: "Turkey"}, - }, - }, - } - - a := &A{B: b} - m := Map(a) - - if typ := reflect.TypeOf(m).Kind(); typ != reflect.Map { - t.Errorf("Map should return a map type, got: %v", typ) - } - - in, ok := m["B"].(map[string]interface{}) - if !ok { - t.Errorf("Nested type of map should be of type map[string]interface{}, have %T", m["B"]) - } - - foo := in["Foo"].(map[string]interface{}) - - addresses := foo["example_key"].([]interface{}) - - addr, ok := addresses[0].(map[string]interface{}) - if !ok { - t.Errorf("Nested type of map should be of type map[string]interface{}, have %T", m["B"]) - } - - if _, exists := addr["country"]; !exists { - t.Errorf("Expecting country, but found Country") - } -} - -func TestMap_NestedSliceWithStructValues(t *testing.T) { - type address struct { - Country string `structs:"customCountryName"` - } - - type person struct { - Name string `structs:"name"` - Addresses []address `structs:"addresses"` - } - - p := person{ - Name: "test", - Addresses: []address{ - address{Country: "England"}, - address{Country: "Italy"}, - }, - } - mp := Map(p) - - mpAddresses := mp["addresses"].([]interface{}) - if _, exists := mpAddresses[0].(map[string]interface{})["Country"]; exists { - t.Errorf("Expecting customCountryName, but found Country") - } - - if _, exists := mpAddresses[0].(map[string]interface{})["customCountryName"]; !exists { - t.Errorf("customCountryName key not found") - } -} - -func TestMap_NestedSliceWithPointerOfStructValues(t *testing.T) { - type address struct { - Country string `structs:"customCountryName"` - } - - type person struct { - Name string `structs:"name"` - Addresses []*address `structs:"addresses"` - } - - p := person{ - Name: "test", - Addresses: []*address{ - &address{Country: "England"}, - &address{Country: "Italy"}, - }, - } - mp := Map(p) - - mpAddresses := mp["addresses"].([]interface{}) - if _, exists := mpAddresses[0].(map[string]interface{})["Country"]; exists { - t.Errorf("Expecting customCountryName, but found Country") - } - - if _, exists := mpAddresses[0].(map[string]interface{})["customCountryName"]; !exists { - t.Errorf("customCountryName key not found") - } -} - -func TestMap_NestedSliceWithIntValues(t *testing.T) { - type person struct { - Name string `structs:"name"` - Ports []int `structs:"ports"` - } - - p := person{ - Name: "test", - Ports: []int{80}, - } - m := Map(p) - - ports, ok := m["ports"].([]int) - if !ok { - t.Errorf("Nested type of map should be of type []int, have %T", m["ports"]) - } - - if ports[0] != 80 { - t.Errorf("Map nested struct's ports field should give 80, got: %v", ports) - } -} - -func TestMap_Anonymous(t *testing.T) { - type A struct { - Name string - } - a := &A{Name: "example"} - - type B struct { - *A - } - b := &B{} - b.A = a - - m := Map(b) - - if typ := reflect.TypeOf(m).Kind(); typ != reflect.Map { - t.Errorf("Map should return a map type, got: %v", typ) - } - - in, ok := m["A"].(map[string]interface{}) - if !ok { - t.Error("Embedded structs is not available in the map") - } - - if name := in["Name"].(string); name != "example" { - t.Errorf("Embedded A struct's Name field should give example, got: %s", name) - } -} - -func TestMap_Flatnested(t *testing.T) { - type A struct { - Name string - } - a := A{Name: "example"} - - type B struct { - A `structs:",flatten"` - C int - } - b := &B{C: 123} - b.A = a - - m := Map(b) - - _, ok := m["A"].(map[string]interface{}) - if ok { - t.Error("Embedded A struct with tag flatten has to be flat in the map") - } - - expectedMap := map[string]interface{}{"Name": "example", "C": 123} - if !reflect.DeepEqual(m, expectedMap) { - t.Errorf("The exprected map %+v does't correspond to %+v", expectedMap, m) - } - -} - -func TestMap_FlatnestedOverwrite(t *testing.T) { - type A struct { - Name string - } - a := A{Name: "example"} - - type B struct { - A `structs:",flatten"` - Name string - C int - } - b := &B{C: 123, Name: "bName"} - b.A = a - - m := Map(b) - - _, ok := m["A"].(map[string]interface{}) - if ok { - t.Error("Embedded A struct with tag flatten has to be flat in the map") - } - - expectedMap := map[string]interface{}{"Name": "bName", "C": 123} - if !reflect.DeepEqual(m, expectedMap) { - t.Errorf("The exprected map %+v does't correspond to %+v", expectedMap, m) - } -} - -func TestMap_TimeField(t *testing.T) { - type A struct { - CreatedAt time.Time - } - - a := &A{CreatedAt: time.Now().UTC()} - m := Map(a) - - _, ok := m["CreatedAt"].(time.Time) - if !ok { - t.Error("Time field must be final") - } -} - -func TestFillMap(t *testing.T) { - var T = struct { - A string - B int - C bool - }{ - A: "a-value", - B: 2, - C: true, - } - - a := make(map[string]interface{}, 0) - FillMap(T, a) - - // we have three fields - if len(a) != 3 { - t.Errorf("FillMap should fill a map of len 3, got: %d", len(a)) - } - - inMap := func(val interface{}) bool { - for _, v := range a { - if reflect.DeepEqual(v, val) { - return true - } - } - - return false - } - - for _, val := range []interface{}{"a-value", 2, true} { - if !inMap(val) { - t.Errorf("FillMap should have the value %v", val) - } - } -} - -func TestFillMap_Nil(t *testing.T) { - var T = struct { - A string - B int - C bool - }{ - A: "a-value", - B: 2, - C: true, - } - - defer func() { - err := recover() - if err != nil { - t.Error("FillMap should not panic if a nil map is passed") - } - }() - - // nil should no - FillMap(T, nil) -} -func TestStruct(t *testing.T) { - var T = struct{}{} - - if !IsStruct(T) { - t.Errorf("T should be a struct, got: %T", T) - } - - if !IsStruct(&T) { - t.Errorf("T should be a struct, got: %T", T) - } - -} - -func TestValues(t *testing.T) { - var T = struct { - A string - B int - C bool - }{ - A: "a-value", - B: 2, - C: true, - } - - s := Values(T) - - if typ := reflect.TypeOf(s).Kind(); typ != reflect.Slice { - t.Errorf("Values should return a slice type, got: %v", typ) - } - - inSlice := func(val interface{}) bool { - for _, v := range s { - if reflect.DeepEqual(v, val) { - return true - } - } - return false - } - - for _, val := range []interface{}{"a-value", 2, true} { - if !inSlice(val) { - t.Errorf("Values should have the value %v", val) - } - } -} - -func TestValues_OmitEmpty(t *testing.T) { - type A struct { - Name string - Value int `structs:",omitempty"` - } - - a := A{Name: "example"} - s := Values(a) - - if len(s) != 1 { - t.Errorf("Values of omitted empty fields should be not counted") - } - - if s[0].(string) != "example" { - t.Errorf("Values of omitted empty fields should left the value example") - } -} - -func TestValues_OmitNested(t *testing.T) { - type A struct { - Name string - Value int - } - - a := A{ - Name: "example", - Value: 123, - } - - type B struct { - A A `structs:",omitnested"` - C int - } - b := &B{A: a, C: 123} - - s := Values(b) - - if len(s) != 2 { - t.Errorf("Values of omitted nested struct should be not counted") - } - - inSlice := func(val interface{}) bool { - for _, v := range s { - if reflect.DeepEqual(v, val) { - return true - } - } - return false - } - - for _, val := range []interface{}{123, a} { - if !inSlice(val) { - t.Errorf("Values should have the value %v", val) - } - } -} - -func TestValues_Nested(t *testing.T) { - type A struct { - Name string - } - a := A{Name: "example"} - - type B struct { - A A - C int - } - b := &B{A: a, C: 123} - - s := Values(b) - - inSlice := func(val interface{}) bool { - for _, v := range s { - if reflect.DeepEqual(v, val) { - return true - } - } - return false - } - - for _, val := range []interface{}{"example", 123} { - if !inSlice(val) { - t.Errorf("Values should have the value %v", val) - } - } -} - -func TestValues_Anonymous(t *testing.T) { - type A struct { - Name string - } - a := A{Name: "example"} - - type B struct { - A - C int - } - b := &B{C: 123} - b.A = a - - s := Values(b) - - inSlice := func(val interface{}) bool { - for _, v := range s { - if reflect.DeepEqual(v, val) { - return true - } - } - return false - } - - for _, val := range []interface{}{"example", 123} { - if !inSlice(val) { - t.Errorf("Values should have the value %v", val) - } - } -} - -func TestNames(t *testing.T) { - var T = struct { - A string - B int - C bool - }{ - A: "a-value", - B: 2, - C: true, - } - - s := Names(T) - - if len(s) != 3 { - t.Errorf("Names should return a slice of len 3, got: %d", len(s)) - } - - inSlice := func(val string) bool { - for _, v := range s { - if reflect.DeepEqual(v, val) { - return true - } - } - return false - } - - for _, val := range []string{"A", "B", "C"} { - if !inSlice(val) { - t.Errorf("Names should have the value %v", val) - } - } -} - -func TestFields(t *testing.T) { - var T = struct { - A string - B int - C bool - }{ - A: "a-value", - B: 2, - C: true, - } - - s := Fields(T) - - if len(s) != 3 { - t.Errorf("Fields should return a slice of len 3, got: %d", len(s)) - } - - inSlice := func(val string) bool { - for _, v := range s { - if reflect.DeepEqual(v.Name(), val) { - return true - } - } - return false - } - - for _, val := range []string{"A", "B", "C"} { - if !inSlice(val) { - t.Errorf("Fields should have the value %v", val) - } - } -} - -func TestFields_OmitNested(t *testing.T) { - type A struct { - Name string - Enabled bool - } - a := A{Name: "example"} - - type B struct { - A A - C int - Value string `structs:"-"` - Number int - } - b := &B{A: a, C: 123} - - s := Fields(b) - - if len(s) != 3 { - t.Errorf("Fields should omit nested struct. Expecting 2 got: %d", len(s)) - } - - inSlice := func(val interface{}) bool { - for _, v := range s { - if reflect.DeepEqual(v.Name(), val) { - return true - } - } - return false - } - - for _, val := range []interface{}{"A", "C"} { - if !inSlice(val) { - t.Errorf("Fields should have the value %v", val) - } - } -} - -func TestFields_Anonymous(t *testing.T) { - type A struct { - Name string - } - a := A{Name: "example"} - - type B struct { - A - C int - } - b := &B{C: 123} - b.A = a - - s := Fields(b) - - inSlice := func(val interface{}) bool { - for _, v := range s { - if reflect.DeepEqual(v.Name(), val) { - return true - } - } - return false - } - - for _, val := range []interface{}{"A", "C"} { - if !inSlice(val) { - t.Errorf("Fields should have the value %v", val) - } - } -} - -func TestIsZero(t *testing.T) { - var T = struct { - A string - B int - C bool `structs:"-"` - D []string - }{} - - ok := IsZero(T) - if !ok { - t.Error("IsZero should return true because none of the fields are initialized.") - } - - var X = struct { - A string - F *bool - }{ - A: "a-value", - } - - ok = IsZero(X) - if ok { - t.Error("IsZero should return false because A is initialized") - } - - var Y = struct { - A string - B int - }{ - A: "a-value", - B: 123, - } - - ok = IsZero(Y) - if ok { - t.Error("IsZero should return false because A and B is initialized") - } -} - -func TestIsZero_OmitNested(t *testing.T) { - type A struct { - Name string - D string - } - a := A{Name: "example"} - - type B struct { - A A `structs:",omitnested"` - C int - } - b := &B{A: a, C: 123} - - ok := IsZero(b) - if ok { - t.Error("IsZero should return false because A, B and C are initialized") - } - - aZero := A{} - bZero := &B{A: aZero} - - ok = IsZero(bZero) - if !ok { - t.Error("IsZero should return true because neither A nor B is initialized") - } - -} - -func TestIsZero_Nested(t *testing.T) { - type A struct { - Name string - D string - } - a := A{Name: "example"} - - type B struct { - A A - C int - } - b := &B{A: a, C: 123} - - ok := IsZero(b) - if ok { - t.Error("IsZero should return false because A, B and C are initialized") - } - - aZero := A{} - bZero := &B{A: aZero} - - ok = IsZero(bZero) - if !ok { - t.Error("IsZero should return true because neither A nor B is initialized") - } - -} - -func TestIsZero_Anonymous(t *testing.T) { - type A struct { - Name string - D string - } - a := A{Name: "example"} - - type B struct { - A - C int - } - b := &B{C: 123} - b.A = a - - ok := IsZero(b) - if ok { - t.Error("IsZero should return false because A, B and C are initialized") - } - - aZero := A{} - bZero := &B{} - bZero.A = aZero - - ok = IsZero(bZero) - if !ok { - t.Error("IsZero should return true because neither A nor B is initialized") - } -} - -func TestHasZero(t *testing.T) { - var T = struct { - A string - B int - C bool `structs:"-"` - D []string - }{ - A: "a-value", - B: 2, - } - - ok := HasZero(T) - if !ok { - t.Error("HasZero should return true because A and B are initialized.") - } - - var X = struct { - A string - F *bool - }{ - A: "a-value", - } - - ok = HasZero(X) - if !ok { - t.Error("HasZero should return true because A is initialized") - } - - var Y = struct { - A string - B int - }{ - A: "a-value", - B: 123, - } - - ok = HasZero(Y) - if ok { - t.Error("HasZero should return false because A and B is initialized") - } -} - -func TestHasZero_OmitNested(t *testing.T) { - type A struct { - Name string - D string - } - a := A{Name: "example"} - - type B struct { - A A `structs:",omitnested"` - C int - } - b := &B{A: a, C: 123} - - // Because the Field A inside B is omitted HasZero should return false - // because it will stop iterating deeper andnot going to lookup for D - ok := HasZero(b) - if ok { - t.Error("HasZero should return false because A and C are initialized") - } -} - -func TestHasZero_Nested(t *testing.T) { - type A struct { - Name string - D string - } - a := A{Name: "example"} - - type B struct { - A A - C int - } - b := &B{A: a, C: 123} - - ok := HasZero(b) - if !ok { - t.Error("HasZero should return true because D is not initialized") - } -} - -func TestHasZero_Anonymous(t *testing.T) { - type A struct { - Name string - D string - } - a := A{Name: "example"} - - type B struct { - A - C int - } - b := &B{C: 123} - b.A = a - - ok := HasZero(b) - if !ok { - t.Error("HasZero should return false because D is not initialized") - } -} - -func TestName(t *testing.T) { - type Foo struct { - A string - B bool - } - f := &Foo{} - - n := Name(f) - if n != "Foo" { - t.Errorf("Name should return Foo, got: %s", n) - } - - unnamed := struct{ Name string }{Name: "Cihangir"} - m := Name(unnamed) - if m != "" { - t.Errorf("Name should return empty string for unnamed struct, got: %s", n) - } - - defer func() { - err := recover() - if err == nil { - t.Error("Name should panic if a non struct is passed") - } - }() - - Name([]string{}) -} - -func TestNestedNilPointer(t *testing.T) { - type Collar struct { - Engraving string - } - - type Dog struct { - Name string - Collar *Collar - } - - type Person struct { - Name string - Dog *Dog - } - - person := &Person{ - Name: "John", - } - - personWithDog := &Person{ - Name: "Ron", - Dog: &Dog{ - Name: "Rover", - }, - } - - personWithDogWithCollar := &Person{ - Name: "Kon", - Dog: &Dog{ - Name: "Ruffles", - Collar: &Collar{ - Engraving: "If lost, call Kon", - }, - }, - } - - defer func() { - err := recover() - if err != nil { - fmt.Printf("err %+v\n", err) - t.Error("Internal nil pointer should not panic") - } - }() - - _ = Map(person) // Panics - _ = Map(personWithDog) // Panics - _ = Map(personWithDogWithCollar) // Doesn't panic -} - -func TestSetValueOnNestedField(t *testing.T) { - type Base struct { - ID int - } - - type User struct { - Base - Name string - } - - u := User{} - s := New(&u) - f := s.Field("Base").Field("ID") - err := f.Set(10) - if err != nil { - t.Errorf("Error %v", err) - } - if f.Value().(int) != 10 { - t.Errorf("Value should be equal to 10, got %v", f.Value()) - } -} - -type Person struct { - Name string - Age int -} - -func (p *Person) String() string { - return fmt.Sprintf("%s(%d)", p.Name, p.Age) -} - -func TestTagWithStringOption(t *testing.T) { - - type Address struct { - Country string `json:"country"` - Person *Person `json:"person,string"` - } - - person := &Person{ - Name: "John", - Age: 23, - } - - address := &Address{ - Country: "EU", - Person: person, - } - - defer func() { - err := recover() - if err != nil { - fmt.Printf("err %+v\n", err) - t.Error("Internal nil pointer should not panic") - } - }() - - s := New(address) - - s.TagName = "json" - m := s.Map() - - if m["person"] != person.String() { - t.Errorf("Value for field person should be %s, got: %s", person.String(), m["person"]) - } - - vs := s.Values() - if vs[1] != person.String() { - t.Errorf("Value for 2nd field (person) should be %T, got: %T", person.String(), vs[1]) - } -} - -type Animal struct { - Name string - Age int -} - -type Dog struct { - Animal *Animal `json:"animal,string"` -} - -func TestNonStringerTagWithStringOption(t *testing.T) { - a := &Animal{ - Name: "Fluff", - Age: 4, - } - - d := &Dog{ - Animal: a, - } - - defer func() { - err := recover() - if err != nil { - fmt.Printf("err %+v\n", err) - t.Error("Internal nil pointer should not panic") - } - }() - - s := New(d) - - s.TagName = "json" - m := s.Map() - - if _, exists := m["animal"]; exists { - t.Errorf("Value for field Animal should not exist") - } -} - -func TestMap_InterfaceValue(t *testing.T) { - type TestStruct struct { - A interface{} - } - - expected := []byte("test value") - - a := TestStruct{A: expected} - s := Map(a) - if !reflect.DeepEqual(s["A"], expected) { - t.Errorf("Value does not match expected: %q != %q", s["A"], expected) - } -} - -func TestPointer2Pointer(t *testing.T) { - defer func() { - err := recover() - if err != nil { - fmt.Printf("err %+v\n", err) - t.Error("Internal nil pointer should not panic") - } - }() - a := &Animal{ - Name: "Fluff", - Age: 4, - } - _ = Map(&a) - - b := &a - _ = Map(&b) - - c := &b - _ = Map(&c) -} - -func TestMap_InterfaceTypeWithMapValue(t *testing.T) { - type A struct { - Name string `structs:"name"` - Ip string `structs:"ip"` - Query string `structs:"query"` - Payload interface{} `structs:"payload"` - } - - a := A{ - Name: "test", - Ip: "127.0.0.1", - Query: "", - Payload: map[string]string{"test_param": "test_param"}, - } - - defer func() { - err := recover() - if err != nil { - t.Error("Converting Map with an interface{} type with map value should not panic") - } - }() - - _ = Map(a) -} diff --git a/vendor/src/github.com/fatih/structs/tags.go b/vendor/src/github.com/fatih/structs/tags.go deleted file mode 100644 index 136a31e..0000000 --- a/vendor/src/github.com/fatih/structs/tags.go +++ /dev/null @@ -1,32 +0,0 @@ -package structs - -import "strings" - -// tagOptions contains a slice of tag options -type tagOptions []string - -// Has returns true if the given option is available in tagOptions -func (t tagOptions) Has(opt string) bool { - for _, tagOpt := range t { - if tagOpt == opt { - return true - } - } - - return false -} - -// parseTag splits a struct field's tag into its name and a list of options -// which comes after a name. A tag is in the form of: "name,option1,option2". -// The name can be neglectected. -func parseTag(tag string) (string, tagOptions) { - // tag is one of followings: - // "" - // "name" - // "name,opt" - // "name,opt,opt2" - // ",opt" - - res := strings.Split(tag, ",") - return res[0], res[1:] -} diff --git a/vendor/src/github.com/fatih/structs/tags_test.go b/vendor/src/github.com/fatih/structs/tags_test.go deleted file mode 100644 index 5d12724..0000000 --- a/vendor/src/github.com/fatih/structs/tags_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package structs - -import "testing" - -func TestParseTag_Name(t *testing.T) { - tags := []struct { - tag string - has bool - }{ - {"", false}, - {"name", true}, - {"name,opt", true}, - {"name , opt, opt2", false}, // has a single whitespace - {", opt, opt2", false}, - } - - for _, tag := range tags { - name, _ := parseTag(tag.tag) - - if (name != "name") && tag.has { - t.Errorf("Parse tag should return name: %#v", tag) - } - } -} - -func TestParseTag_Opts(t *testing.T) { - tags := []struct { - opts string - has bool - }{ - {"name", false}, - {"name,opt", true}, - {"name , opt, opt2", false}, // has a single whitespace - {",opt, opt2", true}, - {", opt3, opt4", false}, - } - - // search for "opt" - for _, tag := range tags { - _, opts := parseTag(tag.opts) - - if opts.Has("opt") != tag.has { - t.Errorf("Tag opts should have opt: %#v", tag) - } - } -}