129 lines
2.8 KiB
Go
129 lines
2.8 KiB
Go
package templates
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"maps"
|
|
"slices"
|
|
"testing"
|
|
|
|
"github.com/evcc-io/evcc/plugin/auth"
|
|
"github.com/evcc-io/evcc/util"
|
|
"go.yaml.in/yaml/v4"
|
|
)
|
|
|
|
// test renders and instantiates plus yaml-parses the template per usage
|
|
func test(t *testing.T, tmpl Template, values map[string]any, cb func(values map[string]any)) {
|
|
t.Helper()
|
|
|
|
b, _, err := tmpl.RenderResult(RenderModeInstance, values)
|
|
if err != nil {
|
|
t.Log(string(b))
|
|
t.Error(err)
|
|
return
|
|
}
|
|
|
|
var instance any
|
|
if err := yaml.Unmarshal(b, &instance); err != nil {
|
|
t.Log(string(b))
|
|
t.Error(err)
|
|
return
|
|
}
|
|
|
|
// don't execute if skip test is set
|
|
if slices.Contains(tmpl.Requirements.EVCC, RequirementSkipTest) {
|
|
return
|
|
}
|
|
|
|
cb(values)
|
|
}
|
|
|
|
func testAuth(other map[string]any) error {
|
|
if len(other) == 0 {
|
|
return nil
|
|
}
|
|
|
|
var cc struct {
|
|
Type string
|
|
Params []string
|
|
}
|
|
|
|
if err := util.DecodeOther(other, &cc); err != nil {
|
|
return err
|
|
}
|
|
|
|
params := make(map[string]any)
|
|
for _, p := range cc.Params {
|
|
params[p] = "foo"
|
|
}
|
|
|
|
_, err := auth.NewFromConfig(context.TODO(), cc.Type, params)
|
|
|
|
// ConfigError indicates invalid parameters in mapstructure decode
|
|
if _, ok := errors.AsType[*util.ConfigError](err); ok {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func TestClass(t *testing.T, class Class, instantiate func(t *testing.T, values map[string]any)) {
|
|
t.Parallel()
|
|
|
|
for _, tmpl := range ByClass(class, WithDeprecated()) {
|
|
// set default values for all params
|
|
values := tmpl.Defaults(RenderModeUnitTest)
|
|
|
|
// set modbus default test values
|
|
if values[ParamModbus] != nil {
|
|
modbusChoices := tmpl.ModbusChoices()
|
|
// we only test one modbus setup
|
|
if slices.Contains(modbusChoices, ModbusChoiceTCPIP) {
|
|
values[ModbusKeyTCPIP] = true
|
|
} else if slices.Contains(modbusChoices, ModbusChoiceUDP) {
|
|
values[ModbusKeyUDP] = true
|
|
} else {
|
|
values[ModbusKeyRS485TCPIP] = true
|
|
}
|
|
tmpl.ModbusValues(RenderModeUnitTest, values)
|
|
}
|
|
|
|
// set the template value which is needed for rendering
|
|
values["template"] = tmpl.Template
|
|
// https://github.com/evcc-io/evcc/pull/10272 - override example IP (192.0.2.2)
|
|
values["host"] = "localhost"
|
|
|
|
// test auth configuration
|
|
if err := testAuth(tmpl.Auth); err != nil {
|
|
t.Error("authorization:", err)
|
|
}
|
|
|
|
usages := tmpl.Usages()
|
|
if len(usages) == 0 {
|
|
t.Run(tmpl.Template, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
test(t, tmpl, values, func(values map[string]any) {
|
|
instantiate(t, values)
|
|
})
|
|
})
|
|
|
|
continue
|
|
}
|
|
|
|
for _, u := range usages {
|
|
// create a copy of the map for parallel execution
|
|
usageValues := maps.Clone(values)
|
|
usageValues[ParamUsage] = u
|
|
|
|
// subtest for each usage
|
|
t.Run(tmpl.Template+"/"+u, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
test(t, tmpl, usageValues, func(values map[string]any) {
|
|
instantiate(t, values)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|