320 lines
8.1 KiB
Go
320 lines
8.1 KiB
Go
package pkg_test
|
|
|
|
import (
|
|
"math/big"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/rwadurian/mpc-system/pkg/utils"
|
|
)
|
|
|
|
func TestGenerateID(t *testing.T) {
|
|
t.Run("should generate unique IDs", func(t *testing.T) {
|
|
id1 := utils.GenerateID()
|
|
id2 := utils.GenerateID()
|
|
|
|
assert.NotEqual(t, id1, id2)
|
|
})
|
|
}
|
|
|
|
func TestParseUUID(t *testing.T) {
|
|
t.Run("should parse valid UUID", func(t *testing.T) {
|
|
id := utils.GenerateID()
|
|
parsed, err := utils.ParseUUID(id.String())
|
|
require.NoError(t, err)
|
|
assert.Equal(t, id, parsed)
|
|
})
|
|
|
|
t.Run("should fail on invalid UUID", func(t *testing.T) {
|
|
_, err := utils.ParseUUID("invalid-uuid")
|
|
assert.Error(t, err)
|
|
})
|
|
}
|
|
|
|
func TestIsValidUUID(t *testing.T) {
|
|
t.Run("should return true for valid UUID", func(t *testing.T) {
|
|
id := utils.GenerateID()
|
|
assert.True(t, utils.IsValidUUID(id.String()))
|
|
})
|
|
|
|
t.Run("should return false for invalid UUID", func(t *testing.T) {
|
|
assert.False(t, utils.IsValidUUID("not-a-uuid"))
|
|
})
|
|
}
|
|
|
|
func TestJSON(t *testing.T) {
|
|
t.Run("should marshal and unmarshal JSON", func(t *testing.T) {
|
|
original := map[string]interface{}{
|
|
"key": "value",
|
|
"count": float64(42),
|
|
}
|
|
|
|
data, err := utils.ToJSON(original)
|
|
require.NoError(t, err)
|
|
|
|
var result map[string]interface{}
|
|
err = utils.FromJSON(data, &result)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, original["key"], result["key"])
|
|
assert.Equal(t, original["count"], result["count"])
|
|
})
|
|
}
|
|
|
|
func TestNowUTC(t *testing.T) {
|
|
t.Run("should return UTC time", func(t *testing.T) {
|
|
now := utils.NowUTC()
|
|
assert.Equal(t, time.UTC, now.Location())
|
|
})
|
|
}
|
|
|
|
func TestTimePtr(t *testing.T) {
|
|
t.Run("should return pointer to time", func(t *testing.T) {
|
|
now := time.Now()
|
|
ptr := utils.TimePtr(now)
|
|
|
|
require.NotNil(t, ptr)
|
|
assert.Equal(t, now, *ptr)
|
|
})
|
|
}
|
|
|
|
func TestBigIntBytes(t *testing.T) {
|
|
t.Run("should convert big.Int to bytes and back", func(t *testing.T) {
|
|
original, _ := new(big.Int).SetString("12345678901234567890", 10)
|
|
bytes := utils.BigIntToBytes(original)
|
|
assert.Len(t, bytes, 32)
|
|
|
|
result := utils.BytesToBigInt(bytes)
|
|
assert.Equal(t, 0, original.Cmp(result))
|
|
})
|
|
|
|
t.Run("should handle nil big.Int", func(t *testing.T) {
|
|
bytes := utils.BigIntToBytes(nil)
|
|
assert.Len(t, bytes, 32)
|
|
assert.Equal(t, make([]byte, 32), bytes)
|
|
})
|
|
}
|
|
|
|
func TestStringSliceContains(t *testing.T) {
|
|
t.Run("should find existing value", func(t *testing.T) {
|
|
slice := []string{"a", "b", "c"}
|
|
assert.True(t, utils.StringSliceContains(slice, "b"))
|
|
})
|
|
|
|
t.Run("should not find missing value", func(t *testing.T) {
|
|
slice := []string{"a", "b", "c"}
|
|
assert.False(t, utils.StringSliceContains(slice, "d"))
|
|
})
|
|
|
|
t.Run("should handle empty slice", func(t *testing.T) {
|
|
assert.False(t, utils.StringSliceContains([]string{}, "a"))
|
|
})
|
|
}
|
|
|
|
func TestStringSliceRemove(t *testing.T) {
|
|
t.Run("should remove existing value", func(t *testing.T) {
|
|
slice := []string{"a", "b", "c"}
|
|
result := utils.StringSliceRemove(slice, "b")
|
|
|
|
assert.Len(t, result, 2)
|
|
assert.Contains(t, result, "a")
|
|
assert.Contains(t, result, "c")
|
|
assert.NotContains(t, result, "b")
|
|
})
|
|
|
|
t.Run("should not modify slice if value not found", func(t *testing.T) {
|
|
slice := []string{"a", "b", "c"}
|
|
result := utils.StringSliceRemove(slice, "d")
|
|
|
|
assert.Len(t, result, 3)
|
|
})
|
|
}
|
|
|
|
func TestUniqueStrings(t *testing.T) {
|
|
t.Run("should return unique strings", func(t *testing.T) {
|
|
slice := []string{"a", "b", "a", "c", "b"}
|
|
result := utils.UniqueStrings(slice)
|
|
|
|
assert.Len(t, result, 3)
|
|
assert.Contains(t, result, "a")
|
|
assert.Contains(t, result, "b")
|
|
assert.Contains(t, result, "c")
|
|
})
|
|
|
|
t.Run("should preserve order", func(t *testing.T) {
|
|
slice := []string{"c", "a", "b", "a"}
|
|
result := utils.UniqueStrings(slice)
|
|
|
|
assert.Equal(t, []string{"c", "a", "b"}, result)
|
|
})
|
|
}
|
|
|
|
func TestTruncateString(t *testing.T) {
|
|
t.Run("should truncate long string", func(t *testing.T) {
|
|
s := "hello world"
|
|
result := utils.TruncateString(s, 5)
|
|
assert.Equal(t, "hello", result)
|
|
})
|
|
|
|
t.Run("should not truncate short string", func(t *testing.T) {
|
|
s := "hi"
|
|
result := utils.TruncateString(s, 5)
|
|
assert.Equal(t, "hi", result)
|
|
})
|
|
}
|
|
|
|
func TestSafeString(t *testing.T) {
|
|
t.Run("should return string value", func(t *testing.T) {
|
|
s := "test"
|
|
result := utils.SafeString(&s)
|
|
assert.Equal(t, "test", result)
|
|
})
|
|
|
|
t.Run("should return empty string for nil", func(t *testing.T) {
|
|
result := utils.SafeString(nil)
|
|
assert.Equal(t, "", result)
|
|
})
|
|
}
|
|
|
|
func TestPointerHelpers(t *testing.T) {
|
|
t.Run("StringPtr", func(t *testing.T) {
|
|
ptr := utils.StringPtr("test")
|
|
require.NotNil(t, ptr)
|
|
assert.Equal(t, "test", *ptr)
|
|
})
|
|
|
|
t.Run("IntPtr", func(t *testing.T) {
|
|
ptr := utils.IntPtr(42)
|
|
require.NotNil(t, ptr)
|
|
assert.Equal(t, 42, *ptr)
|
|
})
|
|
|
|
t.Run("BoolPtr", func(t *testing.T) {
|
|
ptr := utils.BoolPtr(true)
|
|
require.NotNil(t, ptr)
|
|
assert.True(t, *ptr)
|
|
})
|
|
}
|
|
|
|
func TestCoalesce(t *testing.T) {
|
|
t.Run("should return first non-zero value", func(t *testing.T) {
|
|
result := utils.Coalesce("", "", "value", "other")
|
|
assert.Equal(t, "value", result)
|
|
})
|
|
|
|
t.Run("should return zero if all values are zero", func(t *testing.T) {
|
|
result := utils.Coalesce("", "", "")
|
|
assert.Equal(t, "", result)
|
|
})
|
|
|
|
t.Run("should work with ints", func(t *testing.T) {
|
|
result := utils.Coalesce(0, 0, 42, 100)
|
|
assert.Equal(t, 42, result)
|
|
})
|
|
}
|
|
|
|
func TestMapKeys(t *testing.T) {
|
|
t.Run("should return all keys", func(t *testing.T) {
|
|
m := map[string]int{"a": 1, "b": 2, "c": 3}
|
|
keys := utils.MapKeys(m)
|
|
|
|
assert.Len(t, keys, 3)
|
|
assert.Contains(t, keys, "a")
|
|
assert.Contains(t, keys, "b")
|
|
assert.Contains(t, keys, "c")
|
|
})
|
|
|
|
t.Run("should return empty slice for empty map", func(t *testing.T) {
|
|
m := map[string]int{}
|
|
keys := utils.MapKeys(m)
|
|
assert.Empty(t, keys)
|
|
})
|
|
}
|
|
|
|
func TestMapValues(t *testing.T) {
|
|
t.Run("should return all values", func(t *testing.T) {
|
|
m := map[string]int{"a": 1, "b": 2, "c": 3}
|
|
values := utils.MapValues(m)
|
|
|
|
assert.Len(t, values, 3)
|
|
assert.Contains(t, values, 1)
|
|
assert.Contains(t, values, 2)
|
|
assert.Contains(t, values, 3)
|
|
})
|
|
}
|
|
|
|
func TestMinMax(t *testing.T) {
|
|
t.Run("Min should return smaller value", func(t *testing.T) {
|
|
assert.Equal(t, 1, utils.Min(1, 2))
|
|
assert.Equal(t, 1, utils.Min(2, 1))
|
|
assert.Equal(t, -5, utils.Min(-5, 0))
|
|
})
|
|
|
|
t.Run("Max should return larger value", func(t *testing.T) {
|
|
assert.Equal(t, 2, utils.Max(1, 2))
|
|
assert.Equal(t, 2, utils.Max(2, 1))
|
|
assert.Equal(t, 0, utils.Max(-5, 0))
|
|
})
|
|
}
|
|
|
|
func TestClamp(t *testing.T) {
|
|
t.Run("should clamp value to range", func(t *testing.T) {
|
|
assert.Equal(t, 5, utils.Clamp(5, 0, 10)) // within range
|
|
assert.Equal(t, 0, utils.Clamp(-5, 0, 10)) // below min
|
|
assert.Equal(t, 10, utils.Clamp(15, 0, 10)) // above max
|
|
})
|
|
}
|
|
|
|
func TestMaskString(t *testing.T) {
|
|
t.Run("should mask middle of string", func(t *testing.T) {
|
|
result := utils.MaskString("1234567890", 2)
|
|
assert.Equal(t, "12******90", result)
|
|
})
|
|
|
|
t.Run("should mask short strings completely", func(t *testing.T) {
|
|
result := utils.MaskString("1234", 3)
|
|
assert.Equal(t, "****", result)
|
|
})
|
|
}
|
|
|
|
func TestRetry(t *testing.T) {
|
|
t.Run("should succeed on first attempt", func(t *testing.T) {
|
|
attempts := 0
|
|
err := utils.Retry(3, time.Millisecond, func() error {
|
|
attempts++
|
|
return nil
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 1, attempts)
|
|
})
|
|
|
|
t.Run("should retry on failure and eventually succeed", func(t *testing.T) {
|
|
attempts := 0
|
|
err := utils.Retry(3, time.Millisecond, func() error {
|
|
attempts++
|
|
if attempts < 3 {
|
|
return assert.AnError
|
|
}
|
|
return nil
|
|
})
|
|
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 3, attempts)
|
|
})
|
|
|
|
t.Run("should fail after max attempts", func(t *testing.T) {
|
|
attempts := 0
|
|
err := utils.Retry(3, time.Millisecond, func() error {
|
|
attempts++
|
|
return assert.AnError
|
|
})
|
|
|
|
assert.Error(t, err)
|
|
assert.Equal(t, 3, attempts)
|
|
})
|
|
}
|