Best Go-testdeep code snippet using tdhttp.CmpResponse
test_api_test.go
Source:test_api_test.go
...126 CmpHeader(td.SuperMapOf(http.Header{}, td.MapEntries{127 "X-Testdeep-Method": td.Bag(td.Re(`(?i)^head\z`)),128 })).129 NoBody().130 CmpResponse(td.Code(func(assert *td.T, resp *http.Response) {131 assert.Cmp(resp.StatusCode, 200)132 assert.Cmp(resp.Header, containsKey)133 assert.Smuggle(resp.Body, io.ReadAll, td.Empty())134 })).135 Failed())136 td.CmpEmpty(t, mockT.LogBuf())137 mockT = tdutil.NewT("test")138 td.CmpFalse(t,139 tdhttp.NewTestAPI(mockT, mux).140 Head("/any").141 CmpStatus(200).142 CmpHeader(containsKey).143 CmpBody(td.Empty()).144 CmpResponse(td.Code(func(assert *td.T, resp *http.Response) {145 assert.Cmp(resp.StatusCode, 200)146 assert.Cmp(resp.Header, containsKey)147 assert.Smuggle(resp.Body, io.ReadAll, td.Empty())148 })).149 Failed())150 td.CmpEmpty(t, mockT.LogBuf())151 mockT = tdutil.NewT("test")152 td.CmpFalse(t,153 tdhttp.NewTestAPI(mockT, mux).154 Get("/any").155 CmpStatus(200).156 CmpHeader(containsKey).157 CmpBody("GET!").158 CmpResponse(td.Code(func(assert *td.T, resp *http.Response) {159 assert.Cmp(resp.StatusCode, 200)160 assert.Cmp(resp.Header, containsKey)161 assert.Smuggle(resp.Body, io.ReadAll, td.String("GET!"))162 })).163 Failed())164 td.CmpEmpty(t, mockT.LogBuf())165 mockT = tdutil.NewT("test")166 td.CmpFalse(t,167 tdhttp.NewTestAPI(mockT, mux).168 Get("/any").169 CmpStatus(200).170 CmpHeader(containsKey).171 CmpBody(td.Contains("GET")).172 CmpResponse(td.Code(func(assert *td.T, resp *http.Response) {173 assert.Cmp(resp.StatusCode, 200)174 assert.Cmp(resp.Header, containsKey)175 assert.Smuggle(resp.Body, io.ReadAll, td.Contains("GET"))176 })).177 Failed())178 td.CmpEmpty(t, mockT.LogBuf())179 mockT = tdutil.NewT("test")180 td.CmpFalse(t,181 tdhttp.NewTestAPI(mockT, mux).182 Options("/any", strings.NewReader("OPTIONS body")).183 CmpStatus(200).184 CmpHeader(containsKey).185 CmpBody("OPTIONS!\n---\nOPTIONS body").186 CmpResponse(td.Code(func(assert *td.T, resp *http.Response) {187 assert.Cmp(resp.StatusCode, 200)188 assert.Cmp(resp.Header, containsKey)189 assert.Smuggle(resp.Body, io.ReadAll, td.String("OPTIONS!\n---\nOPTIONS body"))190 })).191 Failed())192 td.CmpEmpty(t, mockT.LogBuf())193 mockT = tdutil.NewT("test")194 td.CmpFalse(t,195 tdhttp.NewTestAPI(mockT, mux).196 Post("/any", strings.NewReader("POST body")).197 CmpStatus(200).198 CmpHeader(containsKey).199 CmpBody("POST!\n---\nPOST body").200 CmpResponse(td.Code(func(assert *td.T, resp *http.Response) {201 assert.Cmp(resp.StatusCode, 200)202 assert.Cmp(resp.Header, containsKey)203 assert.Smuggle(resp.Body, io.ReadAll, td.String("POST!\n---\nPOST body"))204 })).205 Failed())206 td.CmpEmpty(t, mockT.LogBuf())207 mockT = tdutil.NewT("test")208 td.CmpFalse(t,209 tdhttp.NewTestAPI(mockT, mux).210 PostForm("/any", url.Values{"p1": []string{"v1"}, "p2": []string{"v2"}}).211 CmpStatus(200).212 CmpHeader(containsKey).213 CmpBody("POST!\n---\np1=v1&p2=v2").214 CmpResponse(td.Code(func(assert *td.T, resp *http.Response) {215 assert.Cmp(resp.StatusCode, 200)216 assert.Cmp(resp.Header, containsKey)217 assert.Smuggle(resp.Body, io.ReadAll, td.String("POST!\n---\np1=v1&p2=v2"))218 })).219 Failed())220 td.CmpEmpty(t, mockT.LogBuf())221 mockT = tdutil.NewT("test")222 td.CmpFalse(t,223 tdhttp.NewTestAPI(mockT, mux).224 PostForm("/any", tdhttp.Q{"p1": "v1", "p2": "v2"}).225 CmpStatus(200).226 CmpHeader(containsKey).227 CmpBody("POST!\n---\np1=v1&p2=v2").228 CmpResponse(td.Code(func(assert *td.T, resp *http.Response) {229 assert.Cmp(resp.StatusCode, 200)230 assert.Cmp(resp.Header, containsKey)231 assert.Smuggle(resp.Body, io.ReadAll, td.String("POST!\n---\np1=v1&p2=v2"))232 })).233 Failed())234 td.CmpEmpty(t, mockT.LogBuf())235 mockT = tdutil.NewT("test")236 td.CmpFalse(t,237 tdhttp.NewTestAPI(mockT, mux).238 PostMultipartFormData("/any", &tdhttp.MultipartBody{239 Boundary: "BoUnDaRy",240 Parts: []*tdhttp.MultipartPart{241 tdhttp.NewMultipartPartString("pipo", "bingo"),242 },243 }).244 CmpStatus(200).245 CmpHeader(containsKey).246 CmpBody(strings.ReplaceAll(247 `POST!248---249--BoUnDaRy%CR250Content-Disposition: form-data; name="pipo"%CR251Content-Type: text/plain; charset=utf-8%CR252%CR253bingo%CR254--BoUnDaRy--%CR255`,256 "%CR", "\r")).257 Failed())258 td.CmpEmpty(t, mockT.LogBuf())259 mockT = tdutil.NewT("test")260 td.CmpFalse(t,261 tdhttp.NewTestAPI(mockT, mux).262 Put("/any", strings.NewReader("PUT body")).263 CmpStatus(200).264 CmpHeader(containsKey).265 CmpBody("PUT!\n---\nPUT body").266 Failed())267 td.CmpEmpty(t, mockT.LogBuf())268 mockT = tdutil.NewT("test")269 td.CmpFalse(t,270 tdhttp.NewTestAPI(mockT, mux).271 Patch("/any", strings.NewReader("PATCH body")).272 CmpStatus(200).273 CmpHeader(containsKey).274 CmpBody("PATCH!\n---\nPATCH body").275 Failed())276 td.CmpEmpty(t, mockT.LogBuf())277 mockT = tdutil.NewT("test")278 td.CmpFalse(t,279 tdhttp.NewTestAPI(mockT, mux).280 Delete("/any", strings.NewReader("DELETE body")).281 CmpStatus(200).282 CmpHeader(containsKey).283 CmpBody("DELETE!\n---\nDELETE body").284 Failed())285 td.CmpEmpty(t, mockT.LogBuf())286 })287 t.Run("No JSON error", func(t *testing.T) {288 requestBody := map[string]any{"hey": 123}289 expectedBody := func(m string) td.TestDeep {290 return td.JSON(`{"method": $1, "body": {"hey": 123}}`, m)291 }292 mockT := tdutil.NewT("test")293 td.CmpFalse(t,294 tdhttp.NewTestAPI(mockT, mux).295 NewJSONRequest("GET", "/mirror/json", json.RawMessage(`null`)).296 CmpStatus(200).297 CmpHeader(containsKey).298 CmpJSONBody(nil).299 Failed())300 td.CmpEmpty(t, mockT.LogBuf())301 mockT = tdutil.NewT("test")302 td.CmpFalse(t,303 tdhttp.NewTestAPI(mockT, mux).304 NewJSONRequest("ZIP", "/any/json", requestBody).305 CmpStatus(200).306 CmpHeader(containsKey).307 CmpJSONBody(expectedBody("ZIP")).308 Failed())309 td.CmpEmpty(t, mockT.LogBuf())310 mockT = tdutil.NewT("test")311 td.CmpFalse(t,312 tdhttp.NewTestAPI(mockT, mux).313 NewJSONRequest("ZIP", "/any/json", requestBody).314 CmpStatus(200).315 CmpHeader(containsKey).316 CmpJSONBody(td.JSONPointer("/body/hey", 123)).317 Failed())318 td.CmpEmpty(t, mockT.LogBuf())319 mockT = tdutil.NewT("test")320 td.CmpFalse(t,321 tdhttp.NewTestAPI(mockT, mux).322 PostJSON("/any/json", requestBody).323 CmpStatus(200).324 CmpHeader(containsKey).325 CmpJSONBody(expectedBody("POST")).326 Failed())327 td.CmpEmpty(t, mockT.LogBuf())328 mockT = tdutil.NewT("test")329 td.CmpFalse(t,330 tdhttp.NewTestAPI(mockT, mux).331 PutJSON("/any/json", requestBody).332 CmpStatus(200).333 CmpHeader(containsKey).334 CmpJSONBody(expectedBody("PUT")).335 Failed())336 td.CmpEmpty(t, mockT.LogBuf())337 mockT = tdutil.NewT("test")338 td.CmpFalse(t,339 tdhttp.NewTestAPI(mockT, mux).340 PatchJSON("/any/json", requestBody).341 CmpStatus(200).342 CmpHeader(containsKey).343 CmpJSONBody(expectedBody("PATCH")).344 Failed())345 td.CmpEmpty(t, mockT.LogBuf())346 mockT = tdutil.NewT("test")347 td.CmpFalse(t,348 tdhttp.NewTestAPI(mockT, mux).349 DeleteJSON("/any/json", requestBody).350 CmpStatus(200).351 CmpHeader(containsKey).352 CmpJSONBody(expectedBody("DELETE")).353 Failed())354 td.CmpEmpty(t, mockT.LogBuf())355 // With anchors356 type ReqBody struct {357 Hey int `json:"hey"`358 }359 type Resp struct {360 Method string `json:"method"`361 ReqBody ReqBody `json:"body"`362 }363 mockT = tdutil.NewT("test")364 tt := td.NewT(mockT)365 td.CmpFalse(t,366 tdhttp.NewTestAPI(mockT, mux).367 DeleteJSON("/any/json", requestBody).368 CmpStatus(200).369 CmpHeader(containsKey).370 CmpJSONBody(Resp{371 Method: tt.A(td.Re(`^(?i)delete\z`), "").(string),372 ReqBody: ReqBody{373 Hey: tt.A(td.Between(120, 130)).(int),374 },375 }).376 Failed())377 td.CmpEmpty(t, mockT.LogBuf())378 // JSON and root operator (here SuperMapOf)379 mockT = tdutil.NewT("test")380 td.CmpFalse(t,381 tdhttp.NewTestAPI(mockT, mux).382 PostJSON("/any/json", true).383 CmpStatus(200).384 CmpJSONBody(td.JSON(`SuperMapOf({"body":Ignore()})`)).385 Failed())386 td.CmpEmpty(t, mockT.LogBuf())387 // td.Bag+td.JSON388 mockT = tdutil.NewT("test")389 td.CmpFalse(t,390 tdhttp.NewTestAPI(mockT, mux).391 PostJSON("/mirror/json",392 json.RawMessage(`[{"name":"Bob"},{"name":"Alice"}]`)).393 CmpStatus(200).394 CmpJSONBody(td.Bag(395 td.JSON(`{"name":"Alice"}`),396 td.JSON(`{"name":"Bob"}`),397 )).398 Failed())399 td.CmpEmpty(t, mockT.LogBuf())400 // td.Bag+literal401 type People struct {402 Name string `json:"name"`403 }404 mockT = tdutil.NewT("test")405 td.CmpFalse(t,406 tdhttp.NewTestAPI(mockT, mux).407 PostJSON("/mirror/json",408 json.RawMessage(`[{"name":"Bob"},{"name":"Alice"}]`)).409 CmpStatus(200).410 CmpJSONBody(td.Bag(People{"Alice"}, People{"Bob"})).411 Failed())412 td.CmpEmpty(t, mockT.LogBuf())413 })414 t.Run("No XML error", func(t *testing.T) {415 type XBody struct {416 Hey int `xml:"hey"`417 }418 type XResp struct {419 Method string `xml:"method"`420 ReqBody *XBody `xml:"XBody"`421 }422 requestBody := XBody{Hey: 123}423 expectedBody := func(m string) XResp {424 return XResp{425 Method: m,426 ReqBody: &requestBody,427 }428 }429 mockT := tdutil.NewT("test")430 td.CmpFalse(t,431 tdhttp.NewTestAPI(mockT, mux).432 NewXMLRequest("ZIP", "/any/xml", requestBody).433 CmpStatus(200).434 CmpHeader(containsKey).435 CmpXMLBody(expectedBody("ZIP")).436 Failed())437 td.CmpEmpty(t, mockT.LogBuf())438 mockT = tdutil.NewT("test")439 td.CmpFalse(t,440 tdhttp.NewTestAPI(mockT, mux).441 PostXML("/any/xml", requestBody).442 CmpStatus(200).443 CmpHeader(containsKey).444 CmpXMLBody(expectedBody("POST")).445 Failed())446 td.CmpEmpty(t, mockT.LogBuf())447 mockT = tdutil.NewT("test")448 td.CmpFalse(t,449 tdhttp.NewTestAPI(mockT, mux).450 PutXML("/any/xml", requestBody).451 CmpStatus(200).452 CmpHeader(containsKey).453 CmpXMLBody(expectedBody("PUT")).454 Failed())455 td.CmpEmpty(t, mockT.LogBuf())456 mockT = tdutil.NewT("test")457 td.CmpFalse(t,458 tdhttp.NewTestAPI(mockT, mux).459 PatchXML("/any/xml", requestBody).460 CmpStatus(200).461 CmpHeader(containsKey).462 CmpXMLBody(expectedBody("PATCH")).463 Failed())464 td.CmpEmpty(t, mockT.LogBuf())465 mockT = tdutil.NewT("test")466 td.CmpFalse(t,467 tdhttp.NewTestAPI(mockT, mux).468 DeleteXML("/any/xml", requestBody).469 CmpStatus(200).470 CmpHeader(containsKey).471 CmpXMLBody(expectedBody("DELETE")).472 Failed())473 td.CmpEmpty(t, mockT.LogBuf())474 // With anchors475 mockT = tdutil.NewT("test")476 tt := td.NewT(mockT)477 td.CmpFalse(tt,478 tdhttp.NewTestAPI(mockT, mux).479 DeleteXML("/any/xml", requestBody).480 CmpStatus(200).481 CmpHeader(containsKey).482 CmpXMLBody(XResp{483 Method: tt.A(td.Re(`^(?i)delete\z`), "").(string),484 ReqBody: &XBody{485 Hey: tt.A(td.Between(120, 130)).(int),486 },487 }).488 Failed())489 td.CmpEmpty(t, mockT.LogBuf())490 })491 t.Run("Cookies", func(t *testing.T) {492 mockT := tdutil.NewT("test")493 td.CmpFalse(t,494 tdhttp.NewTestAPI(mockT, mux).495 Get("/any/cookies").496 CmpCookies([]*http.Cookie{497 {498 Name: "first",499 Value: "cookie1",500 MaxAge: 123456,501 Expires: time.Date(2021, time.August, 12, 11, 22, 33, 0, time.UTC),502 },503 {504 Name: "second",505 Value: "cookie2",506 MaxAge: 654321,507 },508 }).509 Failed())510 td.CmpEmpty(t, mockT.LogBuf())511 mockT = tdutil.NewT("test")512 td.CmpTrue(t,513 tdhttp.NewTestAPI(mockT, mux).514 Get("/any/cookies").515 CmpCookies([]*http.Cookie{516 {517 Name: "first",518 Value: "cookie1",519 MaxAge: 123456,520 Expires: time.Date(2021, time.August, 12, 11, 22, 33, 0, time.UTC),521 },522 }).523 Failed())524 td.CmpContains(t, mockT.LogBuf(),525 "Failed test 'cookies should match'")526 td.CmpContains(t, mockT.LogBuf(),527 "Response.Cookie: comparing slices, from index #1")528 // 2 cookies are here whatever their order is using Bag529 mockT = tdutil.NewT("test")530 td.CmpFalse(t,531 tdhttp.NewTestAPI(mockT, mux).532 Get("/any/cookies").533 CmpCookies(td.Bag(534 td.Smuggle("Name", "second"),535 td.Smuggle("Name", "first"),536 )).537 Failed())538 td.CmpEmpty(t, mockT.LogBuf())539 // Testing only Name & Value whatever their order is using Bag540 mockT = tdutil.NewT("test")541 td.CmpFalse(t,542 tdhttp.NewTestAPI(mockT, mux).543 Get("/any/cookies").544 CmpCookies(td.Bag(545 td.Struct(&http.Cookie{Name: "first", Value: "cookie1"}, nil),546 td.Struct(&http.Cookie{Name: "second", Value: "cookie2"}, nil),547 )).548 Failed())549 td.CmpEmpty(t, mockT.LogBuf())550 // Testing the presence of only one using SuperBagOf551 mockT = tdutil.NewT("test")552 td.CmpFalse(t,553 tdhttp.NewTestAPI(mockT, mux).554 Get("/any/cookies").555 CmpCookies(td.SuperBagOf(556 td.Struct(&http.Cookie{Name: "first", Value: "cookie1"}, nil),557 )).558 Failed())559 td.CmpEmpty(t, mockT.LogBuf())560 // Testing only the number of cookies561 mockT = tdutil.NewT("test")562 td.CmpFalse(t,563 tdhttp.NewTestAPI(mockT, mux).564 Get("/any/cookies").565 CmpCookies(td.Len(2)).566 Failed())567 td.CmpEmpty(t, mockT.LogBuf())568 // Error followed by a success: Failed() should return true anyway569 mockT = tdutil.NewT("test")570 td.CmpTrue(t,571 tdhttp.NewTestAPI(mockT, mux).572 Get("/any").573 CmpCookies(td.Len(100)). // fails574 CmpCookies(td.Len(2)). // succeeds575 Failed())576 td.CmpContains(t, mockT.LogBuf(),577 "Failed test 'cookies should match'")578 // AutoDumpResponse579 mockT = tdutil.NewT("test")580 td.CmpTrue(t,581 tdhttp.NewTestAPI(mockT, mux).582 AutoDumpResponse().583 Get("/any/cookies").584 Name("my test").585 CmpCookies(td.Len(100)).586 Failed())587 td.CmpContains(t, mockT.LogBuf(),588 "Failed test 'my test: cookies should match'")589 td.CmpContains(t, mockT.LogBuf(), "Response.Cookie: bad length")590 td.Cmp(t, mockT.LogBuf(), td.Contains("Received response:\n"))591 // Request not sent592 mockT = tdutil.NewT("test")593 ta := tdhttp.NewTestAPI(mockT, mux).594 Name("my test").595 CmpCookies(td.Len(2))596 td.CmpTrue(t, ta.Failed())597 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: request is sent'\n")598 td.CmpContains(t, mockT.LogBuf(), "Request not sent!\n")599 td.CmpContains(t, mockT.LogBuf(), "A request must be sent before testing status, header, body or full response\n")600 td.CmpNot(t, mockT.LogBuf(), td.Contains("No response received yet\n"))601 })602 t.Run("Trailer", func(t *testing.T) {603 mockT := tdutil.NewT("test")604 td.CmpFalse(t,605 tdhttp.NewTestAPI(mockT, mux).606 Get("/any").607 CmpStatus(200).608 CmpTrailer(nil). // No trailer at all609 Failed())610 mockT = tdutil.NewT("test")611 td.CmpFalse(t,612 tdhttp.NewTestAPI(mockT, mux).613 Get("/any/trailer").614 CmpStatus(200).615 CmpTrailer(containsKey).616 Failed())617 mockT = tdutil.NewT("test")618 td.CmpFalse(t,619 tdhttp.NewTestAPI(mockT, mux).620 Get("/any/trailer").621 CmpStatus(200).622 CmpTrailer(http.Header{623 "X-Testdeep-Method": {"GET"},624 "X-Testdeep-Foo": {"bar"},625 }).626 Failed())627 // AutoDumpResponse628 mockT = tdutil.NewT("test")629 td.CmpTrue(t,630 tdhttp.NewTestAPI(mockT, mux).631 AutoDumpResponse().632 Get("/any/trailer").633 Name("my test").634 CmpTrailer(http.Header{}).635 Failed())636 td.CmpContains(t, mockT.LogBuf(),637 "Failed test 'my test: trailer should match'")638 td.Cmp(t, mockT.LogBuf(), td.Contains("Received response:\n"))639 // OrDumpResponse640 mockT = tdutil.NewT("test")641 td.CmpTrue(t,642 tdhttp.NewTestAPI(mockT, mux).643 Get("/any/trailer").644 Name("my test").645 CmpTrailer(http.Header{}).646 OrDumpResponse().647 OrDumpResponse(). // only one log648 Failed())649 td.CmpContains(t, mockT.LogBuf(),650 "Failed test 'my test: trailer should match'")651 logPos := strings.Index(mockT.LogBuf(), "Received response:\n")652 if td.Cmp(t, logPos, td.Gte(0)) {653 // Only one occurrence654 td.Cmp(t,655 strings.Index(mockT.LogBuf()[logPos+1:], "Received response:\n"),656 -1)657 }658 mockT = tdutil.NewT("test")659 ta := tdhttp.NewTestAPI(mockT, mux).660 Name("my test").661 CmpTrailer(http.Header{})662 td.CmpTrue(t, ta.Failed())663 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: request is sent'\n")664 td.CmpContains(t, mockT.LogBuf(), "Request not sent!\n")665 td.CmpContains(t, mockT.LogBuf(), "A request must be sent before testing status, header, body or full response\n")666 td.CmpNot(t, mockT.LogBuf(), td.Contains("No response received yet\n"))667 end := len(mockT.LogBuf())668 ta.OrDumpResponse()669 td.CmpContains(t, mockT.LogBuf()[end:], "No response received yet\n")670 })671 t.Run("Status error", func(t *testing.T) {672 mockT := tdutil.NewT("test")673 td.CmpTrue(t,674 tdhttp.NewTestAPI(mockT, mux).675 Get("/any").676 CmpStatus(400).677 Failed())678 td.CmpContains(t, mockT.LogBuf(),679 "Failed test 'status code should match'")680 // Error followed by a success: Failed() should return true anyway681 mockT = tdutil.NewT("test")682 td.CmpTrue(t,683 tdhttp.NewTestAPI(mockT, mux).684 Get("/any").685 CmpStatus(400). // fails686 CmpStatus(200). // succeeds687 Failed())688 td.CmpContains(t, mockT.LogBuf(),689 "Failed test 'status code should match'")690 mockT = tdutil.NewT("test")691 td.CmpTrue(t,692 tdhttp.NewTestAPI(mockT, mux).693 Get("/any").694 Name("my test").695 CmpStatus(400).696 Failed())697 td.CmpContains(t, mockT.LogBuf(),698 "Failed test 'my test: status code should match'")699 td.CmpNot(t, mockT.LogBuf(), td.Contains("Received response:\n"))700 // AutoDumpResponse701 mockT = tdutil.NewT("test")702 td.CmpTrue(t,703 tdhttp.NewTestAPI(mockT, mux).704 AutoDumpResponse().705 Get("/any").706 Name("my test").707 CmpStatus(400).708 Failed())709 td.CmpContains(t, mockT.LogBuf(),710 "Failed test 'my test: status code should match'")711 td.Cmp(t, mockT.LogBuf(), td.Contains("Received response:\n"))712 // OrDumpResponse713 mockT = tdutil.NewT("test")714 td.CmpTrue(t,715 tdhttp.NewTestAPI(mockT, mux).716 Get("/any").717 Name("my test").718 CmpStatus(400).719 OrDumpResponse().720 OrDumpResponse(). // only one log721 Failed())722 td.CmpContains(t, mockT.LogBuf(),723 "Failed test 'my test: status code should match'")724 logPos := strings.Index(mockT.LogBuf(), "Received response:\n")725 if td.Cmp(t, logPos, td.Gte(0)) {726 // Only one occurrence727 td.Cmp(t,728 strings.Index(mockT.LogBuf()[logPos+1:], "Received response:\n"),729 -1)730 }731 mockT = tdutil.NewT("test")732 ta := tdhttp.NewTestAPI(mockT, mux).733 Name("my test").734 CmpStatus(400)735 td.CmpTrue(t, ta.Failed())736 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: request is sent'\n")737 td.CmpContains(t, mockT.LogBuf(), "Request not sent!\n")738 td.CmpContains(t, mockT.LogBuf(), "A request must be sent before testing status, header, body or full response\n")739 td.CmpNot(t, mockT.LogBuf(), td.Contains("No response received yet\n"))740 end := len(mockT.LogBuf())741 ta.OrDumpResponse()742 td.CmpContains(t, mockT.LogBuf()[end:], "No response received yet\n")743 })744 t.Run("Header error", func(t *testing.T) {745 mockT := tdutil.NewT("test")746 td.CmpTrue(t,747 tdhttp.NewTestAPI(mockT, mux).748 Get("/any").749 CmpHeader(td.Not(containsKey)).750 Failed())751 td.CmpContains(t, mockT.LogBuf(),752 "Failed test 'header should match'")753 // Error followed by a success: Failed() should return true anyway754 mockT = tdutil.NewT("test")755 td.CmpTrue(t,756 tdhttp.NewTestAPI(mockT, mux).757 Get("/any").758 CmpHeader(td.Not(containsKey)). // fails759 CmpHeader(td.Ignore()). // succeeds760 Failed())761 td.CmpContains(t, mockT.LogBuf(),762 "Failed test 'header should match'")763 mockT = tdutil.NewT("test")764 td.CmpTrue(t,765 tdhttp.NewTestAPI(mockT, mux).766 Get("/any").767 Name("my test").768 CmpHeader(td.Not(containsKey)).769 Failed())770 td.CmpContains(t, mockT.LogBuf(),771 "Failed test 'my test: header should match'")772 td.CmpNot(t, mockT.LogBuf(), td.Contains("Received response:\n"))773 // AutoDumpResponse774 mockT = tdutil.NewT("test")775 td.CmpTrue(t,776 tdhttp.NewTestAPI(mockT, mux).777 AutoDumpResponse().778 Get("/any").779 Name("my test").780 CmpHeader(td.Not(containsKey)).781 Failed())782 td.CmpContains(t, mockT.LogBuf(),783 "Failed test 'my test: header should match'")784 td.Cmp(t, mockT.LogBuf(), td.Contains("Received response:\n"))785 mockT = tdutil.NewT("test")786 td.CmpTrue(t,787 tdhttp.NewTestAPI(mockT, mux).788 Name("my test").789 CmpHeader(td.Not(containsKey)).790 Failed())791 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: request is sent'\n")792 td.CmpContains(t, mockT.LogBuf(), "Request not sent!\n")793 td.CmpContains(t, mockT.LogBuf(), "A request must be sent before testing status, header, body or full response\n")794 })795 t.Run("Body error", func(t *testing.T) {796 mockT := tdutil.NewT("test")797 td.CmpTrue(t,798 tdhttp.NewTestAPI(mockT, mux).799 Get("/any").800 CmpBody("xxx").801 Failed())802 td.CmpContains(t, mockT.LogBuf(), "Failed test 'body contents is OK'")803 td.CmpContains(t, mockT.LogBuf(), "Response.Body: values differ\n")804 td.CmpContains(t, mockT.LogBuf(), `expected: "xxx"`)805 td.CmpContains(t, mockT.LogBuf(), `got: "GET!"`)806 // Error followed by a success: Failed() should return true anyway807 mockT = tdutil.NewT("test")808 td.CmpTrue(t,809 tdhttp.NewTestAPI(mockT, mux).810 Get("/any").811 CmpBody("xxx"). // fails812 CmpBody(td.Ignore()). // succeeds813 Failed())814 // Without AutoDumpResponse815 mockT = tdutil.NewT("test")816 td.CmpTrue(t,817 tdhttp.NewTestAPI(mockT, mux).818 Get("/any").819 Name("my test").820 CmpBody("xxx").821 Failed())822 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: body contents is OK'")823 td.CmpNot(t, mockT.LogBuf(), td.Contains("Received response:\n"))824 // AutoDumpResponse825 mockT = tdutil.NewT("test")826 td.CmpTrue(t,827 tdhttp.NewTestAPI(mockT, mux).828 AutoDumpResponse().829 Get("/any").830 Name("my test").831 CmpBody("xxx").832 Failed())833 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: body contents is OK'")834 td.Cmp(t, mockT.LogBuf(), td.Contains("Received response:\n"))835 mockT = tdutil.NewT("test")836 td.CmpTrue(t,837 tdhttp.NewTestAPI(mockT, mux).838 Name("my test").839 CmpBody("xxx").840 Failed())841 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: request is sent'\n")842 td.CmpContains(t, mockT.LogBuf(), "Request not sent!\n")843 td.CmpContains(t, mockT.LogBuf(), "A request must be sent before testing status, header, body or full response\n")844 // NoBody845 mockT = tdutil.NewT("test")846 td.CmpTrue(t,847 tdhttp.NewTestAPI(mockT, mux).848 Name("my test").849 NoBody().850 Failed())851 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: request is sent'\n")852 td.CmpContains(t, mockT.LogBuf(), "Request not sent!\n")853 td.CmpContains(t, mockT.LogBuf(), "A request must be sent before testing status, header, body or full response\n")854 td.CmpNot(t, mockT.LogBuf(), td.Contains("Received response:\n"))855 // Error followed by a success: Failed() should return true anyway856 mockT = tdutil.NewT("test")857 td.CmpTrue(t,858 tdhttp.NewTestAPI(mockT, mux).859 Name("my test").860 Head("/any").861 CmpBody("fail"). // fails862 NoBody(). // succeeds863 Failed())864 // No JSON body865 mockT = tdutil.NewT("test")866 td.CmpTrue(t,867 tdhttp.NewTestAPI(mockT, mux).868 Head("/any").869 CmpStatus(200).870 CmpHeader(containsKey).871 CmpJSONBody(json.RawMessage(`{}`)).872 Failed())873 td.CmpContains(t, mockT.LogBuf(), "Failed test 'body should not be empty'")874 td.CmpContains(t, mockT.LogBuf(), "Response body is empty!")875 td.CmpContains(t, mockT.LogBuf(), "Body cannot be empty when using CmpJSONBody")876 td.CmpNot(t, mockT.LogBuf(), td.Contains("Received response:\n"))877 // Error followed by a success: Failed() should return true anyway878 mockT = tdutil.NewT("test")879 td.CmpTrue(t,880 tdhttp.NewTestAPI(mockT, mux).881 Get("/any/json").882 CmpStatus(200).883 CmpHeader(containsKey).884 CmpJSONBody(json.RawMessage(`{}`)). // fails885 CmpJSONBody(td.Ignore()). // succeeds886 Failed())887 // No JSON body + AutoDumpResponse888 mockT = tdutil.NewT("test")889 td.CmpTrue(t,890 tdhttp.NewTestAPI(mockT, mux).891 AutoDumpResponse().892 Head("/any").893 CmpStatus(200).894 CmpHeader(containsKey).895 CmpJSONBody(json.RawMessage(`{}`)).896 Failed())897 td.CmpContains(t, mockT.LogBuf(), "Failed test 'body should not be empty'")898 td.CmpContains(t, mockT.LogBuf(), "Response body is empty!")899 td.CmpContains(t, mockT.LogBuf(), "Body cannot be empty when using CmpJSONBody")900 td.Cmp(t, mockT.LogBuf(), td.Contains("Received response:\n"))901 // No XML body902 mockT = tdutil.NewT("test")903 td.CmpTrue(t,904 tdhttp.NewTestAPI(mockT, mux).905 Head("/any").906 CmpStatus(200).907 CmpHeader(containsKey).908 CmpXMLBody(struct{ Test string }{}).909 Failed())910 td.CmpContains(t, mockT.LogBuf(), "Failed test 'body should not be empty'")911 td.CmpContains(t, mockT.LogBuf(), "Response body is empty!")912 td.CmpContains(t, mockT.LogBuf(), "Body cannot be empty when using CmpXMLBody")913 })914 t.Run("Response error", func(t *testing.T) {915 mockT := tdutil.NewT("test")916 td.CmpTrue(t,917 tdhttp.NewTestAPI(mockT, mux).918 Get("/any").919 CmpResponse(nil).920 Failed())921 td.CmpContains(t, mockT.LogBuf(), "Failed test 'full response should match'")922 td.CmpContains(t, mockT.LogBuf(), "Response: values differ")923 td.CmpContains(t, mockT.LogBuf(), "got: (*http.Response)(")924 td.CmpContains(t, mockT.LogBuf(), "expected: nil")925 // Error followed by a success: Failed() should return true anyway926 mockT = tdutil.NewT("test")927 td.CmpTrue(t,928 tdhttp.NewTestAPI(mockT, mux).929 Get("/any").930 CmpResponse(nil). // fails931 CmpResponse(td.Ignore()). // succeeds932 Failed())933 // Without AutoDumpResponse934 mockT = tdutil.NewT("test")935 td.CmpTrue(t,936 tdhttp.NewTestAPI(mockT, mux).937 Get("/any").938 Name("my test").939 CmpResponse(nil).940 Failed())941 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: full response should match'")942 td.CmpNot(t, mockT.LogBuf(), td.Contains("Received response:\n"))943 // AutoDumpResponse944 mockT = tdutil.NewT("test")945 td.CmpTrue(t,946 tdhttp.NewTestAPI(mockT, mux).947 AutoDumpResponse().948 Get("/any").949 Name("my test").950 CmpResponse(nil).951 Failed())952 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: full response should match'")953 td.Cmp(t, mockT.LogBuf(), td.Contains("Received response:\n"))954 mockT = tdutil.NewT("test")955 td.CmpTrue(t,956 tdhttp.NewTestAPI(mockT, mux).957 Name("my test").958 CmpResponse(nil).959 Failed())960 td.CmpContains(t, mockT.LogBuf(), "Failed test 'my test: request is sent'\n")961 td.CmpContains(t, mockT.LogBuf(), "Request not sent!\n")962 td.CmpContains(t, mockT.LogBuf(), "A request must be sent before testing status, header, body or full response\n")963 })964 t.Run("Request error", func(t *testing.T) {965 var ta *tdhttp.TestAPI966 checkFatal := func(fn func()) {967 mockT := tdutil.NewT("test")968 td.CmpTrue(t, mockT.CatchFailNow(func() {969 ta = tdhttp.NewTestAPI(mockT, mux)970 fn()971 }))972 td.Cmp(t,...
http_test.go
Source:http_test.go
...20func TestMain(m *testing.M) {21 color.SaveState()22 os.Exit(m.Run())23}24type CmpResponseTest struct {25 Name string26 Handler func(w http.ResponseWriter, r *http.Request)27 Success bool28 ExpectedResp tdhttp.Response29 ExpectedLogs []string30}31func TestCmpResponse(tt *testing.T) {32 handlerNonEmpty := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {33 w.Header().Add("X-TestDeep", "foobar")34 w.WriteHeader(242)35 fmt.Fprintln(w, "text response")36 })37 cookie := http.Cookie{Name: "Cookies-Testdeep", Value: "foobar"}38 handlerWithCokies := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {39 w.Header().Add("X-TestDeep", "cookies")40 http.SetCookie(w, &cookie)41 w.WriteHeader(242)42 })43 handlerEmpty := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {44 w.Header().Add("X-TestDeep", "zip")45 w.WriteHeader(424)46 })47 t := td.NewT(tt)48 for _, curTest := range []CmpResponseTest{49 // Non-empty success50 {51 Name: "string body only",52 Handler: handlerNonEmpty,53 Success: true,54 ExpectedResp: tdhttp.Response{Body: "text response\n"},55 },56 {57 Name: "[]byte status + body",58 Handler: handlerNonEmpty,59 Success: true,60 ExpectedResp: tdhttp.Response{61 Status: 242,62 Body: []byte("text response\n"),63 },64 },65 {66 Name: "[]byte status + header + body",67 Handler: handlerNonEmpty,68 Success: true,69 ExpectedResp: tdhttp.Response{70 Status: 242,71 Header: http.Header{"X-Testdeep": []string{"foobar"}},72 Body: []byte("text response\n"),73 },74 },75 {76 Name: "with TestDeep operators",77 Handler: handlerNonEmpty,78 Success: true,79 ExpectedResp: tdhttp.Response{80 Status: td.Between(200, 300),81 Header: td.ContainsKey("X-Testdeep"),82 Body: td.All(83 td.Isa(""), // enforces TypeBehind â string84 td.Contains("response"),85 ),86 },87 },88 {89 Name: "ignore body explicitly",90 Handler: handlerNonEmpty,91 Success: true,92 ExpectedResp: tdhttp.Response{93 Status: 242,94 Header: http.Header{"X-Testdeep": []string{"foobar"}},95 Body: td.Ignore(),96 },97 },98 {99 Name: "body just not empty",100 Handler: handlerNonEmpty,101 Success: true,102 ExpectedResp: tdhttp.Response{103 Status: 242,104 Header: http.Header{"X-Testdeep": []string{"foobar"}},105 Body: td.NotEmpty(),106 },107 },108 // Non-empty failures109 {110 Name: "bad status",111 Handler: handlerNonEmpty,112 Success: false,113 ExpectedResp: tdhttp.Response{Status: 243, Body: td.NotEmpty()},114 ExpectedLogs: []string{115 `~ Failed test 'status code should match'116\s+Response.Status: values differ117\s+got: 242118\s+expected: 243`,119 `~ Received response:120\s+\x60(?s:.+?)121\s+122\s+text response123\s+\x60124`, // check the complete body is shown125 },126 },127 {128 Name: "bad body",129 Handler: handlerNonEmpty,130 Success: false,131 ExpectedResp: tdhttp.Response{Body: "BAD!"},132 ExpectedLogs: []string{133 `~ Failed test 'body contents is OK'134\s+Response.Body: values differ135\s+got: \x60text response136\s+\x60137\s+expected: "BAD!"`,138 },139 },140 {141 Name: "bad body, as non-empty",142 Handler: handlerNonEmpty,143 Success: false,144 ExpectedResp: tdhttp.Response{},145 ExpectedLogs: []string{146 `~ Failed test 'body should be empty'147\s+Response.Body is not empty148\s+got: not empty149\s+expected: empty`,150 `~ Received response:151\s+\x60(?s:.+?)152\s+153\s+text response154\s+\x60155`, // check the complete body is shown156 },157 },158 {159 Name: "bad header",160 Handler: handlerNonEmpty,161 Success: false,162 ExpectedResp: tdhttp.Response{163 Header: http.Header{"X-Testdeep": []string{"zzz"}},164 Body: td.NotEmpty(),165 },166 ExpectedLogs: []string{167 `~ Failed test 'header should match'168\s+Response.Header\["X-Testdeep"\]\[0\]: values differ169\s+got: "foobar"170\s+expected: "zzz"`,171 },172 },173 {174 Name: "bad cookies",175 Handler: handlerWithCokies,176 Success: false,177 ExpectedResp: tdhttp.Response{178 Cookies: []*http.Cookie{{Name: "Cookies-Testdeep", Value: "squalala"}},179 Body: td.Empty(),180 },181 ExpectedLogs: []string{182 `~ Failed test 'cookies should match'183\s+Response.Cookie\[0\]\.Value: values differ184\s+got: "foobar"185\s+expected: "squalala"`,186 },187 },188 {189 Name: "good cookies",190 Handler: handlerWithCokies,191 Success: true,192 ExpectedResp: tdhttp.Response{193 Header: http.Header{194 "X-Testdeep": []string{"cookies"},195 "Set-Cookie": []string{cookie.String()},196 },197 Cookies: []*http.Cookie{&cookie},198 Body: td.Empty(),199 },200 },201 {202 Name: "cannot unmarshal",203 Handler: handlerNonEmpty,204 Success: false,205 ExpectedResp: tdhttp.Response{Body: 123},206 ExpectedLogs: []string{207 `~ Failed test 'body unmarshaling'208\s+unmarshal\(Response\.Body\): should NOT be an error209\s+got: .*Cmp(Response|Body) only accepts expected(Resp\.)?Body be a \[\]byte, a string or a TestDeep operator allowing to match these types, but not type int.*210\s+expected: nil`,211 `~ Received response:212\s+\x60(?s:.+?)213\s+214\s+text response215\s+\x60216`, // check the complete body is shown217 },218 },219 // Empty success220 {221 Name: "empty body",222 Handler: handlerEmpty,223 Success: true,224 ExpectedResp: tdhttp.Response{225 Status: 424,226 Header: http.Header{"X-Testdeep": []string{"zip"}},227 Body: nil,228 },229 },230 // Empty failures231 {232 Name: "should not be empty",233 Handler: handlerEmpty,234 Success: false,235 ExpectedResp: tdhttp.Response{Body: "NOT EMPTY!"},236 ExpectedLogs: []string{237 `~ Failed test 'body contents is OK'238\s+Response.Body: values differ239\s+got: ""240\s+expected: "NOT EMPTY!"`,241 },242 },243 } {244 t.Run(curTest.Name,245 func(t *td.T) {246 testCmpResponse(t, tdhttp.CmpResponse, "CmpResponse", curTest)247 })248 t.Run(curTest.Name+" TestAPI",249 func(t *td.T) {250 testTestAPI(t, (*tdhttp.TestAPI).CmpBody, "CmpBody", curTest)251 })252 }253}254func TestCmpJSONResponse(tt *testing.T) {255 handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {256 w.Header().Add("X-TestDeep", "foobar")257 w.WriteHeader(242)258 fmt.Fprintln(w, `{"name":"Bob"}`)259 })260 type JResp struct {261 Name string `json:"name"`262 }263 t := td.NewT(tt)264 for _, curTest := range []CmpResponseTest{265 // Success266 {267 Name: "JSON OK",268 Handler: handler,269 Success: true,270 ExpectedResp: tdhttp.Response{271 Status: 242,272 Header: http.Header{"X-Testdeep": []string{"foobar"}},273 Body: JResp{Name: "Bob"},274 },275 },276 {277 Name: "JSON ptr OK",278 Handler: handler,279 Success: true,280 ExpectedResp: tdhttp.Response{281 Status: 242,282 Header: http.Header{"X-Testdeep": []string{"foobar"}},283 Body: &JResp{Name: "Bob"},284 },285 },286 // Failure287 {288 Name: "JSON failure",289 Handler: handler,290 Success: false,291 ExpectedResp: tdhttp.Response{292 Body: 123,293 },294 ExpectedLogs: []string{295 `~ Failed test 'body unmarshaling'296\s+unmarshal\(Response\.Body\): should NOT be an error297\s+got: .*cannot unmarshal object into Go value of type int.*298\s+expected: nil`,299 `~ Received response:300\s+\x60(?s:.+?)301\s+302\s+\{"name":"Bob"\}303\s+\x60304`, // check the complete body is shown305 },306 },307 } {308 t.Run(curTest.Name,309 func(t *td.T) {310 testCmpResponse(t, tdhttp.CmpJSONResponse, "CmpJSONResponse", curTest)311 })312 t.Run(curTest.Name+" TestAPI",313 func(t *td.T) {314 testTestAPI(t, (*tdhttp.TestAPI).CmpJSONBody, "CmpJSONBody", curTest)315 })316 }317}318func TestCmpJSONResponseAnchor(tt *testing.T) {319 t := td.NewT(tt)320 handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {321 w.WriteHeader(242)322 fmt.Fprintln(w, `{"name":"Bob"}`)323 })324 req := httptest.NewRequest("GET", "/path", nil)325 type JResp struct {326 Name string `json:"name"`327 }328 // With *td.T329 tdhttp.CmpJSONResponse(t, req, handler,330 tdhttp.Response{331 Status: 242,332 Body: JResp{333 Name: t.A(td.Re("(?i)bob"), "").(string),334 },335 })336 // With *testing.T337 tdhttp.CmpJSONResponse(tt, req, handler,338 tdhttp.Response{339 Status: 242,340 Body: JResp{341 Name: t.A(td.Re("(?i)bob"), "").(string),342 },343 })344 func() {345 defer t.AnchorsPersistTemporarily()()346 op := t.A(td.Re("(?i)bob"), "").(string)347 // All calls should succeed, as op persists348 tdhttp.CmpJSONResponse(t, req, handler,349 tdhttp.Response{350 Status: 242,351 Body: JResp{Name: op},352 })353 tdhttp.CmpJSONResponse(t, req, handler,354 tdhttp.Response{355 Status: 242,356 Body: JResp{Name: op},357 })358 // Even with the original *testing.T instance (here tt)359 tdhttp.CmpJSONResponse(tt, req, handler,360 tdhttp.Response{361 Status: 242,362 Body: JResp{Name: op},363 })364 }()365 // Failures366 t.FailureIsFatal().False(t.DoAnchorsPersist()) // just to be sure367 mt := td.NewT(tdutil.NewT("tdhttp_persistence_test"))368 op := mt.A(td.Re("(?i)bob"), "").(string)369 // First call should succeed370 t.True(tdhttp.CmpJSONResponse(mt, req, handler,371 tdhttp.Response{372 Status: 242,373 Body: JResp{Name: op},374 }))375 // Second one should fail, as previously anchored operator has been reset376 t.False(tdhttp.CmpJSONResponse(mt, req, handler,377 tdhttp.Response{378 Status: 242,379 Body: JResp{Name: op},380 }))381}382func TestCmpXMLResponse(tt *testing.T) {383 handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {384 w.Header().Add("X-TestDeep", "foobar")385 w.WriteHeader(242)386 fmt.Fprintln(w, `<XResp><name>Bob</name></XResp>`)387 })388 type XResp struct {389 Name string `xml:"name"`390 }391 t := td.NewT(tt)392 for _, curTest := range []CmpResponseTest{393 // Success394 {395 Name: "XML OK",396 Handler: handler,397 Success: true,398 ExpectedResp: tdhttp.Response{399 Status: 242,400 Header: http.Header{"X-Testdeep": []string{"foobar"}},401 Body: XResp{Name: "Bob"},402 },403 },404 {405 Name: "XML ptr OK",406 Handler: handler,407 Success: true,408 ExpectedResp: tdhttp.Response{409 Status: 242,410 Header: http.Header{"X-Testdeep": []string{"foobar"}},411 Body: &XResp{Name: "Bob"},412 },413 },414 // Failure415 {416 Name: "XML failure",417 Handler: handler,418 Success: false,419 ExpectedResp: tdhttp.Response{420 // xml.Unmarshal does not raise an error when trying to421 // unmarshal in an int, as json does...422 Body: func() {},423 },424 ExpectedLogs: []string{425 `~ Failed test 'body unmarshaling'426\s+unmarshal\(Response\.Body\): should NOT be an error427\s+got: .*unknown type func\(\).*428\s+expected: nil`,429 `~ Received response:430\s+\x60(?s:.+?)431\s+432\s+<XResp><name>Bob</name></XResp>433\s+\x60434`, // check the complete body is shown435 },436 },437 } {438 t.Run(curTest.Name,439 func(t *td.T) {440 testCmpResponse(t, tdhttp.CmpXMLResponse, "CmpXMLResponse", curTest)441 })442 t.Run(curTest.Name+" TestAPI",443 func(t *td.T) {444 testTestAPI(t, (*tdhttp.TestAPI).CmpXMLBody, "CmpXMLBody", curTest)445 })446 }447}448var logsViz = strings.NewReplacer(449 " ", "·",450 "\t", "â",451 "\r", "<cr>",452)453func testLogs(t *td.T, mockT *tdutil.T, curTest CmpResponseTest) {454 t.Helper()455 dumpLogs := !t.Cmp(mockT.Failed(), !curTest.Success, "test failure")456 for _, expectedLog := range curTest.ExpectedLogs {457 if strings.HasPrefix(expectedLog, "~") {458 re := regexp.MustCompile(expectedLog[1:])459 if !re.MatchString(mockT.LogBuf()) {460 t.Errorf(`logs do not match "%s" regexp`, re)461 dumpLogs = true462 }463 } else if !strings.Contains(mockT.LogBuf(), expectedLog) {464 t.Errorf(`"%s" not found in test logs`, expectedLog)465 dumpLogs = true466 }467 }468 if dumpLogs {469 t.Errorf(`Test logs: "%s"`, logsViz.Replace(mockT.LogBuf()))470 }471}472func testCmpResponse(t *td.T,473 cmp func(testing.TB, *http.Request, func(http.ResponseWriter, *http.Request), tdhttp.Response, ...any) bool,474 cmpName string,475 curTest CmpResponseTest,476) {477 t.Helper()478 mockT := tdutil.NewT(cmpName)479 t.Cmp(cmp(mockT,480 httptest.NewRequest("GET", "/path", nil),481 curTest.Handler,482 curTest.ExpectedResp),483 curTest.Success)484 testLogs(t, mockT, curTest)485}486func testTestAPI(t *td.T,487 cmpBody func(*tdhttp.TestAPI, any) *tdhttp.TestAPI,488 cmpName string,489 curTest CmpResponseTest,490) {491 t.Helper()492 mockT := tdutil.NewT(cmpName)493 ta := tdhttp.NewTestAPI(mockT, http.HandlerFunc(curTest.Handler)).494 Get("/path")495 if curTest.ExpectedResp.Status != nil {496 ta.CmpStatus(curTest.ExpectedResp.Status)497 }498 if curTest.ExpectedResp.Header != nil {499 ta.CmpHeader(curTest.ExpectedResp.Header)500 }501 if curTest.ExpectedResp.Cookies != nil {502 ta.CmpCookies(curTest.ExpectedResp.Cookies)503 }504 cmpBody(ta, curTest.ExpectedResp.Body)505 t.Cmp(ta.Failed(), !curTest.Success)506 testLogs(t, mockT, curTest)507}508func TestMux(t *testing.T) {509 mux := http.NewServeMux()510 // GET /text511 mux.HandleFunc("/text", func(w http.ResponseWriter, req *http.Request) {512 if req.Method != "GET" {513 http.NotFound(w, req)514 return515 }516 w.Header().Set("Content-Type", "text/plain")517 w.WriteHeader(http.StatusOK)518 fmt.Fprintf(w, "Text result!")519 })520 // GET /json521 mux.HandleFunc("/json", func(w http.ResponseWriter, req *http.Request) {522 w.Header().Set("Content-Type", "application/json")523 w.WriteHeader(http.StatusOK)524 if req.Method != "GET" {525 fmt.Fprintf(w, `{"code":404,"message":"Not found"}`)526 return527 }528 fmt.Fprintf(w, `{"comment":"JSON result!"}`)529 })530 // GET /xml531 mux.HandleFunc("/xml", func(w http.ResponseWriter, req *http.Request) {532 if req.Method != "GET" {533 http.NotFound(w, req)534 return535 }536 w.Header().Set("Content-Type", "application/xml")537 w.WriteHeader(http.StatusOK)538 fmt.Fprintf(w, `<XResp><comment>XML result!</comment></XResp>`)539 })540 //541 // Check GET /text route542 t.Run("/text route", func(t *testing.T) {543 tdhttp.CmpResponse(t, tdhttp.NewRequest("GET", "/text", nil),544 mux.ServeHTTP,545 tdhttp.Response{546 Status: http.StatusOK,547 Header: td.SuperMapOf(http.Header{548 "Content-Type": []string{"text/plain"},549 }, nil),550 Body: "Text result!",551 },552 "GET /text should return 200 + text/plain + Text result!")553 tdhttp.CmpResponse(t, tdhttp.NewRequest("PATCH", "/text", nil),554 mux.ServeHTTP,555 tdhttp.Response{556 Status: http.StatusNotFound,557 Body: td.Ignore(),558 },559 "PATCH /text should return Not Found")560 t.Run("/text route via CmpResponseFunc", tdhttp.CmpResponseFunc(561 tdhttp.NewRequest("GET", "/text", nil),562 mux.ServeHTTP,563 tdhttp.Response{564 Status: http.StatusOK,565 Header: td.SuperMapOf(http.Header{566 "Content-Type": []string{"text/plain"},567 }, nil),568 Body: "Text result!",569 }))570 t.Run("/text route via CmpMarshaledResponseFunc", tdhttp.CmpMarshaledResponseFunc(571 tdhttp.NewRequest("GET", "/text", nil),572 mux.ServeHTTP,573 func(body []byte, target any) error {574 *target.(*string) = string(body)...
http.go
Source:http.go
...83) bool {84 t.Helper()85 return cmpMarshaledResponse(t, req, handler, false, unmarshal, expectedResp, args...)86}87// CmpResponse is used to match a []byte or string response body. req88// is launched against handler. If expectedResp.Body is non-nil, the89// response body is converted to []byte or string, depending on the90// expectedResp.Body type. The response is then tested against91// expectedResp.92//93// args... are optional and allow to name the test, a t.Log() done94// before starting any test. If len(args) > 1 and the first item of95// args is a string and contains a '%' rune then [fmt.Fprintf] is used96// to compose the name, else args are passed to [fmt.Fprint].97//98// It returns true if the tests succeed, false otherwise.99//100// ok := tdhttp.CmpResponse(t,101// tdhttp.Get("/test"),102// myAPI.ServeHTTP,103// Response{104// Status: http.StatusOK,105// Header: td.ContainsKey("X-Custom-Header"),106// Body: "OK!\n",107// },108// "/test route")109//110// Response.Status, Response.Header and Response.Body fields can all111// be [td.TestDeep] operators as it is for Response.Header field112// here. Otherwise, Response.Status should be an int, Response.Header113// a [http.Header] and Response.Body a []byte or a string.114//115// See [TestAPI] type and its methods for more flexible tests.116func CmpResponse(t testing.TB,117 req *http.Request,118 handler func(w http.ResponseWriter, r *http.Request),119 expectedResp Response,120 args ...any) bool {121 t.Helper()122 return cmpMarshaledResponse(t,123 req,124 handler,125 true,126 func(body []byte, target any) error {127 switch t := target.(type) {128 case *string:129 *t = string(body)130 case *[]byte:131 *t = body132 case *any:133 *t = body134 default:135 // cmpMarshaledBody (behind cmpMarshaledResponse) always calls136 // us with target as a pointer137 return fmt.Errorf(138 "CmpResponse only accepts expectedResp.Body be a []byte, a string or a TestDeep operator allowing to match these types, but not type %s",139 reflect.TypeOf(target).Elem())140 }141 return nil142 },143 expectedResp,144 args...)145}146// CmpJSONResponse is used to match a JSON response body. req is147// launched against handler. If expectedResp.Body is non-nil, the148// response body is [json.Unmarshal]'ed. The response is then tested149// against expectedResp.150//151// args... are optional and allow to name the test, a t.Log() done152// before starting any test. If len(args) > 1 and the first item of153// args is a string and contains a '%' rune then [fmt.Fprintf] is used154// to compose the name, else args are passed to [fmt.Fprint].155//156// It returns true if the tests succeed, false otherwise.157//158// ok := tdhttp.CmpJSONResponse(t,159// tdhttp.Get("/person/42"),160// myAPI.ServeHTTP,161// Response{162// Status: http.StatusOK,163// Header: td.ContainsKey("X-Custom-Header"),164// Body: Person{165// ID: 42,166// Name: "Bob",167// Age: 26,168// },169// },170// "/person/{id} route")171//172// Response.Status, Response.Header and Response.Body fields can all173// be [td.TestDeep] operators as it is for Response.Header field174// here. Otherwise, Response.Status should be an int, Response.Header175// a [http.Header] and Response.Body any type one can176// [json.Unmarshal] into.177//178// If Response.Status and Response.Header are omitted (or nil), they179// are not tested.180//181// If Response.Body is omitted (or nil), it means the body response has to be182// empty. If you want to ignore the body response, use [td.Ignore]183// explicitly.184//185// See [TestAPI] type and its methods for more flexible tests.186func CmpJSONResponse(t testing.TB,187 req *http.Request,188 handler func(w http.ResponseWriter, r *http.Request),189 expectedResp Response,190 args ...any,191) bool {192 t.Helper()193 return CmpMarshaledResponse(t,194 req,195 handler,196 json.Unmarshal,197 expectedResp,198 args...)199}200// CmpXMLResponse is used to match an XML response body. req201// is launched against handler. If expectedResp.Body is202// non-nil, the response body is [xml.Unmarshal]'ed. The response is203// then tested against expectedResp.204//205// args... are optional and allow to name the test, a t.Log() done206// before starting any test. If len(args) > 1 and the first item of207// args is a string and contains a '%' rune then [fmt.Fprintf] is used208// to compose the name, else args are passed to [fmt.Fprint].209//210// It returns true if the tests succeed, false otherwise.211//212// ok := tdhttp.CmpXMLResponse(t,213// tdhttp.Get("/person/42"),214// myAPI.ServeHTTP,215// Response{216// Status: http.StatusOK,217// Header: td.ContainsKey("X-Custom-Header"),218// Body: Person{219// ID: 42,220// Name: "Bob",221// Age: 26,222// },223// },224// "/person/{id} route")225//226// Response.Status, Response.Header and Response.Body fields can all227// be [td.TestDeep] operators as it is for Response.Header field228// here. Otherwise, Response.Status should be an int, Response.Header229// a [http.Header] and Response.Body any type one can [xml.Unmarshal]230// into.231//232// If Response.Status and Response.Header are omitted (or nil), they233// are not tested.234//235// If Response.Body is omitted (or nil), it means the body response236// has to be empty. If you want to ignore the body response, use237// [td.Ignore] explicitly.238//239// See [TestAPI] type and its methods for more flexible tests.240func CmpXMLResponse(t testing.TB,241 req *http.Request,242 handler func(w http.ResponseWriter, r *http.Request),243 expectedResp Response,244 args ...any,245) bool {246 t.Helper()247 return CmpMarshaledResponse(t,248 req,249 handler,250 xml.Unmarshal,251 expectedResp,252 args...)253}254// CmpMarshaledResponseFunc returns a function ready to be used with255// [testing.T.Run], calling [CmpMarshaledResponse] behind the scene. As it256// is intended to be used in conjunction with [testing.T.Run] which257// names the sub-test, the test name part (args...) is voluntary258// omitted.259//260// t.Run("Subtest name", tdhttp.CmpMarshaledResponseFunc(261// tdhttp.Get("/text"),262// mux.ServeHTTP,263// tdhttp.Response{264// Status: http.StatusOK,265// }))266//267// See [CmpMarshaledResponse] for details.268//269// See [TestAPI] type and its methods for more flexible tests.270func CmpMarshaledResponseFunc(req *http.Request,271 handler func(w http.ResponseWriter, r *http.Request),272 unmarshal func([]byte, any) error,273 expectedResp Response) func(t *testing.T) {274 return func(t *testing.T) {275 t.Helper()276 CmpMarshaledResponse(t, req, handler, unmarshal, expectedResp)277 }278}279// CmpResponseFunc returns a function ready to be used with280// [testing.T.Run], calling [CmpResponse] behind the scene. As it is281// intended to be used in conjunction with [testing.T.Run] which names282// the sub-test, the test name part (args...) is voluntary omitted.283//284// t.Run("Subtest name", tdhttp.CmpResponseFunc(285// tdhttp.Get("/text"),286// mux.ServeHTTP,287// tdhttp.Response{288// Status: http.StatusOK,289// }))290//291// See [CmpResponse] documentation for details.292//293// See [TestAPI] type and its methods for more flexible tests.294func CmpResponseFunc(req *http.Request,295 handler func(w http.ResponseWriter, r *http.Request),296 expectedResp Response) func(t *testing.T) {297 return func(t *testing.T) {298 t.Helper()299 CmpResponse(t, req, handler, expectedResp)300 }301}302// CmpJSONResponseFunc returns a function ready to be used with303// [testing.T.Run], calling [CmpJSONResponse] behind the scene. As it is304// intended to be used in conjunction with [testing.T.Run] which names305// the sub-test, the test name part (args...) is voluntary omitted.306//307// t.Run("Subtest name", tdhttp.CmpJSONResponseFunc(308// tdhttp.Get("/json"),309// mux.ServeHTTP,310// tdhttp.Response{311// Status: http.StatusOK,312// Body: JResp{Comment: "expected comment!"},313// }))...
CmpResponse
Using AI Code Generation
1import (2func main() {3 client := telegram.Client{}4 client.Initialize()5 client.Create()6 client.SetLogVerbosityLevel(0)7 client.SetDatabaseDirectory("")8 client.SetFilesDirectory("")9 client.SetLogVerbosityLevel(0)10 client.SetTdlibParameters(&tg.TdlibParameters{11 })12 for {13 update := client.Receive(10 * time.Second)14 if update == nil {15 fmt.Println("Receive timeout")16 }17 switch update.GetConstructor() {18 state := update.GetData().(*tg.UpdateAuthorizationState).AuthorizationState19 switch state.GetConstructor() {
CmpResponse
Using AI Code Generation
1import (2type tdhttp struct {3}4func main() {5 plugin.Serve(&plugin.ServeOpts{6 TableMap: map[string]*plugin.Table{7 "tdhttp": &plugin.Table{8 Get: &plugin.GetConfig{9 KeyColumns: plugin.SingleColumn("url"),10 },11 Columns: []*plugin.Column{12 {13 Transform: transform.FromField("URL"),14 },15 {16 Transform: transform.FromField("StatusCode"),17 },18 {19 Transform: transform.FromField("StatusText"),20 },21 {22 Transform: transform.FromField("ContentLength"),23 },24 {25 Transform: transform.FromField("ContentType"),26 },27 {28 Transform: transform.FromField("Body"),29 },30 },31 },32 },33 })34}35func tdhttpGet(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {36 url := d.KeyColumnQuals["url"].GetStringValue()37 resp, err := tdhttp.CmpResponse(ctx, url)38 if err != nil {39 }40 d.StreamListItem(ctx, resp)41}42import (
CmpResponse
Using AI Code Generation
1import (2func main() {3 client := tdhttp.NewClient()4 if err != nil {5 log.Fatal(err)6 }7 defer resp.Body.Close()8 fmt.Println(resp.CmpResponse(&http.Response{9 Header: http.Header{10 "Content-Type": []string{"text/html; charset=ISO-8859-1"},11 },12 Body: ioutil.NopCloser(nil),13 }))14}15import (16func main() {17 client := tdhttp.NewClient()18 if err != nil {19 log.Fatal(err)20 }21 defer resp.Body.Close()22 fmt.Println(resp.CmpResponse(&http.Response{23 Header: http.Header{24 "Content-Type": []string{"text/html; charset=ISO-8859-1"},25 },26 Body: ioutil.NopCloser(nil),27 }))28}29import (30func main() {31 client := tdhttp.NewClient()32 if err != nil {33 log.Fatal(err)34 }35 defer resp.Body.Close()36 fmt.Println(resp.CmpResponse(&http.Response{37 Header: http.Header{38 "Content-Type": []string{"text/html; charset=ISO-8859-1"},39 },40 Body: ioutil.NopCloser(nil),41 }))42}43import (
CmpResponse
Using AI Code Generation
1import (2func main() {3fmt.Println(str)4}5import (6func main() {7fmt.Println(str)8}9import (10func main() {11fmt.Println(str)12}13import (14func main() {
CmpResponse
Using AI Code Generation
1import "fmt"2import "github.com/tdlib/tdlib"3func main() {4 client := tdlib.NewClient(tdlib.Config{5 })6 for {7 update := client.Receive(10.0)8 if update == nil {9 fmt.Println("Update is nil")10 }11 switch update.GetClass() {12 state := update.(*tdlib.UpdateAuthorizationState).AuthorizationState13 switch state.GetClass() {14 fmt.Println("WaitTdlibParameters")15 fmt.Println("WaitEncryptionKey")16 fmt.Println("WaitPhoneNumber")17 _, _ = client.Send(&tdlib.SetAuthenticationPhoneNumber{18 })19 fmt.Println("WaitCode")20 _, _ = client.Send(&tdlib.CheckAuthenticationCode{21 })22 fmt.Println("WaitPassword")23 _, _ = client.Send(&tdlib.CheckAuthenticationPassword{24 })25 fmt.Println("Ready")26 _, _ = client.Send(&tdlib.SendHTTPRequest{27 })
CmpResponse
Using AI Code Generation
1func main() {2 myhttp.CmpResponse()3}4import "fmt"5type tdhttp struct{}6func (tdhttp) CmpResponse() {7 fmt.Println("Response")8}9import (10func main() {11 fmt.Println("Hello, world!")12 sub.SayHello()13}14import "fmt"15func SayHello() {16 fmt.Println("Hello, sub!")17}18import (19func TestSayHello(t *testing.T) {20 sub.SayHello()21}22 /usr/lib/go-1.6/src/sub (from $GOROOT)23 /home/username/go/src/sub (from $GOPATH)24I have a project which has a main.go file in the root directory. I have a sub directory in the root directory, and I want to create a sub.go file in that sub directory. I want to be able to import the sub package in the main.go file. How can I do this?
CmpResponse
Using AI Code Generation
1import (2func main() {3 if err != nil {4 fmt.Println("Error:", err)5 }6 testdeep.CmpResponse(response, &http.Response{7 Header: http.Header{8 "Content-Type": {"text/plain; charset=utf-8"},9 },10 Body: testdeep.ReaderContainsString("Hello, world"),11 })12}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!