EdgexAgent/device-gps-go/internal/transformer/transformresult_test.go
2025-07-10 20:30:06 +08:00

291 lines
13 KiB
Go

// -*- Mode: Go; indent-tabs-mode: t -*-
//
// Copyright (C) 2019-2023 IOTech Ltd
//
// SPDX-License-Identifier: Apache-2.0
package transformer
import (
"math"
"testing"
"github.com/edgexfoundry/go-mod-core-contracts/v4/common"
"github.com/edgexfoundry/go-mod-core-contracts/v4/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/edgexfoundry/device-sdk-go/v4/pkg/models"
)
func Test_transformReadBase(t *testing.T) {
tests := []struct {
name string
value interface{}
base float64
expected interface{}
expectedErr bool
}{
{"valid - uint8 base transformation", uint8(2), 10, uint8(100), false},
{"invalid - uint8 base transformation overflow", uint8(10), 10, nil, true},
{"valid - uint16 base transformation", uint16(2), 100, uint16(10000), false},
{"invalid - uint16 base transformation overflow", uint16(100), 10, nil, true},
{"valid - uint32 base transformation", uint32(2), 10000, uint32(100000000), false},
{"invalid - uint32 base transformation overflow", uint32(10000), 10, nil, true},
{"valid - uint64 base transformation", uint64(2), 100000, uint64(10000000000), false},
{"invalid - uint64 base transformation overflow", uint64(100000000), 10, nil, true},
{"valid - int8 base transformation", int8(2), 10, int8(100), false},
{"invalid - int8 base transformation overflow", int8(10), 10, nil, true},
{"valid - int16 base transformation", int16(2), 100, int16(10000), false},
{"invalid - int16 base transformation overflow", int16(100), 10, nil, true},
{"valid - int32 base transformation", int32(2), 10000, int32(100000000), false},
{"invalid - int32 base transformation overflow", int32(10000), 10, nil, true},
{"valid - int64 base transformation", int64(2), 100000, int64(10000000000), false},
{"invalid - int64 base transformation overflow", int64(100000000), 10, nil, true},
{"valid - float32 base transformation", float32(1.1), 2, float32(2.143547), false},
{"invalid - float32 base transformation overflow", math.MaxFloat32, 2, nil, true},
{"valid - float64 base transformation", float64(1.1), 2, float64(2.1435469250725863), false},
{"invalid - float64 base transformation overflow", math.MaxFloat64, 2, nil, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
res, err := transformBase(tt.value, tt.base, true)
if !tt.expectedErr {
require.NoError(t, err)
assert.Equal(t, tt.expected, res)
} else {
require.Error(t, err)
assert.Equal(t, errors.Kind(err), errors.KindOverflowError, "expect Overflow ErrKind")
}
})
}
}
func Test_transformReadScale(t *testing.T) {
tests := []struct {
name string
value interface{}
scale float64
expected interface{}
expectedErr bool
}{
{"valid - uint8 scale transformation", uint8(math.MaxUint8 / 5), 5, uint8(math.MaxUint8), false},
{"invalid - uint8 scale transformation overflow", uint8(math.MaxUint8 / 5), 6, nil, true},
{"valid - uint16 scale transformation", uint16(math.MaxUint16 / 5), 5, uint16(math.MaxUint16), false},
{"invalid - uint16 scale transformation overflow", uint16(math.MaxUint16 / 5), 6, nil, true},
{"valid - uint32 scale transformation", uint32(math.MaxUint32 / 5), 5, uint32(math.MaxUint32), false},
{"invalid - uint32 scale transformation overflow", uint32(math.MaxUint32 / 5), 6, nil, true},
{"valid - uint64 scale transformation", uint64(math.MaxUint64 / 5), 5, uint64(math.MaxUint64), false},
{"valid - int8 scale transformation", int8(10), 10, int8(100), false},
{"invalid - int8 scale transformation overflow", int8(10), 30, nil, true},
{"valid - int16 scale transformation", int16(10000), 3, int16(30000), false},
{"invalid - int16 scale transformation overflow", int16(10000), 4, nil, true},
{"valid - int32 scale transformation", int32(1000000000), 2, int32(2000000000), false},
{"invalid - int32 scale transformation overflow", int32(1000000000), 3, nil, true},
{"valid - int64 scale transformation", int64(1000000000), 1000000000, int64(1000000000000000000), false},
{"valid - float32 scale transformation", float32(12.1), 10, float32(121), false},
{"invalid - float32 scale transformation overflow", float32(math.MaxFloat32 / 2), 3, nil, true},
{"valid - float64 scale transformation", float64(111111111.1), 2, float64(222222222.2), false},
{"invalid - float64 scale transformation overflow", float64(math.MaxFloat64), 2, nil, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
res, err := transformScale(tt.value, tt.scale, true)
if !tt.expectedErr {
require.NoError(t, err)
assert.Equal(t, tt.expected, res)
} else {
require.Error(t, err)
assert.Equal(t, errors.Kind(err), errors.KindOverflowError, "expect Overflow ErrKind")
}
})
}
}
func Test_transformReadOffset(t *testing.T) {
tests := []struct {
name string
value interface{}
offset float64
expected interface{}
expectedErr bool
}{
{"valid - uint8 offset transformation", uint8(math.MaxUint8 - 1), 1, uint8(math.MaxUint8), false},
{"invalid - uint8 offset transformation overflow", uint8(math.MaxUint8), 1, nil, true},
{"valid - uint16 offset transformation", uint16(math.MaxUint16 - 1), 1, uint16(math.MaxUint16), false},
{"invalid - uint16 offset transformation overflow", uint16(math.MaxUint16), 1, nil, true},
{"valid - uint32 offset transformation", uint32(math.MaxUint32 - 1), 1, uint32(math.MaxUint32), false},
{"invalid - uint32 offset transformation overflow", uint32(math.MaxUint32), 1, nil, true},
{"valid - uint64 offset transformation", uint64(math.MaxUint64) - uint64(1), 1, uint64(math.MaxUint64), false},
{"valid - int8 offset transformation", int8(math.MaxInt8 - 1), 1, int8(math.MaxInt8), false},
{"invalid - int8 offset transformation overflow", int8(math.MaxInt8), 1, nil, true},
{"valid - int16 offset transformation", int16(math.MaxInt16 - 1), 1, int16(math.MaxInt16), false},
{"invalid - int16 offset transformation overflow", int16(math.MaxInt16), 1, nil, true},
{"valid - int32 offset transformation", int32(math.MaxInt32 - 1), 1, int32(math.MaxInt32), false},
{"invalid - int32 offset transformation overflow", int32(math.MaxInt32), 1, nil, true},
{"valid - int64 offset transformation", int64(math.MaxInt64 - 1), 1, int64(math.MaxInt64), false},
{"valid - float32 offset transformation", float32(1.1), 1, float32(2.1), false},
{"invalid - float32 offset transformation overflow", float32(math.MaxFloat32), math.MaxFloat32, nil, true},
{"valid - float64 offset transformation", float64(1.1), 1, float64(2.1), false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
res, err := transformOffset(tt.value, tt.offset, true)
if !tt.expectedErr {
require.NoError(t, err)
assert.Equal(t, tt.expected, res)
} else {
require.Error(t, err)
assert.Equal(t, errors.Kind(err), errors.KindOverflowError, "expect Overflow ErrKind")
}
})
}
}
func Test_transformReadMask(t *testing.T) {
tests := []struct {
name string
value interface{}
mask uint64
expected interface{}
expectedErr bool
}{
{"valid - uint8 mask transformation", uint8(math.MaxUint8), 15, uint8(15), false},
{"valid - uint16 mask transformation", uint16(math.MaxUint16), 256, uint16(256), false},
{"valid - uint32 mask transformation", uint32(math.MaxUint32), 256, uint32(256), false},
{"valid - uint64 mask transformation", uint64(math.MaxUint64), 256, uint64(256), false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
res, err := transformReadMask(tt.value, tt.mask)
if !tt.expectedErr {
require.NoError(t, err)
assert.Equal(t, tt.expected, res)
} else {
require.Error(t, err)
}
})
}
}
func Test_transformReadShift(t *testing.T) {
tests := []struct {
name string
value interface{}
shift int64
expected interface{}
expectedErr bool
}{
{"valid - uint8 shift transformation with positive shift value", uint8(0b1), 4, uint8(0b10000), false},
{"valid - uint8 shift transformation with negative shift value", uint8(0b11111111), -4, uint8(0b00001111), false},
{"valid - uint16 shift transformation with positive shift value", uint16(0b1), 8, uint16(0b100000000), false},
{"valid - uint16 shift transformation with negative shift value", uint16(0b1111111100000000), -8, uint16(0b0000000011111111), false},
{"valid - uint32 shift transformation with positive shift value", uint32(0b1), 16, uint32(0b10000000000000000), false},
{"valid - uint32 shift transformation with negative shift value", uint32(0b11111111111111110000000000000000), -16, uint32(0b00000000000000001111111111111111), false},
{"valid - uint64 shift transformation with positive shift value", uint64(0b1), 32, uint64(0b100000000000000000000000000000000), false},
{"valid - uint64 shift transformation with negative shift value", uint64(0b1111111111111111111111111111111100000000000000000000000000000000), -32, uint64(0b0000000000000000000000000000000011111111111111111111111111111111), false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
res, err := transformReadShift(tt.value, tt.shift)
if !tt.expectedErr {
require.NoError(t, err)
assert.Equal(t, tt.expected, res)
} else {
require.Error(t, err)
}
})
}
}
func Test_commandValueForTransform(t *testing.T) {
u8, err := models.NewCommandValue("test-resource", common.ValueTypeUint8, uint8(0))
require.NoError(t, err)
u16, err := models.NewCommandValue("test-resource", common.ValueTypeUint16, uint16(0))
require.NoError(t, err)
u32, err := models.NewCommandValue("test-resource", common.ValueTypeUint32, uint32(0))
require.NoError(t, err)
u64, err := models.NewCommandValue("test-resource", common.ValueTypeUint64, uint64(0))
require.NoError(t, err)
i8, err := models.NewCommandValue("test-resource", common.ValueTypeInt8, int8(0))
require.NoError(t, err)
i16, err := models.NewCommandValue("test-resource", common.ValueTypeInt16, int16(0))
require.NoError(t, err)
i32, err := models.NewCommandValue("test-resource", common.ValueTypeInt32, int32(0))
require.NoError(t, err)
i64, err := models.NewCommandValue("test-resource", common.ValueTypeInt64, int64(0))
require.NoError(t, err)
f32, err := models.NewCommandValue("test-resource", common.ValueTypeFloat32, float32(0))
require.NoError(t, err)
f64, err := models.NewCommandValue("test-resource", common.ValueTypeFloat64, float64(0))
require.NoError(t, err)
s, err := models.NewCommandValue("test-resource", common.ValueTypeString, "invalid")
require.NoError(t, err)
tests := []struct {
name string
cv *models.CommandValue
expectedValue interface{}
expectedErr bool
}{
{"valid - uint8 CommandValue", u8, uint8(0), false},
{"valid - uint16 CommandValue", u16, uint16(0), false},
{"valid - uint32 CommandValue", u32, uint32(0), false},
{"valid - uint64 CommandValue", u64, uint64(0), false},
{"valid - int8 CommandValue", i8, int8(0), false},
{"valid - int16 CommandValue", i16, int16(0), false},
{"valid - int32 CommandValue", i32, int32(0), false},
{"valid - int64 CommandValue", i64, int64(0), false},
{"valid - float32 CommandValue", f32, float32(0), false},
{"valid - float64 CommandValue", f64, float64(0), false},
{"invalid - unsupported type for transformation", s, nil, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := commandValueForTransform(tt.cv)
if !tt.expectedErr {
assert.NoError(t, err)
} else {
assert.NotNil(t, err)
}
})
}
}
func Test_mapCommandValue(t *testing.T) {
numericValue, err := models.NewCommandValue("test-resource", common.ValueTypeFloat32, float32(123.456))
require.NoError(t, err)
stringValue, err := models.NewCommandValue("test-resource", common.ValueTypeString, "key")
require.NoError(t, err)
arrayValue, err := models.NewCommandValue("test-resource", common.ValueTypeInt8Array, []int8{1, 2, 3})
require.NoError(t, err)
invalid, err := models.NewCommandValue("test-resource", common.ValueTypeString, "invalid")
require.NoError(t, err)
mappings := map[string]string{
"123.456": "value",
"key": "value",
"[1 2 3]": "value",
}
tests := []struct {
name string
cv *models.CommandValue
success bool
}{
{"valid - CommandValue with numeric mapping", numericValue, true},
{"valid - CommandValue with string mapping", stringValue, true},
{"valid - CommandValue with array mapping", arrayValue, true},
{"invalid - mapping not found", invalid, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
res, ok := mapCommandValue(tt.cv, mappings)
require.Equal(t, ok, tt.success)
if ok {
assert.Equal(t, res.Value, "value")
}
})
}
}