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 )
}
for k , _ := range actual {
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 )
}
for k , _ := range actual {
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
}
for k , _ := range actual {
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
}
for k , _ := range actual {
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 )
}
for k , _ := range actual {
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 )
}
for k , _ := range actual {
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 )
}
for k , _ := range actual {
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 )
}
for k , _ := range actual {
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 {
tCase { "" , "" , true } ,
tCase { "*" , "*" , true } ,
tCase { "**" , "**" , true } ,
tCase { "*t" , "t" , true } ,
tCase { "*t" , "test" , true } ,
tCase { "t*" , "test" , true } ,
tCase { "*test" , "test" , true } ,
tCase { "*test" , "a test" , true } ,
tCase { "test" , "a test" , false } ,
tCase { "*test" , "tests" , false } ,
tCase { "test*" , "test" , true } ,
tCase { "test*" , "testsss" , true } ,
tCase { "test**" , "testsss" , false } ,
tCase { "test**" , "test*" , true } ,
tCase { "**test" , "*test" , true } ,
tCase { "TEST" , "test" , false } ,
tCase { "test" , "test" , true } ,
}
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
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 {
tCase { [ ] string { } , [ ] string { } , false } ,
tCase { [ ] string { } , [ ] string { } , true } ,
tCase { [ ] string { "a" , "b" , "a" } , [ ] string { "a" , "b" } , false } ,
tCase { [ ] string { "A" , "b" , "a" } , [ ] string { "A" , "a" , "b" } , false } ,
tCase { [ ] string { "A" , "b" , "a" } , [ ] string { "a" , "b" } , true } ,
}
for _ , tc := range tCases {
actual := RemoveDuplicates ( tc . input , tc . lowercase )
if ! reflect . DeepEqual ( actual , tc . expect ) {
t . Fatalf ( "Bad testcase %#v, expected %v, got %v" , tc , tc . expect , actual )
}
}
}