Files
akvorado/common/helpers/tests_config.go
Vincent Bernat de65ee6072 tests: introduce helpers.Pos/helpers.Mark
This helps locating the position of a test.
2024-07-01 07:42:36 +02:00

94 lines
2.5 KiB
Go

// SPDX-FileCopyrightText: 2022 Free Mobile
// SPDX-License-Identifier: AGPL-3.0-only
//go:build !release
package helpers
import (
"fmt"
"testing"
"github.com/mitchellh/mapstructure"
"akvorado/common/helpers/yaml"
)
// ConfigurationDecodeCases describes a test case for configuration
// decode. We use functions to return value as the decoding process
// may mutate the configuration.
type ConfigurationDecodeCases []struct {
Description string
Pos Pos
Initial func() interface{} // initial value for configuration
Configuration func() interface{} // configuration to decode
Expected interface{}
Error bool
SkipValidation bool
}
// TestConfigurationDecode helps decoding configuration. It also test decoding from YAML.
func TestConfigurationDecode(t *testing.T, cases ConfigurationDecodeCases, options ...DiffOption) {
t.Helper()
for _, tc := range cases {
for _, fromYAML := range []bool{false, true} {
title := tc.Description
if fromYAML {
title = fmt.Sprintf("%s (from YAML)", title)
if tc.Configuration == nil {
continue
}
}
t.Run(title, func(t *testing.T) {
t.Helper()
var configuration interface{}
if fromYAML {
// Encode and decode with YAML
out, err := yaml.Marshal(tc.Configuration())
if err != nil {
t.Fatalf("%syaml.Marshal() error:\n%+v", tc.Pos, err)
}
if err := yaml.Unmarshal(out, &configuration); err != nil {
t.Fatalf("%syaml.Unmarshal() error:\n%+v", tc.Pos, err)
}
} else {
// Just use as is
configuration = tc.Configuration()
}
got := tc.Initial()
decoder, err := mapstructure.NewDecoder(GetMapStructureDecoderConfig(&got))
if err != nil {
t.Fatalf("%sNewDecoder() error:\n%+v", tc.Pos, err)
}
err = decoder.Decode(configuration)
if err != nil && !tc.Error {
t.Fatalf("%sDecode() error:\n%+v", tc.Pos, err)
} else if tc.Error && err != nil {
return
}
if !tc.SkipValidation {
err = Validate.Struct(got)
if err != nil && !tc.Error {
t.Fatalf("%sValidate() error:\n%+v", tc.Pos, err)
} else if tc.Error && err != nil {
return
}
if tc.Error {
t.Errorf("%sDecode() and Validate() did not error", tc.Pos)
}
} else {
if tc.Error {
t.Errorf("%sDecode() did not error", tc.Pos)
}
}
if diff := Diff(got, tc.Expected, options...); diff != "" && err == nil {
t.Fatalf("%sDecode() (-got, +want):\n%s", tc.Pos, diff)
}
})
}
}
}