v1.11.0
ADDED:
* `stringsx` package
** `stringsx.Indent()`, to indent/prefix multiline strings
** `stringsx.Redact()`, to mask strings
** `stringsx.TrimLines()`, like strings.TrimSpace() but multiline
** `stringsx.TrimSpaceLeft()`, like strings.TrimSpace() but only to the
left of a string.
** `stringsx.TrimSpaceRight()`, like strings.TrimSpace() but only to the
right of a string.
This commit is contained in:
451
stringsx/funcs_test.go
Normal file
451
stringsx/funcs_test.go
Normal file
@@ -0,0 +1,451 @@
|
||||
package stringsx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type (
|
||||
testIndentSet struct {
|
||||
name string
|
||||
orig string
|
||||
indent string
|
||||
lvl uint
|
||||
ws bool
|
||||
empty bool
|
||||
tgt string
|
||||
}
|
||||
testRedactSet struct {
|
||||
name string
|
||||
orig string
|
||||
leading uint
|
||||
trailing uint
|
||||
tgt string
|
||||
newline bool
|
||||
mask string // defaults to DefMaskStr.
|
||||
}
|
||||
testTrimLinesSet struct {
|
||||
name string
|
||||
orig string
|
||||
left bool
|
||||
right bool
|
||||
tgt string
|
||||
}
|
||||
testTrimSet struct {
|
||||
name string
|
||||
orig string
|
||||
tgt string
|
||||
}
|
||||
)
|
||||
|
||||
func TestIndent(t *testing.T) {
|
||||
|
||||
var out string
|
||||
var tests []testIndentSet = []testIndentSet{
|
||||
testIndentSet{
|
||||
name: "standard, no trailing newline",
|
||||
orig: "foo\nbar\nbaz",
|
||||
indent: "",
|
||||
lvl: 1,
|
||||
ws: false,
|
||||
empty: false,
|
||||
tgt: "\tfoo\n\tbar\n\tbaz",
|
||||
},
|
||||
testIndentSet{
|
||||
name: "standard, trailing newline",
|
||||
orig: "foo\nbar\nbaz\n",
|
||||
indent: "",
|
||||
lvl: 1,
|
||||
ws: false,
|
||||
empty: false,
|
||||
tgt: "\tfoo\n\tbar\n\tbaz\n",
|
||||
},
|
||||
testIndentSet{
|
||||
name: "standard, trailing newline with empty",
|
||||
orig: "foo\nbar\nbaz\n",
|
||||
indent: "",
|
||||
lvl: 1,
|
||||
ws: false,
|
||||
empty: true,
|
||||
tgt: "\tfoo\n\tbar\n\tbaz\n\t",
|
||||
},
|
||||
testIndentSet{
|
||||
name: "standard, trailing newline with ws",
|
||||
orig: "foo\nbar\nbaz\n",
|
||||
indent: "",
|
||||
lvl: 1,
|
||||
ws: true,
|
||||
empty: false,
|
||||
tgt: "\tfoo\n\tbar\n\tbaz\n",
|
||||
},
|
||||
testIndentSet{
|
||||
name: "standard, trailing newline with ws and empty",
|
||||
orig: "foo\nbar\nbaz\n",
|
||||
indent: "",
|
||||
lvl: 1,
|
||||
ws: true,
|
||||
empty: true,
|
||||
tgt: "\tfoo\n\tbar\n\tbaz\n\t",
|
||||
},
|
||||
testIndentSet{
|
||||
name: "standard, trailing ws newline with empty",
|
||||
orig: "foo\nbar\nbaz\n ",
|
||||
indent: "",
|
||||
lvl: 1,
|
||||
ws: false,
|
||||
empty: true,
|
||||
tgt: "\tfoo\n\tbar\n\tbaz\n ",
|
||||
},
|
||||
testIndentSet{
|
||||
name: "standard, trailing ws newline with ws",
|
||||
orig: "foo\nbar\nbaz\n ",
|
||||
indent: "",
|
||||
lvl: 1,
|
||||
ws: true,
|
||||
empty: false,
|
||||
tgt: "\tfoo\n\tbar\n\tbaz\n\t ",
|
||||
},
|
||||
testIndentSet{
|
||||
name: "standard, trailing ws newline with ws and empty",
|
||||
orig: "foo\nbar\nbaz\n \n",
|
||||
indent: "",
|
||||
lvl: 1,
|
||||
ws: true,
|
||||
empty: true,
|
||||
tgt: "\tfoo\n\tbar\n\tbaz\n\t \n\t",
|
||||
},
|
||||
testIndentSet{
|
||||
name: "comment",
|
||||
orig: "foo\nbar\nbaz",
|
||||
indent: "# ",
|
||||
lvl: 1,
|
||||
ws: false,
|
||||
empty: false,
|
||||
tgt: "# foo\n# bar\n# baz",
|
||||
},
|
||||
}
|
||||
|
||||
for idx, ts := range tests {
|
||||
out = Indent(ts.orig, ts.indent, ts.lvl, ts.ws, ts.empty)
|
||||
if out == ts.tgt {
|
||||
t.Logf("[%d] OK (%s): %#v: got %#v", idx, ts.name, ts.orig, out)
|
||||
} else {
|
||||
t.Errorf(
|
||||
"[%d] FAIL (%s): %#v (len %d):\n"+
|
||||
"\t\t\texpected (len %d): %#v\n"+
|
||||
"\t\t\tgot (len %d): %#v\n"+
|
||||
"\t\t%#v",
|
||||
idx, ts.name, ts.orig, len(ts.orig),
|
||||
len(ts.tgt), ts.tgt,
|
||||
len(out), out,
|
||||
ts,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestRedact(t *testing.T) {
|
||||
|
||||
var out string
|
||||
var tests []testRedactSet = []testRedactSet{
|
||||
testRedactSet{
|
||||
name: "empty in, empty out",
|
||||
orig: "",
|
||||
leading: 0,
|
||||
trailing: 0,
|
||||
tgt: "",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "standard",
|
||||
orig: "password",
|
||||
leading: 0,
|
||||
trailing: 0,
|
||||
tgt: "************************",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "standard with newline",
|
||||
orig: "pass\nword",
|
||||
leading: 0,
|
||||
trailing: 0,
|
||||
tgt: "************\n************",
|
||||
newline: true,
|
||||
},
|
||||
testRedactSet{
|
||||
name: "standard with Windows newline",
|
||||
orig: "pass\r\nword",
|
||||
leading: 0,
|
||||
trailing: 0,
|
||||
tgt: "************\r\n************",
|
||||
newline: true,
|
||||
},
|
||||
testRedactSet{
|
||||
name: "standard with newline without newlines",
|
||||
orig: "pass\nword",
|
||||
leading: 0,
|
||||
trailing: 0,
|
||||
tgt: "***************************",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "single leading",
|
||||
orig: "password",
|
||||
leading: 1,
|
||||
trailing: 0,
|
||||
tgt: "p*********************",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "single trailing",
|
||||
orig: "password",
|
||||
leading: 0,
|
||||
trailing: 1,
|
||||
tgt: "*********************d",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "three leading",
|
||||
orig: "password",
|
||||
leading: 3,
|
||||
trailing: 0,
|
||||
tgt: "pas***************",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "three trailing",
|
||||
orig: "password",
|
||||
leading: 0,
|
||||
trailing: 3,
|
||||
tgt: "***************ord",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "three leading and trailing",
|
||||
orig: "password",
|
||||
leading: 3,
|
||||
trailing: 3,
|
||||
tgt: "pas******ord",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "unmask overflow leading",
|
||||
orig: "password",
|
||||
leading: 5,
|
||||
trailing: 4,
|
||||
tgt: "************************",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "unmask overflow trailing",
|
||||
orig: "password",
|
||||
leading: 4,
|
||||
trailing: 5,
|
||||
tgt: "************************",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "single mask",
|
||||
orig: "password",
|
||||
leading: 0,
|
||||
trailing: 0,
|
||||
tgt: "********",
|
||||
mask: "*",
|
||||
},
|
||||
testRedactSet{
|
||||
name: "standard trailing newline with newlines",
|
||||
orig: "password\n",
|
||||
leading: 0,
|
||||
trailing: 0,
|
||||
tgt: "************************\n",
|
||||
newline: true,
|
||||
},
|
||||
testRedactSet{
|
||||
name: "standard trailing newline without newlines",
|
||||
orig: "password\n",
|
||||
leading: 0,
|
||||
trailing: 0,
|
||||
tgt: "***************************",
|
||||
},
|
||||
}
|
||||
|
||||
for idx, ts := range tests {
|
||||
out = Redact(ts.orig, ts.mask, ts.leading, ts.trailing, ts.newline)
|
||||
if out == ts.tgt {
|
||||
t.Logf("[%d] OK (%s): %#v: got %#v", idx, ts.name, ts.orig, out)
|
||||
} else {
|
||||
t.Errorf(
|
||||
"[%d] FAIL (%s): %#v (len %d):\n"+
|
||||
"\t\t\texpected (len %d): %#v\n"+
|
||||
"\t\t\tgot (len %d): %#v\n"+
|
||||
"\t\t%#v",
|
||||
idx, ts.name, ts.orig, len(ts.orig),
|
||||
len(ts.tgt), ts.tgt,
|
||||
len(out), out,
|
||||
ts,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrimLines(t *testing.T) {
|
||||
|
||||
var out string
|
||||
var tests []testTrimLinesSet = []testTrimLinesSet{
|
||||
testTrimLinesSet{
|
||||
name: "none",
|
||||
orig: " foo \n bar \n baz ",
|
||||
left: false,
|
||||
right: false,
|
||||
tgt: " foo \n bar \n baz ",
|
||||
},
|
||||
testTrimLinesSet{
|
||||
name: "standard",
|
||||
orig: " foo \n bar \n baz ",
|
||||
left: true,
|
||||
right: true,
|
||||
tgt: "foo\nbar\nbaz",
|
||||
},
|
||||
testTrimLinesSet{
|
||||
name: "left only",
|
||||
orig: " foo \n bar \n baz ",
|
||||
left: true,
|
||||
right: false,
|
||||
tgt: "foo \nbar \nbaz ",
|
||||
},
|
||||
testTrimLinesSet{
|
||||
name: "right only",
|
||||
orig: " foo \n bar \n baz ",
|
||||
left: false,
|
||||
right: true,
|
||||
tgt: " foo\n bar\n baz",
|
||||
},
|
||||
testTrimLinesSet{
|
||||
name: "standard, trailing newline",
|
||||
orig: " foo \n bar \n baz \n",
|
||||
left: true,
|
||||
right: true,
|
||||
tgt: "foo\nbar\nbaz\n",
|
||||
},
|
||||
testTrimLinesSet{
|
||||
name: "left only, trailing newline",
|
||||
orig: " foo \n bar \n baz \n",
|
||||
left: true,
|
||||
right: false,
|
||||
tgt: "foo \nbar \nbaz \n",
|
||||
},
|
||||
testTrimLinesSet{
|
||||
name: "right only, trailing newline",
|
||||
orig: " foo \n bar \n baz \n",
|
||||
left: false,
|
||||
right: true,
|
||||
tgt: " foo\n bar\n baz\n",
|
||||
},
|
||||
// Since there's no "non-space" boundary, both of these condition tests do the same thing.
|
||||
testTrimLinesSet{
|
||||
name: "left only, trailing newline and ws",
|
||||
orig: " foo \n bar \n baz \n ",
|
||||
left: true,
|
||||
right: false,
|
||||
tgt: "foo \nbar \nbaz \n",
|
||||
},
|
||||
testTrimLinesSet{
|
||||
name: "right only, trailing newline and ws",
|
||||
orig: " foo \n bar \n baz \n ",
|
||||
left: false,
|
||||
right: true,
|
||||
tgt: " foo\n bar\n baz\n",
|
||||
},
|
||||
}
|
||||
|
||||
for idx, ts := range tests {
|
||||
out = TrimLines(ts.orig, ts.left, ts.right)
|
||||
if out == ts.tgt {
|
||||
t.Logf("[%d] OK (%s): %#v: got %#v", idx, ts.name, ts.orig, out)
|
||||
} else {
|
||||
t.Errorf(
|
||||
"[%d] FAIL (%s): %#v (len %d):\n"+
|
||||
"\t\t\texpected (len %d): %#v\n"+
|
||||
"\t\t\tgot (len %d): %#v\n"+
|
||||
"\t\t%#v",
|
||||
idx, ts.name, ts.orig, len(ts.orig),
|
||||
len(ts.tgt), ts.tgt,
|
||||
len(out), out,
|
||||
ts,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestTrimSpaceLeft(t *testing.T) {
|
||||
|
||||
var out string
|
||||
var tests []testTrimSet = []testTrimSet{
|
||||
testTrimSet{
|
||||
name: "standard",
|
||||
orig: " foo ",
|
||||
tgt: "foo ",
|
||||
},
|
||||
testTrimSet{
|
||||
name: "tabs",
|
||||
orig: "\t\tfoo\t\t",
|
||||
tgt: "foo\t\t",
|
||||
},
|
||||
testTrimSet{
|
||||
name: "newlines",
|
||||
orig: "\n\nfoo\n\n",
|
||||
tgt: "foo\n\n",
|
||||
},
|
||||
}
|
||||
|
||||
for idx, ts := range tests {
|
||||
out = TrimSpaceLeft(ts.orig)
|
||||
if out == ts.tgt {
|
||||
t.Logf("[%d] OK (%s): %#v: got %#v", idx, ts.name, ts.orig, out)
|
||||
} else {
|
||||
t.Errorf(
|
||||
"[%d] FAIL (%s): %#v (len %d):\n"+
|
||||
"\t\t\texpected (len %d): %#v\n"+
|
||||
"\t\t\tgot (len %d): %#v\n"+
|
||||
"\t\t%#v",
|
||||
idx, ts.name, ts.orig, len(ts.orig),
|
||||
len(ts.tgt), ts.tgt,
|
||||
len(out), out,
|
||||
ts,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestTrimSpaceRight(t *testing.T) {
|
||||
|
||||
var out string
|
||||
var tests []testTrimSet = []testTrimSet{
|
||||
testTrimSet{
|
||||
name: "standard",
|
||||
orig: " foo ",
|
||||
tgt: " foo",
|
||||
},
|
||||
testTrimSet{
|
||||
name: "tabs",
|
||||
orig: "\t\tfoo\t\t",
|
||||
tgt: "\t\tfoo",
|
||||
},
|
||||
testTrimSet{
|
||||
name: "newlines",
|
||||
orig: "\n\nfoo\n\n",
|
||||
tgt: "\n\nfoo",
|
||||
},
|
||||
}
|
||||
|
||||
for idx, ts := range tests {
|
||||
out = TrimSpaceRight(ts.orig)
|
||||
if out == ts.tgt {
|
||||
t.Logf("[%d] OK (%s): %#v: got %#v", idx, ts.name, ts.orig, out)
|
||||
} else {
|
||||
t.Errorf(
|
||||
"[%d] FAIL (%s): %#v (len %d):\n"+
|
||||
"\t\t\texpected (len %d): %#v\n"+
|
||||
"\t\t\tgot (len %d): %#v\n"+
|
||||
"\t\t%#v",
|
||||
idx, ts.name, ts.orig, len(ts.orig),
|
||||
len(ts.tgt), ts.tgt,
|
||||
len(out), out,
|
||||
ts,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user