diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 343a9b9..6801c30 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,10 +11,10 @@ jobs: test: strategy: matrix: - go-version: [1.16.x, 1.17.x, 1.18.x, 1.19.x, 1.20.x, 1.21.x, 1.22.x, tip] + go-version: [1.16.x, 1.17.x, 1.18.x, 1.19.x, 1.20.x, 1.21.x, 1.22.x, 1.23.x, tip] full-tests: [false] include: - - go-version: 1.23.x + - go-version: 1.24.x full-tests: true runs-on: ubuntu-latest @@ -22,7 +22,7 @@ jobs: steps: - name: Setup go run: | - curl -sL https://raw.githubusercontent.com/maxatome/install-go/v3.6/install-go.pl | + curl -sL https://raw.githubusercontent.com/maxatome/install-go/v3.7/install-go.pl | perl - ${{ matrix.go-version }} $HOME/go - name: Checkout code @@ -32,24 +32,8 @@ jobs: if: matrix.full-tests run: | curl -sL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | - sh -s -- -b $HOME/go/bin v1.61.0 - $HOME/go/bin/golangci-lint run --max-issues-per-linter 0 \ - --max-same-issues 0 \ - --exclude="unused-parameter: parameter '[^']+' seems to be unused, consider removing or renaming it as _" \ - -E asciicheck \ - -E bidichk \ - -E durationcheck \ - -E exportloopref \ - -E gocritic \ - -E godot \ - -E goimports \ - -E govet \ - -E misspell \ - -E prealloc \ - -E revive \ - -E unconvert \ - -E whitespace \ - ./... + sh -s -- -b $HOME/go/bin v2.0.2 + $HOME/go/bin/golangci-lint run - name: Testing continue-on-error: ${{ matrix.go-version == 'tip' }} diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..1de7a59 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,49 @@ +version: "2" +issues: + max-issues-per-linter: 0 + max-same-issues: 0 +linters: + default: none + enable: + - asasalint + - asciicheck + - bidichk + - dupl + - durationcheck + - errcheck + - exhaustive + - gocritic + - godot + - govet + - importas + - ineffassign + - misspell + - prealloc + - revive + - staticcheck + - testableexamples + - unconvert + - unused + - wastedassign + - whitespace + settings: + staticcheck: + checks: + - all + - -ST1012 + - -ST1000 + revive: + rules: + - name: unused-parameter + disabled: true +formatters: + enable: + - gci + - goimports + settings: + gci: + sections: + - standard + - default + - localmodule + custom-order: true diff --git a/file.go b/file.go index c88a236..0fafc34 100644 --- a/file.go +++ b/file.go @@ -2,7 +2,7 @@ package httpmock import ( "fmt" - "io/ioutil" //nolint: staticcheck + "os" ) // File is a file name. The contents of this file is loaded on demand @@ -32,7 +32,7 @@ func (f File) MarshalJSON() ([]byte, error) { } func (f File) bytes() ([]byte, error) { - return ioutil.ReadFile(string(f)) + return os.ReadFile(string(f)) } // Bytes returns the content of file as a []byte. If an error occurs diff --git a/file_test.go b/file_test.go index 66dcf3c..fae564d 100644 --- a/file_test.go +++ b/file_test.go @@ -15,8 +15,7 @@ var _ json.Marshaler = httpmock.File("test.json") func TestFile(t *testing.T) { assert := td.Assert(t) - dir, cleanup := tmpDir(assert) - defer cleanup() + dir := assert.TempDir() assert.Run("Valid JSON file", func(assert *td.T) { okFile := filepath.Join(dir, "ok.json") diff --git a/match.go b/match.go index eceb4b8..538e347 100644 --- a/match.go +++ b/match.go @@ -4,7 +4,6 @@ import ( "bytes" "fmt" "io" - "io/ioutil" //nolint: staticcheck "net/http" "runtime" "strings" @@ -227,7 +226,7 @@ func BodyContainsBytes(subslice []byte) Matcher { return NewMatcher("", func(req *http.Request) bool { rearmBody(req) - b, err := ioutil.ReadAll(req.Body) + b, err := io.ReadAll(req.Body) return err == nil && bytes.Contains(b, subslice) }) } @@ -247,7 +246,7 @@ func BodyContainsString(substr string) Matcher { return NewMatcher("", func(req *http.Request) bool { rearmBody(req) - b, err := ioutil.ReadAll(req.Body) + b, err := io.ReadAll(req.Body) return err == nil && bytes.Contains(b, []byte(substr)) }) } @@ -500,8 +499,8 @@ func (b *bodyCopyOnRead) rearm() { func (b *bodyCopyOnRead) copy() { if _, ok := b.body.(buffer); !ok && b.body != nil && b.body != http.NoBody { - buf, _ := ioutil.ReadAll(b.body) - b.body.Close() + buf, _ := io.ReadAll(b.body) + b.body.Close() //nolint: errcheck b.body = buffer{bytes.NewReader(buf)} } } diff --git a/match_test.go b/match_test.go index 737683b..e6981ce 100644 --- a/match_test.go +++ b/match_test.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" //nolint: staticcheck "net/http" "reflect" "strings" @@ -300,7 +299,7 @@ func TestMatchResponders_add_remove(t *testing.T) { func TestMatchResponders_findMatchResponder(t *testing.T) { newReq := func() *http.Request { - req, _ := http.NewRequest("GET", "/foo", ioutil.NopCloser(bytes.NewReader([]byte(`BODY`)))) + req, _ := http.NewRequest("GET", "/foo", io.NopCloser(bytes.NewReader([]byte(`BODY`)))) req.Header.Set("X-Foo", "bar") return req } @@ -353,7 +352,7 @@ func TestMatchResponders_findMatchResponder(t *testing.T) { mrBody1 := httpmock.NewMatchResponder( httpmock.NewMatcher("body-FOO", func(req *http.Request) bool { - b, err := ioutil.ReadAll(req.Body) + b, err := io.ReadAll(req.Body) return err == nil && bytes.Equal(b, []byte("FOO")) }), resp) @@ -364,7 +363,7 @@ func TestMatchResponders_findMatchResponder(t *testing.T) { mrBody2 := httpmock.NewMatchResponder( httpmock.NewMatcher("body-BODY", func(req *http.Request) bool { - b, err := ioutil.ReadAll(req.Body) + b, err := io.ReadAll(req.Body) return err == nil && bytes.Equal(b, []byte("BODY")) }), resp) @@ -374,7 +373,7 @@ func TestMatchResponders_findMatchResponder(t *testing.T) { assert.Cmp(mrs.FindMatchResponder(req), &mrBody2) // The request body should still be readable - b, err := ioutil.ReadAll(req.Body) + b, err := io.ReadAll(req.Body) assert.CmpNoError(err) assert.String(b, "BODY") } @@ -401,7 +400,7 @@ func TestMatchRouteKey(t *testing.T) { func TestBodyCopyOnRead(t *testing.T) { t.Run("non-nil body", func(t *testing.T) { - body := ioutil.NopCloser(bytes.NewReader([]byte(`BODY`))) + body := io.NopCloser(bytes.NewReader([]byte(`BODY`))) bc := httpmock.NewBodyCopyOnRead(body) diff --git a/response.go b/response.go index 4e2c666..94c29a0 100644 --- a/response.go +++ b/response.go @@ -576,7 +576,7 @@ func NewBytesResponder(status int, body []byte) Responder { // To pass the content of an existing file as body use [File] as in: // // httpmock.NewJsonResponse(200, httpmock.File("body.json")) -func NewJsonResponse(status int, body any) (*http.Response, error) { //nolint: revive +func NewJsonResponse(status int, body any) (*http.Response, error) { //nolint: revive,staticcheck encoded, err := json.Marshal(body) if err != nil { return nil, err @@ -604,7 +604,7 @@ func NewJsonResponse(status int, body any) (*http.Response, error) { //nolint: r // To pass the content of an existing file as body use [File] as in: // // httpmock.NewJsonResponseOrPanic(200, httpmock.File("body.json")) -func NewJsonResponseOrPanic(status int, body any) *http.Response { //nolint: revive +func NewJsonResponseOrPanic(status int, body any) *http.Response { //nolint: revive,staticcheck response, err := NewJsonResponse(status, body) if err != nil { panic(err) @@ -618,7 +618,7 @@ func NewJsonResponseOrPanic(status int, body any) *http.Response { //nolint: rev // To pass the content of an existing file as body use [File] as in: // // httpmock.NewJsonResponder(200, httpmock.File("body.json")) -func NewJsonResponder(status int, body any) (Responder, error) { //nolint: revive +func NewJsonResponder(status int, body any) (Responder, error) { //nolint: revive,staticcheck resp, err := NewJsonResponse(status, body) if err != nil { return nil, err @@ -642,7 +642,7 @@ func NewJsonResponder(status int, body any) (Responder, error) { //nolint: reviv // To pass the content of an existing file as body use [File] as in: // // httpmock.NewJsonResponderOrPanic(200, httpmock.File("body.json")) -func NewJsonResponderOrPanic(status int, body any) Responder { //nolint: revive +func NewJsonResponderOrPanic(status int, body any) Responder { //nolint: revive,staticcheck responder, err := NewJsonResponder(status, body) if err != nil { panic(err) @@ -657,7 +657,7 @@ func NewJsonResponderOrPanic(status int, body any) Responder { //nolint: revive // To pass the content of an existing file as body use [File] as in: // // httpmock.NewXmlResponse(200, httpmock.File("body.xml")) -func NewXmlResponse(status int, body any) (*http.Response, error) { //nolint: revive +func NewXmlResponse(status int, body any) (*http.Response, error) { //nolint: revive,staticcheck var ( encoded []byte err error @@ -681,7 +681,7 @@ func NewXmlResponse(status int, body any) (*http.Response, error) { //nolint: re // To pass the content of an existing file as body use [File] as in: // // httpmock.NewXmlResponder(200, httpmock.File("body.xml")) -func NewXmlResponder(status int, body any) (Responder, error) { //nolint: revive +func NewXmlResponder(status int, body any) (Responder, error) { //nolint: revive,staticcheck resp, err := NewXmlResponse(status, body) if err != nil { return nil, err @@ -705,7 +705,7 @@ func NewXmlResponder(status int, body any) (Responder, error) { //nolint: revive // To pass the content of an existing file as body use [File] as in: // // httpmock.NewXmlResponderOrPanic(200, httpmock.File("body.xml")) -func NewXmlResponderOrPanic(status int, body any) Responder { //nolint: revive +func NewXmlResponderOrPanic(status int, body any) Responder { //nolint: revive,staticcheck responder, err := NewXmlResponder(status, body) if err != nil { panic(err) @@ -759,7 +759,7 @@ func (d *dummyReadCloser) setup() { case io.ReadCloser: var buf bytes.Buffer io.Copy(&buf, body) //nolint: errcheck - body.Close() + body.Close() //nolint: errcheck d.body = bytes.NewReader(buf.Bytes()) } } diff --git a/response_test.go b/response_test.go index 9c828d5..140653d 100644 --- a/response_test.go +++ b/response_test.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" //nolint: staticcheck "net/http" "path/filepath" "strconv" @@ -137,7 +136,7 @@ func TestNewStringResponse(t *testing.T) { ) response := httpmock.NewStringResponse(status, body) - data, err := ioutil.ReadAll(response.Body) + data, err := io.ReadAll(response.Body) require.CmpNoError(err) assert.String(data, body) @@ -153,7 +152,7 @@ func TestNewBytesResponse(t *testing.T) { ) response := httpmock.NewBytesResponse(status, []byte(body)) - data, err := ioutil.ReadAll(response.Body) + data, err := io.ReadAll(response.Body) require.CmpNoError(err) assert.String(data, body) @@ -167,8 +166,7 @@ func TestNewJsonResponse(t *testing.T) { Hello string `json:"hello"` } - dir, cleanup := tmpDir(assert) - defer cleanup() + dir := assert.TempDir() fileName := filepath.Join(dir, "ok.json") writeFile(assert, fileName, []byte(`{ "test": true }`)) @@ -203,8 +201,7 @@ func TestNewJsonResponseOrPanic(t *testing.T) { Hello string `json:"hello"` } - dir, cleanup := tmpDir(assert) - defer cleanup() + dir := assert.TempDir() fileName := filepath.Join(dir, "ok.json") writeFile(assert, fileName, []byte(`{ "test": true }`)) @@ -261,8 +258,7 @@ func TestNewJsonResponder(t *testing.T) { }) assert.Run("OK file", func(assert *td.T) { - dir, cleanup := tmpDir(assert) - defer cleanup() + dir := assert.TempDir() fileName := filepath.Join(dir, "ok.json") writeFile(assert, fileName, []byte(`{ "foo" : 42 }`)) @@ -308,8 +304,7 @@ func TestNewXmlResponse(t *testing.T) { } expectedBody := string(b) - dir, cleanup := tmpDir(assert) - defer cleanup() + dir := assert.TempDir() fileName := filepath.Join(dir, "ok.xml") writeFile(assert, fileName, b) @@ -354,8 +349,7 @@ func TestNewXmlResponder(t *testing.T) { }) assert.Run("OK file", func(assert *td.T) { - dir, cleanup := tmpDir(assert) - defer cleanup() + dir := assert.TempDir() fileName := filepath.Join(dir, "ok.xml") writeFile(assert, fileName, b) @@ -568,7 +562,7 @@ func TestResponder_Then(t *testing.T) { if !assert.CmpNoError(err, "Responder call") { return } - b, err := ioutil.ReadAll(resp.Body) + b, err := io.ReadAll(resp.Body) if !assert.CmpNoError(err, "Read response") { return } @@ -673,7 +667,7 @@ func TestResponder_SetContentLength(t *testing.T) { name: "custom without Len", r: func(req *http.Request) (*http.Response, error) { return &http.Response{ - Body: ioutil.NopCloser(strings.NewReader("BODY")), + Body: io.NopCloser(strings.NewReader("BODY")), StatusCode: 200, ContentLength: -1, }, nil @@ -803,7 +797,7 @@ func TestParallelResponder(t *testing.T) { go func() { defer wg.Done() resp, _ := r(req) - b, err := ioutil.ReadAll(resp.Body) + b, err := io.ReadAll(resp.Body) td.CmpNoError(t, err, "resp #%d", ir) td.CmpLen(t, b, 4000, "resp #%d", ir) td.CmpHasPrefix(t, b, "ABC-", "resp #%d", ir) diff --git a/transport_test.go b/transport_test.go index ca668c6..6e8909b 100644 --- a/transport_test.go +++ b/transport_test.go @@ -6,7 +6,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" //nolint: staticcheck + "io" "net" "net/http" "net/url" @@ -43,7 +43,7 @@ func TestMockTransport(t *testing.T) { assert := td.Assert(t) - // Read it as a simple string (ioutil.ReadAll of assertBody will + // Read it as a simple string (io.ReadAll of assertBody will // trigger io.EOF) assert.RunAssertRequire("simple", func(assert, require *td.T) { resp, err := http.Get(url) @@ -91,7 +91,7 @@ func TestMockTransport(t *testing.T) { assert.RunAssertRequire(fmt.Sprintf("try #%d", i), func(assert, require *td.T) { resp, err := http.Get(url) require.CmpNoError(err) - defer resp.Body.Close() + defer resp.Body.Close() //nolint: errcheck var res []string err = json.NewDecoder(resp.Body).Decode(&res) @@ -116,7 +116,7 @@ func TestRegisterMatcherResponder(t *testing.T) { httpmock.NewMatcher( "01-body-BAR", func(r *http.Request) bool { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) return err == nil && bytes.Contains(b, []byte("BAR")) }), httpmock.NewStringResponder(200, "body-BAR")) @@ -125,7 +125,7 @@ func TestRegisterMatcherResponder(t *testing.T) { httpmock.NewMatcher( "02-body-FOO", func(r *http.Request) bool { - b, err := ioutil.ReadAll(r.Body) + b, err := io.ReadAll(r.Body) return err == nil && bytes.Contains(b, []byte("FOO")) }), httpmock.NewStringResponder(200, "body-FOO")) diff --git a/util_test.go b/util_test.go index 194b2f4..37e39fc 100644 --- a/util_test.go +++ b/util_test.go @@ -1,7 +1,7 @@ package httpmock_test import ( - "io/ioutil" //nolint: staticcheck + "io" "net/http" "os" "testing" @@ -15,22 +15,15 @@ func assertBody(t testing.TB, resp *http.Response, expected string) bool { require := td.Require(t) require.NotNil(resp) - defer resp.Body.Close() + defer resp.Body.Close() //nolint: errcheck - data, err := ioutil.ReadAll(resp.Body) + data, err := io.ReadAll(resp.Body) require.CmpNoError(err) return td.CmpString(t, data, expected) } -func tmpDir(t testing.TB) (string, func()) { - t.Helper() - dir, err := ioutil.TempDir("", "httpmock") - td.Require(t).CmpNoError(err) - return dir, func() { os.RemoveAll(dir) } -} - func writeFile(t testing.TB, file string, content []byte) { t.Helper() - td.Require(t).CmpNoError(ioutil.WriteFile(file, content, 0644)) + td.Require(t).CmpNoError(os.WriteFile(file, content, 0644)) }