mirror-to-gitea/vendor/github.com/onsi/ginkgo/formatter/formatter.go
vendor/github.com/onsi/ginkgo/formatter/formatter.goRaw
1package formatter
2
3import (
4 "fmt"
5 "regexp"
6 "strings"
7)
8
9const COLS = 80
10
11type ColorMode uint8
12
13const (
14 ColorModeNone ColorMode = iota
15 ColorModeTerminal
16 ColorModePassthrough
17)
18
19var SingletonFormatter = New(ColorModeTerminal)
20
21func F(format string, args ...interface{}) string {
22 return SingletonFormatter.F(format, args...)
23}
24
25func Fi(indentation uint, format string, args ...interface{}) string {
26 return SingletonFormatter.Fi(indentation, format, args...)
27}
28
29func Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string {
30 return SingletonFormatter.Fiw(indentation, maxWidth, format, args...)
31}
32
33type Formatter struct {
34 ColorMode ColorMode
35 colors map[string]string
36 styleRe *regexp.Regexp
37 preserveColorStylingTags bool
38}
39
40func NewWithNoColorBool(noColor bool) Formatter {
41 if noColor {
42 return New(ColorModeNone)
43 }
44 return New(ColorModeTerminal)
45}
46
47func New(colorMode ColorMode) Formatter {
48 f := Formatter{
49 ColorMode: colorMode,
50 colors: map[string]string{
51 "/": "\x1b[0m",
52 "bold": "\x1b[1m",
53 "underline": "\x1b[4m",
54
55 "red": "\x1b[38;5;9m",
56 "orange": "\x1b[38;5;214m",
57 "coral": "\x1b[38;5;204m",
58 "magenta": "\x1b[38;5;13m",
59 "green": "\x1b[38;5;10m",
60 "dark-green": "\x1b[38;5;28m",
61 "yellow": "\x1b[38;5;11m",
62 "light-yellow": "\x1b[38;5;228m",
63 "cyan": "\x1b[38;5;14m",
64 "gray": "\x1b[38;5;243m",
65 "light-gray": "\x1b[38;5;246m",
66 "blue": "\x1b[38;5;12m",
67 },
68 }
69 colors := []string{}
70 for color := range f.colors {
71 colors = append(colors, color)
72 }
73 f.styleRe = regexp.MustCompile("{{(" + strings.Join(colors, "|") + ")}}")
74 return f
75}
76
77func (f Formatter) F(format string, args ...interface{}) string {
78 return f.Fi(0, format, args...)
79}
80
81func (f Formatter) Fi(indentation uint, format string, args ...interface{}) string {
82 return f.Fiw(indentation, 0, format, args...)
83}
84
85func (f Formatter) Fiw(indentation uint, maxWidth uint, format string, args ...interface{}) string {
86 out := fmt.Sprintf(f.style(format), args...)
87
88 if indentation == 0 && maxWidth == 0 {
89 return out
90 }
91
92 lines := strings.Split(out, "\n")
93
94 if maxWidth != 0 {
95 outLines := []string{}
96
97 maxWidth = maxWidth - indentation*2
98 for _, line := range lines {
99 if f.length(line) <= maxWidth {
100 outLines = append(outLines, line)
101 continue
102 }
103 outWords := []string{}
104 length := uint(0)
105 words := strings.Split(line, " ")
106 for _, word := range words {
107 wordLength := f.length(word)
108 if length+wordLength <= maxWidth {
109 length += wordLength
110 outWords = append(outWords, word)
111 continue
112 }
113 outLines = append(outLines, strings.Join(outWords, " "))
114 outWords = []string{word}
115 length = wordLength
116 }
117 if len(outWords) > 0 {
118 outLines = append(outLines, strings.Join(outWords, " "))
119 }
120 }
121
122 lines = outLines
123 }
124
125 if indentation == 0 {
126 return strings.Join(lines, "\n")
127 }
128
129 padding := strings.Repeat(" ", int(indentation))
130 for i := range lines {
131 if lines[i] != "" {
132 lines[i] = padding + lines[i]
133 }
134 }
135
136 return strings.Join(lines, "\n")
137}
138
139func (f Formatter) length(styled string) uint {
140 n := uint(0)
141 inStyle := false
142 for _, b := range styled {
143 if inStyle {
144 if b == 'm' {
145 inStyle = false
146 }
147 continue
148 }
149 if b == '\x1b' {
150 inStyle = true
151 continue
152 }
153 n += 1
154 }
155 return n
156}
157
158func (f Formatter) CycleJoin(elements []string, joiner string, cycle []string) string {
159 if len(elements) == 0 {
160 return ""
161 }
162 n := len(cycle)
163 out := ""
164 for i, text := range elements {
165 out += cycle[i%n] + text
166 if i < len(elements)-1 {
167 out += joiner
168 }
169 }
170 out += "{{/}}"
171 return f.style(out)
172}
173
174func (f Formatter) style(s string) string {
175 switch f.ColorMode {
176 case ColorModeNone:
177 return f.styleRe.ReplaceAllString(s, "")
178 case ColorModePassthrough:
179 return s
180 case ColorModeTerminal:
181 return f.styleRe.ReplaceAllStringFunc(s, func(match string) string {
182 if out, ok := f.colors[strings.Trim(match, "{}")]; ok {
183 return out
184 }
185 return match
186 })
187 }
188
189 return ""
190}