Last active
August 10, 2018 13:17
-
-
Save Code-Hex/71d48d14b7fec37527d3202689dd8d7f to your computer and use it in GitHub Desktop.
Revisions
-
Code-Hex revised this gist
Aug 10, 2018 . 2 changed files with 164 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,163 @@ package main import ( "reflect" "testing" ) type TS struct { id int name string } type TestStruct struct { Str string Int int Float64 float64 Slice []complex128 Bool bool Uint uint Ary [2]string Value TS Pointer *TS SliceTestStruct []*TS MapTestStruct map[string][]*TS } func TestValidateEmptyStructValue(t *testing.T) { testcases := []struct { name string typ interface{} wantErr string unexpectedErr bool }{ { name: "valid struct pointer", typ: &TestStruct{}, }, { name: "struct value", typ: &TestStruct{}, wantErr: "must pass a empty struct pointer", }, { name: "int", typ: 10, wantErr: "must pass a empty struct pointer", }, { name: "string", typ: "10", wantErr: "must pass a empty struct pointer", }, { name: "nil", typ: nil, wantErr: "must pass a empty struct pointer", }, { name: "non empty struct (string)", typ: &TestStruct{Str: "Hello"}, wantErr: "must pass a empty struct pointer, you passed containing values", }, { name: "non empty struct (int)", typ: &TestStruct{Int: 10}, wantErr: "must pass a empty struct pointer, you passed containing values", }, { name: "non empty struct (float64)", typ: &TestStruct{Float64: 30.5}, wantErr: "must pass a empty struct pointer, you passed containing values", }, { name: "non empty struct ([]complex128])", typ: &TestStruct{Slice: []complex128{-23, 1i}}, wantErr: "must pass a empty struct pointer, you passed containing values", }, { name: "non empty struct (bool)", typ: &TestStruct{Bool: true}, wantErr: "must pass a empty struct pointer, you passed containing values", }, { name: "non empty struct (array)", typ: &TestStruct{Ary: [2]string{}}, wantErr: "must pass a empty struct pointer, you passed containing values", }, { name: "non empty struct (struct value)", typ: &TestStruct{Value: TS{id: 1}}, wantErr: "must pass a empty struct pointer, you passed containing values", }, { name: "non empty struct (struct pointer)", typ: &TestStruct{Pointer: &TS{}}, wantErr: "must pass a empty struct pointer, you passed containing values", }, { name: "non empty struct (slice of struct pointer)", typ: &TestStruct{SliceTestStruct: make([]*TS, 1)}, wantErr: "must pass a empty struct pointer, you passed containing values", }, { name: "non empty struct (map of slice of struct pointer)", typ: &TestStruct{MapTestStruct: make(map[string][]*TS, 1)}, wantErr: "must pass a empty struct pointer, you passed containing values", }, } for _, testcase := range testcases { t.Run(testcase.name, func(t *testing.T) { v := reflect.ValueOf(testcase.typ) err := validateEmptyStructValue(v) if err != nil { if err.Error() != testcase.wantErr { t.Fatalf(`expected "%s", but got "%s"`, testcase.wantErr, err) } } }) } } func Test_validateSendChannel(t *testing.T) { testcases := []struct { name string typ interface{} wantErr string }{ { name: "channel", typ: make(chan struct{}), }, { name: "send channel", typ: make(chan<- struct{}), }, { name: "another type", typ: 10, wantErr: `must pass a channel which is send direction (got "int")`, }, { name: "nil", typ: nil, wantErr: `must pass a channel which is send direction (got "nil")`, }, { name: "recv channel", typ: make(<-chan struct{}), wantErr: "must pass a channel which is send direction", }, } for _, testcase := range testcases { t.Run(testcase.name, func(t *testing.T) { v := reflect.ValueOf(testcase.typ) err := validateSendChannel(v) if err != nil { if err.Error() != testcase.wantErr { t.Fatalf(`expected "%s", but got "%s"`, testcase.wantErr, err) } } }) } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ package main import ( "errors" -
Code-Hex revised this gist
Aug 10, 2018 . No changes.There are no files selected for viewing
-
Code-Hex created this gist
Aug 10, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,74 @@ package fetcher import ( "errors" "fmt" "reflect" ) func validateEmptyStructValue(v reflect.Value) error { if !v.IsValid() || v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { return errors.New("must pass a empty struct pointer") } if !isZero(v) { return errors.New("must pass a empty struct pointer, you passed containing values") } return nil } func validateSendChannel(chrv reflect.Value) error { if !chrv.IsValid() || chrv.Kind() != reflect.Chan { typ := "nil" if chrv.IsValid() { typ = chrv.Type().String() } return fmt.Errorf(`must pass a channel which is send direction (got "%s")`, typ) } if (chrv.Type().ChanDir() & reflect.SendDir) == 0 { return errors.New(`must pass a channel which is send direction`) } return nil } func isZero(v reflect.Value) bool { switch v.Kind() { case reflect.Bool: return v.Bool() == false case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return v.Int() == 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: return v.Uint() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 case reflect.Complex64, reflect.Complex128: return v.Complex() == 0 case reflect.Ptr, reflect.Interface: return !v.IsNil() case reflect.Array: for i := 0; i < v.Len(); i++ { if !isZero(v.Index(i)) { return false } } return true case reflect.Slice, reflect.String, reflect.Map: return v.Len() == 0 case reflect.Struct: for i, n := 0, v.NumField(); i < n; i++ { if !isZero(v.Field(i)) { return false } } return true } return false }