diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d614a0..904a7c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG +## v1.0.10 (2026-05-09) +- **CI/CD 对齐**: + - 修复测试用例由于默认绑定泛地址导致的 `connection refused` 错误,显式绑定本地测试服务器至 `127.0.0.1`,提高 macOS 与多网卡环境下的测试稳定性。 + - 更新 `TEST.md`,同步最新的测试用例覆盖场景(包括 `Multipart` 和 `Form` 的验证)及真实 Benchmark。 + ## v1.0.9 (2026-05-09) - **基础设施对齐**: - 升级 `apigo.cc/go/log` 至 `v1.1.13`。 diff --git a/TEST.md b/TEST.md index 4f05d6d..7faf673 100644 --- a/TEST.md +++ b/TEST.md @@ -4,9 +4,10 @@ - **基础请求**: 验证了使用 `Get` 获取 JSON 响应并通过 `To[T]` 进行泛型绑定的功能。 - **本地服务器**: 验证了客户端与本地测试服务器的交互。 - **H2C 支持**: 验证了 H2C (HTTP/2 Cleartext) 的兼容性。 -- **手动请求**: 验证了通过 `ManualDo` 进行精细化控制的流程。 +- **手动请求**: 验证了通过 `ManualDo` 进行精细化控制的流式请求。 - **文件下载**: 验证了使用 `Download` 进行并发分段下载的功能。 -- **多部分表单**: 验证了使用 `MPost` 上传文件和表单数据的正确性。 +- **多部分表单 (Multipart)**: 验证了使用流式 `io.Pipe` 的 `Multipart` 发送,以及多类型、多值字段的支持。 +- **表单与映射**: 验证了使用 `Form`, `map[string]string`, `map[string][]string`, 和 `map[string][]any` 自动转为正确的 `application/x-www-form-urlencoded` 或 `application/json`。 ## 性能测试结果 (Benchmark) ``` @@ -14,5 +15,8 @@ goos: darwin goarch: amd64 pkg: apigo.cc/go/http cpu: Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz -BenchmarkGet-16 15944 73379 ns/op +BenchmarkGet-16 16364 74735 ns/op ``` + +## 测试覆盖率 +- **整体覆盖率**: 56.5% of statements diff --git a/client_test.go b/client_test.go index d5bb7ea..1faffc2 100644 --- a/client_test.go +++ b/client_test.go @@ -44,7 +44,7 @@ func TestLocalServer(t *testing.T) { _, _ = w.Write([]byte("world")) }) - server := &http.Server{Addr: ":18080", Handler: handler} + server := &http.Server{Addr: "127.0.0.1:18080", Handler: handler} go func() { _ = server.ListenAndServe() }() defer server.Close() @@ -102,7 +102,7 @@ func BenchmarkGet(b *testing.B) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("ok")) }) - server := &http.Server{Addr: ":18082", Handler: handler} + server := &http.Server{Addr: "127.0.0.1:18082", Handler: handler} go func() { _ = server.ListenAndServe() }() defer server.Close() time.Sleep(100 * time.Millisecond) @@ -121,7 +121,7 @@ func TestManualDo(t *testing.T) { handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte("stream")) }) - server := &http.Server{Addr: ":18083", Handler: handler} + server := &http.Server{Addr: "127.0.0.1:18083", Handler: handler} go func() { _ = server.ListenAndServe() }() defer server.Close() time.Sleep(100 * time.Millisecond) @@ -157,7 +157,7 @@ func TestDownload(t *testing.T) { } _, _ = w.Write([]byte(content)) }) - server := &http.Server{Addr: ":18084", Handler: handler} + server := &http.Server{Addr: "127.0.0.1:18084", Handler: handler} go func() { _ = server.ListenAndServe() }() defer server.Close() time.Sleep(100 * time.Millisecond) @@ -189,7 +189,7 @@ func TestMultipartDo(t *testing.T) { } fmt.Fprintf(w, "foo=%s,file=%s", f, string(fileContent)) }) - server := &http.Server{Addr: ":18086", Handler: handler} + server := &http.Server{Addr: "127.0.0.1:18086", Handler: handler} go func() { _ = server.ListenAndServe() }() defer server.Close() time.Sleep(100 * time.Millisecond) @@ -210,7 +210,7 @@ func TestFormAndMap(t *testing.T) { body, _ := io.ReadAll(r.Body) fmt.Fprintf(w, "ct=%s,body=%s", ct, string(body)) }) - server := &http.Server{Addr: ":18087", Handler: handler} + server := &http.Server{Addr: "127.0.0.1:18087", Handler: handler} go func() { _ = server.ListenAndServe() }() defer server.Close() time.Sleep(100 * time.Millisecond) diff --git a/optimization_test.go b/optimization_test.go index 2f1a978..a4b451d 100644 --- a/optimization_test.go +++ b/optimization_test.go @@ -20,7 +20,7 @@ func TestOptimizationForms(t *testing.T) { } fmt.Fprintf(w, "foo=%v", r.Form["foo"]) }) - server := &http.Server{Addr: ":18088", Handler: handler} + server := &http.Server{Addr: "127.0.0.1:18088", Handler: handler} go func() { _ = server.ListenAndServe() }() defer server.Close() time.Sleep(100 * time.Millisecond) @@ -62,7 +62,7 @@ func TestMultipartStreaming(t *testing.T) { } fmt.Fprintf(w, "foo=%s,file=%s", f1, string(fileContent)) }) - server := &http.Server{Addr: ":18089", Handler: handler} + server := &http.Server{Addr: "127.0.0.1:18089", Handler: handler} go func() { _ = server.ListenAndServe() }() defer server.Close() time.Sleep(100 * time.Millisecond) @@ -86,7 +86,7 @@ func TestMultipartMultipleParts(t *testing.T) { _ = r.ParseMultipartForm(10 << 20) fmt.Fprintf(w, "foo=%v", r.MultipartForm.Value["foo"]) }) - server := &http.Server{Addr: ":18090", Handler: handler} + server := &http.Server{Addr: "127.0.0.1:18090", Handler: handler} go func() { _ = server.ListenAndServe() }() defer server.Close() time.Sleep(100 * time.Millisecond)