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

pace / bricks / 13717956986

06 Mar 2025 02:30PM UTC coverage: 51.823% (-4.8%) from 56.612%
13717956986

push

github

web-flow
Merge pull request #406 from pace/gomod-update

This updates all dependencies to the latest version, excluding

github.com/bsm/redislock
github.com/dave/jennifer

as newer versions lead to unwanted behavior.

54 of 82 new or added lines in 9 files covered. (65.85%)

453 existing lines in 15 files now uncovered.

4889 of 9434 relevant lines covered (51.82%)

20.93 hits per line

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

84.76
/http/jsonapi/generator/generate_helper.go
1
// Copyright © 2018 by PACE Telematics GmbH. All rights reserved.
2

3
package generator
4

5
import (
6
        "fmt"
7
        "path/filepath"
8
        "regexp"
9
        "strings"
10

11
        "github.com/dave/jennifer/jen"
12
        "github.com/getkin/kin-openapi/openapi3"
13
        "golang.org/x/text/cases"
14
        "golang.org/x/text/language"
15
)
16

17
func (g *Generator) addGoDoc(typeName, description string) {
404✔
18
        if description != "" {
693✔
19
                g.goSource.Comment(fmt.Sprintf("%s %s", typeName, description))
289✔
20
        } else {
404✔
21
                g.goSource.Comment(fmt.Sprintf("%s ...", typeName))
115✔
22
        }
115✔
23
}
24

25
func (g *Generator) goType(stmt *jen.Statement, schema *openapi3.Schema, tags map[string]string) *typeGenerator { // nolint: gocyclo
345✔
26
        return &typeGenerator{
345✔
27
                g:      g,
345✔
28
                stmt:   stmt,
345✔
29
                schema: schema,
345✔
30
                tags:   tags,
345✔
31
        }
345✔
32
}
345✔
33

34
type typeGenerator struct {
35
        g       *Generator
36
        stmt    *jen.Statement
37
        schema  *openapi3.Schema
38
        tags    map[string]string
39
        isParam bool
40
}
41

42
func (g *typeGenerator) invoke() error { // nolint: gocyclo
345✔
43
        if g.schema.Type.Is("string") {
620✔
44
                switch g.schema.Format {
275✔
45
                case "byte": // TODO: needs to be base64 encoded/decoded
×
46
                        g.stmt.Index().Byte()
×
47
                case "binary":
×
48
                        g.stmt.Index().Byte()
×
49
                case "date-time":
29✔
50
                        if jsonapi, ok := g.tags["jsonapi"]; ok { // add hint for jsonapi that time is in iso8601 format
55✔
51
                                g.tags["jsonapi"] = jsonapi + ",iso8601"
26✔
52
                        } else {
29✔
53
                                addValidator(g.tags, "iso8601")
3✔
54
                        }
3✔
55

56
                        if g.isParam {
32✔
57
                                g.stmt.Qual("time", "Time")
3✔
58
                        } else {
29✔
59
                                g.stmt.Op("*").Qual("time", "Time") // time.Time can not be nil, so a pointer is needed for omitempty to work
26✔
60
                        }
26✔
61
                case "date":
1✔
62
                        addValidator(g.tags, "time(2006-01-02)")
1✔
63
                        if g.isParam {
1✔
64
                                g.stmt.Qual("time", "Time")
×
65
                        } else {
1✔
66
                                g.stmt.Op("*").Qual("time", "Time") // time.Time can not be nil, so a pointer is needed for omitempty to work
1✔
67
                        }
1✔
68
                case "uuid":
78✔
69
                        addValidator(g.tags, "uuid")
78✔
70
                        if g.schema.Nullable {
78✔
71
                                g.stmt.Op("*").String()
×
72
                        } else {
78✔
73
                                g.stmt.String()
78✔
74
                        }
78✔
75
                case "decimal":
2✔
76
                        addValidator(g.tags, "matches(^(\\d*\\.)?\\d+$)")
2✔
77
                        if g.isParam {
4✔
78
                                g.stmt.Qual(pkgDecimal, "Decimal")
2✔
79
                        } else {
2✔
80
                                g.stmt.Op("*").Qual(pkgDecimal, "Decimal")
×
81
                        }
×
82
                default:
165✔
83
                        if g.schema.Nullable {
166✔
84
                                g.stmt.Op("*").String()
1✔
85
                        } else {
165✔
86
                                g.stmt.String()
164✔
87
                        }
164✔
88
                }
89
        } else if g.schema.Type.Is("integer") {
88✔
90
                removeOmitempty(g.tags)
18✔
91
                switch g.schema.Format {
18✔
92
                case "int32":
×
93
                        if g.schema.Nullable {
×
94
                                g.stmt.Op("*").Int32()
×
95
                        } else {
×
96
                                g.stmt.Int32()
×
97
                        }
×
98
                default:
18✔
99
                        if g.schema.Nullable {
18✔
100
                                g.stmt.Op("*").Int64()
×
101
                        } else {
18✔
102
                                g.stmt.Int64()
18✔
103
                        }
18✔
104
                }
105
        } else if g.schema.Type.Is("number") {
98✔
106
                switch g.schema.Format {
46✔
107
                case "decimal":
10✔
108
                        if g.isParam {
10✔
109
                                removeOmitempty(g.tags)
×
110
                                g.stmt.Qual(pkgDecimal, "Decimal")
×
111
                        } else {
10✔
112
                                g.stmt.Op("*").Qual(pkgDecimal, "Decimal")
10✔
113
                        }
10✔
114
                case "float":
31✔
115
                        removeOmitempty(g.tags)
31✔
116
                        if g.schema.Nullable {
32✔
117
                                g.stmt.Op("*").Float32()
1✔
118
                        } else {
31✔
119
                                g.stmt.Float32()
30✔
120
                        }
30✔
121
                case "double":
×
122
                        fallthrough
×
123
                default:
5✔
124
                        removeOmitempty(g.tags)
5✔
125
                        if g.schema.Nullable {
5✔
126
                                g.stmt.Op("*").Float64()
×
127
                        } else {
5✔
128
                                g.stmt.Float64()
5✔
129
                        }
5✔
130
                }
131
        } else if g.schema.Type.Is("boolean") {
10✔
132
                removeOmitempty(g.tags)
4✔
133
                if g.schema.Nullable {
5✔
134
                        g.stmt.Op("*").Bool()
1✔
135
                } else {
4✔
136
                        g.stmt.Bool()
3✔
137
                }
3✔
138
        } else if g.schema.Type.Is("array") {
4✔
139
                removeOmitempty(g.tags)
2✔
140
                err := g.g.goType(g.stmt.Index(), g.schema.Items.Value, g.tags).invoke()
2✔
141
                if err != nil {
2✔
142
                        return err
×
143
                }
×
NEW
144
        } else {
×
145
                return fmt.Errorf("unknown type: %s", g.schema.Type)
×
UNCOV
146
        }
×
147

148
        // add enum validation
149
        if len(g.schema.Enum) > 0 {
392✔
150
                strs := make([]string, len(g.schema.Enum))
47✔
151
                for i := 0; i < len(g.schema.Enum); i++ {
323✔
152
                        strs[i] = fmt.Sprintf("%v", g.schema.Enum[i])
276✔
153
                }
276✔
154

155
                // in case the field/value is optional
156
                // an empty value needs to be added to the enum validator
157
                if hasValidator(g.tags, "optional") {
79✔
158
                        strs = append(strs, "")
32✔
159
                }
32✔
160

161
                addValidator(g.tags, fmt.Sprintf("in(%v)", strings.Join(strs, "|")))
47✔
162
        }
163

164
        return nil
345✔
165
}
166

