2016-04-06 00:30:38 +00:00
package strutil
2016-05-30 18:30:01 +00:00
import (
"encoding/base64"
2016-08-03 18:57:36 +00:00
"encoding/json"
2016-05-30 18:30:01 +00:00
"reflect"
"testing"
)
2016-04-06 00:30:38 +00:00
2016-12-16 05:36:39 +00:00
func TestStrUtil_StrListDelete ( t * testing . T ) {
output := StrListDelete ( [ ] string { "item1" , "item2" , "item3" } , "item1" )
if StrListContains ( output , "item1" ) {
t . Fatal ( "bad: 'item1' should not have been present" )
}
output = StrListDelete ( [ ] string { "item1" , "item2" , "item3" } , "item2" )
if StrListContains ( output , "item2" ) {
t . Fatal ( "bad: 'item2' should not have been present" )
}
output = StrListDelete ( [ ] string { "item1" , "item2" , "item3" } , "item3" )
if StrListContains ( output , "item3" ) {
t . Fatal ( "bad: 'item3' should not have been present" )
}
output = StrListDelete ( [ ] string { "item1" , "item1" , "item3" } , "item1" )
if ! StrListContains ( output , "item1" ) {
t . Fatal ( "bad: 'item1' should have been present" )
}
output = StrListDelete ( output , "item1" )
if StrListContains ( output , "item1" ) {
t . Fatal ( "bad: 'item1' should not have been present" )
}
output = StrListDelete ( output , "random" )
if len ( output ) != 1 {
2016-12-21 18:08:27 +00:00
t . Fatalf ( "bad: expected: 1, actual: %d" , len ( output ) )
2016-12-16 05:36:39 +00:00
}
output = StrListDelete ( output , "item3" )
if StrListContains ( output , "item3" ) {
t . Fatal ( "bad: 'item3' should not have been present" )
}
}
2016-07-22 12:44:16 +00:00
func TestStrutil_EquivalentSlices ( t * testing . T ) {
2016-07-22 14:21:45 +00:00
slice1 := [ ] string { "test2" , "test1" , "test3" }
slice2 := [ ] string { "test3" , "test2" , "test1" }
2016-07-22 12:44:16 +00:00
if ! EquivalentSlices ( slice1 , slice2 ) {
t . Fatalf ( "bad: expected a match" )
}
slice2 = append ( slice2 , "test4" )
if EquivalentSlices ( slice1 , slice2 ) {
t . Fatalf ( "bad: expected a mismatch" )
}
}
2017-10-30 20:24:25 +00:00
func TestStrutil_ListContainsGlob ( t * testing . T ) {
haystack := [ ] string {
"dev" ,
"ops*" ,
"root/*" ,
"*-dev" ,
"_*_" ,
}
if StrListContainsGlob ( haystack , "tubez" ) {
t . Fatalf ( "Value shouldn't exist" )
}
if ! StrListContainsGlob ( haystack , "root/test" ) {
t . Fatalf ( "Value should exist" )
}
if ! StrListContainsGlob ( haystack , "ops_test" ) {
t . Fatalf ( "Value should exist" )
}
if ! StrListContainsGlob ( haystack , "ops" ) {
t . Fatalf ( "Value should exist" )
}
if ! StrListContainsGlob ( haystack , "dev" ) {
t . Fatalf ( "Value should exist" )
}
if ! StrListContainsGlob ( haystack , "test-dev" ) {
t . Fatalf ( "Value should exist" )
}
if ! StrListContainsGlob ( haystack , "_test_" ) {
t . Fatalf ( "Value should exist" )
}
}
2016-05-30 18:30:01 +00:00
func TestStrutil_ListContains ( t * testing . T ) {
2016-04-06 00:30:38 +00:00
haystack := [ ] string {
"dev" ,
"ops" ,
"prod" ,
"root" ,
}
if StrListContains ( haystack , "tubez" ) {
t . Fatalf ( "Bad" )
}
if ! StrListContains ( haystack , "root" ) {
t . Fatalf ( "Bad" )
}
}
2016-05-30 18:30:01 +00:00
func TestStrutil_ListSubset ( t * testing . T ) {
2016-04-06 00:30:38 +00:00
parent := [ ] string {
"dev" ,
"ops" ,
"prod" ,
"root" ,
}
child := [ ] string {
"prod" ,
"ops" ,
}
if ! StrListSubset ( parent , child ) {
t . Fatalf ( "Bad" )
}
if ! StrListSubset ( parent , parent ) {
t . Fatalf ( "Bad" )
}
if ! StrListSubset ( child , child ) {
t . Fatalf ( "Bad" )
}
if ! StrListSubset ( child , nil ) {
t . Fatalf ( "Bad" )
}
if StrListSubset ( child , parent ) {
t . Fatalf ( "Bad" )
}
if StrListSubset ( nil , child ) {
t . Fatalf ( "Bad" )
}
}
2016-05-30 18:30:01 +00:00
func TestStrutil_ParseKeyValues ( t * testing . T ) {
actual := make ( map [ string ] string )
expected := map [ string ] string {
"key1" : "value1" ,
"key2" : "value2" ,
}
var input string
var err error
input = "key1=value1,key2=value2"
2016-08-03 18:18:22 +00:00
err = ParseKeyValues ( input , actual , "," )
2016-05-30 18:30:01 +00:00
if err != nil {
t . Fatal ( err )
}
if ! reflect . DeepEqual ( expected , actual ) {
t . Fatalf ( "bad: expected: %#v\nactual: %#v" , expected , actual )
}
2021-04-08 16:43:39 +00:00
for k := range actual {
2016-05-30 18:30:01 +00:00
delete ( actual , k )
}
input = "key1 = value1, key2 = value2"
2016-08-03 18:18:22 +00:00
err = ParseKeyValues ( input , actual , "," )
2016-05-30 18:30:01 +00:00
if err != nil {
t . Fatal ( err )
}
if ! reflect . DeepEqual ( expected , actual ) {
t . Fatalf ( "bad: expected: %#v\nactual: %#v" , expected , actual )
}
2021-04-08 16:43:39 +00:00
for k := range actual {
2016-05-30 18:30:01 +00:00
delete ( actual , k )
}
input = "key1 = value1, key2 = "
2016-08-03 18:18:22 +00:00
err = ParseKeyValues ( input , actual , "," )
2016-05-30 18:30:01 +00:00
if err == nil {
2017-05-18 01:47:13 +00:00
t . Fatalf ( "expected an error" )
2016-05-30 18:30:01 +00:00
}
2021-04-08 16:43:39 +00:00
for k := range actual {
2016-05-30 18:30:01 +00:00
delete ( actual , k )
}
input = "key1 = value1, = value2 "
2016-08-03 18:18:22 +00:00
err = ParseKeyValues ( input , actual , "," )
2016-05-30 18:30:01 +00:00
if err == nil {
2017-05-18 01:47:13 +00:00
t . Fatalf ( "expected an error" )
2016-05-30 18:30:01 +00:00
}
2021-04-08 16:43:39 +00:00
for k := range actual {
2016-05-30 18:30:01 +00:00
delete ( actual , k )
}
2017-05-18 01:47:13 +00:00
input = "key1"
err = ParseKeyValues ( input , actual , "," )
if err == nil {
t . Fatalf ( "expected an error" )
}
2016-05-30 18:30:01 +00:00
}
func TestStrutil_ParseArbitraryKeyValues ( t * testing . T ) {
actual := make ( map [ string ] string )
expected := map [ string ] string {
"key1" : "value1" ,
"key2" : "value2" ,
}
var input string
var err error
// Test <key>=<value> as comma separated string
input = "key1=value1,key2=value2"
2016-08-03 18:18:22 +00:00
err = ParseArbitraryKeyValues ( input , actual , "," )
2016-05-30 18:30:01 +00:00
if err != nil {
t . Fatal ( err )
}
if ! reflect . DeepEqual ( expected , actual ) {
t . Fatalf ( "bad: expected: %#v\nactual: %#v" , expected , actual )
}
2021-04-08 16:43:39 +00:00
for k := range actual {
2016-05-30 18:30:01 +00:00
delete ( actual , k )
}
// Test <key>=<value> as base64 encoded comma separated string
input = base64 . StdEncoding . EncodeToString ( [ ] byte ( input ) )
2016-08-03 18:18:22 +00:00
err = ParseArbitraryKeyValues ( input , actual , "," )
2016-05-30 18:30:01 +00:00
if err != nil {
t . Fatal ( err )
}
if ! reflect . DeepEqual ( expected , actual ) {
t . Fatalf ( "bad: expected: %#v\nactual: %#v" , expected , actual )
}
2021-04-08 16:43:39 +00:00
for k := range actual {
2016-05-30 18:30:01 +00:00
delete ( actual , k )
}
// Test JSON encoded <key>=<value> tuples
input = ` { "key1":"value1", "key2":"value2"} `
2016-08-03 18:18:22 +00:00
err = ParseArbitraryKeyValues ( input , actual , "," )
2016-05-30 18:30:01 +00:00
if err != nil {
t . Fatal ( err )
}
if ! reflect . DeepEqual ( expected , actual ) {
t . Fatalf ( "bad: expected: %#v\nactual: %#v" , expected , actual )
}
2021-04-08 16:43:39 +00:00
for k := range actual {
2016-05-30 18:30:01 +00:00
delete ( actual , k )
}
// Test base64 encoded JSON string of <key>=<value> tuples
input = base64 . StdEncoding . EncodeToString ( [ ] byte ( input ) )
2016-08-03 18:18:22 +00:00
err = ParseArbitraryKeyValues ( input , actual , "," )
2016-05-30 18:30:01 +00:00
if err != nil {
t . Fatal ( err )
}
if ! reflect . DeepEqual ( expected , actual ) {
t . Fatalf ( "bad: expected: %#v\nactual: %#v" , expected , actual )
}
2021-04-08 16:43:39 +00:00
for k := range actual {
2016-05-30 18:30:01 +00:00
delete ( actual , k )
}
}
2016-08-03 18:57:36 +00:00
func TestStrutil_ParseArbitraryStringSlice ( t * testing . T ) {
input := ` CREATE ROLE " {{ name }} " WITH LOGIN PASSWORD ' {{ password }} ' VALID UNTIL ' {{ expiration }} ';GRANT "foo-role" TO " {{ name }} ";ALTER ROLE " {{ name }} " SET search_path = foo;GRANT CONNECT ON DATABASE "postgres" TO " {{ name }} "; `
jsonExpected := [ ] string {
` DO $ $
BEGIN
IF NOT EXISTS ( SELECT * FROM pg_catalog . pg_roles WHERE rolname = ' foo - role ' ) THEN
CREATE ROLE "foo-role" ;
CREATE SCHEMA IF NOT EXISTS foo AUTHORIZATION "foo-role" ;
ALTER ROLE "foo-role" SET search_path = foo ;
GRANT TEMPORARY ON DATABASE "postgres" TO "foo-role" ;
GRANT ALL PRIVILEGES ON SCHEMA foo TO "foo-role" ;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA foo TO "foo-role" ;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA foo TO "foo-role" ;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA foo TO "foo-role" ;
END IF ;
END
$ $ ` ,
` CREATE ROLE " {{ name }} " WITH LOGIN PASSWORD ' {{ password }} ' VALID UNTIL ' {{ expiration }} ' ` ,
` GRANT "foo-role" TO " {{ name }} " ` ,
` ALTER ROLE " {{ name }} " SET search_path = foo ` ,
` GRANT CONNECT ON DATABASE "postgres" TO " {{ name }} " ` ,
` ` ,
}
nonJSONExpected := jsonExpected [ 1 : ]
var actual [ ] string
var inputB64 string
var err error
// Test non-JSON string
actual = ParseArbitraryStringSlice ( input , ";" )
if ! reflect . DeepEqual ( nonJSONExpected , actual ) {
t . Fatalf ( "bad: expected:\n%#v\nactual:\n%#v" , nonJSONExpected , actual )
}
// Test base64-encoded non-JSON string
inputB64 = base64 . StdEncoding . EncodeToString ( [ ] byte ( input ) )
actual = ParseArbitraryStringSlice ( inputB64 , ";" )
if ! reflect . DeepEqual ( nonJSONExpected , actual ) {
t . Fatalf ( "bad: expected:\n%#v\nactual:\n%#v" , nonJSONExpected , actual )
}
// Test JSON encoded
inputJSON , err := json . Marshal ( jsonExpected )
if err != nil {
t . Fatal ( err )
}
actual = ParseArbitraryStringSlice ( string ( inputJSON ) , ";" )
if ! reflect . DeepEqual ( jsonExpected , actual ) {
t . Fatalf ( "bad: expected:\n%#v\nactual:\n%#v" , string ( inputJSON ) , actual )
}
// Test base64 encoded JSON string of <key>=<value> tuples
inputB64 = base64 . StdEncoding . EncodeToString ( inputJSON )
actual = ParseArbitraryStringSlice ( inputB64 , ";" )
if ! reflect . DeepEqual ( jsonExpected , actual ) {
t . Fatalf ( "bad: expected:\n%#v\nactual:\n%#v" , jsonExpected , actual )
}
}
2017-03-03 22:50:55 +00:00
func TestGlobbedStringsMatch ( t * testing . T ) {
type tCase struct {
item string
val string
expect bool
}
tCases := [ ] tCase {
2021-04-08 16:43:39 +00:00
{ "" , "" , true } ,
{ "*" , "*" , true } ,
{ "**" , "**" , true } ,
{ "*t" , "t" , true } ,
{ "*t" , "test" , true } ,
{ "t*" , "test" , true } ,
{ "*test" , "test" , true } ,
{ "*test" , "a test" , true } ,
{ "test" , "a test" , false } ,
{ "*test" , "tests" , false } ,
{ "test*" , "test" , true } ,
{ "test*" , "testsss" , true } ,
{ "test**" , "testsss" , false } ,
{ "test**" , "test*" , true } ,
{ "**test" , "*test" , true } ,
{ "TEST" , "test" , false } ,
{ "test" , "test" , true } ,
2017-03-03 22:50:55 +00:00
}
for _ , tc := range tCases {
actual := GlobbedStringsMatch ( tc . item , tc . val )
if actual != tc . expect {
2018-02-05 01:37:57 +00:00
t . Fatalf ( "Bad testcase %#v, expected %t, got %t" , tc , tc . expect , actual )
2017-03-03 22:50:55 +00:00
}
}
}
2017-04-18 20:02:31 +00:00
func TestTrimStrings ( t * testing . T ) {
input := [ ] string { "abc" , "123" , "abcd " , "123 " }
expected := [ ] string { "abc" , "123" , "abcd" , "123" }
actual := TrimStrings ( input )
if ! reflect . DeepEqual ( expected , actual ) {
t . Fatalf ( "Bad TrimStrings: expected:%#v, got:%#v" , expected , actual )
}
}
2017-06-16 15:09:15 +00:00
2018-12-14 14:12:26 +00:00
func TestRemoveEmpty ( t * testing . T ) {
input := [ ] string { "abc" , "" , "abc" , "" }
expected := [ ] string { "abc" , "abc" }
actual := RemoveEmpty ( input )
if ! reflect . DeepEqual ( expected , actual ) {
t . Fatalf ( "Bad TrimStrings: expected:%#v, got:%#v" , expected , actual )
}
input = [ ] string { "" }
expected = [ ] string { }
actual = RemoveEmpty ( input )
if ! reflect . DeepEqual ( expected , actual ) {
t . Fatalf ( "Bad TrimStrings: expected:%#v, got:%#v" , expected , actual )
}
}
2017-06-16 15:09:15 +00:00
func TestStrutil_AppendIfMissing ( t * testing . T ) {
keys := [ ] string { }
keys = AppendIfMissing ( keys , "foo" )
if len ( keys ) != 1 {
t . Fatalf ( "expected slice to be length of 1: %v" , keys )
}
if keys [ 0 ] != "foo" {
t . Fatalf ( "expected slice to contain key 'foo': %v" , keys )
}
keys = AppendIfMissing ( keys , "bar" )
if len ( keys ) != 2 {
t . Fatalf ( "expected slice to be length of 2: %v" , keys )
}
if keys [ 0 ] != "foo" {
t . Fatalf ( "expected slice to contain key 'foo': %v" , keys )
}
if keys [ 1 ] != "bar" {
t . Fatalf ( "expected slice to contain key 'bar': %v" , keys )
}
keys = AppendIfMissing ( keys , "foo" )
if len ( keys ) != 2 {
t . Fatalf ( "expected slice to still be length of 2: %v" , keys )
}
if keys [ 0 ] != "foo" {
t . Fatalf ( "expected slice to still contain key 'foo': %v" , keys )
}
if keys [ 1 ] != "bar" {
t . Fatalf ( "expected slice to still contain key 'bar': %v" , keys )
}
}
2018-01-17 16:53:49 +00:00
func TestStrUtil_RemoveDuplicates ( t * testing . T ) {
type tCase struct {
input [ ] string
expect [ ] string
lowercase bool
}
tCases := [ ] tCase {
2021-04-08 16:43:39 +00:00
{ [ ] string { } , [ ] string { } , false } ,
{ [ ] string { } , [ ] string { } , true } ,
{ [ ] string { "a" , "b" , "a" } , [ ] string { "a" , "b" } , false } ,
{ [ ] string { "A" , "b" , "a" } , [ ] string { "A" , "a" , "b" } , false } ,
{ [ ] string { "A" , "b" , "a" } , [ ] string { "a" , "b" } , true } ,
2018-01-17 16:53:49 +00:00
}
for _ , tc := range tCases {
actual := RemoveDuplicates ( tc . input , tc . lowercase )
2019-05-02 21:31:29 +00:00
if ! reflect . DeepEqual ( actual , tc . expect ) {
t . Fatalf ( "Bad testcase %#v, expected %v, got %v" , tc , tc . expect , actual )
}
}
}
func TestStrUtil_RemoveDuplicatesStable ( t * testing . T ) {
type tCase struct {
input [ ] string
expect [ ] string
caseInsensitive bool
}
tCases := [ ] tCase {
2021-04-08 16:43:39 +00:00
{ [ ] string { } , [ ] string { } , false } ,
{ [ ] string { } , [ ] string { } , true } ,
{ [ ] string { "a" , "b" , "a" } , [ ] string { "a" , "b" } , false } ,
{ [ ] string { "A" , "b" , "a" } , [ ] string { "A" , "b" , "a" } , false } ,
{ [ ] string { "A" , "b" , "a" } , [ ] string { "A" , "b" } , true } ,
{ [ ] string { " " , "d" , "c" , "d" } , [ ] string { "d" , "c" } , false } ,
{ [ ] string { "Z " , " z" , " z " , "y" } , [ ] string { "Z " , "y" } , true } ,
{ [ ] string { "Z " , " z" , " z " , "y" } , [ ] string { "Z " , " z" , "y" } , false } ,
2019-05-02 21:31:29 +00:00
}
for _ , tc := range tCases {
actual := RemoveDuplicatesStable ( tc . input , tc . caseInsensitive )
2018-01-17 16:53:49 +00:00
if ! reflect . DeepEqual ( actual , tc . expect ) {
t . Fatalf ( "Bad testcase %#v, expected %v, got %v" , tc , tc . expect , actual )
}
}
}
2018-08-09 18:13:37 +00:00
func TestStrUtil_ParseStringSlice ( t * testing . T ) {
type tCase struct {
input string
sep string
expect [ ] string
}
tCases := [ ] tCase {
2021-04-08 16:43:39 +00:00
{ "" , "" , [ ] string { } } ,
{ " " , "," , [ ] string { } } ,
{ ", " , "," , [ ] string { "" , "" } } ,
{ "a" , "," , [ ] string { "a" } } ,
{ " a, b, c " , "," , [ ] string { "a" , "b" , "c" } } ,
{ " a; b; c " , ";" , [ ] string { "a" , "b" , "c" } } ,
{ " a :: b :: c " , "::" , [ ] string { "a" , "b" , "c" } } ,
2018-08-09 18:13:37 +00:00
}
for _ , tc := range tCases {
actual := ParseStringSlice ( tc . input , tc . sep )
if ! reflect . DeepEqual ( actual , tc . expect ) {
t . Fatalf ( "Bad testcase %#v, expected %v, got %v" , tc , tc . expect , actual )
}
}
}
2018-08-09 20:37:36 +00:00
func TestStrUtil_MergeSlices ( t * testing . T ) {
res := MergeSlices ( [ ] string { "a" , "c" , "d" } , [ ] string { } , [ ] string { "c" , "f" , "a" } , nil , [ ] string { "foo" } )
expect := [ ] string { "a" , "c" , "d" , "f" , "foo" }
if ! reflect . DeepEqual ( res , expect ) {
t . Fatalf ( "expected %v, got %v" , expect , res )
}
}
2018-10-01 19:20:31 +00:00
func TestDifference ( t * testing . T ) {
testCases := [ ] struct {
Name string
SetA [ ] string
SetB [ ] string
Lowercase bool
ExpectedResult [ ] string
} {
{
Name : "case_sensitive" ,
SetA : [ ] string { "a" , "b" , "c" } ,
SetB : [ ] string { "b" , "c" } ,
Lowercase : false ,
ExpectedResult : [ ] string { "a" } ,
} ,
{
Name : "case_insensitive" ,
SetA : [ ] string { "a" , "B" , "c" } ,
SetB : [ ] string { "b" , "C" } ,
Lowercase : true ,
ExpectedResult : [ ] string { "a" } ,
} ,
{
Name : "no_match" ,
SetA : [ ] string { "a" , "b" , "c" } ,
SetB : [ ] string { "d" } ,
Lowercase : false ,
ExpectedResult : [ ] string { "a" , "b" , "c" } ,
} ,
{
Name : "empty_set_a" ,
SetA : [ ] string { } ,
SetB : [ ] string { "d" , "e" } ,
Lowercase : false ,
ExpectedResult : [ ] string { } ,
} ,
{
Name : "empty_set_b" ,
SetA : [ ] string { "a" , "b" } ,
SetB : [ ] string { } ,
Lowercase : false ,
ExpectedResult : [ ] string { "a" , "b" } ,
} ,
}
for _ , tc := range testCases {
t . Run ( tc . Name , func ( t * testing . T ) {
actualResult := Difference ( tc . SetA , tc . SetB , tc . Lowercase )
if ! reflect . DeepEqual ( actualResult , tc . ExpectedResult ) {
t . Fatalf ( "expected %v, got %v" , tc . ExpectedResult , actualResult )
}
} )
}
}
2019-01-23 16:26:50 +00:00
func TestStrUtil_EqualStringMaps ( t * testing . T ) {
m1 := map [ string ] string {
"foo" : "a" ,
}
m2 := map [ string ] string {
"foo" : "a" ,
"bar" : "b" ,
}
var m3 map [ string ] string
m4 := map [ string ] string {
"dog" : "" ,
}
m5 := map [ string ] string {
"cat" : "" ,
}
tests := [ ] struct {
a map [ string ] string
b map [ string ] string
result bool
} {
{ m1 , m1 , true } ,
{ m2 , m2 , true } ,
{ m1 , m2 , false } ,
{ m2 , m1 , false } ,
{ m2 , m2 , true } ,
{ m3 , m1 , false } ,
{ m3 , m3 , true } ,
{ m4 , m5 , false } ,
}
for i , test := range tests {
actual := EqualStringMaps ( test . a , test . b )
if actual != test . result {
t . Fatalf ( "case %d, expected %v, got %v" , i , test . result , actual )
}
}
}
2021-02-04 23:05:56 +00:00
func TestGetString ( t * testing . T ) {
type testCase struct {
m map [ string ] interface { }
key string
expectedStr string
expectErr bool
}
tests := map [ string ] testCase {
"nil map" : {
m : nil ,
key : "foo" ,
expectedStr : "" ,
expectErr : true ,
} ,
"empty key" : {
m : map [ string ] interface { } {
"foo" : "bar" ,
} ,
key : "" ,
expectedStr : "" ,
expectErr : true ,
} ,
"missing key" : {
m : map [ string ] interface { } {
"foo" : "bar" ,
} ,
key : "baz" ,
expectedStr : "" ,
expectErr : false ,
} ,
"value is not a string" : {
m : map [ string ] interface { } {
"foo" : 42 ,
} ,
key : "foo" ,
expectedStr : "" ,
expectErr : true ,
} ,
"happy path" : {
m : map [ string ] interface { } {
"foo" : "bar" ,
} ,
key : "foo" ,
expectedStr : "bar" ,
expectErr : false ,
} ,
}
for name , test := range tests {
t . Run ( name , func ( t * testing . T ) {
actual , err := GetString ( test . m , test . key )
if test . expectErr && err == nil {
t . Fatalf ( "err expected, got nil" )
}
if ! test . expectErr && err != nil {
t . Fatalf ( "no error expected, got: %s" , err )
}
if actual != test . expectedStr {
t . Fatalf ( "Actual: [%s] Expected: [%s]" , actual , test . expectedStr )
}
} )
}
}