Skip to content

Commit 03f52d4

Browse files
committed
chore: add unit test
1 parent 47a4f7b commit 03f52d4

File tree

8 files changed

+422
-33
lines changed

8 files changed

+422
-33
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.vscode/
2+
.idea/
3+
config.yaml
4+
.env
5+
.envrc
6+
cover.out
7+
vendor/**
8+
.DS_Store

Makefile

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
GOMIGRATE_VERSION = 4.14.1
2+
GOLANGCI_VERSION = 1.31.0
3+
PLATFORM := $(shell uname | tr '[:upper:]' '[:lower:]')
4+
PATH := bin:$(PATH)
5+
SHELL := env PATH=$(PATH) /bin/bash
6+
7+
## help: print this help message
8+
.PHONY: help
9+
help:
10+
@echo 'Usage:'
11+
@sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' | sed -e 's/^/ /'
12+
13+
.PHONY: confirm
14+
confirm:
15+
@echo -n 'Are you sure? [y/N] ' && read ans && [ $${ans:-N} = y ]
16+
17+
bin/golangci-lint: bin/golangci-lint-${GOLANGCI_VERSION}
18+
@ln -sf golangci-lint-${GOLANGCI_VERSION} bin/golangci-lint
19+
20+
bin/golangci-lint-${GOLANGCI_VERSION}:
21+
@mkdir -p $(OUTDIR)
22+
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b ./bin/ v${GOLANGCI_VERSION}
23+
@mv bin/golangci-lint "$@"
24+
25+
## audit: tidy and vendor dependencies and format, vet, lint and test all code
26+
.PHONY: audit
27+
audit: fmt tidy lint vet test
28+
@echo 'Auditing code done'
29+
30+
## vet: vetting code
31+
.PHONY: vet
32+
vet:
33+
@echo 'Vetting code...'
34+
@go vet $(shell go list ./... | grep -v /vendor/|xargs echo)
35+
36+
## test: test all code
37+
.PHONY: test
38+
test:
39+
@echo 'Running tests...'
40+
@CGO_ENABLED=0 go test $(shell go list ./... | grep -v /vendor/|xargs echo) -cover -coverprofile=cover.out
41+
go tool cover -func=cover.out
42+
43+
## fmt: formatting code
44+
fmt:
45+
@echo 'Formatting code...'
46+
@go fmt $(shell go list ./... | grep -v /vendor/|xargs echo)
47+
48+
## vendor: tidy dependencies
49+
.PHONY: tidy
50+
tidy:
51+
@echo 'Tidying and verifying module dependencies...'
52+
@go mod tidy
53+
@go mod verify
54+
55+
## lint: linting code
56+
.PHONY: lint
57+
lint: bin/golangci-lint ## Run linter
58+
@echo 'Linting code...'
59+
golangci-lint run

httpc/errors.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ import "fmt"
55
var (
66
// ErrRetryExceeded
77
ErrRetryExceeded = fmt.Errorf("http retry exceeded the limit")
8+
9+
// ErrProtocolRequired
10+
ErrProtocolRequired = fmt.Errorf("invalid http host, protocol/scheme is required")
811
)

httpc/options.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ func WithUnmarshaler(fn UnmarshalFunc) Option {
7777
}
7878
}
7979

80-
// WithStatusCodeHandler set custom handler for a given HTTP status code
81-
func WithStatusCodeHandler(code int, fn StatusCodeHandleFunc) Option {
80+
// WithCustomHandler set custom handler for a given HTTP status code
81+
func WithCustomHandler(code int, fn StatusCodeHandleFunc) Option {
8282
return func(req *Request) error {
8383
if fn == nil {
8484
return fmt.Errorf("status code handle func MUST not be nil")

httpc/request.go

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ func NewRequest(client Doer, baseURL string, opts ...Option) (*Request, error) {
4444
return nil, err
4545
}
4646

47+
if u.Scheme == "" {
48+
return nil, ErrProtocolRequired
49+
}
50+
4751
r := &Request{
4852
httpc: client,
4953
url: u,
@@ -80,53 +84,57 @@ func (r *Request) Invoke() error {
8084
}
8185
req.Header = r.header
8286

83-
var retryCount int
87+
var (
88+
retryCount int
89+
response *http.Response
90+
)
8491

8592
doRequest:
86-
for {
87-
if retryCount > r.retryLimit {
88-
return ErrRetryExceeded
93+
for ; retryCount <= r.retryLimit; retryCount++ {
94+
if response != nil {
95+
response.Body.Close()
8996
}
9097

91-
resp, err := r.httpc.Do(req)
98+
var err error
99+
response, err = r.httpc.Do(req)
92100
if err != nil {
93101
return err
94102
}
95103

96104
if len(r.retryOn) > 0 {
97105
for _, retryOn := range r.retryOn {
98-
if valid := retryOn(resp.StatusCode); valid {
99-
resp.Body.Close()
100-
101-
retryCount++
106+
if valid := retryOn(response.StatusCode); valid {
102107
continue doRequest
103108
}
104109
}
105110
}
106111

107-
if handler, ok := r.statusCodeHandlers[resp.StatusCode]; ok {
108-
defer resp.Body.Close()
109-
if err := handler(resp); err != nil {
112+
if handler, ok := r.statusCodeHandlers[response.StatusCode]; ok {
113+
if err := handler(response); err != nil {
110114
return err
111115
}
112116

113117
return nil
114118
}
115119

116-
defer resp.Body.Close()
117-
data, err := ioutil.ReadAll(resp.Body)
120+
defer response.Body.Close()
121+
data, err := ioutil.ReadAll(response.Body)
118122
if err != nil {
119123
return err
120124
}
121125

122-
contentType := resp.Header.Get(HeaderContentType)
126+
contentType := response.Header.Get(HeaderContentType)
123127
if err := r.unmarshal(contentType, data, r.receiver); err != nil {
124128
return err
125129
}
126130

127131
break
128132
}
129133

134+
if retryCount > r.retryLimit {
135+
return ErrRetryExceeded
136+
}
137+
130138
return nil
131139
}
132140

@@ -135,7 +143,7 @@ func (r *Request) unmarshal(contentType string, data []byte, out interface{}) er
135143
// we assume it might be also customized how to interact
136144
// with the response receiver
137145
if r.unmarshalFunc != nil {
138-
return r.unmarshalFunc(data, out)
146+
return r.unmarshalFunc(contentType, data, out)
139147
}
140148

141149
// if out is nil, will skip the unmarshal step

0 commit comments

Comments
 (0)