mirror of
https://github.com/jwetzell/showbridge-go.git
synced 2026-04-26 21:05:30 +00:00
add more convenience functions for getting slices from params and add tests
This commit is contained in:
@@ -3,6 +3,7 @@ package config
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -85,6 +86,90 @@ func (p Params) GetStringSlice(key string) ([]string, error) {
|
|||||||
return stringSlice, nil
|
return stringSlice, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p Params) GetIntSlice(key string) ([]int, error) {
|
||||||
|
value, ok := p[key]
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrParamNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
interfaceSlice, ok := value.([]any)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrParamNotSlice
|
||||||
|
}
|
||||||
|
|
||||||
|
intSlice := make([]int, len(interfaceSlice))
|
||||||
|
for i, v := range interfaceSlice {
|
||||||
|
|
||||||
|
intValue, ok := v.(int)
|
||||||
|
if ok {
|
||||||
|
intSlice[i] = intValue
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
uintValue, ok := v.(uint)
|
||||||
|
if ok {
|
||||||
|
intSlice[i] = int(uintValue)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
floatValue, ok := v.(float64)
|
||||||
|
if ok {
|
||||||
|
if floatValue != math.Floor(floatValue) {
|
||||||
|
return nil, fmt.Errorf("element at index %d is not an integer", i)
|
||||||
|
}
|
||||||
|
intSlice[i] = int(floatValue)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("element at index %d is not a number", i)
|
||||||
|
}
|
||||||
|
return intSlice, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Params) GetByteSlice(key string) ([]byte, error) {
|
||||||
|
value, ok := p[key]
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrParamNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
byteSlice, ok := value.([]any)
|
||||||
|
if !ok {
|
||||||
|
return nil, ErrParamNotSlice
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]byte, len(byteSlice))
|
||||||
|
for i, v := range byteSlice {
|
||||||
|
uintValue, ok := v.(uint)
|
||||||
|
if ok {
|
||||||
|
if uintValue > 255 {
|
||||||
|
return nil, fmt.Errorf("element at index %d is out of byte range", i)
|
||||||
|
}
|
||||||
|
result[i] = byte(uintValue)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
intValue, ok := v.(int)
|
||||||
|
if ok {
|
||||||
|
if intValue < 0 || intValue > 255 {
|
||||||
|
return nil, fmt.Errorf("element at index %d is out of byte range", i)
|
||||||
|
}
|
||||||
|
result[i] = byte(intValue)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
floatValue, ok := v.(float64)
|
||||||
|
if ok {
|
||||||
|
if floatValue != math.Floor(floatValue) {
|
||||||
|
return nil, fmt.Errorf("element at index %d is not an integer", i)
|
||||||
|
}
|
||||||
|
if floatValue < 0 || floatValue > 255 {
|
||||||
|
return nil, fmt.Errorf("element at index %d is out of byte range", i)
|
||||||
|
}
|
||||||
|
result[i] = byte(floatValue)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("element at index %d is not a number", i)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
type ModuleConfig struct {
|
type ModuleConfig struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
|||||||
213
internal/config/config_test.go
Normal file
213
internal/config/config_test.go
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
package config_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"slices"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/jwetzell/showbridge-go/internal/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGoodStringParamsJSON(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
paramsJSON string
|
||||||
|
key string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "string param",
|
||||||
|
paramsJSON: `{"key": "value"}`,
|
||||||
|
key: "key",
|
||||||
|
expected: "value",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
params := config.Params{}
|
||||||
|
err := json.Unmarshal([]byte(testCase.paramsJSON), ¶ms)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to unmarshal params JSON: %v", err)
|
||||||
|
}
|
||||||
|
value, err := params.GetString(testCase.key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetString returned error: %v", err)
|
||||||
|
}
|
||||||
|
if value != testCase.expected {
|
||||||
|
t.Fatalf("GetString got %s, expected %s", value, testCase.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoodIntParamsJSON(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
paramsJSON string
|
||||||
|
key string
|
||||||
|
expected int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "int param",
|
||||||
|
paramsJSON: `{"key": 1}`,
|
||||||
|
key: "key",
|
||||||
|
expected: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
params := config.Params{}
|
||||||
|
err := json.Unmarshal([]byte(testCase.paramsJSON), ¶ms)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to unmarshal params JSON: %v", err)
|
||||||
|
}
|
||||||
|
value, err := params.GetInt(testCase.key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetInt returned error: %v", err)
|
||||||
|
}
|
||||||
|
if value != testCase.expected {
|
||||||
|
t.Fatalf("GetInt got %d, expected %d", value, testCase.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoodBoolParamsJSON(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
paramsJSON string
|
||||||
|
key string
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "bool param",
|
||||||
|
paramsJSON: `{"key": true}`,
|
||||||
|
key: "key",
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
params := config.Params{}
|
||||||
|
err := json.Unmarshal([]byte(testCase.paramsJSON), ¶ms)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to unmarshal params JSON: %v", err)
|
||||||
|
}
|
||||||
|
value, err := params.GetBool(testCase.key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetBool returned error: %v", err)
|
||||||
|
}
|
||||||
|
if value != testCase.expected {
|
||||||
|
t.Fatalf("GetBool got %t, expected %t", value, testCase.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoodStringSliceParamsJSON(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
paramsJSON string
|
||||||
|
key string
|
||||||
|
expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "string array",
|
||||||
|
paramsJSON: `{"key": ["value1", "value2"]}`,
|
||||||
|
key: "key",
|
||||||
|
expected: []string{"value1", "value2"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
params := config.Params{}
|
||||||
|
err := json.Unmarshal([]byte(testCase.paramsJSON), ¶ms)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to unmarshal params JSON: %v", err)
|
||||||
|
}
|
||||||
|
value, err := params.GetStringSlice(testCase.key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetStringSlice returned error: %v", err)
|
||||||
|
}
|
||||||
|
if !slices.Equal(value, testCase.expected) {
|
||||||
|
t.Fatalf("GetStringSlice got %v, expected %v", value, testCase.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoodIntSliceParamsJSON(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
paramsJSON string
|
||||||
|
key string
|
||||||
|
expected []int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "int array",
|
||||||
|
paramsJSON: `{"key": [1, 2, 3]}`,
|
||||||
|
key: "key",
|
||||||
|
expected: []int{1, 2, 3},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
params := config.Params{}
|
||||||
|
err := json.Unmarshal([]byte(testCase.paramsJSON), ¶ms)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to unmarshal params JSON: %v", err)
|
||||||
|
}
|
||||||
|
value, err := params.GetIntSlice(testCase.key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetIntSlice returned error: %v", err)
|
||||||
|
}
|
||||||
|
if !slices.Equal(value, testCase.expected) {
|
||||||
|
t.Fatalf("GetIntSlice got %v, expected %v", value, testCase.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGoodByteSliceParamsJSON(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
paramsJSON string
|
||||||
|
key string
|
||||||
|
expected []byte
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "byte array",
|
||||||
|
paramsJSON: `{"key": [1,2,3,4]}`,
|
||||||
|
key: "key",
|
||||||
|
expected: []byte{1, 2, 3, 4},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "byte array with floats",
|
||||||
|
paramsJSON: `{"key": [1.0,2.0,3.0,4.0]}`,
|
||||||
|
key: "key",
|
||||||
|
expected: []byte{1, 2, 3, 4},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
params := config.Params{}
|
||||||
|
err := json.Unmarshal([]byte(testCase.paramsJSON), ¶ms)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to unmarshal params JSON: %v", err)
|
||||||
|
}
|
||||||
|
value, err := params.GetByteSlice(testCase.key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GetByteSlice returned error: %v", err)
|
||||||
|
}
|
||||||
|
if !slices.Equal(value, testCase.expected) {
|
||||||
|
t.Fatalf("GetByteSlice got %v, expected %v", value, testCase.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user