Your IP : 216.73.216.224


Current Path : /home/hotlineuser/mobius/hotline/
Upload File :
Current File : //home/hotlineuser/mobius/hotline/stats_test.go

package hotline

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestStats_Increment(t *testing.T) {
	tests := []struct {
		name     string
		keys     []int
		expected map[int]int
	}{
		{
			name: "single key increment",
			keys: []int{StatCurrentlyConnected},
			expected: map[int]int{
				StatCurrentlyConnected: 1,
			},
		},
		{
			name: "multiple keys increment",
			keys: []int{StatCurrentlyConnected, StatDownloadCounter, StatUploadCounter},
			expected: map[int]int{
				StatCurrentlyConnected: 1,
				StatDownloadCounter:    1,
				StatUploadCounter:      1,
			},
		},
		{
			name: "duplicate keys increment",
			keys: []int{StatCurrentlyConnected, StatCurrentlyConnected},
			expected: map[int]int{
				StatCurrentlyConnected: 2,
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			stats := NewStats()
			stats.Increment(tt.keys...)

			for key, expectedVal := range tt.expected {
				assert.Equal(t, expectedVal, stats.Get(key))
			}
		})
	}
}

func TestStats_Increment_Multiple_Calls(t *testing.T) {
	stats := NewStats()

	stats.Increment(StatCurrentlyConnected)
	assert.Equal(t, 1, stats.Get(StatCurrentlyConnected))

	stats.Increment(StatCurrentlyConnected)
	assert.Equal(t, 2, stats.Get(StatCurrentlyConnected))

	stats.Increment(StatCurrentlyConnected, StatDownloadCounter)
	assert.Equal(t, 3, stats.Get(StatCurrentlyConnected))
	assert.Equal(t, 1, stats.Get(StatDownloadCounter))
}

func TestStats_Decrement(t *testing.T) {
	tests := []struct {
		name       string
		setupValue int
		key        int
		expected   int
	}{
		{
			name:       "decrement from positive value",
			setupValue: 5,
			key:        StatCurrentlyConnected,
			expected:   4,
		},
		{
			name:       "decrement from zero stays zero",
			setupValue: 0,
			key:        StatCurrentlyConnected,
			expected:   0,
		},
		{
			name:       "decrement from one",
			setupValue: 1,
			key:        StatCurrentlyConnected,
			expected:   0,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			stats := NewStats()
			stats.Set(tt.key, tt.setupValue)

			stats.Decrement(tt.key)

			assert.Equal(t, tt.expected, stats.Get(tt.key))
		})
	}
}

func TestStats_Decrement_Multiple_Calls(t *testing.T) {
	stats := NewStats()

	stats.Set(StatCurrentlyConnected, 10)
	assert.Equal(t, 10, stats.Get(StatCurrentlyConnected))

	stats.Decrement(StatCurrentlyConnected)
	assert.Equal(t, 9, stats.Get(StatCurrentlyConnected))

	stats.Decrement(StatCurrentlyConnected)
	assert.Equal(t, 8, stats.Get(StatCurrentlyConnected))
}

func TestStats_Set(t *testing.T) {
	tests := []struct {
		name     string
		key      int
		value    int
		expected int
	}{
		{
			name:     "set positive value",
			key:      StatCurrentlyConnected,
			value:    42,
			expected: 42,
		},
		{
			name:     "set zero value",
			key:      StatDownloadCounter,
			value:    0,
			expected: 0,
		},
		{
			name:     "set negative value",
			key:      StatUploadCounter,
			value:    -5,
			expected: -5,
		},
		{
			name:     "overwrite existing value",
			key:      StatConnectionPeak,
			value:    100,
			expected: 100,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			stats := NewStats()

			if tt.name == "overwrite existing value" {
				stats.Set(tt.key, 50)
			}

			stats.Set(tt.key, tt.value)

			assert.Equal(t, tt.expected, stats.Get(tt.key))
		})
	}
}

func TestStats_Get(t *testing.T) {
	tests := []struct {
		name     string
		key      int
		setValue int
		expected int
	}{
		{
			name:     "get initialized value",
			key:      StatCurrentlyConnected,
			setValue: 0,
			expected: 0,
		},
		{
			name:     "get set value",
			key:      StatDownloadCounter,
			setValue: 25,
			expected: 25,
		},
		{
			name:     "get after increment",
			key:      StatUploadCounter,
			setValue: -1,
			expected: 1,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			stats := NewStats()

			if tt.name == "get after increment" {
				stats.Increment(tt.key)
			} else {
				stats.Set(tt.key, tt.setValue)
			}

			result := stats.Get(tt.key)
			assert.Equal(t, tt.expected, result)
		})
	}
}

func TestStats_Get_Default_Values(t *testing.T) {
	stats := NewStats()

	expectedDefaults := map[int]int{
		StatCurrentlyConnected:  0,
		StatDownloadsInProgress: 0,
		StatUploadsInProgress:   0,
		StatWaitingDownloads:    0,
		StatConnectionPeak:      0,
		StatDownloadCounter:     0,
		StatUploadCounter:       0,
		StatConnectionCounter:   0,
	}

	for key, expected := range expectedDefaults {
		assert.Equal(t, expected, stats.Get(key))
	}
}

func TestStats_Values(t *testing.T) {
	stats := NewStats()

	// Test default values
	values := stats.Values()

	assert.Equal(t, 0, values["CurrentlyConnected"])
	assert.Equal(t, 0, values["DownloadsInProgress"])
	assert.Equal(t, 0, values["UploadsInProgress"])
	assert.Equal(t, 0, values["WaitingDownloads"])
	assert.Equal(t, 0, values["ConnectionPeak"])
	assert.Equal(t, 0, values["ConnectionCounter"])
	assert.Equal(t, 0, values["DownloadCounter"])
	assert.Equal(t, 0, values["UploadCounter"])
	assert.NotNil(t, values["Since"])

	// Verify Since is a time.Time
	_, ok := values["Since"].(time.Time)
	assert.True(t, ok, "Since should be a time.Time")
}

func TestStats_Values_WithModifiedStats(t *testing.T) {
	stats := NewStats()

	// Modify some stats
	stats.Set(StatCurrentlyConnected, 10)
	stats.Set(StatDownloadsInProgress, 5)
	stats.Increment(StatConnectionCounter)
	stats.Increment(StatDownloadCounter, StatUploadCounter)

	values := stats.Values()

	assert.Equal(t, 10, values["CurrentlyConnected"])
	assert.Equal(t, 5, values["DownloadsInProgress"])
	assert.Equal(t, 0, values["UploadsInProgress"])
	assert.Equal(t, 0, values["WaitingDownloads"])
	assert.Equal(t, 0, values["ConnectionPeak"])
	assert.Equal(t, 1, values["ConnectionCounter"])
	assert.Equal(t, 1, values["DownloadCounter"])
	assert.Equal(t, 1, values["UploadCounter"])
}

func TestStats_Values_ContainsAllKeys(t *testing.T) {
	stats := NewStats()
	values := stats.Values()

	expectedKeys := []string{
		"CurrentlyConnected",
		"DownloadsInProgress",
		"UploadsInProgress",
		"WaitingDownloads",
		"ConnectionPeak",
		"ConnectionCounter",
		"DownloadCounter",
		"UploadCounter",
		"Since",
	}

	for _, key := range expectedKeys {
		_, exists := values[key]
		assert.True(t, exists, "Key %s should exist in Values() output", key)
	}

	// Should have exactly 9 keys
	assert.Equal(t, 9, len(values))
}