88 lines
2.4 KiB
C#
88 lines
2.4 KiB
C#
using FluentAssertions;
|
|
using StellaOps.Policy.Determinization.Models;
|
|
using Xunit;
|
|
|
|
namespace StellaOps.Policy.Determinization.Tests.Models;
|
|
|
|
public class ObservationDecayTests
|
|
{
|
|
[Fact]
|
|
public void Fresh_Should_CreateZeroAgeDecay()
|
|
{
|
|
// Arrange
|
|
var now = DateTimeOffset.UtcNow;
|
|
|
|
// Act
|
|
var decay = ObservationDecay.Fresh(now);
|
|
|
|
// Assert
|
|
decay.ObservedAt.Should().Be(now);
|
|
decay.RefreshedAt.Should().Be(now);
|
|
decay.CalculateDecay(now).Should().Be(1.0);
|
|
}
|
|
|
|
[Fact]
|
|
public void CalculateDecay_Should_ApplyHalfLifeFormula()
|
|
{
|
|
// Arrange
|
|
var observedAt = new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
|
var decay = ObservationDecay.Create(observedAt, observedAt);
|
|
|
|
// After 14 days (one half-life), decay should be ~0.5
|
|
var after14Days = observedAt.AddDays(14);
|
|
|
|
// Act
|
|
var decayValue = decay.CalculateDecay(after14Days);
|
|
|
|
// Assert
|
|
decayValue.Should().BeApproximately(0.5, 0.01);
|
|
}
|
|
|
|
[Fact]
|
|
public void CalculateDecay_Should_NotDropBelowFloor()
|
|
{
|
|
// Arrange
|
|
var observedAt = new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
|
var decay = ObservationDecay.Create(observedAt, observedAt);
|
|
|
|
// Very old observation (1 year)
|
|
var afterYear = observedAt.AddDays(365);
|
|
|
|
// Act
|
|
var decayValue = decay.CalculateDecay(afterYear);
|
|
|
|
// Assert
|
|
decayValue.Should().BeGreaterThanOrEqualTo(decay.Floor);
|
|
}
|
|
|
|
[Fact]
|
|
public void IsStale_Should_DetectStaleObservations()
|
|
{
|
|
// Arrange
|
|
var observedAt = new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero);
|
|
var decay = ObservationDecay.Create(observedAt, observedAt);
|
|
|
|
// Decay drops below 0.5 threshold around 14 days
|
|
var before = observedAt.AddDays(10);
|
|
var after = observedAt.AddDays(20);
|
|
|
|
// Act & Assert
|
|
decay.CheckIsStale(before).Should().BeFalse();
|
|
decay.CheckIsStale(after).Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void CalculateDecay_Should_ReturnOneForFutureDates()
|
|
{
|
|
// Arrange
|
|
var now = DateTimeOffset.UtcNow;
|
|
var decay = ObservationDecay.Fresh(now);
|
|
|
|
// Act (future date, should not decay)
|
|
var futureDecay = decay.CalculateDecay(now.AddDays(-1));
|
|
|
|
// Assert
|
|
futureDecay.Should().Be(1.0);
|
|
}
|
|
}
|