1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-02-14 01:32:27 +08:00

feat: add UpperKebabCase/UpperSnakeCase

This commit is contained in:
dudaodong
2022-12-15 16:05:02 +08:00
parent 279d0754ba
commit 43c2fd2a22
5 changed files with 403 additions and 138 deletions

View File

@@ -28,14 +28,15 @@ import (
- [Capitalize](#Capitalize) - [Capitalize](#Capitalize)
- [IsString](#IsString) - [IsString](#IsString)
- [KebabCase](#KebabCase) - [KebabCase](#KebabCase)
- [UpperKebabCase](#UpperKebabCase)
- [LowerFirst](#LowerFirst) - [LowerFirst](#LowerFirst)
- [UpperFirst](#UpperFirst) - [UpperFirst](#UpperFirst)
- [PadEnd](#PadEnd) - [PadEnd](#PadEnd)
- [PadStart](#PadStart) - [PadStart](#PadStart)
- [ReverseStr](#ReverseStr) - [ReverseStr](#ReverseStr)
- [SnakeCase](#SnakeCase) - [SnakeCase](#SnakeCase)
- [UpperSnakeCase](#UpperSnakeCase)
- [Wrap](#Wrap) - [Wrap](#Wrap)
- [Unwrap](#Unwrap) - [Unwrap](#Unwrap)
- [SplitEx](#SplitEx) - [SplitEx](#SplitEx)
@@ -169,7 +170,7 @@ func main() {
### <span id="CamelCase">CamelCase</span> ### <span id="CamelCase">CamelCase</span>
<p>Covert string to camelCase string.</p> <p>Coverts string to camelCase string, non letters and numbers will be ignored.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -196,7 +197,9 @@ func main() {
s4 := strutil.CamelCase("foo bar") s4 := strutil.CamelCase("foo bar")
fmt.Println(s4) //fooBar fmt.Println(s4) //fooBar
}
s4 := strutil.CamelCase("Foo-#1😄$_%^&*(1bar")
fmt.Println(s4) //foo11Bar
``` ```
@@ -261,7 +264,7 @@ func main() {
### <span id="KebabCase">KebabCase</span> ### <span id="KebabCase">KebabCase</span>
<p>Covert string to kebab-case.</p> <p>KebabCase covert string to kebab-case, non letters and numbers will be ignored.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -287,12 +290,44 @@ func main() {
fmt.Println(s3) //foo-bar fmt.Println(s3) //foo-bar
s4 := strutil.KebabCase("__FOO_BAR__") s4 := strutil.KebabCase("__FOO_BAR__")
fmt.Println(s4) //f-o-o-b-a-r fmt.Println(s4) //foo-bar
} }
``` ```
### <span id="UpperKebabCase">UpperKebabCase</span>
<p>UpperKebabCase covert string to upper KEBAB-CASE, non letters and numbers will be ignored.</p>
<b>Signature:</b>
```go
func KebabCase(s string) string
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/strutil"
)
func main() {
s1 := strutil.UpperKebabCase("Foo Bar-")
fmt.Println(s1) //FOO-BAR
s2 := strutil.UpperKebabCase("foo_Bar")
fmt.Println(s2) //FOO-BAR
s3 := strutil.UpperKebabCase("fooBar")
fmt.Println(s3) //FOO-BAR
s4 := strutil.UpperKebabCase("__FOO_BAR__")
fmt.Println(s4) //FOO-BAR
}
```
### <span id="LowerFirst">LowerFirst</span> ### <span id="LowerFirst">LowerFirst</span>
<p>Convert the first character of string to lower case.</p> <p>Convert the first character of string to lower case.</p>
@@ -456,9 +491,8 @@ func main() {
``` ```
### <span id="SnakeCase">SnakeCase</span> ### <span id="SnakeCase">SnakeCase</span>
<p>Covert string to snake_case.</p> <p>Coverts string to snake_case, non letters and numbers will be ignored.</p>
<b>Signature:</b> <b>Signature:</b>
@@ -484,14 +518,48 @@ func main() {
fmt.Println(s3) //foo_bar fmt.Println(s3) //foo_bar
s4 := strutil.SnakeCase("__FOO_BAR__") s4 := strutil.SnakeCase("__FOO_BAR__")
fmt.Println(s4) //f_o_o_b_a_r fmt.Println(s4) //foo_bar
s5 := strutil.SnakeCase("aBbc-s$@a&%_B.B^C") s5 := strutil.SnakeCase("Foo-#1😄$_%^&*(1bar")
fmt.Println(s5) //a_bbc_s_a_b_b_c fmt.Println(s5) //foo_1_1_bar
} }
``` ```
### <span id="UpperSnakeCase">UpperSnakeCase</span>
<p>Coverts string to upper KEBAB-CASE, non letters and numbers will be ignored.</p>
<b>Signature:</b>
```go
func SnakeCase(s string) string
```
<b>Example:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/strutil"
)
func main() {
s1 := strutil.UpperSnakeCase("Foo Bar-")
fmt.Println(s1) //FOO_BAR
s2 := strutil.UpperSnakeCase("foo_Bar")
fmt.Println(s2) //FOO_BAR
s3 := strutil.UpperSnakeCase("fooBar")
fmt.Println(s3) //FOO_BAR
s4 := strutil.UpperSnakeCase("__FOO_BAR__")
fmt.Println(s4) //FOO_BAR
s5 := strutil.UpperSnakeCase("Foo-#1😄$_%^&*(1bar")
fmt.Println(s5) //FOO_1_1_BAR
}
```
### <span id="Wrap">Wrap</span> ### <span id="Wrap">Wrap</span>

View File

@@ -28,14 +28,15 @@ import (
- [Capitalize](#Capitalize) - [Capitalize](#Capitalize)
- [IsString](#IsString) - [IsString](#IsString)
- [KebabCase](#KebabCase) - [KebabCase](#KebabCase)
- [UpperKebabCase](#UpperKebabCase)
- [LowerFirst](#LowerFirst) - [LowerFirst](#LowerFirst)
- [UpperFirst](#UpperFirst) - [UpperFirst](#UpperFirst)
- [PadEnd](#PadEnd) - [PadEnd](#PadEnd)
- [PadStart](#PadStart) - [PadStart](#PadStart)
- [ReverseStr](#ReverseStr) - [ReverseStr](#ReverseStr)
- [SnakeCase](#SnakeCase) - [SnakeCase](#SnakeCase)
- [UpperSnakeCase](#UpperSnakeCase)
- [Wrap](#Wrap) - [Wrap](#Wrap)
- [Unwrap](#Unwrap) - [Unwrap](#Unwrap)
- [SplitEx](#SplitEx) - [SplitEx](#SplitEx)
@@ -170,7 +171,7 @@ func main() {
### <span id="CamelCase">CamelCase</span> ### <span id="CamelCase">CamelCase</span>
<p>将字符串转换为驼峰式字符串</p> <p>将字符串转换为驼峰式字符串, 非字母和数字会被忽略</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -197,6 +198,9 @@ func main() {
s4 := strutil.CamelCase("foo bar") s4 := strutil.CamelCase("foo bar")
fmt.Println(s4) //fooBar fmt.Println(s4) //fooBar
s4 := strutil.CamelCase("Foo-#1😄$_%^&*(1bar")
fmt.Println(s4) //foo11Bar
} }
``` ```
@@ -260,9 +264,8 @@ func main() {
``` ```
### <span id="KebabCase">KebabCase</span> ### <span id="KebabCase">KebabCase</span>
<p>将字符串转换为kebab-case</p> <p>将字符串转换为kebab-case, 非字母和数字会被忽略</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -288,12 +291,43 @@ func main() {
fmt.Println(s3) //foo-bar fmt.Println(s3) //foo-bar
s4 := strutil.KebabCase("__FOO_BAR__") s4 := strutil.KebabCase("__FOO_BAR__")
fmt.Println(s4) //f-o-o-b-a-r fmt.Println(s4) //foo-bar
} }
``` ```
### <span id="UpperKebabCase">UpperKebabCase</span>
<p>将字符串转换为大写KEBAB-CASE, 非字母和数字会被忽略</p>
<b>函数签名:</b>
```go
func KebabCase(s string) string
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/strutil"
)
func main() {
s1 := strutil.UpperKebabCase("Foo Bar-")
fmt.Println(s1) //FOO-BAR
s2 := strutil.UpperKebabCase("foo_Bar")
fmt.Println(s2) //FOO-BAR
s3 := strutil.UpperKebabCase("fooBar")
fmt.Println(s3) //FOO-BAR
s4 := strutil.UpperKebabCase("__FOO_BAR__")
fmt.Println(s4) //FOO-BAR
}
```
### <span id="LowerFirst">LowerFirst</span> ### <span id="LowerFirst">LowerFirst</span>
<p>将字符串的第一个字符转换为小写</p> <p>将字符串的第一个字符转换为小写</p>
@@ -457,9 +491,8 @@ func main() {
``` ```
### <span id="SnakeCase">SnakeCase</span> ### <span id="SnakeCase">SnakeCase</span>
<p>将字符串转换为snake_case形式</p> <p>将字符串转换为snake_case形式, 非字母和数字会被忽略</p>
<b>函数签名:</b> <b>函数签名:</b>
@@ -485,14 +518,48 @@ func main() {
fmt.Println(s3) //foo_bar fmt.Println(s3) //foo_bar
s4 := strutil.SnakeCase("__FOO_BAR__") s4 := strutil.SnakeCase("__FOO_BAR__")
fmt.Println(s4) //f_o_o_b_a_r fmt.Println(s4) //foo_bar
s5 := strutil.SnakeCase("aBbc-s$@a&%_B.B^C") s5 := strutil.SnakeCase("Foo-#1😄$_%^&*(1bar")
fmt.Println(s5) //a_bbc_s_a_b_b_c fmt.Println(s5) //foo_1_1_bar
} }
``` ```
### <span id="UpperSnakeCase">UpperSnakeCase</span>
<p>将字符串转换为大写SNAKE_CASE形式, 非字母和数字会被忽略</p>
<b>函数签名:</b>
```go
func SnakeCase(s string) string
```
<b>例子:</b>
```go
import (
"fmt"
"github.com/duke-git/lancet/strutil"
)
func main() {
s1 := strutil.UpperSnakeCase("Foo Bar-")
fmt.Println(s1) //FOO_BAR
s2 := strutil.UpperSnakeCase("foo_Bar")
fmt.Println(s2) //FOO_BAR
s3 := strutil.UpperSnakeCase("fooBar")
fmt.Println(s3) //FOO_BAR
s4 := strutil.UpperSnakeCase("__FOO_BAR__")
fmt.Println(s4) //FOO_BAR
s5 := strutil.UpperSnakeCase("Foo-#1😄$_%^&*(1bar")
fmt.Println(s5) //FOO_1_1_BAR
}
```
### <span id="Wrap">Wrap</span> ### <span id="Wrap">Wrap</span>

View File

@@ -5,53 +5,41 @@
package strutil package strutil
import ( import (
"regexp"
"strings" "strings"
"unicode" "unicode"
"unicode/utf8" "unicode/utf8"
) )
// CamelCase covert string to camelCase string. // CamelCase covert string to camelCase string.
// non letters and numbers will be ignored
// eg. "Foo-#1😄$_%^&*(1bar" => "foo11Bar"
func CamelCase(s string) string { func CamelCase(s string) string {
if len(s) == 0 { var builder strings.Builder
return ""
}
res := "" strs := splitIntoStrings(s, false)
blankSpace := " " for i, str := range strs {
regex, _ := regexp.Compile("[-_&]+")
ss := regex.ReplaceAllString(s, blankSpace)
for i, v := range strings.Split(ss, blankSpace) {
vv := []rune(v)
if i == 0 { if i == 0 {
if vv[i] >= 65 && vv[i] <= 96 { builder.WriteString(strings.ToLower(str))
vv[0] += 32
}
res += string(vv)
} else { } else {
res += Capitalize(v) builder.WriteString(Capitalize(str))
} }
} }
return res return builder.String()
} }
// Capitalize converts the first character of a string to upper case and the remaining to lower case. // Capitalize converts the first character of a string to upper case and the remaining to lower case.
func Capitalize(s string) string { func Capitalize(s string) string {
if len(s) == 0 { result := make([]rune, len(s))
return ""
}
out := make([]rune, len(s))
for i, v := range s { for i, v := range s {
if i == 0 { if i == 0 {
out[i] = unicode.ToUpper(v) result[i] = unicode.ToUpper(v)
} else { } else {
out[i] = unicode.ToLower(v) result[i] = unicode.ToLower(v)
} }
} }
return string(out) return string(result)
} }
// UpperFirst converts the first character of string to upper case. // UpperFirst converts the first character of string to upper case.
@@ -117,47 +105,35 @@ func PadStart(source string, size int, padStr string) string {
} }
// KebabCase covert string to kebab-case // KebabCase covert string to kebab-case
// non letters and numbers will be ignored
// eg. "Foo-#1😄$_%^&*(1bar" => "foo-1-1-bar"
func KebabCase(s string) string { func KebabCase(s string) string {
if len(s) == 0 { result := splitIntoStrings(s, false)
return "" return strings.Join(result, "-")
} }
regex := regexp.MustCompile(`[\W|_]+`) // UpperKebabCase covert string to upper KEBAB-CASE
blankSpace := " " // non letters and numbers will be ignored
match := regex.ReplaceAllString(s, blankSpace) // eg. "Foo-#1😄$_%^&*(1bar" => "FOO-1-1-BAR"
rs := strings.Split(match, blankSpace) func UpperKebabCase(s string) string {
result := splitIntoStrings(s, true)
var res []string return strings.Join(result, "-")
for _, v := range rs {
splitWords := splitWordsToLower(v)
if len(splitWords) > 0 {
res = append(res, splitWords...)
}
}
return strings.Join(res, "-")
} }
// SnakeCase covert string to snake_case // SnakeCase covert string to snake_case
// non letters and numbers will be ignored
// eg. "Foo-#1😄$_%^&*(1bar" => "foo_1_1_bar"
func SnakeCase(s string) string { func SnakeCase(s string) string {
if len(s) == 0 { result := splitIntoStrings(s, false)
return "" return strings.Join(result, "_")
} }
regex := regexp.MustCompile(`[\W|_]+`) // UpperSnakeCase covert string to upper SNAKE_CASE
blankSpace := " " // non letters and numbers will be ignored
match := regex.ReplaceAllString(s, blankSpace) // eg. "Foo-#1😄$_%^&*(1bar" => "FOO_1_1_BAR"
rs := strings.Split(match, blankSpace) func UpperSnakeCase(s string) string {
result := splitIntoStrings(s, true)
var res []string return strings.Join(result, "_")
for _, v := range rs {
splitWords := splitWordsToLower(v)
if len(splitWords) > 0 {
res = append(res, splitWords...)
}
}
return strings.Join(res, "_")
} }
// Before create substring in source string before position when char first appear // Before create substring in source string before position when char first appear

View File

@@ -1,40 +1,98 @@
package strutil package strutil
import "strings" import "unicode"
// splitWordsToLower split a string into worlds by uppercase char func splitIntoStrings(s string, upperCase bool) []string {
func splitWordsToLower(s string) []string { var runes [][]rune
var res []string lastCharType := 0
charType := 0
upperIndexes := upperIndex(s) // split into fields based on type of unicode character
l := len(upperIndexes) for _, r := range s {
if upperIndexes == nil || l == 0 { switch true {
if s != "" { case isLower(r):
res = append(res, s) charType = 1
case isUpper(r):
charType = 2
case isDigit(r):
charType = 3
default:
charType = 4
} }
return res
} if charType == lastCharType {
for i := 0; i < l; i++ { runes[len(runes)-1] = append(runes[len(runes)-1], r)
if i < l-1 {
res = append(res, strings.ToLower(s[upperIndexes[i]:upperIndexes[i+1]]))
} else { } else {
res = append(res, strings.ToLower(s[upperIndexes[i]:])) runes = append(runes, []rune{r})
} }
} lastCharType = charType
return res
}
// upperIndex get a int slice which elements are all the uppercase char index of a string
func upperIndex(s string) []int {
var res []int
for i := 0; i < len(s); i++ {
if 64 < s[i] && s[i] < 91 {
res = append(res, i)
}
}
if len(s) > 0 && res != nil && res[0] != 0 {
res = append([]int{0}, res...)
} }
return res for i := 0; i < len(runes)-1; i++ {
if isUpper(runes[i][0]) && isLower(runes[i+1][0]) {
runes[i+1] = append([]rune{runes[i][len(runes[i])-1]}, runes[i+1]...)
runes[i] = runes[i][:len(runes[i])-1]
}
}
// filter all none letters and none digit
var result []string
for _, rs := range runes {
if len(rs) > 0 && (unicode.IsLetter(rs[0]) || isDigit(rs[0])) {
if upperCase {
result = append(result, string(toUpperAll(rs)))
} else {
result = append(result, string(toLowerAll(rs)))
}
}
}
return result
}
// isDigit checks if a character is digit ('0' to '9')
func isDigit(r rune) bool {
return r >= '0' && r <= '9'
}
// isLower checks if a character is lower case ('a' to 'z')
func isLower(r rune) bool {
return r >= 'a' && r <= 'z'
}
// isUpper checks if a character is upper case ('A' to 'Z')
func isUpper(r rune) bool {
return r >= 'A' && r <= 'Z'
}
// toLower converts a character 'A' to 'Z' to its lower case
func toLower(r rune) rune {
if r >= 'A' && r <= 'Z' {
return r + 32
}
return r
}
// toLowerAll converts a character 'A' to 'Z' to its lower case
func toLowerAll(rs []rune) []rune {
for i := range rs {
rs[i] = toLower(rs[i])
}
return rs
}
// toUpper converts a character 'a' to 'z' to its upper case
func toUpper(r rune) rune {
if r >= 'a' && r <= 'z' {
return r - 32
}
return r
}
// toUpperAll converts a character 'a' to 'z' to its upper case
func toUpperAll(rs []rune) []rune {
for i := range rs {
rs[i] = toUpper(rs[i])
}
return rs
} }

View File

@@ -9,67 +9,163 @@ import (
func TestCamelCase(t *testing.T) { func TestCamelCase(t *testing.T) {
assert := internal.NewAssert(t, "TestCamelCase") assert := internal.NewAssert(t, "TestCamelCase")
assert.Equal("fooBar", CamelCase("foo_bar")) cases := map[string]string{
assert.Equal("fooBar", CamelCase("Foo-Bar")) "": "",
assert.Equal("fooBar", CamelCase("Foo&bar")) "foobar": "foobar",
assert.Equal("fooBar", CamelCase("foo bar")) "&FOO:BAR$BAZ": "fooBarBaz",
"fooBar": "fooBar",
"FOObar": "foObar",
"$foo%": "foo",
" $#$Foo 22 bar ": "foo22Bar",
"Foo-#1😄$_%^&*(1bar": "foo11Bar",
}
assert.NotEqual("FooBar", CamelCase("foo_bar")) for k, v := range cases {
assert.Equal(v, CamelCase(k))
}
} }
func TestCapitalize(t *testing.T) { func TestCapitalize(t *testing.T) {
assert := internal.NewAssert(t, "TestCapitalize") assert := internal.NewAssert(t, "TestCapitalize")
assert.Equal("Foo", Capitalize("foo")) cases := map[string]string{
assert.Equal("Foo", Capitalize("Foo")) "": "",
assert.Equal("Foo", Capitalize("Foo")) "Foo": "Foo",
"_foo": "_foo",
"foobar": "Foobar",
"fooBar": "Foobar",
"foo Bar": "Foo bar",
"foo-bar": "Foo-bar",
"$foo%": "$foo%",
}
assert.NotEqual("foo", Capitalize("Foo")) for k, v := range cases {
assert.Equal(v, Capitalize(k))
}
} }
func TestKebabCase(t *testing.T) { func TestKebabCase(t *testing.T) {
assert := internal.NewAssert(t, "TestKebabCase") assert := internal.NewAssert(t, "TestKebabCase")
assert.Equal("foo-bar", KebabCase("Foo Bar-")) cases := map[string]string{
assert.Equal("foo-bar", KebabCase("foo_Bar")) "": "",
assert.Equal("foo-bar", KebabCase("fooBar")) "foo-bar": "foo-bar",
assert.Equal("f-o-o-b-a-r", KebabCase("__FOO_BAR__")) "--Foo---Bar-": "foo-bar",
"Foo Bar-": "foo-bar",
"foo_Bar": "foo-bar",
"fooBar": "foo-bar",
"FOOBAR": "foobar",
"FOO_BAR": "foo-bar",
"__FOO_BAR__": "foo-bar",
"$foo@Bar": "foo-bar",
" $#$Foo 22 bar ": "foo-22-bar",
"Foo-#1😄$_%^&*(1bar": "foo-1-1-bar",
}
assert.NotEqual("foo_bar", KebabCase("fooBar")) for k, v := range cases {
assert.Equal(v, KebabCase(k))
}
}
func TestUpperKebabCase(t *testing.T) {
assert := internal.NewAssert(t, "TestUpperKebabCase")
cases := map[string]string{
"": "",
"foo-bar": "FOO-BAR",
"--Foo---Bar-": "FOO-BAR",
"Foo Bar-": "FOO-BAR",
"foo_Bar": "FOO-BAR",
"fooBar": "FOO-BAR",
"FOOBAR": "FOOBAR",
"FOO_BAR": "FOO-BAR",
"__FOO_BAR__": "FOO-BAR",
"$foo@Bar": "FOO-BAR",
" $#$Foo 22 bar ": "FOO-22-BAR",
"Foo-#1😄$_%^&*(1bar": "FOO-1-1-BAR",
}
for k, v := range cases {
assert.Equal(v, UpperKebabCase(k))
}
} }
func TestSnakeCase(t *testing.T) { func TestSnakeCase(t *testing.T) {
assert := internal.NewAssert(t, "TestSnakeCase") assert := internal.NewAssert(t, "TestSnakeCase")
assert.Equal("foo_bar", SnakeCase("Foo Bar-")) cases := map[string]string{
assert.Equal("foo_bar", SnakeCase("foo_Bar")) "": "",
assert.Equal("foo_bar", SnakeCase("fooBar")) "foo-bar": "foo_bar",
assert.Equal("f_o_o_b_a_r", SnakeCase("__FOO_BAR__")) "--Foo---Bar-": "foo_bar",
assert.Equal("a_bbc_s_a_b_b_c", SnakeCase("aBbc-s$@a&%_B.B^C")) "Foo Bar-": "foo_bar",
"foo_Bar": "foo_bar",
"fooBar": "foo_bar",
"FOOBAR": "foobar",
"FOO_BAR": "foo_bar",
"__FOO_BAR__": "foo_bar",
"$foo@Bar": "foo_bar",
" $#$Foo 22 bar ": "foo_22_bar",
"Foo-#1😄$_%^&*(1bar": "foo_1_1_bar",
}
assert.NotEqual("foo-bar", SnakeCase("foo_Bar")) for k, v := range cases {
assert.Equal(v, SnakeCase(k))
}
}
func TestUpperSnakeCase(t *testing.T) {
assert := internal.NewAssert(t, "TestUpperSnakeCase")
cases := map[string]string{
"": "",
"foo-bar": "FOO_BAR",
"--Foo---Bar-": "FOO_BAR",
"Foo Bar-": "FOO_BAR",
"foo_Bar": "FOO_BAR",
"fooBar": "FOO_BAR",
"FOOBAR": "FOOBAR",
"FOO_BAR": "FOO_BAR",
"__FOO_BAR__": "FOO_BAR",
"$foo@Bar": "FOO_BAR",
" $#$Foo 22 bar ": "FOO_22_BAR",
"Foo-#1😄$_%^&*(1bar": "FOO_1_1_BAR",
}
for k, v := range cases {
assert.Equal(v, UpperSnakeCase(k))
}
} }
func TestUpperFirst(t *testing.T) { func TestUpperFirst(t *testing.T) {
assert := internal.NewAssert(t, "TestLowerFirst") assert := internal.NewAssert(t, "TestLowerFirst")
assert.Equal("Foo", UpperFirst("foo")) cases := map[string]string{
assert.Equal("BAR", UpperFirst("bAR")) "": "",
assert.Equal("FOo", UpperFirst("FOo")) "foo": "Foo",
assert.Equal("FOo大", UpperFirst("fOo大")) "bAR": "BAR",
"FOo": "FOo",
"fOo大": "FOo大",
}
assert.NotEqual("Bar", UpperFirst("BAR")) for k, v := range cases {
assert.Equal(v, UpperFirst(k))
}
} }
func TestLowerFirst(t *testing.T) { func TestLowerFirst(t *testing.T) {
assert := internal.NewAssert(t, "TestLowerFirst") assert := internal.NewAssert(t, "TestLowerFirst")
assert.Equal("foo", LowerFirst("foo")) cases := map[string]string{
assert.Equal("bAR", LowerFirst("BAR")) "": "",
assert.Equal("fOo", LowerFirst("FOo")) "foo": "foo",
assert.Equal("fOo大", LowerFirst("FOo大")) "bAR": "bAR",
"FOo": "fOo",
"fOo大": "fOo大",
}
assert.NotEqual("Bar", LowerFirst("BAR")) for k, v := range cases {
assert.Equal(v, LowerFirst(k))
}
} }
func TestPadEnd(t *testing.T) { func TestPadEnd(t *testing.T) {