• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mlange-42 / modo / 12916744138

22 Jan 2025 08:44PM CUT coverage: 61.572%. Remained the same
12916744138

push

github

web-flow
Package for commands, extend CLI help (#100)

* move commands to package
* improve file structure
* remove commented out code
* add guide link to CLI help
* tweak user guide

987 of 1603 relevant lines covered (61.57%)

29.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.95
/document/doctest.go
1
package document
2

3
import (
4
        "bufio"
5
        "fmt"
6
        "path"
7
        "strings"
8
)
9

10
const docTestAttr = "doctest"
11
const hideAttr = "hide"
12
const globalAttr = "global"
13

14
func (proc *Processor) extractDocTests() error {
6✔
15
        proc.docTests = []*docTest{}
6✔
16
        return proc.walkDocs(proc.Docs, proc.extractTests, func(elem Named) string {
51✔
17
                return elem.GetFileName()
45✔
18
        })
45✔
19
}
20

21
func (proc *Processor) writeDocTests(dir string) error {
×
22
        if dir == "" {
×
23
                return nil
×
24
        }
×
25
        err := proc.mkDirs(dir)
×
26
        if err != nil {
×
27
                return err
×
28
        }
×
29
        for _, test := range proc.docTests {
×
30
                b := strings.Builder{}
×
31
                err := proc.Template.ExecuteTemplate(&b, "doctest.mojo", test)
×
32
                if err != nil {
×
33
                        return err
×
34
                }
×
35
                filePath := strings.Join(test.Path, "_")
×
36
                filePath += "_" + test.Name + "_test.mojo"
×
37
                fullPath := path.Join(dir, filePath)
×
38

×
39
                err = proc.WriteFile(fullPath, b.String())
×
40
                if err != nil {
×
41
                        return err
×
42
                }
×
43
        }
44
        fmt.Printf("Extracted %d tests.\n", len(proc.docTests))
×
45
        return nil
×
46
}
47

48
func (proc *Processor) extractTests(text string, elems []string, modElems int) (string, error) {
295✔
49
        _ = modElems
295✔
50
        scanner := bufio.NewScanner(strings.NewReader(text))
295✔
51
        outText := strings.Builder{}
295✔
52

295✔
53
        fenced := false
295✔
54
        blocks := map[string]*docTest{}
295✔
55
        var blockLines []string
295✔
56
        var globalLines []string
295✔
57
        var blockName string
295✔
58
        var excluded bool
295✔
59
        var global bool
295✔
60
        var count int
295✔
61
        for scanner.Scan() {
506✔
62
                origLine := scanner.Text()
211✔
63

211✔
64
                isStart := false
211✔
65
                isFence := strings.HasPrefix(origLine, codeFence3)
211✔
66
                if isFence && !fenced {
225✔
67
                        var ok bool
14✔
68
                        var err error
14✔
69
                        blockName, excluded, global, ok, err = parseBlockAttr(origLine)
14✔
70
                        if err != nil {
14✔
71
                                if err := proc.warnOrError("%s in %s", err.Error(), strings.Join(elems, ".")); err != nil {
×
72
                                        return "", err
×
73
                                }
×
74
                        }
75
                        if !ok {
14✔
76
                                blockName = ""
×
77
                        }
×
78
                        fenced = true
14✔
79
                        isStart = true
14✔
80
                }
81

82
                if !excluded {
386✔
83
                        outText.WriteString(origLine)
175✔
84
                        outText.WriteRune('\n')
175✔
85
                }
175✔
86

87
                if fenced && !isFence && blockName != "" {
234✔
88
                        if global {
33✔
89
                                globalLines = append(globalLines, origLine)
10✔
90
                        } else {
23✔
91
                                blockLines = append(blockLines, origLine)
13✔
92
                        }
13✔
93
                }
94
                count++
211✔
95

211✔
96
                if isFence && fenced && !isStart {
225✔
97
                        if blockName == "" {
14✔
98
                                excluded = false
×
99
                                global = false
×
100
                                fenced = false
×
101
                                continue
×
102
                        }
103
                        if dt, ok := blocks[blockName]; ok {
23✔
104
                                dt.Code = append(dt.Code, blockLines...)
9✔
105
                                dt.Global = append(dt.Global, globalLines...)
9✔
106
                        } else {
14✔
107
                                blocks[blockName] = &docTest{
5✔
108
                                        Name:   blockName,
5✔
109
                                        Path:   elems,
5✔
110
                                        Code:   append([]string{}, blockLines...),
5✔
111
                                        Global: append([]string{}, globalLines...),
5✔
112
                                }
5✔
113
                        }
5✔
114
                        blockLines = blockLines[:0]
14✔
115
                        globalLines = globalLines[:0]
14✔
116
                        excluded = false
14✔
117
                        global = false
14✔
118
                        fenced = false
14✔
119
                }
120
        }
121
        if err := scanner.Err(); err != nil {
295✔
122
                panic(err)
×
123
        }
124
        if fenced {
295✔
125
                if err := proc.warnOrError("unbalanced code block in %s", strings.Join(elems, ".")); err != nil {
×
126
                        return "", err
×
127
                }
×
128
        }
129

130
        for _, block := range blocks {
300✔
131
                proc.docTests = append(proc.docTests, block)
5✔
132
        }
5✔
133

134
        return strings.TrimSuffix(outText.String(), "\n"), nil
295✔
135
}
136

137
func parseBlockAttr(line string) (name string, hide bool, global bool, ok bool, err error) {
21✔
138
        parts := strings.SplitN(line, "{", 2)
21✔
139
        if len(parts) < 2 {
22✔
140
                return
1✔
141
        }
1✔
142
        attrString := strings.TrimSpace(parts[1])
20✔
143
        if !strings.HasSuffix(attrString, "}") {
20✔
144
                err = fmt.Errorf("missing closing parentheses in code block attributes")
×
145
                return
×
146
        }
×
147
        attrString = strings.TrimSuffix(attrString, "}")
20✔
148

20✔
149
        quoted := false
20✔
150
        attrPairs := strings.FieldsFunc(attrString, func(r rune) bool {
493✔
151
                if r == '"' {
513✔
152
                        quoted = !quoted
40✔
153
                }
40✔
154
                return !quoted && r == ' '
473✔
155
        })
156

157
        for _, pair := range attrPairs {
59✔
158
                elems := strings.Split(pair, "=")
39✔
159
                if len(elems) > 2 {
39✔
160
                        err = fmt.Errorf("malformed code block attributes '%s'", pair)
×
161
                        return
×
162
                }
×
163
                if len(elems) < 2 {
41✔
164
                        continue
2✔
165
                }
166

167
                key := strings.TrimSpace(elems[0])
37✔
168
                if key == docTestAttr {
56✔
169
                        name = strings.Trim(elems[1], "\"")
19✔
170
                        continue
19✔
171
                }
172
                if key == hideAttr {
30✔
173
                        h := strings.Trim(elems[1], "\" ")
12✔
174
                        if h == "true" {
24✔
175
                                hide = true
12✔
176
                        }
12✔
177
                        continue
12✔
178
                }
179
                if key == globalAttr {
11✔
180
                        g := strings.Trim(elems[1], "\"")
5✔
181
                        if g == "true" {
10✔
182
                                global = true
5✔
183
                        }
5✔
184
                        continue
5✔
185
                }
186
        }
187
        ok = true
20✔
188
        return
20✔
189
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc