@@ -2,11 +2,13 @@ package hasaki
22
33import (
44 "context"
5+ "encoding/xml"
56 "fmt"
67 "net"
78 "net/http"
89 "net/url"
910 "strconv"
11+ "strings"
1012 "sync/atomic"
1113 "testing"
1214 "time"
@@ -263,6 +265,7 @@ func TestMiddleware(t *testing.T) {
263265
264266 after := WithAfter (func (ctx context.Context , response * http.Response ) (context.Context , error ) {
265267 t0 := ctx .Value ("t0" ).(time.Time )
268+ time .Sleep (time .Millisecond )
266269 return context .WithValue (ctx , "latency" , time .Since (t0 ).Nanoseconds ()), nil
267270 })
268271
@@ -410,3 +413,191 @@ func TestRequest_ReadBody(t *testing.T) {
410413 assert .NoError (t , err )
411414 })
412415}
416+
417+ func TestWithBaseURL (t * testing.T ) {
418+ addr := nextAddr ()
419+ srv := & http.Server {Addr : addr }
420+ srv .Handler = http .Handler (http .HandlerFunc (func (writer http.ResponseWriter , request * http.Request ) {
421+ switch request .URL .Path {
422+ case "/api/users" :
423+ writer .WriteHeader (http .StatusOK )
424+ case "/users" :
425+ writer .WriteHeader (http .StatusOK )
426+ default :
427+ writer .WriteHeader (http .StatusOK )
428+ }
429+ }))
430+ go srv .ListenAndServe ()
431+ time .Sleep (100 * time .Millisecond )
432+
433+ t .Run ("base url with relative path" , func (t * testing.T ) {
434+ baseURL := "http://" + addr
435+ cli , _ := NewClient (WithBaseURL (baseURL ))
436+ req := cli .Get ("/api/users" )
437+ expectedURL := baseURL + "/api/users"
438+ assert .Equal (t , req .url , expectedURL )
439+ })
440+
441+ t .Run ("base url with absolute path" , func (t * testing.T ) {
442+ baseURL := "http://" + addr
443+ cli , _ := NewClient (WithBaseURL (baseURL ))
444+ req := cli .Get ("http://example.com/users" )
445+ // 当传入绝对 URL 时,应该直接使用该 URL(当前实现是字符串拼接)
446+ expectedURL := baseURL + "http://example.com/users"
447+ assert .Equal (t , req .url , expectedURL )
448+ })
449+
450+ t .Run ("base url with empty path" , func (t * testing.T ) {
451+ baseURL := "http://" + addr
452+ cli , _ := NewClient (WithBaseURL (baseURL ))
453+ req := cli .Get ("" )
454+ expectedURL := baseURL
455+ assert .Equal (t , req .url , expectedURL )
456+ })
457+
458+ t .Run ("base url with formatted path" , func (t * testing.T ) {
459+ baseURL := "http://" + addr
460+ cli , _ := NewClient (WithBaseURL (baseURL ))
461+ req := cli .Get ("/api/%s" , "users" )
462+ expectedURL := baseURL + "/api/users"
463+ assert .Equal (t , req .url , expectedURL )
464+ })
465+
466+ t .Run ("base url actual request" , func (t * testing.T ) {
467+ baseURL := "http://" + addr
468+ cli , _ := NewClient (WithBaseURL (baseURL ))
469+ resp := cli .Get ("/api/users" ).Send (nil )
470+ assert .NoError (t , resp .Err ())
471+ assert .Equal (t , resp .StatusCode , http .StatusOK )
472+ })
473+
474+ t .Run ("base url without trailing slash" , func (t * testing.T ) {
475+ baseURL := "http://" + addr
476+ cli , _ := NewClient (WithBaseURL (baseURL ))
477+ req := cli .Get ("/users" )
478+ expectedURL := baseURL + "/users"
479+ assert .Equal (t , req .url , expectedURL )
480+ })
481+
482+ t .Run ("base url with trailing slash" , func (t * testing.T ) {
483+ baseURL := "http://" + addr + "/"
484+ cli , _ := NewClient (WithBaseURL (baseURL ))
485+ req := cli .Get ("users" )
486+ expectedURL := baseURL + "users"
487+ assert .Equal (t , req .url , expectedURL )
488+ })
489+ }
490+
491+ func TestResponse_BindJSON (t * testing.T ) {
492+ addr := nextAddr ()
493+ srv := & http.Server {Addr : addr }
494+ srv .Handler = http .Handler (http .HandlerFunc (func (writer http.ResponseWriter , request * http.Request ) {
495+ writer .WriteHeader (http .StatusOK )
496+ writer .Write ([]byte (`{"name":"test","age":18}` ))
497+ }))
498+ go srv .ListenAndServe ()
499+ time .Sleep (100 * time .Millisecond )
500+
501+ t .Run ("bind json success" , func (t * testing.T ) {
502+ type User struct {
503+ Name string `json:"name"`
504+ Age int `json:"age"`
505+ }
506+ var user User
507+ resp := Get ("http://%s" , addr ).Send (nil )
508+ err := resp .BindJSON (& user )
509+ assert .NoError (t , err )
510+ assert .Equal (t , user .Name , "test" )
511+ assert .Equal (t , user .Age , 18 )
512+ })
513+
514+ t .Run ("bind json with error response" , func (t * testing.T ) {
515+ type User struct {
516+ Name string `json:"name"`
517+ }
518+ var user User
519+ resp := Get ("http://127.0.0.1:xx" ).Send (nil )
520+ err := resp .BindJSON (& user )
521+ assert .Error (t , err )
522+ })
523+ }
524+
525+ func TestResponse_BindXML (t * testing.T ) {
526+ addr := nextAddr ()
527+ srv := & http.Server {Addr : addr }
528+ srv .Handler = http .Handler (http .HandlerFunc (func (writer http.ResponseWriter , request * http.Request ) {
529+ writer .WriteHeader (http .StatusOK )
530+ writer .Write ([]byte (`<user><name>test</name><age>18</age></user>` ))
531+ }))
532+ go srv .ListenAndServe ()
533+ time .Sleep (100 * time .Millisecond )
534+
535+ t .Run ("bind xml success" , func (t * testing.T ) {
536+ type User struct {
537+ XMLName xml.Name `xml:"user"`
538+ Name string `xml:"name"`
539+ Age int `xml:"age"`
540+ }
541+ var user User
542+ resp := Get ("http://%s" , addr ).Send (nil )
543+ err := resp .BindXML (& user )
544+ assert .NoError (t , err )
545+ assert .Equal (t , user .Name , "test" )
546+ assert .Equal (t , user .Age , 18 )
547+ })
548+ }
549+
550+ func TestResponse_BindForm (t * testing.T ) {
551+ addr := nextAddr ()
552+ srv := & http.Server {Addr : addr }
553+ srv .Handler = http .Handler (http .HandlerFunc (func (writer http.ResponseWriter , request * http.Request ) {
554+ writer .WriteHeader (http .StatusOK )
555+ writer .Write ([]byte ("name=test&age=18" ))
556+ }))
557+ go srv .ListenAndServe ()
558+ time .Sleep (100 * time .Millisecond )
559+
560+ t .Run ("bind form success" , func (t * testing.T ) {
561+ var params url.Values
562+ resp := Get ("http://%s" , addr ).Send (nil )
563+ err := resp .BindForm (& params )
564+ assert .NoError (t , err )
565+ assert .Equal (t , params .Get ("name" ), "test" )
566+ assert .Equal (t , params .Get ("age" ), "18" )
567+ })
568+ }
569+
570+ func TestRequest_SetEncoder (t * testing.T ) {
571+ req := Get ("https://api.example.com" )
572+ req .SetEncoder (FormCodec )
573+ assert .Equal (t , req .headers .Get ("Content-Type" ), MimeForm )
574+
575+ req .SetEncoder (JsonCodec )
576+ assert .Equal (t , req .headers .Get ("Content-Type" ), MimeJson )
577+
578+ req .SetEncoder (XmlCodec )
579+ assert .Equal (t , req .headers .Get ("Content-Type" ), MimeXml )
580+ }
581+
582+ func TestJsonCodec_Decode (t * testing.T ) {
583+ t .Run ("decode success" , func (t * testing.T ) {
584+ type User struct {
585+ Name string `json:"name"`
586+ Age int `json:"age"`
587+ }
588+ var user User
589+ reader := strings .NewReader (`{"name":"test","age":18}` )
590+ err := JsonCodec .Decode (reader , & user )
591+ assert .NoError (t , err )
592+ assert .Equal (t , user .Name , "test" )
593+ assert .Equal (t , user .Age , 18 )
594+ })
595+
596+ t .Run ("decode map" , func (t * testing.T ) {
597+ var result map [string ]any
598+ reader := strings .NewReader (`{"name":"test","age":18}` )
599+ err := JsonCodec .Decode (reader , & result )
600+ assert .NoError (t , err )
601+ assert .Equal (t , result ["name" ], "test" )
602+ })
603+ }
0 commit comments