Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 33 additions & 26 deletions pkg/codegen/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,33 +57,40 @@ func LowercaseFirstCharacter(str string) string {
// So, "word.word-word+word:word;word_word~word word(word)word{word}[word]"
// would be converted to WordWordWordWordWordWordWordWordWordWordWordWordWord
func ToCamelCase(str string) string {
separators := "-#@!$&=.+:;_~ (){}[]"
specialCharRegexStr := "[-#@!$&=.+:;_~ (){}\\[\\]]"

// Support initialisms
// https://github.com/golang/go/wiki/CodeReviewComments#initialisms
// https://staticcheck.io/docs/configuration/options/#initialisms
acronyms := []string{"ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF",
"GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM",
"RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI",
"GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP",
"XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS"}

acronymsSepRegexStr := fmt.Sprintf("($|%s.)|", specialCharRegexStr)
acronymsInitialRegexStr := strings.Join(acronyms, acronymsSepRegexStr) +
acronymsSepRegexStr
acronymsTrailingRegexStr := strings.Join(acronyms, acronymsSepRegexStr) +
acronymsSepRegexStr

camelCaseRegexStr := fmt.Sprintf("(?i)^(%s[A-Za-z0-9])|%s(%s[A-Za-z0-9])",
acronymsInitialRegexStr,
specialCharRegexStr,
acronymsTrailingRegexStr)

camelCaseRegex := regexp.MustCompile(camelCaseRegexStr)
specialCharRegex := regexp.MustCompile(specialCharRegexStr)

// If you wanted true camelCase without user overriding you could
// set the string to lowercase beforehand
// However, users may expect some degree of override already, and we don't
// want to break backwards compatibility
s := strings.Trim(str, " ")

n := ""
capNext := true
for _, v := range s {
if unicode.IsUpper(v) {
n += string(v)
}
if unicode.IsDigit(v) {
n += string(v)
}
if unicode.IsLower(v) {
if capNext {
n += strings.ToUpper(string(v))
} else {
n += string(v)
}
}

if strings.ContainsRune(separators, v) {
capNext = true
} else {
capNext = false
}
}
return n
s = camelCaseRegex.ReplaceAllStringFunc(s, func(s string) string {
return strings.ToUpper(s)
})
return specialCharRegex.ReplaceAllString(s, "")
}

// This function returns the keys of the given SchemaRef dictionary in sorted
Expand Down
34 changes: 29 additions & 5 deletions pkg/codegen/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,36 @@ import (
"github.com/stretchr/testify/assert"
)

func TestStringOps(t *testing.T) {
// Test that each substitution works
assert.Equal(t, "WordWordWORDWordWordWordWordWordWordWordWordWordWord", ToCamelCase("word.word-WORD+Word_word~word(Word)Word{Word}Word[Word]Word:Word;"), "Camel case conversion failed")
func TestCamelCase(t *testing.T) {
type test struct {
input string
expected string
}

// Make sure numbers don't interact in a funny way.
assert.Equal(t, "Number1234", ToCamelCase("number-1234"), "Number Camelcasing not working.")
tests := []test{
{
input: "word.word-WORD+Word_word~word(Word)Word{Word}Word[Word]Word:Word;",
expected: "WordWordWORDWordWordWordWordWordWordWordWordWordWord",
},
{input: "number-1234", expected: "Number1234"},
{input: "Foo Bar", expected: "FooBar"},
{input: "db_user", expected: "DBUser"},
{input: "Db_uSer", expected: "DBUSer"},
{input: "user_db", expected: "UserDB"},
{input: "USer_dB", expected: "USerDB"},
{input: "user_db_pasta", expected: "UserDBPasta"},
{input: "uSeR_Db_PASta", expected: "USeRDBPASta"},
{input: "user_id_pasta", expected: "UserIDPasta"},
{input: "User_iD_paSTA", expected: "UserIDPaSTA"},
{input: "user_ident_pasta", expected: "UserIdentPasta"},
{input: "usEr_iDENT_pAsta", expected: "UsErIDENTPAsta"},
{input: "identifier", expected: "Identifier"},
{input: "identifier_pasta", expected: "IdentifierPasta"},
}

for _, tc := range tests {
assert.Equal(t, tc.expected, ToCamelCase(tc.input), "Incorrect CamelCase conversion")
}
}

func TestSortedSchemaKeys(t *testing.T) {
Expand Down