128 lines
4.8 KiB
Go
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)
|
|
}
|
|
}
|