github.com/wfusion/gofusion@v1.1.14/test/http/cases/router_test.go (about)

     1  package cases
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"mime/multipart"
    10  	"net/http"
    11  	"net/http/httptest"
    12  	"os"
    13  	"strings"
    14  	"testing"
    15  
    16  	"github.com/gin-gonic/gin"
    17  	"github.com/stretchr/testify/suite"
    18  
    19  	"github.com/wfusion/gofusion/common/env"
    20  	"github.com/wfusion/gofusion/common/utils"
    21  	"github.com/wfusion/gofusion/log"
    22  
    23  	fusHtp "github.com/wfusion/gofusion/http"
    24  	testHtp "github.com/wfusion/gofusion/test/http"
    25  )
    26  
    27  func TestRouter(t *testing.T) {
    28  	testingSuite := &Router{Test: new(testHtp.Test)}
    29  	testingSuite.Init(testingSuite)
    30  	suite.Run(t, testingSuite)
    31  }
    32  
    33  type Router struct {
    34  	*testHtp.Test
    35  }
    36  
    37  func (t *Router) BeforeTest(suiteName, testName string) {
    38  	t.Catch(func() {
    39  		log.Info(context.Background(), "right before %s %s", suiteName, testName)
    40  	})
    41  }
    42  
    43  func (t *Router) AfterTest(suiteName, testName string) {
    44  	t.Catch(func() {
    45  		log.Info(context.Background(), "right after %s %s", suiteName, testName)
    46  	})
    47  }
    48  
    49  // case: func(c *gin.Context)
    50  func (t *Router) TestExample01() {
    51  	t.Catch(func() {
    52  		// Given
    53  		method := http.MethodPost
    54  		path := "/test"
    55  		rspBody := map[string]any{"code": 0, "msg": "ok"}
    56  		hd := func(c *gin.Context) {
    57  			c.JSON(http.StatusOK, rspBody)
    58  		}
    59  
    60  		w := httptest.NewRecorder()
    61  		req, err := http.NewRequest(method, path, nil)
    62  		t.Require().NoError(err)
    63  		engine := t.ServerGiven(method, path, hd)
    64  
    65  		// When
    66  		engine.ServeHTTP(w, req)
    67  
    68  		// Then
    69  		t.Equal(http.StatusOK, w.Code)
    70  		t.Equal(string(utils.MustJsonMarshal(rspBody)), w.Body.String())
    71  	})
    72  }
    73  
    74  // case: func(c *gin.Context, req *Struct FromJsonBody) error
    75  func (t *Router) TestExample02() {
    76  	t.Catch(func() {
    77  		// Given
    78  		type reqStruct struct {
    79  			ID      *string `json:"id"`
    80  			NumList []int   `json:"num_list"`
    81  			Embed   *struct {
    82  				FUID    *string `json:"fuid"`
    83  				Boolean *bool   `json:"boolean"`
    84  			} `json:"embed"`
    85  		}
    86  
    87  		method := http.MethodPost
    88  		path := "/test"
    89  		hd := func(c *gin.Context, req *reqStruct) error {
    90  			t.Require().NotNil(req)
    91  			t.Require().NotEmpty(req.ID)
    92  			t.Require().NotEmpty(req.NumList)
    93  			t.Require().NotEmpty(req.Embed)
    94  			t.Require().NotEmpty(req.Embed.FUID)
    95  			t.Require().NotNil(req.Embed.Boolean)
    96  			return io.ErrUnexpectedEOF
    97  		}
    98  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
    99  			ID:      utils.AnyPtr(utils.UUID()),
   100  			NumList: []int{1, 2, 3, 4, 5, 6},
   101  			Embed: &struct {
   102  				FUID    *string `json:"fuid"`
   103  				Boolean *bool   `json:"boolean"`
   104  			}{
   105  				FUID:    utils.AnyPtr(utils.UUID()),
   106  				Boolean: utils.AnyPtr(true),
   107  			},
   108  		}))
   109  
   110  		w := httptest.NewRecorder()
   111  		req, err := http.NewRequest(method, path, reqBody)
   112  		req.Header.Set("Content-Type", "application/json")
   113  		t.Require().NoError(err)
   114  		engine := t.ServerGiven(method, path, hd)
   115  
   116  		// When
   117  		engine.ServeHTTP(w, req)
   118  
   119  		// Then
   120  		t.Equal(http.StatusOK, w.Code)
   121  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
   122  	})
   123  }
   124  
   125  // case: func(c *gin.Context, req *Struct FromQuery) error
   126  func (t *Router) TestExample03() {
   127  	t.Catch(func() {
   128  		// Given
   129  		type reqStruct struct {
   130  			ID      *string `json:"id"`
   131  			NumList []int   `json:"num_list"`
   132  			Embed   *string `json:"embed"`
   133  		}
   134  
   135  		method := http.MethodGet
   136  		path := "/test"
   137  		hd := func(c *gin.Context, req *reqStruct) error {
   138  			t.Require().NotNil(req)
   139  			t.Require().NotEmpty(req.ID)
   140  			t.Require().NotEmpty(req.NumList)
   141  			t.Require().NotEmpty(req.Embed)
   142  			return io.ErrUnexpectedEOF
   143  		}
   144  		uri := path + "?id=b5890985-47e1-4eca-9dc8-ec95060e896d" +
   145  			"&num_list=1&num_list=2&num_list=3&num_list=4&num_list=5&num_list=6" +
   146  			"&embed={\\\"fuid\\\":\\\"b5890985-47e1-4eca-9dc8-ec95060e896d\\\",\\\"boolean\\\":true}}"
   147  
   148  		w := httptest.NewRecorder()
   149  		req, err := http.NewRequest(method, uri, nil)
   150  		req.Header.Set("Content-Type", "application/json")
   151  		t.Require().NoError(err)
   152  		engine := t.ServerGiven(method, path, hd)
   153  
   154  		// When
   155  		engine.ServeHTTP(w, req)
   156  
   157  		// Then
   158  		t.Equal(http.StatusOK, w.Code)
   159  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
   160  	})
   161  }
   162  
   163  // case: func(c *gin.Context, req *FromJsonBody) (rsp *Struct{Data *struct; Page, Count int; Msg string}, err error)
   164  func (t *Router) TestExample04() {
   165  	t.Catch(func() {
   166  		// Given
   167  		type reqStruct struct {
   168  			ID      *string `json:"id"`
   169  			NumList []int   `json:"num_list"`
   170  			Embed   *struct {
   171  				FUID    *string `json:"fuid"`
   172  				Boolean *bool   `json:"boolean"`
   173  			} `json:"embed"`
   174  		}
   175  		type rspStruct struct {
   176  			Page  int
   177  			Count int
   178  			Msg   string
   179  			Data  *struct {
   180  				Name *string `json:"name"`
   181  				UUID *string `json:"uuid"`
   182  			}
   183  		}
   184  
   185  		method := http.MethodPost
   186  		path := "/test"
   187  		data := &struct {
   188  			Name *string `json:"name"`
   189  			UUID *string `json:"uuid"`
   190  		}{
   191  			Name: utils.AnyPtr("what's your name"),
   192  			UUID: utils.AnyPtr(utils.UUID()),
   193  		}
   194  		hd := func(c *gin.Context, req *reqStruct) (*rspStruct, error) {
   195  			t.Require().NotNil(req)
   196  			t.Require().NotEmpty(req.ID)
   197  			t.Require().NotEmpty(req.NumList)
   198  			t.Require().NotEmpty(req.Embed)
   199  			t.Require().NotEmpty(req.Embed.FUID)
   200  			t.Require().NotNil(req.Embed.Boolean)
   201  			return &rspStruct{Page: 1, Count: 1, Msg: "ok", Data: data}, nil
   202  		}
   203  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
   204  			ID:      utils.AnyPtr(utils.UUID()),
   205  			NumList: []int{1, 2, 3, 4, 5, 6},
   206  			Embed: &struct {
   207  				FUID    *string `json:"fuid"`
   208  				Boolean *bool   `json:"boolean"`
   209  			}{
   210  				FUID:    utils.AnyPtr(utils.UUID()),
   211  				Boolean: utils.AnyPtr(true),
   212  			},
   213  		}))
   214  
   215  		w := httptest.NewRecorder()
   216  		req, err := http.NewRequest(method, path, reqBody)
   217  		req.Header.Set("Content-Type", "application/json")
   218  		t.Require().NoError(err)
   219  		engine := t.ServerGiven(method, path, hd)
   220  
   221  		// When
   222  		engine.ServeHTTP(w, req)
   223  
   224  		// Then
   225  		t.Equal(http.StatusOK, w.Code)
   226  
   227  		rsp := utils.MustJsonUnmarshal[fusHtp.Response](w.Body.Bytes())
   228  		t.Require().EqualValues(1, *rsp.Page)
   229  		t.Require().EqualValues(1, *rsp.Count)
   230  		t.Require().EqualValues("ok", rsp.Message)
   231  		t.Require().NotEmpty(rsp.Data)
   232  		t.Require().EqualValues(utils.MustJsonMarshal(data), utils.MustJsonMarshal(rsp.Data))
   233  	})
   234  }
   235  
   236  // case: func(c *gin.Context, req *FromJsonBody) (rsp *Struct{data *struct; page, count int; msg string}, err error)
   237  func (t *Router) TestExample05() {
   238  	t.Catch(func() {
   239  		// Given
   240  		type reqStruct struct {
   241  			ID      *string `json:"id"`
   242  			NumList []int   `json:"num_list"`
   243  			Embed   *struct {
   244  				FUID    *string `json:"fuid"`
   245  				Boolean *bool   `json:"boolean"`
   246  			} `json:"embed"`
   247  		}
   248  		type rspStruct struct {
   249  			page  int
   250  			count int
   251  			msg   string
   252  			data  *struct {
   253  				Name *string `json:"name"`
   254  				UUID *string `json:"uuid"`
   255  			}
   256  		}
   257  
   258  		method := http.MethodPost
   259  		path := "/test"
   260  		data := &struct {
   261  			Name *string `json:"name"`
   262  			UUID *string `json:"uuid"`
   263  		}{
   264  			Name: utils.AnyPtr("what's your name"),
   265  			UUID: utils.AnyPtr(utils.UUID()),
   266  		}
   267  		hd := func(c *gin.Context, req *reqStruct) (*rspStruct, error) {
   268  			t.Require().NotNil(req)
   269  			t.Require().NotEmpty(req.ID)
   270  			t.Require().NotEmpty(req.NumList)
   271  			t.Require().NotEmpty(req.Embed)
   272  			t.Require().NotEmpty(req.Embed.FUID)
   273  			t.Require().NotNil(req.Embed.Boolean)
   274  			return &rspStruct{page: 1, count: 1, msg: "ok", data: data}, nil
   275  		}
   276  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
   277  			ID:      utils.AnyPtr(utils.UUID()),
   278  			NumList: []int{1, 2, 3, 4, 5, 6},
   279  			Embed: &struct {
   280  				FUID    *string `json:"fuid"`
   281  				Boolean *bool   `json:"boolean"`
   282  			}{
   283  				FUID:    utils.AnyPtr(utils.UUID()),
   284  				Boolean: utils.AnyPtr(true),
   285  			},
   286  		}))
   287  
   288  		w := httptest.NewRecorder()
   289  		req, err := http.NewRequest(method, path, reqBody)
   290  		req.Header.Set("Content-Type", "application/json")
   291  		t.Require().NoError(err)
   292  		engine := t.ServerGiven(method, path, hd)
   293  
   294  		// When
   295  		engine.ServeHTTP(w, req)
   296  
   297  		// Then
   298  		t.Equal(http.StatusOK, w.Code)
   299  
   300  		rsp := utils.MustJsonUnmarshal[fusHtp.Response](w.Body.Bytes())
   301  
   302  		t.Require().EqualValues(1, *rsp.Page)
   303  		t.Require().EqualValues(1, *rsp.Count)
   304  		t.Require().EqualValues("ok", rsp.Message)
   305  		t.Require().NotEmpty(rsp.Data)
   306  		t.Require().EqualValues(utils.MustJsonMarshal(data), utils.MustJsonMarshal(rsp.Data))
   307  	})
   308  }
   309  
   310  // case: func(c *gin.Context, req *FromJsonBody) (rsp *Struct{data struct; page, count int; msg string}, err error)
   311  func (t *Router) TestExample06() {
   312  	t.Catch(func() {
   313  		// Given
   314  		type reqStruct struct {
   315  			ID      *string `json:"id"`
   316  			NumList []int   `json:"num_list"`
   317  			Embed   *struct {
   318  				FUID    *string `json:"fuid"`
   319  				Boolean *bool   `json:"boolean"`
   320  			} `json:"embed"`
   321  		}
   322  		type rspStruct struct {
   323  			page  int
   324  			count int
   325  			msg   string
   326  			data  struct {
   327  				Name *string `json:"name"`
   328  				UUID *string `json:"uuid"`
   329  			}
   330  		}
   331  
   332  		method := http.MethodPost
   333  		path := "/test"
   334  		data := &struct {
   335  			Name *string `json:"name"`
   336  			UUID *string `json:"uuid"`
   337  		}{
   338  			Name: utils.AnyPtr("what's your name"),
   339  			UUID: utils.AnyPtr(utils.UUID()),
   340  		}
   341  		hd := func(c *gin.Context, req *reqStruct) (*rspStruct, error) {
   342  			t.Require().NotNil(req)
   343  			t.Require().NotEmpty(req.ID)
   344  			t.Require().NotEmpty(req.NumList)
   345  			t.Require().NotEmpty(req.Embed)
   346  			t.Require().NotEmpty(req.Embed.FUID)
   347  			t.Require().NotNil(req.Embed.Boolean)
   348  			return &rspStruct{page: 1, count: 1, msg: "ok", data: *data}, nil
   349  		}
   350  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
   351  			ID:      utils.AnyPtr(utils.UUID()),
   352  			NumList: []int{1, 2, 3, 4, 5, 6},
   353  			Embed: &struct {
   354  				FUID    *string `json:"fuid"`
   355  				Boolean *bool   `json:"boolean"`
   356  			}{
   357  				FUID:    utils.AnyPtr(utils.UUID()),
   358  				Boolean: utils.AnyPtr(true),
   359  			},
   360  		}))
   361  
   362  		w := httptest.NewRecorder()
   363  		req, err := http.NewRequest(method, path, reqBody)
   364  		req.Header.Set("Content-Type", "application/json")
   365  		t.Require().NoError(err)
   366  		engine := t.ServerGiven(method, path, hd)
   367  
   368  		// When
   369  		engine.ServeHTTP(w, req)
   370  
   371  		// Then
   372  		t.Equal(http.StatusOK, w.Code)
   373  
   374  		rsp := utils.MustJsonUnmarshal[fusHtp.Response](w.Body.Bytes())
   375  
   376  		t.Require().EqualValues(1, *rsp.Page)
   377  		t.Require().EqualValues(1, *rsp.Count)
   378  		t.Require().EqualValues("ok", rsp.Message)
   379  		t.Require().NotEmpty(rsp.Data)
   380  		t.Require().EqualValues(utils.MustJsonMarshal(data), utils.MustJsonMarshal(rsp.Data))
   381  	})
   382  }
   383  
   384  // case: func(c *gin.Context, req *FromJsonBody) (rsp map[string]any, err error)
   385  func (t *Router) TestExample07() {
   386  	t.Catch(func() {
   387  		// Given
   388  		type reqStruct struct {
   389  			ID      *string `json:"id"`
   390  			NumList []int   `json:"num_list"`
   391  			Embed   *struct {
   392  				FUID    *string `json:"fuid"`
   393  				Boolean *bool   `json:"boolean"`
   394  			} `json:"embed"`
   395  		}
   396  
   397  		method := http.MethodPost
   398  		path := "/test"
   399  		expRsp := map[string]any{
   400  			"page":  1,
   401  			"count": 1,
   402  			"msg":   "ok",
   403  			"data": map[string]any{
   404  				"name": utils.AnyPtr("what's your name"),
   405  				"uuid": utils.AnyPtr(utils.UUID()),
   406  			},
   407  		}
   408  		hd := func(c *gin.Context, req *reqStruct) (map[string]any, error) {
   409  			t.Require().NotNil(req)
   410  			t.Require().NotEmpty(req.ID)
   411  			t.Require().NotEmpty(req.NumList)
   412  			t.Require().NotEmpty(req.Embed)
   413  			t.Require().NotEmpty(req.Embed.FUID)
   414  			t.Require().NotNil(req.Embed.Boolean)
   415  			return expRsp, nil
   416  		}
   417  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
   418  			ID:      utils.AnyPtr(utils.UUID()),
   419  			NumList: []int{1, 2, 3, 4, 5, 6},
   420  			Embed: &struct {
   421  				FUID    *string `json:"fuid"`
   422  				Boolean *bool   `json:"boolean"`
   423  			}{
   424  				FUID:    utils.AnyPtr(utils.UUID()),
   425  				Boolean: utils.AnyPtr(true),
   426  			},
   427  		}))
   428  
   429  		w := httptest.NewRecorder()
   430  		req, err := http.NewRequest(method, path, reqBody)
   431  		req.Header.Set("Content-Type", "application/json")
   432  		t.Require().NoError(err)
   433  		engine := t.ServerGiven(method, path, hd)
   434  
   435  		// When
   436  		engine.ServeHTTP(w, req)
   437  
   438  		// Then
   439  		t.Equal(http.StatusOK, w.Code)
   440  
   441  		rsp := utils.MustJsonUnmarshal[fusHtp.Response](w.Body.Bytes())
   442  
   443  		t.Require().EqualValues(1, *rsp.Page)
   444  		t.Require().EqualValues(1, *rsp.Count)
   445  		t.Require().EqualValues("ok", rsp.Message)
   446  		t.Require().NotEmpty(rsp.Data)
   447  		t.Require().EqualValues(utils.MustJsonMarshal(expRsp["data"]), utils.MustJsonMarshal(rsp.Data))
   448  	})
   449  }
   450  
   451  // case: func(c *gin.Context, req *FromJsonBody) (data *struct, page, count int, msg string, err error)
   452  func (t *Router) TestExample08() {
   453  	t.Catch(func() {
   454  		// Given
   455  		type reqStruct struct {
   456  			ID      *string `json:"id"`
   457  			NumList []int   `json:"num_list"`
   458  			Embed   *struct {
   459  				FUID    *string `json:"fuid"`
   460  				Boolean *bool   `json:"boolean"`
   461  			} `json:"embed"`
   462  		}
   463  		type dataStruct struct {
   464  			Name *string `json:"name"`
   465  			UUID *string `json:"uuid"`
   466  		}
   467  
   468  		method := http.MethodPost
   469  		path := "/test"
   470  		data := &dataStruct{
   471  			Name: utils.AnyPtr("what's your name"),
   472  			UUID: utils.AnyPtr(utils.UUID()),
   473  		}
   474  		hd := func(c *gin.Context, req *reqStruct) (*dataStruct, int, int, string, error) {
   475  			t.Require().NotNil(req)
   476  			t.Require().NotEmpty(req.ID)
   477  			t.Require().NotEmpty(req.NumList)
   478  			t.Require().NotEmpty(req.Embed)
   479  			t.Require().NotEmpty(req.Embed.FUID)
   480  			t.Require().NotNil(req.Embed.Boolean)
   481  			return data, 1, 1, "ok", nil
   482  		}
   483  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
   484  			ID:      utils.AnyPtr(utils.UUID()),
   485  			NumList: []int{1, 2, 3, 4, 5, 6},
   486  			Embed: &struct {
   487  				FUID    *string `json:"fuid"`
   488  				Boolean *bool   `json:"boolean"`
   489  			}{
   490  				FUID:    utils.AnyPtr(utils.UUID()),
   491  				Boolean: utils.AnyPtr(true),
   492  			},
   493  		}))
   494  
   495  		w := httptest.NewRecorder()
   496  		req, err := http.NewRequest(method, path, reqBody)
   497  		req.Header.Set("Content-Type", "application/json")
   498  		t.Require().NoError(err)
   499  		engine := t.ServerGiven(method, path, hd)
   500  
   501  		// When
   502  		engine.ServeHTTP(w, req)
   503  
   504  		// Then
   505  		t.Equal(http.StatusOK, w.Code)
   506  
   507  		rsp := utils.MustJsonUnmarshal[fusHtp.Response](w.Body.Bytes())
   508  		t.Require().EqualValues(1, *rsp.Page)
   509  		t.Require().EqualValues(1, *rsp.Count)
   510  		t.Require().EqualValues("ok", rsp.Message)
   511  		t.Require().NotEmpty(rsp.Data)
   512  		t.Require().EqualValues(utils.MustJsonMarshal(data), utils.MustJsonMarshal(rsp.Data))
   513  	})
   514  }
   515  
   516  // case: func(c *gin.Context, req *FromJsonBody) (data map[string]any, page, count int, err error)
   517  func (t *Router) TestExample09() {
   518  	t.Catch(func() {
   519  		// Given
   520  		type reqStruct struct {
   521  			ID      *string `json:"id"`
   522  			NumList []int   `json:"num_list"`
   523  			Embed   *struct {
   524  				FUID    *string `json:"fuid"`
   525  				Boolean *bool   `json:"boolean"`
   526  			} `json:"embed"`
   527  		}
   528  
   529  		method := http.MethodPost
   530  		path := "/test"
   531  		data := map[string]any{
   532  			"name": utils.AnyPtr("what's your name"),
   533  			"uuid": utils.AnyPtr(utils.UUID()),
   534  		}
   535  		hd := func(c *gin.Context, req *reqStruct) (map[string]any, int, int, string, error) {
   536  			t.Require().NotNil(req)
   537  			t.Require().NotEmpty(req.ID)
   538  			t.Require().NotEmpty(req.NumList)
   539  			t.Require().NotEmpty(req.Embed)
   540  			t.Require().NotEmpty(req.Embed.FUID)
   541  			t.Require().NotNil(req.Embed.Boolean)
   542  			return data, 1, 1, "ok", nil
   543  		}
   544  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
   545  			ID:      utils.AnyPtr(utils.UUID()),
   546  			NumList: []int{1, 2, 3, 4, 5, 6},
   547  			Embed: &struct {
   548  				FUID    *string `json:"fuid"`
   549  				Boolean *bool   `json:"boolean"`
   550  			}{
   551  				FUID:    utils.AnyPtr(utils.UUID()),
   552  				Boolean: utils.AnyPtr(true),
   553  			},
   554  		}))
   555  
   556  		w := httptest.NewRecorder()
   557  		req, err := http.NewRequest(method, path, reqBody)
   558  		req.Header.Set("Content-Type", "application/json")
   559  		t.Require().NoError(err)
   560  		engine := t.ServerGiven(method, path, hd)
   561  
   562  		// When
   563  		engine.ServeHTTP(w, req)
   564  
   565  		// Then
   566  		t.Equal(http.StatusOK, w.Code)
   567  
   568  		rsp := utils.MustJsonUnmarshal[fusHtp.Response](w.Body.Bytes())
   569  
   570  		t.Require().EqualValues(1, *rsp.Page)
   571  		t.Require().EqualValues(1, *rsp.Count)
   572  		t.Require().EqualValues("ok", rsp.Message)
   573  		t.Require().NotEmpty(rsp.Data)
   574  		t.Require().EqualValues(utils.MustJsonMarshal(data), utils.MustJsonMarshal(rsp.Data))
   575  	})
   576  }
   577  
   578  // case: func(c *gin.Context, req *FromJsonBody) (data struct, page, count *int64, msg *string, err error)
   579  func (t *Router) TestExample10() {
   580  	t.Catch(func() {
   581  		// Given
   582  		type reqStruct struct {
   583  			ID      *string `json:"id"`
   584  			NumList []int   `json:"num_list"`
   585  			Embed   *struct {
   586  				FUID    *string `json:"fuid"`
   587  				Boolean *bool   `json:"boolean"`
   588  			} `json:"embed"`
   589  		}
   590  		type dataStruct struct {
   591  			Name *string `json:"name"`
   592  			UUID *string `json:"uuid"`
   593  		}
   594  
   595  		method := http.MethodPost
   596  		path := "/test"
   597  		data := &dataStruct{
   598  			Name: utils.AnyPtr("what's your name"),
   599  			UUID: utils.AnyPtr(utils.UUID()),
   600  		}
   601  		hd := func(c *gin.Context, req *reqStruct) (dataStruct, *int64, *int64, *string, error) {
   602  			t.Require().NotNil(req)
   603  			t.Require().NotEmpty(req.ID)
   604  			t.Require().NotEmpty(req.NumList)
   605  			t.Require().NotEmpty(req.Embed)
   606  			t.Require().NotEmpty(req.Embed.FUID)
   607  			t.Require().NotNil(req.Embed.Boolean)
   608  			return *data, utils.AnyPtr(int64(1)), utils.AnyPtr(int64(1)), utils.AnyPtr("ok"), nil
   609  		}
   610  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
   611  			ID:      utils.AnyPtr(utils.UUID()),
   612  			NumList: []int{1, 2, 3, 4, 5, 6},
   613  			Embed: &struct {
   614  				FUID    *string `json:"fuid"`
   615  				Boolean *bool   `json:"boolean"`
   616  			}{
   617  				FUID:    utils.AnyPtr(utils.UUID()),
   618  				Boolean: utils.AnyPtr(true),
   619  			},
   620  		}))
   621  
   622  		w := httptest.NewRecorder()
   623  		req, err := http.NewRequest(method, path, reqBody)
   624  		req.Header.Set("Content-Type", "application/json")
   625  		t.Require().NoError(err)
   626  		engine := t.ServerGiven(method, path, hd)
   627  
   628  		// When
   629  		engine.ServeHTTP(w, req)
   630  
   631  		// Then
   632  		t.Equal(http.StatusOK, w.Code)
   633  
   634  		rsp := utils.MustJsonUnmarshal[fusHtp.Response](w.Body.Bytes())
   635  
   636  		t.Require().EqualValues(1, *rsp.Page)
   637  		t.Require().EqualValues(1, *rsp.Count)
   638  		t.Require().EqualValues("ok", rsp.Message)
   639  		t.Require().NotEmpty(rsp.Data)
   640  		t.Require().EqualValues(utils.MustJsonMarshal(data), utils.MustJsonMarshal(rsp.Data))
   641  	})
   642  }
   643  
   644  // case: func(c *gin.Context, req *FromJsonBody) (data []map[string]any, page, count int, err error)
   645  func (t *Router) TestExample11() {
   646  	t.Catch(func() {
   647  		// Given
   648  		type reqStruct struct {
   649  			ID      *string `json:"id"`
   650  			NumList []int   `json:"num_list"`
   651  			Embed   *struct {
   652  				FUID    *string `json:"fuid"`
   653  				Boolean *bool   `json:"boolean"`
   654  			} `json:"embed"`
   655  		}
   656  
   657  		method := http.MethodPost
   658  		path := "/test"
   659  		data := []map[string]any{
   660  			{
   661  				"name": utils.AnyPtr("what's your name"),
   662  				"uuid": utils.AnyPtr(utils.UUID()),
   663  			},
   664  		}
   665  		hd := func(c *gin.Context, req *reqStruct) ([]map[string]any, int, int, string, error) {
   666  			t.Require().NotNil(req)
   667  			t.Require().NotEmpty(req.ID)
   668  			t.Require().NotEmpty(req.NumList)
   669  			t.Require().NotEmpty(req.Embed)
   670  			t.Require().NotEmpty(req.Embed.FUID)
   671  			t.Require().NotNil(req.Embed.Boolean)
   672  			return data, 1, 1, "ok", nil
   673  		}
   674  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
   675  			ID:      utils.AnyPtr(utils.UUID()),
   676  			NumList: []int{1, 2, 3, 4, 5, 6},
   677  			Embed: &struct {
   678  				FUID    *string `json:"fuid"`
   679  				Boolean *bool   `json:"boolean"`
   680  			}{
   681  				FUID:    utils.AnyPtr(utils.UUID()),
   682  				Boolean: utils.AnyPtr(true),
   683  			},
   684  		}))
   685  
   686  		w := httptest.NewRecorder()
   687  		req, err := http.NewRequest(method, path, reqBody)
   688  		req.Header.Set("Content-Type", "application/json")
   689  		t.Require().NoError(err)
   690  		engine := t.ServerGiven(method, path, hd)
   691  
   692  		// When
   693  		engine.ServeHTTP(w, req)
   694  
   695  		// Then
   696  		t.Equal(http.StatusOK, w.Code)
   697  
   698  		rsp := utils.MustJsonUnmarshal[fusHtp.Response](w.Body.Bytes())
   699  
   700  		t.Require().EqualValues(1, *rsp.Page)
   701  		t.Require().EqualValues(1, *rsp.Count)
   702  		t.Require().EqualValues("ok", rsp.Message)
   703  		t.Require().NotEmpty(rsp.Data)
   704  		t.Require().EqualValues(utils.MustJsonMarshal(data), utils.MustJsonMarshal(rsp.Data))
   705  	})
   706  }
   707  
   708  // case: func(c *gin.Context, req *Struct FromFormUrlDecodedBody) error
   709  func (t *Router) TestExample12() {
   710  	t.Catch(func() {
   711  		// Given
   712  		type reqStruct struct {
   713  			ID      *string `json:"id"`
   714  			NumList []int   `json:"num_list"`
   715  			Embed   *string `json:"embed"`
   716  		}
   717  
   718  		method := http.MethodPost
   719  		path := "/test"
   720  		hd := func(c *gin.Context, req *reqStruct) error {
   721  			t.Require().NotNil(req)
   722  			t.Require().NotEmpty(req.ID)
   723  			t.Require().NotEmpty(req.NumList)
   724  			t.Require().NotEmpty(req.Embed)
   725  			return io.ErrUnexpectedEOF
   726  		}
   727  		body := strings.NewReader("id=b5890985-47e1-4eca-9dc8-ec95060e896d" +
   728  			"&num_list=1&num_list=2&num_list=3&num_list=4&num_list=5&num_list=6" +
   729  			"&embed={\\\"fuid\\\":\\\"b5890985-47e1-4eca-9dc8-ec95060e896d\\\",\\\"boolean\\\":true}}")
   730  		w := httptest.NewRecorder()
   731  		req, err := http.NewRequest(method, path, body)
   732  		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
   733  		t.Require().NoError(err)
   734  		engine := t.ServerGiven(method, path, hd)
   735  
   736  		// When
   737  		engine.ServeHTTP(w, req)
   738  
   739  		// Then
   740  		t.Equal(http.StatusOK, w.Code)
   741  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
   742  	})
   743  }
   744  
   745  // case: func(c *gin.Context, req *Struct FromMultipartFormDataBody) error
   746  func (t *Router) TestExample13() {
   747  	t.Catch(func() {
   748  		// Given
   749  		type reqStruct struct {
   750  			ID      *string `json:"id"`
   751  			NumList []int   `json:"num_list"`
   752  			Embed   *string `json:"embed"`
   753  			File    []byte  `json:"file"`
   754  		}
   755  
   756  		method := http.MethodPost
   757  		path := "/test"
   758  		hd := func(c *gin.Context, req *reqStruct) error {
   759  			t.Require().NotNil(req)
   760  			t.Require().NotEmpty(req.ID)
   761  			t.Require().NotEmpty(req.NumList)
   762  			t.Require().NotEmpty(req.Embed)
   763  			t.Require().NotEmpty(req.File)
   764  			return io.ErrUnexpectedEOF
   765  		}
   766  
   767  		reqBody := bytes.NewBuffer(nil)
   768  		writer := multipart.NewWriter(reqBody)
   769  
   770  		// write file
   771  		files := t.ConfigFiles()
   772  		filePath := fmt.Sprintf("%s/configs/%s.%s", env.WorkDir, t.AppName(), files[len(files)-1])
   773  		part, err := writer.CreateFormFile("file", filePath)
   774  		t.Require().NoError(err)
   775  		file, err := os.Open(filePath)
   776  		t.Require().NoError(err)
   777  		_, err = io.Copy(part, file)
   778  		t.Require().NoError(err)
   779  
   780  		// write field
   781  		reqMap := map[string]string{
   782  			"id":       utils.UUID(),
   783  			"num_list": string(utils.MustJsonMarshal([]int{1, 2, 3, 4, 5, 6})),
   784  			"embed": string(utils.MustJsonMarshal(&struct {
   785  				FUID    *string `json:"fuid"`
   786  				Boolean *bool   `json:"boolean"`
   787  			}{
   788  				FUID:    utils.AnyPtr(utils.UUID()),
   789  				Boolean: utils.AnyPtr(true),
   790  			})),
   791  		}
   792  		for k, v := range reqMap {
   793  			t.Require().NoError(writer.WriteField(k, v))
   794  		}
   795  		utils.CloseAnyway(writer)
   796  
   797  		w := httptest.NewRecorder()
   798  		req, err := http.NewRequest(method, path, reqBody)
   799  		req.Header.Add("Content-Type", writer.FormDataContentType())
   800  		t.Require().NoError(err)
   801  		engine := t.ServerGiven(method, path, hd)
   802  
   803  		// When
   804  		engine.ServeHTTP(w, req)
   805  
   806  		// Then
   807  		t.Equal(http.StatusOK, w.Code)
   808  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
   809  	})
   810  }
   811  
   812  // case: object.public.method(c *gin.Context, req *FromJsonBody) error
   813  func (t *Router) TestExample14() {
   814  	t.Catch(func() {
   815  		// Given
   816  		method := http.MethodPost
   817  		path := "/test"
   818  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&routerReqStruct{
   819  			ID:      utils.AnyPtr(utils.UUID()),
   820  			NumList: []int{1, 2, 3, 4, 5, 6},
   821  			Embed: &struct {
   822  				FUID    *string `json:"fuid"`
   823  				Boolean *bool   `json:"boolean"`
   824  			}{
   825  				FUID:    utils.AnyPtr(utils.UUID()),
   826  				Boolean: utils.AnyPtr(true),
   827  			},
   828  		}))
   829  
   830  		w := httptest.NewRecorder()
   831  		req, err := http.NewRequest(method, path, reqBody)
   832  		req.Header.Set("Content-Type", "application/json")
   833  		t.Require().NoError(err)
   834  		engine := t.ServerGiven(method, path, t.handle)
   835  
   836  		// When
   837  		engine.ServeHTTP(w, req)
   838  
   839  		// Then
   840  		t.Equal(http.StatusOK, w.Code)
   841  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
   842  	})
   843  }
   844  
   845  // case: object.private.method(c *gin.Context, req *FromJsonBody) error
   846  func (t *Router) TestExample15() {
   847  	t.Catch(func() {
   848  		// Given
   849  		method := http.MethodPost
   850  		path := "/test"
   851  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&routerReqStruct{
   852  			ID:      utils.AnyPtr(utils.UUID()),
   853  			NumList: []int{1, 2, 3, 4, 5, 6},
   854  			Embed: &struct {
   855  				FUID    *string `json:"fuid"`
   856  				Boolean *bool   `json:"boolean"`
   857  			}{
   858  				FUID:    utils.AnyPtr(utils.UUID()),
   859  				Boolean: utils.AnyPtr(true),
   860  			},
   861  		}))
   862  
   863  		w := httptest.NewRecorder()
   864  		req, err := http.NewRequest(method, path, reqBody)
   865  		req.Header.Set("Content-Type", "application/json")
   866  		t.Require().NoError(err)
   867  		engine := t.ServerGiven(method, path, t.handle)
   868  
   869  		// When
   870  		engine.ServeHTTP(w, req)
   871  
   872  		// Then
   873  		t.Equal(http.StatusOK, w.Code)
   874  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
   875  	})
   876  }
   877  
   878  // case: func(c *gin.Context, req *FromJsonBody) error, http redirect
   879  func (t *Router) TestExample16() {
   880  	t.Catch(func() {
   881  		// Given
   882  		type reqStruct struct {
   883  			ID      *string `json:"id"`
   884  			NumList []int   `json:"num_list"`
   885  			Embed   *struct {
   886  				FUID    *string `json:"fuid"`
   887  				Boolean *bool   `json:"boolean"`
   888  			} `json:"embed"`
   889  		}
   890  
   891  		method := http.MethodPost
   892  		path := "/test"
   893  		hd := func(c *gin.Context, req *reqStruct) error {
   894  			t.Require().NotNil(req)
   895  			t.Require().NotEmpty(req.ID)
   896  			t.Require().NotEmpty(req.NumList)
   897  			t.Require().NotEmpty(req.Embed)
   898  			t.Require().NotEmpty(req.Embed.FUID)
   899  			t.Require().NotNil(req.Embed.Boolean)
   900  
   901  			c.Redirect(http.StatusTemporaryRedirect, "https://ctyun.cn")
   902  			return nil
   903  		}
   904  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
   905  			ID:      utils.AnyPtr(utils.UUID()),
   906  			NumList: []int{1, 2, 3, 4, 5, 6},
   907  			Embed: &struct {
   908  				FUID    *string `json:"fuid"`
   909  				Boolean *bool   `json:"boolean"`
   910  			}{
   911  				FUID:    utils.AnyPtr(utils.UUID()),
   912  				Boolean: utils.AnyPtr(true),
   913  			},
   914  		}))
   915  
   916  		w := httptest.NewRecorder()
   917  		req, err := http.NewRequest(method, path, reqBody)
   918  		req.Header.Set("Content-Type", "application/json")
   919  		t.Require().NoError(err)
   920  		engine := t.ServerGiven(method, path, hd)
   921  
   922  		// When
   923  		engine.ServeHTTP(w, req)
   924  
   925  		// Then
   926  		t.Equal(http.StatusTemporaryRedirect, w.Code)
   927  		t.Contains(w.Header().Get("Location"), "ctyun")
   928  	})
   929  }
   930  
   931  // case: func(c *gin.Context, req map[string]any FromJsonBody) error
   932  func (t *Router) TestExample17() {
   933  	t.Catch(func() {
   934  		// Given
   935  		type reqStruct struct {
   936  			ID      *string `json:"id"`
   937  			NumList []int   `json:"num_list"`
   938  			Embed   *struct {
   939  				FUID    *string `json:"fuid"`
   940  				Boolean *bool   `json:"boolean"`
   941  			} `json:"embed"`
   942  		}
   943  
   944  		method := http.MethodPost
   945  		path := "/test"
   946  		hd := func(c *gin.Context, req map[string]any) error {
   947  			t.Require().NotNil(req)
   948  			t.Require().NotEmpty(req["id"])
   949  			t.Require().NotEmpty(req["num_list"])
   950  			t.Require().NotEmpty(req["embed"])
   951  			t.Require().NotEmpty(req["embed"].(map[string]any)["fuid"])
   952  			t.Require().NotNil(req["embed"].(map[string]any)["boolean"])
   953  			return io.ErrUnexpectedEOF
   954  		}
   955  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
   956  			ID:      utils.AnyPtr(utils.UUID()),
   957  			NumList: []int{1, 2, 3, 4, 5, 6},
   958  			Embed: &struct {
   959  				FUID    *string `json:"fuid"`
   960  				Boolean *bool   `json:"boolean"`
   961  			}{
   962  				FUID:    utils.AnyPtr(utils.UUID()),
   963  				Boolean: utils.AnyPtr(true),
   964  			},
   965  		}))
   966  
   967  		w := httptest.NewRecorder()
   968  		req, err := http.NewRequest(method, path, reqBody)
   969  		req.Header.Set("Content-Type", "application/json")
   970  		t.Require().NoError(err)
   971  		engine := t.ServerGiven(method, path, hd)
   972  
   973  		// When
   974  		engine.ServeHTTP(w, req)
   975  
   976  		// Then
   977  		t.Equal(http.StatusOK, w.Code)
   978  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
   979  	})
   980  }
   981  
   982  // case: func(c *gin.Context, req []map[string]any FromJsonBody) error
   983  func (t *Router) TestExample18() {
   984  	t.Catch(func() {
   985  		// Given
   986  		type reqStruct struct {
   987  			ID      *string `json:"id"`
   988  			NumList []int   `json:"num_list"`
   989  			Embed   *struct {
   990  				FUID    *string `json:"fuid"`
   991  				Boolean *bool   `json:"boolean"`
   992  			} `json:"embed"`
   993  		}
   994  
   995  		method := http.MethodPost
   996  		path := "/test"
   997  		hd := func(c *gin.Context, req []map[string]any) error {
   998  			t.Require().NotEmpty(req)
   999  			req1 := req[0]
  1000  			t.Require().NotNil(req1)
  1001  			t.Require().NotEmpty(req1["id"])
  1002  			t.Require().NotEmpty(req1["num_list"])
  1003  			t.Require().NotEmpty(req1["embed"])
  1004  			t.Require().NotEmpty(req1["embed"].(map[string]any)["fuid"])
  1005  			t.Require().NotNil(req1["embed"].(map[string]any)["boolean"])
  1006  			return io.ErrUnexpectedEOF
  1007  		}
  1008  		reqBody := bytes.NewReader(utils.MustJsonMarshal([]any{
  1009  			&reqStruct{
  1010  				ID:      utils.AnyPtr(utils.UUID()),
  1011  				NumList: []int{1, 2, 3, 4, 5, 6},
  1012  				Embed: &struct {
  1013  					FUID    *string `json:"fuid"`
  1014  					Boolean *bool   `json:"boolean"`
  1015  				}{
  1016  					FUID:    utils.AnyPtr(utils.UUID()),
  1017  					Boolean: utils.AnyPtr(true),
  1018  				},
  1019  			},
  1020  			struct {
  1021  				ID uint `json:"id"`
  1022  			}{
  1023  				ID: 1,
  1024  			},
  1025  		}))
  1026  
  1027  		w := httptest.NewRecorder()
  1028  		req, err := http.NewRequest(method, path, reqBody)
  1029  		req.Header.Set("Content-Type", "application/json")
  1030  		t.Require().NoError(err)
  1031  		engine := t.ServerGiven(method, path, hd)
  1032  
  1033  		// When
  1034  		engine.ServeHTTP(w, req)
  1035  
  1036  		// Then
  1037  		t.Equal(http.StatusOK, w.Code)
  1038  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1039  	})
  1040  }
  1041  
  1042  // case: func(c *gin.Context, req Struct FromJsonBody) error
  1043  func (t *Router) TestExample19() {
  1044  	t.Catch(func() {
  1045  		// Given
  1046  		type reqStruct struct {
  1047  			ID      *string `json:"id"`
  1048  			NumList []int   `json:"num_list"`
  1049  			Embed   *struct {
  1050  				FUID    *string `json:"fuid"`
  1051  				Boolean *bool   `json:"boolean"`
  1052  			} `json:"embed"`
  1053  		}
  1054  
  1055  		method := http.MethodPost
  1056  		path := "/test"
  1057  		hd := func(c *gin.Context, req reqStruct) error {
  1058  			t.Require().NotNil(req)
  1059  			t.Require().NotEmpty(req.ID)
  1060  			t.Require().NotEmpty(req.NumList)
  1061  			t.Require().NotEmpty(req.Embed)
  1062  			t.Require().NotEmpty(req.Embed.FUID)
  1063  			t.Require().NotNil(req.Embed.Boolean)
  1064  			return io.ErrUnexpectedEOF
  1065  		}
  1066  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
  1067  			ID:      utils.AnyPtr(utils.UUID()),
  1068  			NumList: []int{1, 2, 3, 4, 5, 6},
  1069  			Embed: &struct {
  1070  				FUID    *string `json:"fuid"`
  1071  				Boolean *bool   `json:"boolean"`
  1072  			}{
  1073  				FUID:    utils.AnyPtr(utils.UUID()),
  1074  				Boolean: utils.AnyPtr(true),
  1075  			},
  1076  		}))
  1077  
  1078  		w := httptest.NewRecorder()
  1079  		req, err := http.NewRequest(method, path, reqBody)
  1080  		req.Header.Set("Content-Type", "application/json")
  1081  		t.Require().NoError(err)
  1082  		engine := t.ServerGiven(method, path, hd)
  1083  
  1084  		// When
  1085  		engine.ServeHTTP(w, req)
  1086  
  1087  		// Then
  1088  		t.Equal(http.StatusOK, w.Code)
  1089  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1090  	})
  1091  }
  1092  
  1093  // case: func(c *gin.Context, req map[string]any FromFormUrlDecodedBody) error
  1094  func (t *Router) TestExample20() {
  1095  	t.Catch(func() {
  1096  		// Given
  1097  		method := http.MethodPost
  1098  		path := "/test"
  1099  		hd := func(c *gin.Context, req map[string]any) error {
  1100  			t.Require().NotNil(req)
  1101  			t.Require().NotEmpty(req["id"])
  1102  			t.Require().NotEmpty(req["num_list"])
  1103  			t.Require().NotEmpty(req["embed"])
  1104  			return io.ErrUnexpectedEOF
  1105  		}
  1106  		body := strings.NewReader("id=b5890985-47e1-4eca-9dc8-ec95060e896d" +
  1107  			"&num_list=1&num_list=2&num_list=3&num_list=4&num_list=5&num_list=6" +
  1108  			"&embed={\\\"fuid\\\":\\\"b5890985-47e1-4eca-9dc8-ec95060e896d\\\",\\\"boolean\\\":true}}")
  1109  		w := httptest.NewRecorder()
  1110  		req, err := http.NewRequest(method, path, body)
  1111  		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  1112  		t.Require().NoError(err)
  1113  		engine := t.ServerGiven(method, path, hd)
  1114  
  1115  		// When
  1116  		engine.ServeHTTP(w, req)
  1117  
  1118  		// Then
  1119  		t.Equal(http.StatusOK, w.Code)
  1120  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1121  	})
  1122  }
  1123  
  1124  // case: func(c *gin.Context, req []map[string]any FromFormUrlDecodedBody) error
  1125  func (t *Router) TestExample21() {
  1126  	t.Catch(func() {
  1127  		// Given
  1128  		method := http.MethodPost
  1129  		path := "/test"
  1130  		hd := func(c *gin.Context, req []map[string]any) error {
  1131  			t.Require().NotEmpty(req)
  1132  			req1 := req[0]
  1133  			t.Require().NotNil(req1)
  1134  			t.Require().NotEmpty(req1["id"])
  1135  			t.Require().NotEmpty(req1["num_list"])
  1136  			t.Require().NotEmpty(req1["embed"])
  1137  			return io.ErrUnexpectedEOF
  1138  		}
  1139  		body := strings.NewReader("id=b5890985-47e1-4eca-9dc8-ec95060e896d" +
  1140  			"&num_list=1&num_list=2&num_list=3&num_list=4&num_list=5&num_list=6" +
  1141  			"&embed={\\\"fuid\\\":\\\"b5890985-47e1-4eca-9dc8-ec95060e896d\\\",\\\"boolean\\\":true}}")
  1142  		w := httptest.NewRecorder()
  1143  		req, err := http.NewRequest(method, path, body)
  1144  		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  1145  		t.Require().NoError(err)
  1146  		engine := t.ServerGiven(method, path, hd)
  1147  
  1148  		// When
  1149  		engine.ServeHTTP(w, req)
  1150  
  1151  		// Then
  1152  		t.Equal(http.StatusOK, w.Code)
  1153  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1154  	})
  1155  }
  1156  
  1157  // case: func(c *gin.Context, req Struct FromFormUrlDecodedBody) error
  1158  func (t *Router) TestExample22() {
  1159  	t.Catch(func() {
  1160  		// Given
  1161  		type reqStruct struct {
  1162  			ID      *string `json:"id"`
  1163  			NumList []int   `json:"num_list"`
  1164  			Embed   *string `json:"embed"`
  1165  		}
  1166  
  1167  		method := http.MethodPost
  1168  		path := "/test"
  1169  		hd := func(c *gin.Context, req reqStruct) error {
  1170  			t.Require().NotNil(req)
  1171  			t.Require().NotEmpty(req.ID)
  1172  			t.Require().NotEmpty(req.NumList)
  1173  			t.Require().NotEmpty(req.Embed)
  1174  			return io.ErrUnexpectedEOF
  1175  		}
  1176  		body := strings.NewReader("id=b5890985-47e1-4eca-9dc8-ec95060e896d" +
  1177  			"&num_list=1&num_list=2&num_list=3&num_list=4&num_list=5&num_list=6" +
  1178  			"&embed={\\\"fuid\\\":\\\"b5890985-47e1-4eca-9dc8-ec95060e896d\\\",\\\"boolean\\\":true}}")
  1179  		w := httptest.NewRecorder()
  1180  		req, err := http.NewRequest(method, path, body)
  1181  		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  1182  		t.Require().NoError(err)
  1183  		engine := t.ServerGiven(method, path, hd)
  1184  
  1185  		// When
  1186  		engine.ServeHTTP(w, req)
  1187  
  1188  		// Then
  1189  		t.Equal(http.StatusOK, w.Code)
  1190  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1191  	})
  1192  }
  1193  
  1194  // case: func(c *gin.Context, req map[string]any FromQuery) error
  1195  func (t *Router) TestExample23() {
  1196  	t.Catch(func() {
  1197  		// Given
  1198  		method := http.MethodGet
  1199  		path := "/test"
  1200  		hd := func(c *gin.Context, req map[string]any) error {
  1201  			t.Require().NotNil(req)
  1202  			t.Require().NotEmpty(req["id"])
  1203  			t.Require().NotEmpty(req["num_list"])
  1204  			t.Require().NotEmpty(req["embed"])
  1205  			return io.ErrUnexpectedEOF
  1206  		}
  1207  		uri := path + "?id=b5890985-47e1-4eca-9dc8-ec95060e896d" +
  1208  			"&num_list=1&num_list=2&num_list=3&num_list=4&num_list=5&num_list=6" +
  1209  			"&embed={\\\"fuid\\\":\\\"b5890985-47e1-4eca-9dc8-ec95060e896d\\\",\\\"boolean\\\":true}}"
  1210  
  1211  		w := httptest.NewRecorder()
  1212  		req, err := http.NewRequest(method, uri, nil)
  1213  		req.Header.Set("Content-Type", "application/json")
  1214  		t.Require().NoError(err)
  1215  		engine := t.ServerGiven(method, path, hd)
  1216  
  1217  		// When
  1218  		engine.ServeHTTP(w, req)
  1219  
  1220  		// Then
  1221  		t.Equal(http.StatusOK, w.Code)
  1222  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1223  	})
  1224  }
  1225  
  1226  // case: func(c *gin.Context, req []map[string]any FromQuery) error
  1227  func (t *Router) TestExample24() {
  1228  	t.Catch(func() {
  1229  		// Given
  1230  		method := http.MethodGet
  1231  		path := "/test"
  1232  		hd := func(c *gin.Context, req []map[string]any) error {
  1233  			t.Require().NotEmpty(req)
  1234  			req1 := req[0]
  1235  			t.Require().NotNil(req1)
  1236  			t.Require().NotEmpty(req1["id"])
  1237  			t.Require().NotEmpty(req1["num_list"])
  1238  			t.Require().NotEmpty(req1["embed"])
  1239  			return io.ErrUnexpectedEOF
  1240  		}
  1241  		uri := path + "?id=b5890985-47e1-4eca-9dc8-ec95060e896d" +
  1242  			"&num_list=1&num_list=2&num_list=3&num_list=4&num_list=5&num_list=6" +
  1243  			"&embed={\\\"fuid\\\":\\\"b5890985-47e1-4eca-9dc8-ec95060e896d\\\",\\\"boolean\\\":true}}"
  1244  
  1245  		w := httptest.NewRecorder()
  1246  		req, err := http.NewRequest(method, uri, nil)
  1247  		req.Header.Set("Content-Type", "application/json")
  1248  		t.Require().NoError(err)
  1249  		engine := t.ServerGiven(method, path, hd)
  1250  
  1251  		// When
  1252  		engine.ServeHTTP(w, req)
  1253  
  1254  		// Then
  1255  		t.Equal(http.StatusOK, w.Code)
  1256  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1257  	})
  1258  }
  1259  
  1260  // case: func(c *gin.Context, req Struct FromQuery) error
  1261  func (t *Router) TestExample25() {
  1262  	t.Catch(func() {
  1263  		// Given
  1264  		type reqStruct struct {
  1265  			ID      *string `json:"id"`
  1266  			NumList []int   `json:"num_list"`
  1267  			Embed   *string `json:"embed"`
  1268  		}
  1269  
  1270  		method := http.MethodGet
  1271  		path := "/test"
  1272  		hd := func(c *gin.Context, req reqStruct) error {
  1273  			t.Require().NotNil(req)
  1274  			t.Require().NotEmpty(req.ID)
  1275  			t.Require().NotEmpty(req.NumList)
  1276  			t.Require().NotEmpty(req.Embed)
  1277  			return io.ErrUnexpectedEOF
  1278  		}
  1279  		uri := path + "?id=b5890985-47e1-4eca-9dc8-ec95060e896d" +
  1280  			"&num_list=1&num_list=2&num_list=3&num_list=4&num_list=5&num_list=6" +
  1281  			"&embed={\\\"fuid\\\":\\\"b5890985-47e1-4eca-9dc8-ec95060e896d\\\",\\\"boolean\\\":true}}"
  1282  
  1283  		w := httptest.NewRecorder()
  1284  		req, err := http.NewRequest(method, uri, nil)
  1285  		req.Header.Set("Content-Type", "application/json")
  1286  		t.Require().NoError(err)
  1287  		engine := t.ServerGiven(method, path, hd)
  1288  
  1289  		// When
  1290  		engine.ServeHTTP(w, req)
  1291  
  1292  		// Then
  1293  		t.Equal(http.StatusOK, w.Code)
  1294  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1295  	})
  1296  }
  1297  
  1298  // case: func(c *gin.Context, req Struct FromMultipartFormDataBody) error
  1299  func (t *Router) TestExample28() {
  1300  	t.Catch(func() {
  1301  		// Given
  1302  		type reqStruct struct {
  1303  			ID      *string `json:"id"`
  1304  			NumList []int   `json:"num_list"`
  1305  			Embed   *string `json:"embed"`
  1306  			File    []byte  `json:"file"`
  1307  		}
  1308  
  1309  		method := http.MethodPost
  1310  		path := "/test"
  1311  		hd := func(c *gin.Context, req reqStruct) error {
  1312  			t.Require().NotNil(req)
  1313  			t.Require().NotEmpty(req.ID)
  1314  			t.Require().NotEmpty(req.NumList)
  1315  			t.Require().NotEmpty(req.Embed)
  1316  			t.Require().NotEmpty(req.File)
  1317  			return io.ErrUnexpectedEOF
  1318  		}
  1319  
  1320  		reqBody := bytes.NewBuffer(nil)
  1321  		writer := multipart.NewWriter(reqBody)
  1322  
  1323  		// write file
  1324  		files := t.ConfigFiles()
  1325  		filePath := fmt.Sprintf("%s/configs/%s.%s", env.WorkDir, t.AppName(), files[len(files)-1])
  1326  		part, err := writer.CreateFormFile("file", filePath)
  1327  		t.Require().NoError(err)
  1328  		file, err := os.Open(filePath)
  1329  		t.Require().NoError(err)
  1330  		_, err = io.Copy(part, file)
  1331  		t.Require().NoError(err)
  1332  
  1333  		// write field
  1334  		reqMap := map[string]string{
  1335  			"id":       utils.UUID(),
  1336  			"num_list": string(utils.MustJsonMarshal([]int{1, 2, 3, 4, 5, 6})),
  1337  			"embed": string(utils.MustJsonMarshal(&struct {
  1338  				FUID    *string `json:"fuid"`
  1339  				Boolean *bool   `json:"boolean"`
  1340  			}{
  1341  				FUID:    utils.AnyPtr(utils.UUID()),
  1342  				Boolean: utils.AnyPtr(true),
  1343  			})),
  1344  		}
  1345  		for k, v := range reqMap {
  1346  			t.Require().NoError(writer.WriteField(k, v))
  1347  		}
  1348  		utils.CloseAnyway(writer)
  1349  
  1350  		w := httptest.NewRecorder()
  1351  		req, err := http.NewRequest(method, path, reqBody)
  1352  		req.Header.Add("Content-Type", writer.FormDataContentType())
  1353  		t.Require().NoError(err)
  1354  		engine := t.ServerGiven(method, path, hd)
  1355  
  1356  		// When
  1357  		engine.ServeHTTP(w, req)
  1358  
  1359  		// Then
  1360  		t.Equal(http.StatusOK, w.Code)
  1361  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1362  	})
  1363  }
  1364  
  1365  // case: func(c *gin.Context, req *FromJsonBody) (rsp *Struct{Embed}, err error)
  1366  func (t *Router) TestExample29() {
  1367  	t.Catch(func() {
  1368  		// Given
  1369  		type reqStruct struct {
  1370  			ID      *string `json:"id"`
  1371  			NumList []int   `json:"num_list"`
  1372  			Embed   *struct {
  1373  				FUID    *string `json:"fuid"`
  1374  				Boolean *bool   `json:"boolean"`
  1375  			} `json:"embed"`
  1376  		}
  1377  		type rspStruct struct {
  1378  			fusHtp.Embed
  1379  
  1380  			Page  int
  1381  			Count int
  1382  			Msg   string
  1383  			Data  *struct {
  1384  				Name *string `json:"name"`
  1385  				UUID *string `json:"uuid"`
  1386  			}
  1387  		}
  1388  
  1389  		method := http.MethodPost
  1390  		path := "/test"
  1391  		data := &struct {
  1392  			Name *string `json:"name"`
  1393  			UUID *string `json:"uuid"`
  1394  		}{
  1395  			Name: utils.AnyPtr("what's your name"),
  1396  			UUID: utils.AnyPtr(utils.UUID()),
  1397  		}
  1398  		hd := func(c *gin.Context, req *reqStruct) (*rspStruct, error) {
  1399  			t.Require().NotNil(req)
  1400  			t.Require().NotEmpty(req.ID)
  1401  			t.Require().NotEmpty(req.NumList)
  1402  			t.Require().NotEmpty(req.Embed)
  1403  			t.Require().NotEmpty(req.Embed.FUID)
  1404  			t.Require().NotNil(req.Embed.Boolean)
  1405  			return &rspStruct{Page: 1, Count: 1, Msg: "ok", Data: data}, nil
  1406  		}
  1407  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
  1408  			ID:      utils.AnyPtr(utils.UUID()),
  1409  			NumList: []int{1, 2, 3, 4, 5, 6},
  1410  			Embed: &struct {
  1411  				FUID    *string `json:"fuid"`
  1412  				Boolean *bool   `json:"boolean"`
  1413  			}{
  1414  				FUID:    utils.AnyPtr(utils.UUID()),
  1415  				Boolean: utils.AnyPtr(true),
  1416  			},
  1417  		}))
  1418  
  1419  		w := httptest.NewRecorder()
  1420  		req, err := http.NewRequest(method, path, reqBody)
  1421  		req.Header.Set("Content-Type", "application/json")
  1422  		t.Require().NoError(err)
  1423  		engine := t.ServerGiven(method, path, hd)
  1424  
  1425  		// When
  1426  		engine.ServeHTTP(w, req)
  1427  
  1428  		// Then
  1429  		t.Equal(http.StatusOK, w.Code)
  1430  
  1431  		rsp := utils.MustJsonUnmarshal[rspStruct](w.Body.Bytes())
  1432  		t.Require().EqualValues(1, rsp.Page)
  1433  		t.Require().EqualValues(1, rsp.Count)
  1434  		t.Require().EqualValues("ok", rsp.Msg)
  1435  		t.Require().NotEmpty(rsp.Data)
  1436  		t.Require().EqualValues(utils.MustJsonMarshal(data), utils.MustJsonMarshal(rsp.Data))
  1437  	})
  1438  }
  1439  
  1440  // case: func(c *gin.Context, req *Struct FromQuery) error
  1441  func (t *Router) TestExample30() {
  1442  	t.Catch(func() {
  1443  		// Given
  1444  		type reqStruct struct {
  1445  			ID      *string `json:"id"`
  1446  			NumList []int   `json:"num_list"`
  1447  			Embed   *string `json:"embed"`
  1448  		}
  1449  
  1450  		method := http.MethodGet
  1451  		path := "/test/:id"
  1452  		hd := func(c *gin.Context, req *reqStruct) error {
  1453  			t.Require().NotNil(req)
  1454  			t.Require().NotEmpty(req.ID)
  1455  			t.Require().NotEmpty(req.NumList)
  1456  			t.Require().NotEmpty(req.Embed)
  1457  			return io.ErrUnexpectedEOF
  1458  		}
  1459  		uri := "/test/b5890985-47e1-4eca-9dc8-ec95060e896d" +
  1460  			"?num_list=1&num_list=2&num_list=3&num_list=4&num_list=5&num_list=6" +
  1461  			"&embed={\\\"fuid\\\":\\\"b5890985-47e1-4eca-9dc8-ec95060e896d\\\",\\\"boolean\\\":true}}"
  1462  
  1463  		w := httptest.NewRecorder()
  1464  		req, err := http.NewRequest(method, uri, nil)
  1465  		req.Header.Set("Content-Type", "application/json")
  1466  		t.Require().NoError(err)
  1467  		engine := t.ServerGiven(method, path, hd)
  1468  
  1469  		// When
  1470  		engine.ServeHTTP(w, req)
  1471  
  1472  		// Then
  1473  		t.Equal(http.StatusOK, w.Code)
  1474  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1475  	})
  1476  }
  1477  
  1478  // case: func(c *gin.Context, req *FromJsonBody) (data *struct , page, count int, msg string, err error) deal error
  1479  func (t *Router) TestExample31() {
  1480  	t.Catch(func() {
  1481  		// Given
  1482  		type reqStruct struct {
  1483  			ID      *string `json:"id"`
  1484  			NumList []int   `json:"num_list"`
  1485  			Embed   *struct {
  1486  				FUID    *string `json:"fuid"`
  1487  				Boolean *bool   `json:"boolean"`
  1488  			} `json:"embed"`
  1489  		}
  1490  		type dataStruct struct {
  1491  			Name *string `json:"name"`
  1492  			UUID *string `json:"uuid"`
  1493  		}
  1494  
  1495  		method := http.MethodPost
  1496  		path := "/test"
  1497  		data := &dataStruct{
  1498  			Name: utils.AnyPtr("what's your name"),
  1499  			UUID: utils.AnyPtr(utils.UUID()),
  1500  		}
  1501  		hd := func(c *gin.Context, req *reqStruct) (*dataStruct, int, int, string, error) {
  1502  			t.Require().NotNil(req)
  1503  			t.Require().NotEmpty(req.ID)
  1504  			t.Require().NotEmpty(req.NumList)
  1505  			t.Require().NotEmpty(req.Embed)
  1506  			t.Require().NotEmpty(req.Embed.FUID)
  1507  			t.Require().NotNil(req.Embed.Boolean)
  1508  			return data, 1, 1, "", errors.New("wrong")
  1509  		}
  1510  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
  1511  			ID:      utils.AnyPtr(utils.UUID()),
  1512  			NumList: []int{1, 2, 3, 4, 5, 6},
  1513  			Embed: &struct {
  1514  				FUID    *string `json:"fuid"`
  1515  				Boolean *bool   `json:"boolean"`
  1516  			}{
  1517  				FUID:    utils.AnyPtr(utils.UUID()),
  1518  				Boolean: utils.AnyPtr(true),
  1519  			},
  1520  		}))
  1521  
  1522  		w := httptest.NewRecorder()
  1523  		req, err := http.NewRequest(method, path, reqBody)
  1524  		req.Header.Set("Content-Type", "application/json")
  1525  		t.Require().NoError(err)
  1526  		engine := t.ServerGiven(method, path, hd)
  1527  
  1528  		// When
  1529  		engine.ServeHTTP(w, req)
  1530  
  1531  		// Then
  1532  		t.Equal(http.StatusOK, w.Code)
  1533  
  1534  		rsp := utils.MustJsonUnmarshal[fusHtp.Response](w.Body.Bytes())
  1535  		t.Require().EqualValues(1, *rsp.Page)
  1536  		t.Require().EqualValues(1, *rsp.Count)
  1537  		t.Require().EqualValues("wrong", rsp.Message)
  1538  		t.Require().NotEmpty(rsp.Data)
  1539  		t.Require().EqualValues(utils.MustJsonMarshal(data), utils.MustJsonMarshal(rsp.Data))
  1540  	})
  1541  }
  1542  
  1543  // case: func(c *gin.Context, req *Struct FromJsonBody) (data []int, err error)
  1544  func (t *Router) TestExample32() {
  1545  	t.Catch(func() {
  1546  		// Given
  1547  		type reqStruct struct {
  1548  			ID      *string `json:"id"`
  1549  			NumList []int   `json:"num_list"`
  1550  			Embed   *struct {
  1551  				FUID    *string `json:"fuid"`
  1552  				Boolean *bool   `json:"boolean"`
  1553  			} `json:"embed"`
  1554  		}
  1555  
  1556  		method := http.MethodPost
  1557  		path := "/test"
  1558  		hd := func(c *gin.Context, req *reqStruct) (data []int, err error) {
  1559  			t.Require().NotNil(req)
  1560  			t.Require().NotEmpty(req.ID)
  1561  			t.Require().NotEmpty(req.NumList)
  1562  			t.Require().NotEmpty(req.Embed)
  1563  			t.Require().NotEmpty(req.Embed.FUID)
  1564  			t.Require().NotNil(req.Embed.Boolean)
  1565  			return []int{1, 2, 3, 4, 5}, io.ErrUnexpectedEOF
  1566  		}
  1567  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
  1568  			ID:      utils.AnyPtr(utils.UUID()),
  1569  			NumList: []int{1, 2, 3, 4, 5, 6},
  1570  			Embed: &struct {
  1571  				FUID    *string `json:"fuid"`
  1572  				Boolean *bool   `json:"boolean"`
  1573  			}{
  1574  				FUID:    utils.AnyPtr(utils.UUID()),
  1575  				Boolean: utils.AnyPtr(true),
  1576  			},
  1577  		}))
  1578  
  1579  		w := httptest.NewRecorder()
  1580  		req, err := http.NewRequest(method, path, reqBody)
  1581  		req.Header.Set("Content-Type", "application/json")
  1582  		t.Require().NoError(err)
  1583  		engine := t.ServerGiven(method, path, hd)
  1584  
  1585  		// When
  1586  		engine.ServeHTTP(w, req)
  1587  
  1588  		// Then
  1589  		t.Equal(http.StatusOK, w.Code)
  1590  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1591  		t.Contains(w.Body.String(), "[1,2,3,4,5]")
  1592  	})
  1593  }
  1594  
  1595  // case: func(c *gin.Context, req *Struct FromJsonBody) (data map[string]int, err error)
  1596  func (t *Router) TestExample33() {
  1597  	t.Catch(func() {
  1598  		// Given
  1599  		method := http.MethodPost
  1600  		path := "/test"
  1601  		hd := func(c *gin.Context, req *routerReqStruct) (data map[string]int, err error) {
  1602  			t.Require().NotNil(req)
  1603  			t.Require().NotEmpty(req.ID)
  1604  			t.Require().NotEmpty(req.NumList)
  1605  			t.Require().NotEmpty(req.Embed)
  1606  			t.Require().NotEmpty(req.Embed.FUID)
  1607  			t.Require().NotNil(req.Embed.Boolean)
  1608  			return map[string]int{"1": 1, "2": 2, "3": 3}, io.ErrUnexpectedEOF
  1609  		}
  1610  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&routerReqStruct{
  1611  			ID:      utils.AnyPtr(utils.UUID()),
  1612  			NumList: []int{1, 2, 3, 4, 5, 6},
  1613  			Embed: &struct {
  1614  				FUID    *string `json:"fuid"`
  1615  				Boolean *bool   `json:"boolean"`
  1616  			}{
  1617  				FUID:    utils.AnyPtr(utils.UUID()),
  1618  				Boolean: utils.AnyPtr(true),
  1619  			},
  1620  		}))
  1621  
  1622  		w := httptest.NewRecorder()
  1623  		req, err := http.NewRequest(method, path, reqBody)
  1624  		req.Header.Set("Content-Type", "application/json")
  1625  		t.Require().NoError(err)
  1626  		engine := t.ServerGiven(method, path, hd)
  1627  
  1628  		// When
  1629  		engine.ServeHTTP(w, req)
  1630  
  1631  		// Then
  1632  		t.Equal(http.StatusOK, w.Code)
  1633  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1634  		t.Contains(w.Body.String(), `"3":3`)
  1635  	})
  1636  }
  1637  
  1638  // case: func(c *gin.Context, req Struct FromFormUrlDecodedBody) error
  1639  func (t *Router) TestExample34() {
  1640  	t.Catch(func() {
  1641  		// Given
  1642  		type reqStruct struct {
  1643  			ID       *string `json:"id" form:"id"`
  1644  			NumList  []int   `json:"num_list" form:"num_list"`
  1645  			Embed    *string `json:"embed" form:"embed"`
  1646  			PageSize int     `json:"pageSize" form:"pageSize,default=10"`
  1647  			PageNo   int     `json:"pageNo" form:"pageNo,default=1"`
  1648  		}
  1649  
  1650  		method := http.MethodPost
  1651  		path := "/test"
  1652  		hd := func(c *gin.Context, req reqStruct) error {
  1653  			t.Require().NotNil(req)
  1654  			t.Require().NotEmpty(req.ID)
  1655  			t.Require().NotEmpty(req.NumList)
  1656  			t.Require().NotEmpty(req.Embed)
  1657  			t.Require().NotZero(req.PageNo)
  1658  			t.Require().NotZero(req.PageSize)
  1659  			return io.ErrUnexpectedEOF
  1660  		}
  1661  		body := strings.NewReader("id=b5890985-47e1-4eca-9dc8-ec95060e896d" +
  1662  			"&num_list=1&num_list=2&num_list=3&num_list=4&num_list=5&num_list=6" +
  1663  			"&embed={\\\"fuid\\\":\\\"b5890985-47e1-4eca-9dc8-ec95060e896d\\\",\\\"boolean\\\":true}}")
  1664  		w := httptest.NewRecorder()
  1665  		req, err := http.NewRequest(method, path, body)
  1666  		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  1667  		t.Require().NoError(err)
  1668  		engine := t.ServerGiven(method, path, hd)
  1669  
  1670  		// When
  1671  		engine.ServeHTTP(w, req)
  1672  
  1673  		// Then
  1674  		t.Equal(http.StatusOK, w.Code)
  1675  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1676  	})
  1677  }
  1678  
  1679  // case: func(c *gin.Context, req *Struct FromJsonBody) error with default tag
  1680  func (t *Router) TestExample35() {
  1681  	t.Catch(func() {
  1682  		// Given
  1683  		type reqStruct struct {
  1684  			ID      *string `json:"id" default:"this is a id"`
  1685  			NumList []int   `json:"num_list"`
  1686  			Embed   *struct {
  1687  				FUID    *string `json:"fuid"`
  1688  				Boolean *bool   `json:"boolean"`
  1689  			} `json:"embed"`
  1690  			M map[string]any `json:"m" default:"a: aaa\nb: 123\nc: {cc: 112233}"`
  1691  			S []any          `json:"s" default:"[{a: aaa, b: 123, c: {cc: 112233}}, ok, 123, d: 666]"`
  1692  		}
  1693  
  1694  		method := http.MethodPost
  1695  		path := "/test"
  1696  		hd := func(c *gin.Context, req *reqStruct) error {
  1697  			t.Require().NotNil(req)
  1698  			t.Require().NotEmpty(req.ID)
  1699  			t.Require().NotEmpty(req.NumList)
  1700  			t.Require().NotEmpty(req.Embed)
  1701  			t.Require().NotEmpty(req.Embed.FUID)
  1702  			t.Require().NotNil(req.Embed.Boolean)
  1703  			t.Require().NotEmpty(req.M)
  1704  			t.Require().NotEmpty(req.S)
  1705  			return io.ErrUnexpectedEOF
  1706  		}
  1707  		reqBody := bytes.NewReader(utils.MustJsonMarshal(&reqStruct{
  1708  			ID:      nil,
  1709  			NumList: []int{1, 2, 3, 4, 5, 6},
  1710  			Embed: &struct {
  1711  				FUID    *string `json:"fuid"`
  1712  				Boolean *bool   `json:"boolean"`
  1713  			}{
  1714  				FUID:    utils.AnyPtr(utils.UUID()),
  1715  				Boolean: utils.AnyPtr(true),
  1716  			},
  1717  		}))
  1718  
  1719  		w := httptest.NewRecorder()
  1720  		req, err := http.NewRequest(method, path, reqBody)
  1721  		req.Header.Set("Content-Type", "application/json")
  1722  		t.Require().NoError(err)
  1723  		engine := t.ServerGiven(method, path, hd)
  1724  
  1725  		// When
  1726  		engine.ServeHTTP(w, req)
  1727  
  1728  		// Then
  1729  		t.Equal(http.StatusOK, w.Code)
  1730  		t.Contains(w.Body.String(), io.ErrUnexpectedEOF.Error())
  1731  	})
  1732  }
  1733  
  1734  type routerReqStruct struct {
  1735  	ID      *string `json:"id"`
  1736  	NumList []int   `json:"num_list"`
  1737  	Embed   *struct {
  1738  		FUID    *string `json:"fuid"`
  1739  		Boolean *bool   `json:"boolean"`
  1740  	} `json:"embed"`
  1741  }
  1742  
  1743  func (t *Router) handle(c *gin.Context, req *routerReqStruct) error {
  1744  	t.Require().NotNil(req)
  1745  	t.Require().NotEmpty(req.ID)
  1746  	t.Require().NotEmpty(req.NumList)
  1747  	t.Require().NotEmpty(req.Embed)
  1748  	t.Require().NotEmpty(req.Embed.FUID)
  1749  	t.Require().NotNil(req.Embed.Boolean)
  1750  	return io.ErrUnexpectedEOF
  1751  }