-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathoptions.go
208 lines (182 loc) · 4.68 KB
/
options.go
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package spec
import (
"io"
"testing"
)
// An Option controls the behavior of a suite, group, or spec.
// Options are inherited by subgroups and subspecs.
//
// Example:
// If the top-level Run group is specified as Random(), each subgroup will
// inherit the Random() order. This means that each group will be randomized
// individually, unless another ordering is specified on any of the subgroups.
// If the Run group is also passed Global(), then all specs inside Run will run
// in completely random order, regardless of any ordering specified on the
// subgroups.
type Option func(*config)
// Report specifies a Reporter for a suite.
//
// Valid Option for:
// New, Run, Focus, Pend
func Report(r Reporter) Option {
return func(c *config) {
c.report = r
}
}
// Seed specifies the random seed used for any randomized specs in a Run block.
// The random seed is always displayed before specs are run.
// If not specified, the current time is used.
//
// Valid Option for:
// New, Run, Focus, Pend
func Seed(s int64) Option {
return func(c *config) {
c.seed = s
}
}
// Sequential indicates that a group of specs should be run in order.
// This is the default behavior.
//
// Valid Option for:
// New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend
func Sequential() Option {
return func(c *config) {
c.order = orderSequential
}
}
// Random indicates that a group of specs should be run in random order.
// Randomization is per group, such that all groupings are maintained.
//
// Valid Option for:
// New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend
func Random() Option {
return func(c *config) {
c.order = orderRandom
}
}
// Reverse indicates that a group of specs should be run in reverse order.
//
// Valid Option for:
// New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend
func Reverse() Option {
return func(c *config) {
c.order = orderReverse
}
}
// Parallel indicates that a spec or group of specs should be run in parallel.
// This Option is equivalent to t.Parallel().
//
// Valid Option for:
// New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend, S
func Parallel() Option {
return func(c *config) {
c.order = orderParallel
}
}
// Local indicates that the test order applies to each subgroup individually.
// For example, a group with Random() and Local() will run all subgroups and
// specs in random order, and each subgroup will be randomized, but specs in
// different subgroups will not be interleaved.
// This is the default behavior.
//
// Valid Option for:
// New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend
func Local() Option {
return func(c *config) {
c.scope = scopeLocal
}
}
// Global indicates that test order applies globally to all descendant specs.
// For example, a group with Random() and Global() will run all descendant
// specs in random order, regardless of subgroup. Specs in different subgroups
// may be interleaved.
//
// Valid Option for:
// New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend
func Global() Option {
return func(c *config) {
c.scope = scopeGlobal
}
}
// Flat indicates that a parent subtest should not be created for the group.
// This is the default behavior.
//
// Valid Option for:
// New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend
func Flat() Option {
return func(c *config) {
c.nest = nestOff
}
}
// Nested indicates that a parent subtest should be created for the group.
// This allows for more control over parallelism.
//
// Valid Option for:
// New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend
func Nested() Option {
return func(c *config) {
c.nest = nestOn
}
}
type order int
const (
orderInherit order = iota
orderSequential
orderParallel
orderRandom
orderReverse
)
func (o order) or(last order) order {
return order(defaultZero(int(o), int(last)))
}
type scope int
const (
scopeInherit scope = iota
scopeLocal
scopeGlobal
)
func (s scope) or(last scope) scope {
return scope(defaultZero(int(s), int(last)))
}
type nest int
const (
nestInherit nest = iota
nestOff
nestOn
)
func (n nest) or(last nest) nest {
return nest(defaultZero(int(n), int(last)))
}
func defaultZero(next, last int) int {
if next == 0 {
return last
}
return next
}
func defaultZero64(next, last int64) int64 {
if next == 0 {
return last
}
return next
}
type config struct {
seed int64
order order
scope scope
nest nest
pend bool
focus bool
before bool
after bool
t *testing.T
out func(io.Writer)
report Reporter
}
type options []Option
func (o options) apply() *config {
cfg := &config{}
for _, opt := range o {
opt(cfg)
}
return cfg
}