File: mocks.go

package info (click to toggle)
golang-github-azure-go-autorest 7.2.0%2BREALLY.7.0.4-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 536 kB
  • ctags: 925
  • sloc: makefile: 4
file content (157 lines) | stat: -rw-r--r-- 3,607 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
Package mocks provides mocks and helpers used in testing.
*/
package mocks

import (
	"fmt"
	"io"
	"net/http"
)

// Body implements acceptable body over a string.
type Body struct {
	s             string
	b             []byte
	isOpen        bool
	closeAttempts int
}

// NewBody creates a new instance of Body.
func NewBody(s string) *Body {
	return (&Body{s: s}).reset()
}

// Read reads into the passed byte slice and returns the bytes read.
func (body *Body) Read(b []byte) (n int, err error) {
	if !body.IsOpen() {
		return 0, fmt.Errorf("ERROR: Body has been closed\n")
	}
	if len(body.b) == 0 {
		return 0, io.EOF
	}
	n = copy(b, body.b)
	body.b = body.b[n:]
	return n, nil
}

// Close closes the body.
func (body *Body) Close() error {
	if body.isOpen {
		body.isOpen = false
		body.closeAttempts++
	}
	return nil
}

// CloseAttempts returns the number of times Close was called.
func (body *Body) CloseAttempts() int {
	return body.closeAttempts
}

// IsOpen returns true if the Body has not been closed, false otherwise.
func (body *Body) IsOpen() bool {
	return body.isOpen
}

func (body *Body) reset() *Body {
	body.isOpen = true
	body.b = []byte(body.s)
	return body
}

// Sender implements a simple null sender.
type Sender struct {
	attempts       int
	responses      []*http.Response
	repeatResponse []int
	err            error
	repeatError    int
	emitErrorAfter int
}

// NewSender creates a new instance of Sender.
func NewSender() *Sender {
	return &Sender{}
}

// Do accepts the passed request and, based on settings, emits a response and possible error.
func (c *Sender) Do(r *http.Request) (resp *http.Response, err error) {
	c.attempts++

	if len(c.responses) > 0 {
		resp = c.responses[0]
		if resp != nil {
			if b, ok := resp.Body.(*Body); ok {
				b.reset()
			}
		}
		c.repeatResponse[0]--
		if c.repeatResponse[0] == 0 {
			c.responses = c.responses[1:]
			c.repeatResponse = c.repeatResponse[1:]
		}
	} else {
		resp = NewResponse()
	}
	if resp != nil {
		resp.Request = r
	}

	if c.emitErrorAfter > 0 {
		c.emitErrorAfter--
	} else if c.err != nil {
		err = c.err
		c.repeatError--
		if c.repeatError == 0 {
			c.err = nil
		}
	}

	return
}

// AppendResponse adds the passed http.Response to the response stack.
func (c *Sender) AppendResponse(resp *http.Response) {
	c.AppendAndRepeatResponse(resp, 1)
}

// AppendAndRepeatResponse adds the passed http.Response to the response stack along with a
// repeat count. A negative repeat count will return the reponse for all remaining calls to Do.
func (c *Sender) AppendAndRepeatResponse(resp *http.Response, repeat int) {
	if c.responses == nil {
		c.responses = []*http.Response{resp}
		c.repeatResponse = []int{repeat}
	} else {
		c.responses = append(c.responses, resp)
		c.repeatResponse = append(c.repeatResponse, repeat)
	}
}

// Attempts returns the number of times Do was called.
func (c *Sender) Attempts() int {
	return c.attempts
}

// SetError sets the error Do should return.
func (c *Sender) SetError(err error) {
	c.SetAndRepeatError(err, 1)
}

// SetAndRepeatError sets the error Do should return and how many calls to Do will return the error.
// A negative repeat value will return the error for all remaining calls to Do.
func (c *Sender) SetAndRepeatError(err error, repeat int) {
	c.err = err
	c.repeatError = repeat
}

// SetEmitErrorAfter sets the number of attempts to be made before errors are emitted.
func (c *Sender) SetEmitErrorAfter(ea int) {
	c.emitErrorAfter = ea
}

// T is a simple testing struct.
type T struct {
	Name string `json:"name" xml:"Name"`
	Age  int    `json:"age" xml:"Age"`
}