Codebase list golang-github-serenize-snaker / 06c5ff6
New upstream version 0.0~git20170425.0.1c7f653 Diego M. Rodriguez 7 years ago
6 changed file(s) with 315 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 language: go
1
2 go:
3 - 1.2
4 - 1.3
5 - tip
6
7 install: go get -t -d -v ./... && go build -v ./...
0 Copyright (c) 2015 Serenize UG (haftungsbeschränkt)
1
2 Permission is hereby granted, free of charge, to any person obtaining a copy
3 of this software and associated documentation files (the "Software"), to deal
4 in the Software without restriction, including without limitation the rights
5 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6 copies of the Software, and to permit persons to whom the Software is
7 furnished to do so, subject to the following conditions:
8
9 The above copyright notice and this permission notice shall be included in
10 all copies or substantial portions of the Software.
11
12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18 THE SOFTWARE.
0 # snaker
1
2 [![Build Status](https://travis-ci.org/serenize/snaker.svg?branch=master)](https://travis-ci.org/serenize/snaker)
3 [![GoDoc](https://godoc.org/github.com/serenize/snaker?status.svg)](https://godoc.org/github.com/serenize/snaker)
4
5 This is a small utility to convert camel cased strings to snake case and back, except some defined words.
6
7 ## QBS Usage
8
9 To replace the original toSnake and back algorithms for [https://github.com/coocood/qbs](https://github.com/coocood/qbs)
10 you can easily use snaker:
11
12 Import snaker
13 ```go
14 import (
15 github.com/coocood/qbs
16 github.com/serenize/snaker
17 )
18 ```
19
20 Register the snaker methods to qbs
21 ```go
22 qbs.ColumnNameToFieldName = snaker.SnakeToCamel
23 qbs.FieldNameToColumnName = snaker.CamelToSnake
24 ```
0 // Package snaker provides methods to convert CamelCase names to snake_case and back.
1 // It considers the list of allowed initialsms used by github.com/golang/lint/golint (e.g. ID or HTTP)
2 package snaker
3
4 import (
5 "strings"
6 "unicode"
7 )
8
9 // CamelToSnake converts a given string to snake case
10 func CamelToSnake(s string) string {
11 var result string
12 var words []string
13 var lastPos int
14 rs := []rune(s)
15
16 for i := 0; i < len(rs); i++ {
17 if i > 0 && unicode.IsUpper(rs[i]) {
18 if initialism := startsWithInitialism(s[lastPos:]); initialism != "" {
19 words = append(words, initialism)
20
21 i += len(initialism) - 1
22 lastPos = i
23 continue
24 }
25
26 words = append(words, s[lastPos:i])
27 lastPos = i
28 }
29 }
30
31 // append the last word
32 if s[lastPos:] != "" {
33 words = append(words, s[lastPos:])
34 }
35
36 for k, word := range words {
37 if k > 0 {
38 result += "_"
39 }
40
41 result += strings.ToLower(word)
42 }
43
44 return result
45 }
46
47 func snakeToCamel(s string, upperCase bool) string {
48 var result string
49
50 words := strings.Split(s, "_")
51
52 for i, word := range words {
53 if upperCase || i > 0 {
54 if upper := strings.ToUpper(word); commonInitialisms[upper] {
55 result += upper
56 continue
57 }
58 }
59
60 if (upperCase || i > 0) && len(word) > 0 {
61 w := []rune(word)
62 w[0] = unicode.ToUpper(w[0])
63 result += string(w)
64 } else {
65 result += word
66 }
67 }
68
69 return result
70 }
71
72 // SnakeToCamel returns a string converted from snake case to uppercase
73 func SnakeToCamel(s string) string {
74 return snakeToCamel(s, true)
75 }
76
77 // SnakeToCamelLower returns a string converted from snake case to lowercase
78 func SnakeToCamelLower(s string) string {
79 return snakeToCamel(s, false)
80 }
81
82 // startsWithInitialism returns the initialism if the given string begins with it
83 func startsWithInitialism(s string) string {
84 var initialism string
85 // the longest initialism is 5 char, the shortest 2
86 for i := 1; i <= 5; i++ {
87 if len(s) > i-1 && commonInitialisms[s[:i]] {
88 initialism = s[:i]
89 }
90 }
91 return initialism
92 }
93
94 // commonInitialisms, taken from
95 // https://github.com/golang/lint/blob/206c0f020eba0f7fbcfbc467a5eb808037df2ed6/lint.go#L731
96 var commonInitialisms = map[string]bool{
97 "ACL": true,
98 "API": true,
99 "ASCII": true,
100 "CPU": true,
101 "CSS": true,
102 "DNS": true,
103 "EOF": true,
104 "GUID": true,
105 "HTML": true,
106 "HTTP": true,
107 "HTTPS": true,
108 "ID": true,
109 "IP": true,
110 "JSON": true,
111 "LHS": true,
112 "OS": true,
113 "QPS": true,
114 "RAM": true,
115 "RHS": true,
116 "RPC": true,
117 "SLA": true,
118 "SMTP": true,
119 "SQL": true,
120 "SSH": true,
121 "TCP": true,
122 "TLS": true,
123 "TTL": true,
124 "UDP": true,
125 "UI": true,
126 "UID": true,
127 "UUID": true,
128 "URI": true,
129 "URL": true,
130 "UTF8": true,
131 "VM": true,
132 "XML": true,
133 "XMPP": true,
134 "XSRF": true,
135 "XSS": true,
136 }
0 package snaker
1
2 import (
3 . "github.com/onsi/ginkgo"
4 . "github.com/onsi/gomega"
5
6 "testing"
7 )
8
9 func TestDb(t *testing.T) {
10 RegisterFailHandler(Fail)
11 RunSpecs(t, "Snaker Suite")
12 }
0 package snaker
1
2 import (
3 . "github.com/onsi/ginkgo"
4 . "github.com/onsi/gomega"
5 )
6
7 var _ = Describe("Snaker", func() {
8 Describe("CamelToSnake test", func() {
9 It("should return an empty string on an empty input", func() {
10 Expect(CamelToSnake("")).To(Equal(""))
11 })
12
13 It("should work with one word", func() {
14 Expect(CamelToSnake("One")).To(Equal("one"))
15 })
16
17 It("should return an uppercase string as seperate words", func() {
18 Expect(CamelToSnake("ONE")).To(Equal("o_n_e"))
19 })
20
21 It("should return ID as lowercase", func() {
22 Expect(CamelToSnake("ID")).To(Equal("id"))
23 })
24
25 It("should work with a single lowercase character", func() {
26 Expect(CamelToSnake("i")).To(Equal("i"))
27 })
28
29 It("should work with a single uppcase character", func() {
30 Expect(CamelToSnake("I")).To(Equal("i"))
31 })
32
33 It("should return a long text as expected", func() {
34 Expect(CamelToSnake("ThisHasToBeConvertedCorrectlyID")).To(
35 Equal("this_has_to_be_converted_correctly_id"))
36 })
37
38 It("should return the text as expected if the initialism is in the middle", func() {
39 Expect(CamelToSnake("ThisIDIsFine")).To(Equal("this_id_is_fine"))
40 })
41
42 It("should work with long initialism", func() {
43 Expect(CamelToSnake("ThisHTTPSConnection")).To(Equal("this_https_connection"))
44 })
45
46 It("should work with multi initialisms", func() {
47 Expect(CamelToSnake("HelloHTTPSConnectionID")).To(Equal("hello_https_connection_id"))
48 })
49
50 It("sould work with concat initialisms", func() {
51 Expect(CamelToSnake("HTTPSID")).To(Equal("https_id"))
52 })
53 })
54
55 Describe("SnakeToCamel test", func() {
56 It("should return an empty string on an empty input", func() {
57 Expect(SnakeToCamel("")).To(Equal(""))
58 })
59
60 It("should not blow up on trailing _", func() {
61 Expect(SnakeToCamel("potato_")).To(Equal("Potato"))
62 })
63
64 It("should return a snaked text as camel case", func() {
65 Expect(SnakeToCamel("this_has_to_be_uppercased")).To(
66 Equal("ThisHasToBeUppercased"))
67 })
68
69 It("should return a snaked text as camel case, except the word ID", func() {
70 Expect(SnakeToCamel("this_is_an_id")).To(Equal("ThisIsAnID"))
71 })
72
73 It("should return 'id' not as uppercase", func() {
74 Expect(SnakeToCamel("this_is_an_identifier")).To(Equal("ThisIsAnIdentifier"))
75 })
76
77 It("should simply work with id", func() {
78 Expect(SnakeToCamel("id")).To(Equal("ID"))
79 })
80 })
81
82 Describe("SnakeToCamelLower test", func() {
83 It("should return an empty string on an empty input", func() {
84 Ω(SnakeToCamelLower("")).To(Equal(""))
85 })
86
87 It("should not blow up on trailing _", func() {
88 Ω(SnakeToCamelLower("potato_")).To(Equal("potato"))
89 })
90
91 It("should return a snaked text as camel case", func() {
92 Ω(SnakeToCamelLower("this_has_to_be_uppercased")).To(
93 Equal("thisHasToBeUppercased"))
94 })
95
96 It("should return a snaked text as camel case, except the word ID", func() {
97 Ω(SnakeToCamelLower("this_is_an_id")).To(Equal("thisIsAnID"))
98 })
99
100 It("should return 'id' not as uppercase", func() {
101 Ω(SnakeToCamelLower("this_is_an_identifier")).To(Equal("thisIsAnIdentifier"))
102 })
103
104 It("should simply work with id", func() {
105 Ω(SnakeToCamelLower("id")).To(Equal("id"))
106 })
107
108 It("should simply work with leading id", func() {
109 Ω(SnakeToCamelLower("id_me_please")).To(Equal("idMePlease"))
110 })
111 })
112 })