Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SetBody支持io.Reader,BindBody支持io.Writer #64

Merged
merged 3 commits into from
Oct 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ gout 是go写的http 客户端,为提高工作效率而开发
- [http header](#http-header)
- [http body](#http-body)
- [body](#body)
- [SetBody](#setbody)
- [BindBody](#bindbody)
- [json](#json)
- [yaml](#yaml)
- [xml](#xml)
Expand Down Expand Up @@ -184,24 +186,36 @@ SetHeader([]string{"active", "enable", "action", "drop"})

## http body
### body
#### SetBody
* SetBody 设置string, []byte等类型数据到http body里面
* BindBody bind body到string, []byte等类型变量里面
```go
// 设置string变量至请求的http body
err := gout.New(nil).POST(url).SetBody("hello world"/*更多支持类型请看下面*/).Do()

err := gout.New(nil).POST(url).SetBody(/*支持的类型如下*/).Do()

// 设置实现io.Reader接口的变量至 请求的http body
err = gout.POST(url).SetBody(bytes.NewBufferString("hello world")).Code(&code).Do()
```
#### bindBody
* BindBody bind body到string, []byte等类型变量里面
```go
// 解析http body到string类型变量里面
var s string
err := gout.New(nil).GET(url).BindBody(&s/*支持的指针类型变量如下*/).Do()
err := gout.New(nil).GET(url).BindBody(&s/*更多支持指针类型变量请看下面*/).Do()

// 解析http body至实现io.Writer接口的变量里面
var b bytes.Buffer{}
err = gout.GET(url).BindBody(&b).Code(&code).Do()
```
## 支持的类型有
#### 支持的类型有
* io.Reader(SetBody 支持)
* io.Writer(BindBody 支持)
* int, int8, int16, int32, int64
* uint, uint8, uint16, uint32, uint64
* string
* []byte
* float32, float64

## 明确不支持的类型有
#### 明确不支持的类型有
* struct
* array, slice

Expand Down
5 changes: 5 additions & 0 deletions decode/body.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ func (b *BodyDecode) Decode(r io.Reader) error {
}

func DecodeBody(r io.Reader, obj interface{}) error {
if w, ok := obj.(io.Writer); ok {
_, err := io.Copy(w, r)
return err
}

all, err := ioutil.ReadAll(r)
if err != nil {
return err
Expand Down
3 changes: 3 additions & 0 deletions decode/body_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ func testDecodeBody(t *testing.T, funcName string) {

{r: bytes.NewBufferString("test string"), need: core.NewPtrVal("test string"), got: new(string)},
{r: bytes.NewBuffer([]byte("test bytes")), need: core.NewPtrVal([]byte("test bytes")), got: new([]byte)},

// test io.Writer
{r: bytes.NewBuffer([]byte("test buffer")), need: bytes.NewBufferString("test buffer"), got: bytes.NewBufferString("")},
}

for _, v := range tests {
Expand Down
6 changes: 6 additions & 0 deletions encode/body.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@ func NewBodyEncode(obj interface{}) *BodyEncode {
}

func (b *BodyEncode) Encode(w io.Writer) error {
if r, ok := b.obj.(io.Reader); ok {
_, err := io.Copy(w, r)
return err
}

val := reflect.ValueOf(b.obj)
val = core.LoopElem(val)

switch t := val.Kind(); t {
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
Expand Down
12 changes: 11 additions & 1 deletion encode/body_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package encode

import (
"bytes"
"github.com/guonaihong/gout/core"
"github.com/stretchr/testify/assert"
"strings"
"testing"
"time"
)

func TestNewBodyEncode(t *testing.T) {
Expand All @@ -18,6 +20,12 @@ type bodyTest struct {
need string
}

func Test_body_EncodeFail(t *testing.T) {
b := NewBodyEncode(&time.Time{})
err := b.Encode(bytes.NewBufferString("hello world"))
assert.Error(t, err)
}

func Test_body_Encode(t *testing.T) {

tests := []bodyTest{
Expand All @@ -35,8 +43,10 @@ func Test_body_Encode(t *testing.T) {
{w: &strings.Builder{}, set: []byte("test bytes"), need: "test bytes"},
{w: &strings.Builder{}, set: "test string", need: "test string"},
{w: &strings.Builder{}, set: int(1), need: "1"},

{w: &strings.Builder{}, set: core.NewPtrVal(1010), need: "1010"},

// test io.Reader
{w: &strings.Builder{}, set: bytes.NewBufferString("set body:hello world"), need: "set body:hello world"},
}

for _, v := range tests {
Expand Down
107 changes: 40 additions & 67 deletions group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -616,12 +616,19 @@ type testBodyNeed struct {
Int64 bool `form:"int64"`
String bool `form:"string"`
Bytes bool `form:"bytes"`
Reader bool `form:"reader"`
}

type testBodyBind struct {
Type string `uri:"type"`
}

type testBodyReq struct {
url string
got interface{}
need interface{}
}

func TestBindBody(t *testing.T) {
router := func() *gin.Engine {
router := gin.Default()
Expand Down Expand Up @@ -660,6 +667,8 @@ func TestBindBody(t *testing.T) {
c.String(200, "string")
case "bytes":
c.String(200, "bytes")
case "io.writer":
c.String(200, "io.writer")
default:
c.String(500, "unknown")
}
Expand All @@ -669,77 +678,34 @@ func TestBindBody(t *testing.T) {
}()

ts := httptest.NewServer(http.HandlerFunc(router.ServeHTTP))
code := 0

var u uint
err := New(nil).GET(ts.URL + "/uint").BindBody(&u).Code(&code).Do()
assert.Equal(t, u, uint(1))
assert.NoError(t, err)

var u8 uint8
err = New(nil).GET(ts.URL + "/uint8").BindBody(&u8).Code(&code).Do()
assert.Equal(t, u8, uint8(2))
assert.NoError(t, err)

var u16 uint16
err = New(nil).GET(ts.URL + "/uint16").BindBody(&u16).Code(&code).Do()
assert.Equal(t, u16, uint16(3))
assert.NoError(t, err)

var u32 uint32
err = New(nil).GET(ts.URL + "/uint32").BindBody(&u32).Code(&code).Do()
assert.Equal(t, u32, uint32(4))
assert.NoError(t, err)

var u64 uint64
err = New(nil).GET(ts.URL + "/uint64").BindBody(&u64).Code(&code).Do()
assert.Equal(t, u64, uint64(5))
assert.NoError(t, err)

var i int
err = New(nil).GET(ts.URL + "/int").BindBody(&i).Code(&code).Do()
assert.Equal(t, i, int(6))
assert.NoError(t, err)

var i8 int8
err = New(nil).GET(ts.URL + "/int8").BindBody(&i8).Code(&code).Do()
assert.Equal(t, i8, int8(7))
assert.NoError(t, err)

var i16 int16
err = New(nil).GET(ts.URL + "/int16").BindBody(&i16).Code(&code).Do()
assert.Equal(t, i16, int16(8))
assert.NoError(t, err)

var i32 int32
err = New(nil).GET(ts.URL + "/int32").BindBody(&i32).Code(&code).Do()
assert.Equal(t, i32, int32(9))
assert.NoError(t, err)

var i64 int64
err = New(nil).GET(ts.URL + "/int64").BindBody(&i64).Code(&code).Do()
assert.Equal(t, i64, int64(10))
assert.NoError(t, err)

var f32 float32
err = New(nil).GET(ts.URL + "/float32").BindBody(&f32).Code(&code).Do()
assert.Equal(t, f32, float32(11))
assert.NoError(t, err)
tests := []testBodyReq{
{url: "/uint", got: new(uint), need: core.NewPtrVal(uint(1))},
{url: "/uint8", got: new(uint8), need: core.NewPtrVal(uint8(2))},
{url: "/uint16", got: new(uint16), need: core.NewPtrVal(uint16(3))},
{url: "/uint32", got: new(uint32), need: core.NewPtrVal(uint32(4))},
{url: "/uint64", got: new(uint64), need: core.NewPtrVal(uint64(5))},
{url: "/int", got: new(int), need: core.NewPtrVal(int(6))},
{url: "/int8", got: new(int8), need: core.NewPtrVal(int8(7))},
{url: "/int16", got: new(int16), need: core.NewPtrVal(int16(8))},
{url: "/int32", got: new(int32), need: core.NewPtrVal(int32(9))},
{url: "/int64", got: new(int64), need: core.NewPtrVal(int64(10))},
{url: "/float32", got: new(float32), need: core.NewPtrVal(float32(11))},
{url: "/float64", got: new(float64), need: core.NewPtrVal(float64(12))},
{url: "/string", got: new(string), need: core.NewPtrVal("string")},
{url: "/bytes", got: new([]byte), need: core.NewPtrVal([]byte("bytes"))},
{url: "/io.writer", got: bytes.NewBufferString(""), need: bytes.NewBufferString("io.writer")},
}

var f64 float64
err = New(nil).GET(ts.URL + "/float64").BindBody(&f64).Code(&code).Do()
assert.Equal(t, f64, float64(12))
assert.NoError(t, err)
for _, v := range tests {

var s string
err = New(nil).GET(ts.URL + "/string").BindBody(&s).Code(&code).Do()
assert.Equal(t, s, "string")
assert.NoError(t, err)
code := 0
err := New(nil).GET(ts.URL + v.url).BindBody(v.got).Code(&code).Do()
assert.Equal(t, code, 200)
assert.NoError(t, err)
assert.Equal(t, v.got, v.need)
}

var b []byte
err = New(nil).GET(ts.URL + "/bytes").BindBody(&b).Code(&code).Do()
assert.Equal(t, b, []byte("bytes"))
assert.NoError(t, err)
}

func TestSetBody(t *testing.T) {
Expand Down Expand Up @@ -787,6 +753,8 @@ func TestSetBody(t *testing.T) {
assert.Equal(t, s, "11")
case testBody.Float64:
assert.Equal(t, s, "12")
case testBody.Reader:
assert.Equal(t, s, "test io.Reader")
default:
c.JSON(500, "unknown type")
}
Expand Down Expand Up @@ -855,6 +823,11 @@ func TestSetBody(t *testing.T) {
err = New(nil).POST(ts.URL).SetQuery(H{"bytes": true}).SetBody([]byte("test bytes")).Code(&code).Do()
assert.NoError(t, err)
assert.Equal(t, code, 200)

// test io.Reader
err = New(nil).POST(ts.URL).SetQuery(H{"reader": true}).SetBody(bytes.NewBufferString("test io.Reader")).Code(&code).Do()
assert.NoError(t, err)
assert.Equal(t, code, 200)
}

func setupProxy(t *testing.T) *gin.Engine {
Expand Down