Skip to content

Commit 8022ae3

Browse files
committed
- [+] add string manipulation functions, close #18
1 parent 9378bb6 commit 8022ae3

File tree

4 files changed

+311
-3
lines changed

4 files changed

+311
-3
lines changed

t_strings_test.go

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
package easygen_test
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/go-easygen/easygen"
8+
)
9+
10+
type testItem struct {
11+
tmplStr, expected string
12+
}
13+
14+
//var tmpl *template.Template
15+
16+
func testStringManipulation(t *testing.T, d []testItem) {
17+
tmpl = easygen.NewTemplate().Funcs(easygen.FuncDefs())
18+
for _, tc := range d {
19+
buf := bytes.NewBufferString("")
20+
easygen.Process0(tmpl, buf, tc.tmplStr, "test/strings")
21+
22+
v := buf.String()
23+
//t.Log(v)
24+
if v != tc.expected {
25+
t.Errorf("'%s' expects '%s', got '%s'", tc.tmplStr, tc.expected, v)
26+
}
27+
}
28+
}
29+
30+
// for standalone test, change package to `main` and the next func def to,
31+
// func main() {
32+
func TestStringManipulation(t *testing.T) {
33+
34+
testData := []testItem{
35+
// == strings functions
36+
{
37+
`{{ stringsContains "seafood" "foo" }}`,
38+
"true",
39+
},
40+
{
41+
`{{ stringsContains "seafood" "bar" }}`,
42+
"false",
43+
},
44+
{
45+
`{{ stringsContainsAny "team" "i" }}`,
46+
"false",
47+
},
48+
{
49+
`{{ stringsContainsAny "failure" "u & i" }}`,
50+
"true",
51+
},
52+
{
53+
`{{ stringsCount "cheese" "e" }}`,
54+
"3",
55+
},
56+
{
57+
`{{ stringsEqualFold "Go" "go" }}`,
58+
"true",
59+
},
60+
{
61+
`{{ stringsFields " foo bar baz " }}`,
62+
"[foo bar baz]",
63+
},
64+
{
65+
`{{ stringsIndex "go gopher" "go" }}`,
66+
"0",
67+
},
68+
{
69+
`{{ stringsLastIndex "go gopher" "go" }}`,
70+
"3",
71+
},
72+
{
73+
`ba{{ stringsRepeat "na" 2 }}`,
74+
"banana",
75+
},
76+
{
77+
`{{ stringsReplace "oink oink oink" "k" "ky" 2 }}`,
78+
"oinky oinky oink",
79+
},
80+
{
81+
`{{ stringsReplace "oink oink oink" "oink" "moo" -1 }}`,
82+
"moo moo moo",
83+
},
84+
{
85+
`{{ stringsSplitN "a,b,c" "," 0 }}`,
86+
`[]`,
87+
},
88+
{
89+
`{{ stringsSplitAfter "a,b,c" "," }}`,
90+
`[a, b, c]`,
91+
},
92+
{
93+
`{{ stringsSplitAfterN "a,b,c" "," 2 }}`,
94+
`[a, b,c]`,
95+
},
96+
{
97+
`{{ stringsTitle "her royal highness" }}`,
98+
"Her Royal Highness",
99+
},
100+
{
101+
`{{ stringsToLower "Gopher" }}`,
102+
"gopher",
103+
},
104+
{
105+
`{{ stringsToUpper "Gopher" }}`,
106+
"GOPHER",
107+
},
108+
{
109+
`{{ stringsTrimSpace " \t\n a lone gopher \n\t\r\n" }}`,
110+
"a lone gopher",
111+
},
112+
{
113+
`{{ stringsTrim " !!! Achtung !!! " "! " }}`,
114+
"Achtung",
115+
},
116+
{
117+
`{{ stringsTrimPrefix "Goodbye,, world!" "Goodbye," }}`,
118+
", world!",
119+
},
120+
{
121+
`{{ stringsTrimSuffix "Hello, goodbye, etc!" "goodbye, etc!" }}`,
122+
"Hello, ",
123+
},
124+
// aliases
125+
{
126+
`The {{if eq .StrTest "these rights belong to those people"}}eq says Yea{{else}}eq says Nay{{end}} but {{if eqf .StrTest "these rights belong to those people"}}eqf says Yea{{else}}eqf says Nay{{end}}.`,
127+
"The eq says Nay but eqf says Yea.",
128+
},
129+
130+
// == regexp functions
131+
{
132+
`{{ regexpFindString "peach punch" "p([a-z]+)ch" }}`,
133+
"peach",
134+
},
135+
{
136+
`{{ regexpFindAllString "peach punch" "p([a-z]+)ch" -1 }}`,
137+
"[peach punch]",
138+
},
139+
{
140+
`{{ regexpFindAllString "peach punch" "p([a-z]+)ch" 1 }}`,
141+
"[peach]",
142+
},
143+
{
144+
`{{ regexpFindStringIndex "peach punch" "p([a-z]+)ch" }}`,
145+
"[0 5]",
146+
},
147+
{
148+
`{{ regexpFindStringSubmatch "peach punch" "p([a-z]+)ch" }}`,
149+
"[peach ea]",
150+
},
151+
{
152+
`{{ regexpFindStringSubmatchIndex "peach punch" "p([a-z]+)ch" }}`,
153+
"[0 5 1 3]",
154+
},
155+
//
156+
{
157+
`{{ regexpMatchString "HTTPS://site/" "(?i)^http" }}`,
158+
"true",
159+
},
160+
//
161+
{
162+
`{{ regexpReplaceAllLiteralString "html HTML Html aa uml bb Uml" "(?i)html|uml" "XML" }}`,
163+
"XML XML XML aa XML bb XML",
164+
},
165+
{
166+
`{{ regexpReplaceAllString .StrTest "(?i)th[eo]se" "the" }}`,
167+
"the rights belong to the people",
168+
},
169+
{
170+
`{{ regexpReplaceAllString "This and these are for THOSE people" "(?i)(this|th[eo]se)" "<b>${1}</b>" }}`,
171+
"<b>This</b> and <b>these</b> are for <b>THOSE</b> people",
172+
},
173+
// {
174+
// `{{ regexpReplaceAllStringFunc "a peach" "p([a-z]+)ch" stringsToUpper }}`,
175+
// "a PEACH",
176+
// },
177+
}
178+
179+
testStringManipulation(t, testData)
180+
}
181+
182+
/*
183+
{
184+
`{{ }}`,
185+
"",
186+
},
187+
188+
*/

