first commit
This commit is contained in:
@@ -0,0 +1,219 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestGetExchangeRate_SameCurrency(t *testing.T) {
|
||||
rate, err := GetExchangeRate("USD", "USD")
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error for same currency, got %v", err)
|
||||
}
|
||||
if rate != 1.0 {
|
||||
t.Errorf("Expected rate 1.0 for same currency, got %f", rate)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertCurrency_SameCurrency(t *testing.T) {
|
||||
amount := 100.0
|
||||
converted, err := ConvertCurrency(amount, "EUR", "EUR")
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error for same currency conversion, got %v", err)
|
||||
}
|
||||
if converted != amount {
|
||||
t.Errorf("Expected %f for same currency conversion, got %f", amount, converted)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatCurrencyAmount(t *testing.T) {
|
||||
tests := []struct {
|
||||
amount float64
|
||||
currency string
|
||||
expected string
|
||||
}{
|
||||
{100.5, "USD", "100.50 USD"},
|
||||
{1234.567, "EUR", "1234.57 EUR"},
|
||||
{0.0, "GBP", "0.00 GBP"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result := FormatCurrencyAmount(test.amount, test.currency)
|
||||
if result != test.expected {
|
||||
t.Errorf("FormatCurrencyAmount(%.2f, %s) = %s, expected %s",
|
||||
test.amount, test.currency, result, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCurrencySymbol(t *testing.T) {
|
||||
tests := []struct {
|
||||
currency string
|
||||
expected string
|
||||
}{
|
||||
{"USD", "$"},
|
||||
{"EUR", "€"},
|
||||
{"GBP", "£"},
|
||||
{"JPY", "¥"},
|
||||
{"CHF", "CHF"},
|
||||
{"UNKNOWN", "UNKNOWN"}, // Should return currency code if symbol not found
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result := GetCurrencySymbol(test.currency)
|
||||
if result != test.expected {
|
||||
t.Errorf("GetCurrencySymbol(%s) = %s, expected %s",
|
||||
test.currency, result, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatCurrencyWithSymbol(t *testing.T) {
|
||||
tests := []struct {
|
||||
amount float64
|
||||
currency string
|
||||
expected string
|
||||
}{
|
||||
{100.5, "USD", "$100.50"},
|
||||
{1234.56, "EUR", "1234.56 €"},
|
||||
{999.99, "GBP", "£999.99"},
|
||||
{500.0, "UNKNOWN", "500.00 UNKNOWN"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result := FormatCurrencyWithSymbol(test.amount, test.currency)
|
||||
if result != test.expected {
|
||||
t.Errorf("FormatCurrencyWithSymbol(%.2f, %s) = %s, expected %s",
|
||||
test.amount, test.currency, result, test.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertAndFormat_SameCurrency(t *testing.T) {
|
||||
amount := 100.0
|
||||
currency := "USD"
|
||||
result := ConvertAndFormat(amount, currency, currency)
|
||||
expected := FormatCurrencyWithSymbol(amount, currency)
|
||||
|
||||
if result != expected {
|
||||
t.Errorf("ConvertAndFormat(%f, %s, %s) = %s, expected %s",
|
||||
amount, currency, currency, result, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBatchConvertCurrency_SameCurrency(t *testing.T) {
|
||||
amounts := []float64{100.0, 200.0, 300.0}
|
||||
currency := "EUR"
|
||||
|
||||
converted, err := BatchConvertCurrency(amounts, currency, currency)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error for same currency batch conversion, got %v", err)
|
||||
}
|
||||
|
||||
if len(converted) != len(amounts) {
|
||||
t.Errorf("Expected %d converted amounts, got %d", len(amounts), len(converted))
|
||||
}
|
||||
|
||||
for i, amount := range amounts {
|
||||
if converted[i] != amount {
|
||||
t.Errorf("Expected converted[%d] = %f, got %f", i, amount, converted[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestClearCache(t *testing.T) {
|
||||
// Add something to cache first
|
||||
cacheMutex.Lock()
|
||||
exchangeRateCache["TEST_USD"] = CachedRate{
|
||||
Rate: 1.5,
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
cacheMutex.Unlock()
|
||||
|
||||
// Verify cache has content
|
||||
info := GetCacheInfo()
|
||||
if len(info) == 0 {
|
||||
t.Error("Expected cache to have content before clearing")
|
||||
}
|
||||
|
||||
// Clear cache
|
||||
ClearCache()
|
||||
|
||||
// Verify cache is empty
|
||||
info = GetCacheInfo()
|
||||
if len(info) != 0 {
|
||||
t.Errorf("Expected empty cache after clearing, got %d items", len(info))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCacheInfo(t *testing.T) {
|
||||
// Clear cache first
|
||||
ClearCache()
|
||||
|
||||
// Add test data to cache
|
||||
testTime := time.Now()
|
||||
cacheMutex.Lock()
|
||||
exchangeRateCache["EUR_USD"] = CachedRate{
|
||||
Rate: 1.2,
|
||||
Timestamp: testTime,
|
||||
}
|
||||
exchangeRateCache["GBP_EUR"] = CachedRate{
|
||||
Rate: 1.15,
|
||||
Timestamp: testTime,
|
||||
}
|
||||
cacheMutex.Unlock()
|
||||
|
||||
info := GetCacheInfo()
|
||||
|
||||
if len(info) != 2 {
|
||||
t.Errorf("Expected 2 cache entries, got %d", len(info))
|
||||
}
|
||||
|
||||
if timestamp, exists := info["EUR_USD"]; !exists {
|
||||
t.Error("Expected EUR_USD entry in cache info")
|
||||
} else if !timestamp.Equal(testTime) {
|
||||
t.Error("Expected timestamp to match test time")
|
||||
}
|
||||
|
||||
if timestamp, exists := info["GBP_EUR"]; !exists {
|
||||
t.Error("Expected GBP_EUR entry in cache info")
|
||||
} else if !timestamp.Equal(testTime) {
|
||||
t.Error("Expected timestamp to match test time")
|
||||
}
|
||||
}
|
||||
|
||||
// Test cache expiration logic
|
||||
func TestCacheExpiration(t *testing.T) {
|
||||
ClearCache()
|
||||
|
||||
// Add expired entry to cache
|
||||
expiredTime := time.Now().Add(-2 * time.Hour) // 2 hours ago
|
||||
cacheMutex.Lock()
|
||||
exchangeRateCache["TEST_EXPIRED"] = CachedRate{
|
||||
Rate: 1.0,
|
||||
Timestamp: expiredTime,
|
||||
}
|
||||
cacheMutex.Unlock()
|
||||
|
||||
// This should not use the expired cache (but will fail API call)
|
||||
// We're mainly testing that it doesn't return the cached expired value
|
||||
_, err := GetExchangeRate("TEST", "EXPIRED")
|
||||
if err == nil {
|
||||
t.Error("Expected error due to invalid currency pair, but got none")
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark tests
|
||||
func BenchmarkGetCurrencySymbol(b *testing.B) {
|
||||
currencies := []string{"USD", "EUR", "GBP", "JPY", "CHF", "UNKNOWN"}
|
||||
for i := 0; i < b.N; i++ {
|
||||
currency := currencies[i%len(currencies)]
|
||||
GetCurrencySymbol(currency)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkFormatCurrencyWithSymbol(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
FormatCurrencyWithSymbol(1234.56, "USD")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user