package utils
import (
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestTimedAggregator(t *testing.T) {
t.Run("functions", func(t *testing.T) {
ta := NewTimedAggregator[float64](TimedAggregatorParams{})
aggregate, aggregateDuration := ta.GetAggregate()
require.Equal(t, 0.0, aggregate)
require.Equal(t, time.Duration(0), aggregateDuration)
require.Equal(t, 0.0, ta.GetAverage())
now := time.Now()
require.NoError(t, ta.AddSampleAt(1.0, now))
aggregate, aggregateDuration = ta.GetAggregate()
require.Equal(t, 0.0, aggregate)
require.Equal(t, time.Duration(0), aggregateDuration)
require.Equal(t, 0.0, ta.GetAverage())
require.NoError(t, ta.AddSampleAt(2.0, now.Add(500*time.Millisecond)))
aggregate, aggregateDuration = ta.GetAggregate()
require.Equal(t, 0.5, aggregate)
require.Equal(t, 500*time.Millisecond, aggregateDuration)
require.Equal(t, 1.0, ta.GetAverage())
require.Error(t, ErrAnachronousSample, ta.AddSampleAt(10.0, now.Add(200*time.Millisecond)))
_, _, err := ta.GetAggregateAt(now.Add(200 * time.Millisecond))
require.Error(t, ErrAnachronousSample, err)
aggregate, aggregateDuration, err = ta.GetAggregateAt(now.Add(1500 * time.Millisecond))
require.Equal(t, 2.5, aggregate)
require.Equal(t, 1500*time.Millisecond, aggregateDuration)
require.NoError(t, err)
require.Equal(t, 2.5/1.5, ta.GetAverage())
aggregate, aggregateDuration, err = ta.GetAggregateAndRestartAt(now.Add(2500 * time.Millisecond))
require.Equal(t, 4.5, aggregate)
require.Equal(t, 2500*time.Millisecond, aggregateDuration)
require.NoError(t, err)
aggregate, aggregateDuration = ta.GetAggregate()
require.Equal(t, 0.0, aggregate)
require.Equal(t, time.Duration(0), aggregateDuration)
require.Equal(t, 0.0, ta.GetAverage())
require.NoError(t, ta.AddSampleAt(20.0, now.Add(2800*time.Millisecond)))
aggregate, aggregateDuration, err = ta.GetAggregateAt(now.Add(3000 * time.Millisecond))
require.Equal(t, 4.6, aggregate)
require.Equal(t, 500*time.Millisecond, aggregateDuration)
require.NoError(t, err)
require.Equal(t, 4.6/0.5, ta.GetAverage())
average, err := ta.GetAverageAt(now.Add(3300 * time.Millisecond))
require.Equal(t, float64(10.6)/float64(0.8), average)
require.NoError(t, err)
aggregate, aggregateDuration = ta.GetAggregate()
require.Equal(t, 10.6, aggregate)
require.Equal(t, 800*time.Millisecond, aggregateDuration)
average, err = ta.GetAverageAndRestartAt(now.Add(3800 * time.Millisecond))
require.Equal(t, float64(20.6)/float64(1.3), average)
require.NoError(t, err)
aggregate, aggregateDuration = ta.GetAggregate()
require.Equal(t, 0.0, aggregate)
require.Equal(t, time.Duration(0), aggregateDuration)
require.NoError(t, ta.AddSampleAt(-2.0, now.Add(4000*time.Millisecond)))
average, err = ta.GetAverageAt(now.Add(4500 * time.Millisecond))
require.Equal(t, float64(3.0)/float64(0.7), average)
require.NoError(t, err)
aggregate, aggregateDuration = ta.GetAggregate()
require.Equal(t, 3.0, aggregate)
require.Equal(t, 700*time.Millisecond, aggregateDuration)
})
t.Run("negative_values", func(t *testing.T) {
ta := NewTimedAggregator[int64](TimedAggregatorParams{
CapNegativeValues: true,
})
now := time.Now()
require.NoError(t, ta.AddSampleAt(1, now))
require.NoError(t, ta.AddSampleAt(-1, now.Add(time.Second)))
require.NoError(t, ta.AddSampleAt(1, now.Add(2*time.Second)))
aggregate, aggregateDuration, err := ta.GetAggregateAt(now.Add(3 * time.Second))
require.Equal(t, int64(2), aggregate)
require.Equal(t, 3*time.Second, aggregateDuration)
require.NoError(t, err)
require.Equal(t, float64(2.0)/float64(3.0), ta.GetAverage())
})
}