template.go

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,69 @@ type EgBase struct {
3535
type FuncMap map[string]interface{}
3636

3737
var egFuncMap = FuncMap{
38-
"eqf": strings.EqualFold,
39-
"split": strings.Fields,
38+
// == strings function definitions
39+
"stringsCompare": strings.Compare,
40+
"stringsContains": strings.Contains,
41+
"stringsContainsAny": strings.ContainsAny,
42+
"stringsContainsRune": strings.ContainsRune,
43+
"stringsCount": strings.Count,
44+
"stringsEqualFold": strings.EqualFold,
45+
"stringsFields": strings.Fields,
46+
"stringsFieldsFunc": strings.FieldsFunc,
47+
"stringsHasPrefix": strings.HasPrefix,
48+
"stringsHasSuffix": strings.HasSuffix,
49+
"stringsIndex": strings.Index,
50+
"stringsIndexAny": strings.IndexAny,
51+
"stringsIndexByte": strings.IndexByte,
52+
"stringsIndexFunc": strings.IndexFunc,
53+
"stringsIndexRune": strings.IndexRune,
54+
"stringsJoin": strings.Join,
55+
"stringsLastIndex": strings.LastIndex,
56+
"stringsLastIndexAny": strings.LastIndexAny,
57+
"stringsLastIndexByte": strings.LastIndexByte,
58+
"stringsLastIndexFunc": strings.LastIndexFunc,
59+
"stringsMap": strings.Map,
60+
"stringsRepeat": strings.Repeat,
61+
"stringsReplace": strings.Replace,
62+
"stringsSplit": strings.Split,
63+
"stringsSplitAfter": strings.SplitAfter,
64+
"stringsSplitAfterN": strings.SplitAfterN,
65+
"stringsSplitN": strings.SplitN,
66+
"stringsTitle": strings.Title,
67+
"stringsToLower": strings.ToLower,
68+
"stringsToLowerSpecial": strings.ToLowerSpecial,
69+
"stringsToTitle": strings.ToTitle,
70+
"stringsToTitleSpecial": strings.ToTitleSpecial,
71+
"stringsToUpper": strings.ToUpper,
72+
"stringsToUpperSpecial": strings.ToUpperSpecial,
73+
"stringsTrim": strings.Trim,
74+
"stringsTrimFunc": strings.TrimFunc,
75+
"stringsTrimLeft": strings.TrimLeft,
76+
"stringsTrimLeftFunc": strings.TrimLeftFunc,
77+
"stringsTrimPrefix": strings.TrimPrefix,
78+
"stringsTrimRight": strings.TrimRight,
79+
"stringsTrimRightFunc": strings.TrimRightFunc,
80+
"stringsTrimSpace": strings.TrimSpace,
81+
"stringsTrimSuffix": strings.TrimSuffix,
82+
// aliases
83+
"eqf": strings.EqualFold,
84+
"split": strings.Fields,
85+
86+
// == regexp function definitions
87+
"regexpFindAllString": regexpFindAllString,
88+
"regexpFindAllStringIndex": regexpFindAllStringIndex,
89+
"regexpFindAllStringSubmatch": regexpFindAllStringSubmatch,
90+
"regexpFindAllStringSubmatchIndex": regexpFindAllStringSubmatchIndex,
91+
"regexpFindString": regexpFindString,
92+
"regexpFindStringIndex": regexpFindStringIndex,
93+
"regexpFindStringSubmatch": regexpFindStringSubmatch,
94+
"regexpFindStringSubmatchIndex": regexpFindStringSubmatchIndex,
95+
"regexpMatchString": regexpMatchString,
96+
"regexpReplaceAllLiteralString": regexpReplaceAllLiteralString,
97+
"regexpReplaceAllString": regexpReplaceAllString,
98+
"regexpReplaceAllStringFunc": regexpReplaceAllStringFunc,
99+
"regexpSplit": regexpSplit,
100+
40101
"replace": replace,
41102
"replacec": replacec,
42103

test/strings.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
StrTest: "These rights belong to those people"

tf-strings.go

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,64 @@ var (
1010
rec *regexp.Regexp
1111
)
1212

13+
////////////////////////////////////////////////////////////////////////////
14+
// Regexp Function Definitions
15+
16+
func regexpFindAllString(s string, regExp string, n int) []string {
17+
return regexp.MustCompile(regExp).FindAllString(s, n)
18+
}
19+
20+
func regexpFindAllStringIndex(s string, regExp string, n int) [][]int {
21+
return regexp.MustCompile(regExp).FindAllStringIndex(s, n)
22+
}
23+
24+
func regexpFindAllStringSubmatch(s string, regExp string, n int) [][]string {
25+
return regexp.MustCompile(regExp).FindAllStringSubmatch(s, n)
26+
}
27+
28+
func regexpFindAllStringSubmatchIndex(s string, regExp string, n int) [][]int {
29+
return regexp.MustCompile(regExp).FindAllStringSubmatchIndex(s, n)
30+
}
31+
32+
func regexpFindString(s string, regExp string) string {
33+
return regexp.MustCompile(regExp).FindString(s)
34+
}
35+
36+
func regexpFindStringIndex(s string, regExp string) (loc []int) {
37+
return regexp.MustCompile(regExp).FindStringIndex(s)
38+
}
39+
40+
func regexpFindStringSubmatch(s string, regExp string) []string {
41+
return regexp.MustCompile(regExp).FindStringSubmatch(s)
42+
}
43+
44+
func regexpFindStringSubmatchIndex(s string, regExp string) []int {
45+
return regexp.MustCompile(regExp).FindStringSubmatchIndex(s)
46+
}
47+
48+
func regexpMatchString(s string, regExp string) bool {
49+
return regexp.MustCompile(regExp).MatchString(s)
50+
}
51+
52+
func regexpReplaceAllLiteralString(src, regExp string, repl string) string {
53+
return regexp.MustCompile(regExp).ReplaceAllLiteralString(src, repl)
54+
}
55+
56+
func regexpReplaceAllString(src, regExp string, repl string) string {
57+
return regexp.MustCompile(regExp).ReplaceAllString(src, repl)
58+
}
59+
60+
func regexpReplaceAllStringFunc(src string, regExp string, repl func(string) string) string {
61+
return regexp.MustCompile(regExp).ReplaceAllStringFunc(src, repl)
62+
}
63+
64+
func regexpSplit(s string, regExp string, n int) []string {
65+
return regexp.MustCompile(regExp).Split(s, n)
66+
}
67+
68+
////////////////////////////////////////////////////////////////////////////
69+
// CLI Function Definitions
70+
1371
// TFStringsInit does initialization for strings related template functions
1472
func TFStringsInit() {
1573
re = regexp.MustCompile(`(?i)` + Opts.StrFrom)
@@ -19,7 +77,7 @@ func TFStringsInit() {
1977
}
2078

2179
//==========================================================================
22-
// template function
80+
// command-line replacing option template function
2381

2482
func replace(replStr string) string {
2583
return re.ReplaceAllString(replStr, Opts.StrTo)

0 commit comments

Comments
 (0)