167
func (g *Generator) commentOrExample(stmt *jen.Statement, schema *openapi3.Schema) {
279✔
168
        if schema.Description != "" {
404✔
169
                stmt.Comment(schema.Description)
125✔
170
        } else if schema.Example != nil {
380✔
171
                stmt.Comment(fmt.Sprintf("Example: \"%v\"", schema.Example))
101✔
172
        }
101✔
173
}
174

175
func hasSecuritySchema(swagger *openapi3.T) bool {
35✔
176
        return len(swagger.Components.SecuritySchemes) > 0
35✔
177
}
35✔
178

179
func addValidator(tags map[string]string, validator string) {
443✔
180
        cur := tags["valid"]
443✔
181
        if cur != "" {
566✔
182
                validator = tags["valid"] + "," + validator
123✔
183
        }
123✔
184
        tags["valid"] = validator
443✔
185
}
186

187
func hasValidator(tags map[string]string, validator string) bool {
47✔
188
        validatorCfg, ok := tags["valid"]
47✔
189
        if !ok {
56✔
190
                return false
9✔
191
        }
9✔
192
        validators := strings.Split(validatorCfg, ",")
38✔
193
        for _, v := range validators {
76✔
194
                if strings.HasPrefix(v, validator) {
70✔
195
                        return true
32✔
196
                }
32✔
197
        }
198

199
        return false
6✔
200
}
201

202
var idRegex = regexp.MustCompile("Id$")
203

204
func goNameHelper(name string) string {
1,878✔
205
        caser := cases.Title(language.Und, cases.NoLower)
1,878✔
206
        name = caser.String(name)
1,878✔
207
        name = strings.Replace(name, "Url", "URL", -1)
1,878✔
208
        name = idRegex.ReplaceAllString(name, "ID")
1,878✔
209
        return name
1,878✔
210
}
1,878✔
211

212
func nameFromSchemaRef(ref *openapi3.SchemaRef) string {
434✔
213
        name := goNameHelper(filepath.Base(ref.Ref))
434✔
214
        if name == "." {
775✔
215
                return ""
341✔
216
        }
341✔
217
        return name
93✔
218
}
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