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

mlange-42 / modo / 12877300192

20 Jan 2025 11:41PM CUT coverage: 60.111%. Remained the same
12877300192

push

github

web-flow
Extend the user guide (#84)

972 of 1617 relevant lines covered (60.11%)

28.0 hits per line

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

70.8
/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 {
6✔
22
        if dir == "" {
12✔
23
                return nil
6✔
24
        }
6✔
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
        return nil
×
45
}
46

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

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

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

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

85
                if fenced && !isFence && blockName != "" {
234✔
86
                        if global {
33✔
87
                                globalLines = append(globalLines, origLine)
10✔
88
                        } else {
23✔
89
                                blockLines = append(blockLines, origLine)
13✔
90
                        }
13✔
91
                }
92

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

127
        for _, block := range blocks {
300✔
128
                proc.docTests = append(proc.docTests, block)
5✔
129
        }
5✔
130

131
        return outText.String(), nil
295✔
132
}
133

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

14✔
147
        for _, pair := range attrPairs {
40✔
148
                elems := strings.Split(pair, "=")
26✔
149
                if len(elems) != 2 {
26✔
150
                        err = fmt.Errorf("malformed code block attributes '%s'", pair)
×
151
                        return
×
152
                }
×
153

154
                key := strings.TrimSpace(elems[0])
26✔
155
                if key == docTestAttr {
40✔
156
                        name = strings.Trim(elems[1], "\"")
14✔
157
                        continue
14✔
158
                }
159
                if key == hideAttr {
21✔
160
                        h := strings.Trim(elems[1], "\"")
9✔
161
                        if h == "true" {
18✔
162
                                hide = true
9✔
163
                        }
9✔
164
                        continue
9✔
165
                }
166
                if key == globalAttr {
6✔
167
                        g := strings.Trim(elems[1], "\"")
3✔
168
                        if g == "true" {
6✔
169
                                global = true
3✔
170
                        }
3✔
171
                        continue
3✔
172
                }
173
        }
174
        ok = true
14✔
175
        return
14✔
176
}
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