mirror-to-gitea/vendor/github.com/onsi/ginkgo/internal/spec/specs.go
vendor/github.com/onsi/ginkgo/internal/spec/specs.goRaw
1package spec
2
3import (
4 "math/rand"
5 "regexp"
6 "sort"
7 "strings"
8)
9
10type Specs struct {
11 specs []*Spec
12 names []string
13
14 hasProgrammaticFocus bool
15 RegexScansFilePath bool
16}
17
18func NewSpecs(specs []*Spec) *Specs {
19 names := make([]string, len(specs))
20 for i, spec := range specs {
21 names[i] = spec.ConcatenatedString()
22 }
23 return &Specs{
24 specs: specs,
25 names: names,
26 }
27}
28
29func (e *Specs) Specs() []*Spec {
30 return e.specs
31}
32
33func (e *Specs) HasProgrammaticFocus() bool {
34 return e.hasProgrammaticFocus
35}
36
37func (e *Specs) Shuffle(r *rand.Rand) {
38 sort.Sort(e)
39 permutation := r.Perm(len(e.specs))
40 shuffledSpecs := make([]*Spec, len(e.specs))
41 names := make([]string, len(e.specs))
42 for i, j := range permutation {
43 shuffledSpecs[i] = e.specs[j]
44 names[i] = e.names[j]
45 }
46 e.specs = shuffledSpecs
47 e.names = names
48}
49
50func (e *Specs) ApplyFocus(description string, focus, skip []string) {
51 if len(focus)+len(skip) == 0 {
52 e.applyProgrammaticFocus()
53 } else {
54 e.applyRegExpFocusAndSkip(description, focus, skip)
55 }
56}
57
58func (e *Specs) applyProgrammaticFocus() {
59 e.hasProgrammaticFocus = false
60 for _, spec := range e.specs {
61 if spec.Focused() && !spec.Pending() {
62 e.hasProgrammaticFocus = true
63 break
64 }
65 }
66
67 if e.hasProgrammaticFocus {
68 for _, spec := range e.specs {
69 if !spec.Focused() {
70 spec.Skip()
71 }
72 }
73 }
74}
75
76// toMatch returns a byte[] to be used by regex matchers. When adding new behaviours to the matching function,
77// this is the place which we append to.
78func (e *Specs) toMatch(description string, i int) []byte {
79 if i > len(e.names) {
80 return nil
81 }
82 if e.RegexScansFilePath {
83 return []byte(
84 description + " " +
85 e.names[i] + " " +
86 e.specs[i].subject.CodeLocation().FileName)
87 } else {
88 return []byte(
89 description + " " +
90 e.names[i])
91 }
92}
93
94func (e *Specs) applyRegExpFocusAndSkip(description string, focus, skip []string) {
95 var focusFilter, skipFilter *regexp.Regexp
96 if len(focus) > 0 {
97 focusFilter = regexp.MustCompile(strings.Join(focus, "|"))
98 }
99 if len(skip) > 0 {
100 skipFilter = regexp.MustCompile(strings.Join(skip, "|"))
101 }
102
103 for i, spec := range e.specs {
104 matchesFocus := true
105 matchesSkip := false
106
107 toMatch := e.toMatch(description, i)
108
109 if focusFilter != nil {
110 matchesFocus = focusFilter.Match(toMatch)
111 }
112
113 if skipFilter != nil {
114 matchesSkip = skipFilter.Match(toMatch)
115 }
116
117 if !matchesFocus || matchesSkip {
118 spec.Skip()
119 }
120 }
121}
122
123func (e *Specs) SkipMeasurements() {
124 for _, spec := range e.specs {
125 if spec.IsMeasurement() {
126 spec.Skip()
127 }
128 }
129}
130
131//sort.Interface
132
133func (e *Specs) Len() int {
134 return len(e.specs)
135}
136
137func (e *Specs) Less(i, j int) bool {
138 return e.names[i] < e.names[j]
139}
140
141func (e *Specs) Swap(i, j int) {
142 e.names[i], e.names[j] = e.names[j], e.names[i]
143 e.specs[i], e.specs[j] = e.specs[j], e.specs[i]
144}