-
Notifications
You must be signed in to change notification settings - Fork 103
/
validate.go
155 lines (125 loc) · 3.88 KB
/
validate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package manifest
import (
"fmt"
"strings"
"unicode"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
const (
// Our longest app name to date. This can be updated, but it will need to
// be tested in the mobile app.
MaxNameLength = 17
// Our longest app summary to date. This can be updated, but it will need to
// be tested in the mobile app.
MaxSummaryLength = 27
dash = '-'
underscore = '_'
)
var punctuation []string = []string{
".",
"!",
"?",
}
var titleCaser cases.Caser
func init() {
titleCaser = cases.Title(language.English, cases.NoLower)
}
// ValidateName ensures the app name provided adheres to the standards for app
// names. We're picky here because these will display in the Tidbyt mobile app
// and need to display properly.
func ValidateName(name string) error {
if name == "" {
return fmt.Errorf("name cannot be empty")
}
if name != titleCase(name) {
return fmt.Errorf("'%s' should be title case, 'Fuzzy Clock' for example", name)
}
if len(name) > MaxNameLength {
return fmt.Errorf("app names need to be less than %d characters", MaxNameLength)
}
return nil
}
// ValidateSummary ensures the app summary provided adheres to the standards
// for app summaries. We're picky here because these will display in the Tidbyt
// mobile app and need to display properly.
func ValidateSummary(summary string) error {
if summary == "" {
return fmt.Errorf("summary cannot be empty")
}
if len(summary) > MaxSummaryLength {
return fmt.Errorf("app summaries need to be less than %d characters", MaxSummaryLength)
}
for _, punct := range punctuation {
if strings.HasSuffix(summary, punct) {
return fmt.Errorf("app summaries should not end in punctuation")
}
}
words := strings.Split(summary, " ")
if len(words) > 0 && words[0] != titleCaser.String(words[0]) {
return fmt.Errorf("app summaries should start with an uppercased character")
}
return nil
}
// ValidateDesc ensures the app description provided adheres to the standards
// for app descriptions. We're picky here because these will display in the
// Tidbyt mobile app and need to display properly.
func ValidateDesc(desc string) error {
if desc == "" {
return fmt.Errorf("desc cannot be empty")
}
found := false
for _, punct := range punctuation {
if strings.HasSuffix(desc, punct) {
found = true
}
}
if !found {
return fmt.Errorf("app descriptions should end in punctuation")
}
words := strings.Split(desc, " ")
if len(words) > 0 && words[0] != titleCaser.String(words[0]) {
return fmt.Errorf("app descriptions should start with an uppercased character")
}
return nil
}
// ValidateAuthor ensures the app author provided adheres to the standards
// for app author. We're picky here because these will display in the
// Tidbyt mobile app and need to display properly.
func ValidateAuthor(author string) error {
if author == "" {
return fmt.Errorf("author cannot be empty")
}
// I don't know what validation where need here just yet. We're going to
// have to eyeball it in pull requests until we get a sense of what doesn't
// work.
return nil
}
// ValidateID ensures the id will parse when we go to add it to our database
// internally.
func ValidateID(id string) error {
if id == "" {
return fmt.Errorf("id cannot be empty")
}
if id != strings.ToLower(id) {
return fmt.Errorf("ids should be lower case, %s != %s", id, strings.ToLower(id))
}
for _, r := range id {
if !(unicode.IsLetter(r) || unicode.IsNumber(r) || r == dash) {
return fmt.Errorf("ids can only contain letters, numbers, or a dash character")
}
}
return nil
}
func titleCase(input string) string {
words := strings.Split(input, " ")
smallwords := " a an on the to of "
for index, word := range words {
if strings.Contains(smallwords, " "+word+" ") && word != string(word[0]) {
words[index] = word
} else {
words[index] = titleCaser.String(word)
}
}
return strings.Join(words, " ")
}