automation-tests/common/internal/attributed-string-slice/attributed_string_slice_tes...

128 lines
4.8 KiB
Go

package attributedstringslice
import (
"bytes"
"testing"
"github.com/BurntSushi/toml"
"github.com/stretchr/testify/require"
)
type testConfig struct {
Array attributedStringSlice `toml:"array,omitempty"`
}
const (
confingDefault = `array=["1", "2", "3"]`
configAppendFront = `array=[{append=true},"4", "5", "6"]`
configAppendMid = `array=["7", {append=true}, "8"]`
configAppendBack = `array=["9", {append=true}]`
configAppendFalse = `array=["10", {append=false}]`
)
var (
bTrue = true
bFalse = false
)
func loadConfigs(configs []string) (*testConfig, error) {
var config testConfig
for _, c := range configs {
if _, err := toml.Decode(c, &config); err != nil {
return nil, err
}
}
return &config, nil
}
func TestAttributedStringSliceLoading(t *testing.T) {
for _, test := range []struct {
configs []string
expectedSlice []string
expectedAppend *bool
expectedErrorSubstring string
}{
// Load single configs
{[]string{confingDefault}, []string{"1", "2", "3"}, nil, ""},
{[]string{configAppendFront}, []string{"4", "5", "6"}, &bTrue, ""},
{[]string{configAppendMid}, []string{"7", "8"}, &bTrue, ""},
{[]string{configAppendBack}, []string{"9"}, &bTrue, ""},
{[]string{configAppendFalse}, []string{"10"}, &bFalse, ""},
// Append=true
{[]string{confingDefault, configAppendFront}, []string{"1", "2", "3", "4", "5", "6"}, &bTrue, ""},
{[]string{configAppendFront, confingDefault}, []string{"4", "5", "6", "1", "2", "3"}, &bTrue, ""}, // The attribute is sticky unless explicitly being turned off in a later config
{[]string{configAppendFront, confingDefault, configAppendBack}, []string{"4", "5", "6", "1", "2", "3", "9"}, &bTrue, ""},
// Append=false
{[]string{confingDefault, configAppendFalse}, []string{"10"}, &bFalse, ""},
{[]string{confingDefault, configAppendMid, configAppendFalse}, []string{"10"}, &bFalse, ""},
{[]string{confingDefault, configAppendFalse, configAppendMid}, []string{"10", "7", "8"}, &bTrue, ""}, // Append can be re-enabled by a later config
// Error checks
{[]string{`array=["1", false]`}, nil, nil, `unsupported item in attributed string slice: false`},
{[]string{`array=["1", 42]`}, nil, nil, `unsupported item in attributed string slice: 42`}, // Stop a `int` such that it passes on 32bit as well
{[]string{`array=["1", {foo=true}]`}, nil, nil, `unsupported key "foo" in map: `},
{[]string{`array=["1", {append="false"}]`}, nil, nil, `unable to cast append to bool: `},
} {
result, err := loadConfigs(test.configs)
if test.expectedErrorSubstring != "" {
require.Error(t, err, "test is expected to fail: %v", test)
require.ErrorContains(t, err, test.expectedErrorSubstring, "error does not match: %v", test)
continue
}
require.NoError(t, err, "test is expected to succeed: %v", test)
require.NotNil(t, result, "loaded config must not be nil: %v", test)
require.Equal(t, result.Array.slice, test.expectedSlice, "slices do not match: %v", test)
require.Equal(t, result.Array.attributes.append, test.expectedAppend, "append field does not match: %v", test)
}
}
func TestAttributedStringSliceEncoding(t *testing.T) {
for _, test := range []struct {
configs []string
marshalledData string
expectedSlice []string
expectedAppend *bool
}{
{
[]string{confingDefault},
"array = [\"1\", \"2\", \"3\"]\n",
[]string{"1", "2", "3"},
nil,
},
{
[]string{configAppendFront},
"array = [\"4\", \"5\", \"6\", {append = true}]\n",
[]string{"4", "5", "6"},
&bTrue,
},
{
[]string{configAppendFront, configAppendFalse},
"array = [\"10\", {append = false}]\n",
[]string{"10"},
&bFalse,
},
} {
// 1) Load the configs
result, err := loadConfigs(test.configs)
require.NoError(t, err, "loading config must succeed")
require.NotNil(t, result, "loaded config must not be nil")
require.Equal(t, result.Array.slice, test.expectedSlice, "slices do not match: %v", test)
require.Equal(t, result.Array.attributes.append, test.expectedAppend, "append field does not match: %v", test)
// 2) Marshal the config to emulate writing it to disk
buf := new(bytes.Buffer)
enc := toml.NewEncoder(buf)
encErr := enc.Encode(result)
require.NoError(t, encErr, "encoding config must work")
require.Equal(t, buf.String(), test.marshalledData)
// 3) Reload the marshaled config to make sure that data is preserved
var reloadedConfig testConfig
_, decErr := toml.Decode(buf.String(), &reloadedConfig)
require.NoError(t, decErr, "loading config must succeed")
require.NotNil(t, reloadedConfig, "re-loaded config must not be nil")
require.Equal(t, reloadedConfig.Array.slice, test.expectedSlice, "slices do not match: %v", test)
require.Equal(t, reloadedConfig.Array.attributes.append, test.expectedAppend, "append field does not match: %v", test)
}
}