Files
QuanTAlib/lib/core/tseries/tests/ITValuePublisher.Tests.cs
Miha Kralj 060649192f docs: remove C# Implementation Considerations sections, clean up temp scripts, reorganize test files
- Remove 'C# Implementation Considerations' sections from 34 indicator .md files
- Delete 29 temp PowerShell scripts (_fix_mojibake.ps1, _hex_scan.ps1, etc.)
- Move test files into tests/ subdirectories for consistent project structure
- Add trader-focused bullet points to indicator documentation
2026-03-12 12:34:16 -07:00

542 lines
16 KiB
C#

namespace QuanTAlib.Tests;
public class TValueEventArgsTests
{
[Fact]
public void Constructor_WithValueAndIsNew_SetsPropertiesCorrectly()
{
var tValue = new TValue(DateTime.UtcNow.Ticks, 123.45);
const bool isNew = true;
var eventArgs = new TValueEventArgs { Value = tValue, IsNew = isNew };
Assert.Equal(tValue, eventArgs.Value);
Assert.True(eventArgs.IsNew);
}
[Fact]
public void Constructor_Default_SetsDefaultValues()
{
var eventArgs = new TValueEventArgs();
Assert.Equal(default(TValue), eventArgs.Value);
Assert.False(eventArgs.IsNew);
}
[Fact]
public void Constructor_WithNaNValue_PreservesNaN()
{
var tValue = new TValue(DateTime.UtcNow.Ticks, double.NaN);
var eventArgs = new TValueEventArgs { Value = tValue, IsNew = false };
Assert.True(double.IsNaN(eventArgs.Value.Value));
}
[Fact]
public void Constructor_WithInfinityValue_PreservesInfinity()
{
var tValue = new TValue(DateTime.UtcNow.Ticks, double.PositiveInfinity);
var eventArgs = new TValueEventArgs { Value = tValue, IsNew = true };
Assert.True(double.IsPositiveInfinity(eventArgs.Value.Value));
}
[Fact]
public void Equals_SameValues_ReturnsTrue()
{
var tValue = new TValue(12345, 100.0);
var args1 = new TValueEventArgs { Value = tValue, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue, IsNew = true };
Assert.True(args1.Equals(args2));
}
[Fact]
public void Equals_DifferentValue_ReturnsFalse()
{
var tValue1 = new TValue(12345, 100.0);
var tValue2 = new TValue(12345, 101.0);
var args1 = new TValueEventArgs { Value = tValue1, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue2, IsNew = true };
Assert.False(args1.Equals(args2));
}
[Fact]
public void Equals_DifferentTime_ReturnsFalse()
{
var tValue1 = new TValue(12345, 100.0);
var tValue2 = new TValue(12346, 100.0);
var args1 = new TValueEventArgs { Value = tValue1, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue2, IsNew = true };
Assert.False(args1.Equals(args2));
}
[Fact]
public void Equals_DifferentIsNew_ReturnsFalse()
{
var tValue = new TValue(12345, 100.0);
var args1 = new TValueEventArgs { Value = tValue, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue, IsNew = false };
Assert.False(args1.Equals(args2));
}
[Fact]
public void Equals_Object_SameTValueEventArgs_ReturnsTrue()
{
var tValue = new TValue(12345, 100.0);
var args1 = new TValueEventArgs { Value = tValue, IsNew = true };
object args2 = new TValueEventArgs { Value = tValue, IsNew = true };
Assert.True(args1.Equals(args2));
}
[Fact]
public void Equals_Object_DifferentType_ReturnsFalse()
{
var args = new TValueEventArgs { Value = new TValue(12345, 100.0), IsNew = true };
object other = "not a TValueEventArgs";
Assert.False(args.Equals(other));
}
[Fact]
public void Equals_Object_Null_ReturnsFalse()
{
var args = new TValueEventArgs { Value = new TValue(12345, 100.0), IsNew = true };
Assert.False(args.Equals(null));
}
[Fact]
public void GetHashCode_SameValues_ReturnsSameHashCode()
{
var tValue = new TValue(12345, 100.0);
var args1 = new TValueEventArgs { Value = tValue, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue, IsNew = true };
Assert.Equal(args1.GetHashCode(), args2.GetHashCode());
}
[Fact]
public void GetHashCode_DifferentValues_ReturnsDifferentHashCode()
{
var tValue1 = new TValue(12345, 100.0);
var tValue2 = new TValue(12346, 100.0);
var args1 = new TValueEventArgs { Value = tValue1, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue2, IsNew = true };
Assert.NotEqual(args1.GetHashCode(), args2.GetHashCode());
}
[Fact]
public void GetHashCode_DifferentIsNew_ReturnsDifferentHashCode()
{
var tValue = new TValue(12345, 100.0);
var args1 = new TValueEventArgs { Value = tValue, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue, IsNew = false };
Assert.NotEqual(args1.GetHashCode(), args2.GetHashCode());
}
[Fact]
public void EqualityOperator_SameValues_ReturnsTrue()
{
var tValue = new TValue(12345, 100.0);
var args1 = new TValueEventArgs { Value = tValue, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue, IsNew = true };
Assert.True(args1 == args2);
}
[Fact]
public void EqualityOperator_DifferentValues_ReturnsFalse()
{
var tValue1 = new TValue(12345, 100.0);
var tValue2 = new TValue(12346, 100.0);
var args1 = new TValueEventArgs { Value = tValue1, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue2, IsNew = true };
Assert.False(args1 == args2);
}
[Fact]
public void InequalityOperator_SameValues_ReturnsFalse()
{
var tValue = new TValue(12345, 100.0);
var args1 = new TValueEventArgs { Value = tValue, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue, IsNew = true };
Assert.False(args1 != args2);
}
[Fact]
public void InequalityOperator_DifferentValues_ReturnsTrue()
{
var tValue1 = new TValue(12345, 100.0);
var tValue2 = new TValue(12346, 100.0);
var args1 = new TValueEventArgs { Value = tValue1, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue2, IsNew = true };
Assert.True(args1 != args2);
}
[Fact]
public void Equals_WithNaN_BothNaN_ReturnsTrue()
{
var tValue1 = new TValue(12345, double.NaN);
var tValue2 = new TValue(12345, double.NaN);
var args1 = new TValueEventArgs { Value = tValue1, IsNew = true };
var args2 = new TValueEventArgs { Value = tValue2, IsNew = true };
Assert.True(args1.Equals(args2));
}
[Fact]
public void GetHashCode_WithNaN_DoesNotThrow()
{
var tValue = new TValue(12345, double.NaN);
var args = new TValueEventArgs { Value = tValue, IsNew = true };
var hash = args.GetHashCode();
Assert.True(hash != 0 || hash == 0); // Just verify it doesn't throw
}
[Fact]
public void Constructor_WithZeroTime_Allowed()
{
var tValue = new TValue(0, 100.0);
var args = new TValueEventArgs { Value = tValue, IsNew = false };
Assert.Equal(0, args.Value.Time);
Assert.Equal(100.0, args.Value.Value);
Assert.False(args.IsNew);
}
[Fact]
public void Constructor_WithNegativeTime_Allowed()
{
var tValue = new TValue(-12345, 100.0);
var args = new TValueEventArgs { Value = tValue, IsNew = true };
Assert.Equal(-12345, args.Value.Time);
Assert.Equal(100.0, args.Value.Value);
Assert.True(args.IsNew);
}
[Fact]
public void Constructor_WithMaxLongTime_Allowed()
{
var tValue = new TValue(long.MaxValue, 100.0);
var args = new TValueEventArgs { Value = tValue, IsNew = false };
Assert.Equal(long.MaxValue, args.Value.Time);
Assert.Equal(100.0, args.Value.Value);
Assert.False(args.IsNew);
}
[Fact]
public void Constructor_WithMaxDoubleValue_Allowed()
{
var tValue = new TValue(DateTime.UtcNow.Ticks, double.MaxValue);
var args = new TValueEventArgs { Value = tValue, IsNew = true };
Assert.Equal(double.MaxValue, args.Value.Value);
Assert.True(args.IsNew);
}
[Fact]
public void Constructor_WithMinDoubleValue_Allowed()
{
var tValue = new TValue(DateTime.UtcNow.Ticks, double.MinValue);
var args = new TValueEventArgs { Value = tValue, IsNew = false };
Assert.Equal(double.MinValue, args.Value.Value);
Assert.False(args.IsNew);
}
[Fact]
public void Constructor_WithEpsilonValue_Allowed()
{
var tValue = new TValue(DateTime.UtcNow.Ticks, double.Epsilon);
var args = new TValueEventArgs { Value = tValue, IsNew = true };
Assert.Equal(double.Epsilon, args.Value.Value);
Assert.True(args.IsNew);
}
}
public class TValuePublishedHandlerTests
{
private class MockPublisher : ITValuePublisher
{
#pragma warning disable CS0067 // Event is never used - intentional for delegate testing
public event TValuePublishedHandler? Pub;
#pragma warning restore CS0067
}
[Fact]
public void Delegate_CanBeAssigned()
{
TValuePublishedHandler handler = (_, in _) => { };
Assert.NotNull(handler);
}
[Fact]
public void Delegate_CanBeInvoked()
{
bool wasCalled = false;
TValuePublishedHandler handler = (object? sender, in TValueEventArgs args) => wasCalled = true;
var args = new TValueEventArgs { Value = new TValue(12345, 100.0), IsNew = true };
handler(null, args);
Assert.True(wasCalled);
}
[Fact]
public void Delegate_ReceivesCorrectArguments()
{
object? receivedSender = null;
TValueEventArgs receivedArgs = default;
TValuePublishedHandler handler = (object? sender, in TValueEventArgs args) =>
{
receivedSender = sender;
receivedArgs = args;
};
var publisher = new MockPublisher();
var expectedArgs = new TValueEventArgs { Value = new TValue(12345, 100.0), IsNew = true };
handler(publisher, expectedArgs);
Assert.Equal(publisher, receivedSender);
Assert.Equal(expectedArgs, receivedArgs);
}
[Fact]
public void Delegate_CanBeNull()
{
TValuePublishedHandler? handler = null;
var exception = Record.Exception(() => handler?.Invoke(null, new TValueEventArgs()));
Assert.Null(exception);
}
}
public class ITValuePublisherTests
{
private class MockPublisher : ITValuePublisher
{
public event TValuePublishedHandler? Pub;
public void RaiseEvent(TValue value, bool isNew = true)
{
Pub?.Invoke(this, new TValueEventArgs { Value = value, IsNew = isNew });
}
}
[Fact]
public void Interface_CanBeImplemented()
{
ITValuePublisher publisher = new MockPublisher();
Assert.NotNull(publisher);
}
[Fact]
public void Pub_Event_CanBeSubscribed()
{
var publisher = new MockPublisher();
bool eventRaised = false;
publisher.Pub += (object? sender, in TValueEventArgs args) => eventRaised = true;
publisher.RaiseEvent(new TValue(12345, 100.0));
Assert.True(eventRaised);
}
[Fact]
public void Pub_Event_CanBeUnsubscribed()
{
var publisher = new MockPublisher();
bool eventRaised = false;
TValuePublishedHandler handler = (object? sender, in TValueEventArgs args) => eventRaised = true;
publisher.Pub += handler;
publisher.RaiseEvent(new TValue(12345, 100.0));
Assert.True(eventRaised);
eventRaised = false;
publisher.Pub -= handler;
publisher.RaiseEvent(new TValue(12346, 101.0));
Assert.False(eventRaised);
}
[Fact]
public void Pub_Event_MultipleSubscribers_AllReceiveEvent()
{
var publisher = new MockPublisher();
bool event1Raised = false;
bool event2Raised = false;
publisher.Pub += (object? sender, in TValueEventArgs args) => event1Raised = true;
publisher.Pub += (object? sender, in TValueEventArgs args) => event2Raised = true;
publisher.RaiseEvent(new TValue(12345, 100.0));
Assert.True(event1Raised);
Assert.True(event2Raised);
}
[Fact]
public void Pub_Event_NoSubscribers_DoesNotThrow()
{
var publisher = new MockPublisher();
var exception = Record.Exception(() => publisher.RaiseEvent(new TValue(12345, 100.0)));
Assert.Null(exception);
}
[Fact]
public void Pub_Event_ReceivesCorrectSender()
{
var publisher = new MockPublisher();
object? receivedSender = null;
publisher.Pub += (object? sender, in TValueEventArgs args) => receivedSender = sender;
publisher.RaiseEvent(new TValue(12345, 100.0));
Assert.Equal(publisher, receivedSender);
}
[Fact]
public void Pub_Event_ReceivesCorrectEventArgs()
{
var publisher = new MockPublisher();
TValueEventArgs receivedArgs = default;
publisher.Pub += (object? sender, in TValueEventArgs args) => receivedArgs = args;
var expectedValue = new TValue(12345, 100.0);
publisher.RaiseEvent(expectedValue, isNew: true);
Assert.Equal(expectedValue, receivedArgs.Value);
Assert.True(receivedArgs.IsNew);
}
[Fact]
public void Pub_Event_IsNew_False_ReceivedCorrectly()
{
var publisher = new MockPublisher();
TValueEventArgs receivedArgs = default;
publisher.Pub += (object? sender, in TValueEventArgs args) => receivedArgs = args;
var expectedValue = new TValue(12345, 100.0);
publisher.RaiseEvent(expectedValue, isNew: false);
Assert.Equal(expectedValue, receivedArgs.Value);
Assert.False(receivedArgs.IsNew);
}
[Fact]
public void Pub_Event_HandlerThrows_ExceptionPropagates()
{
var publisher = new MockPublisher();
publisher.Pub += (object? sender, in TValueEventArgs args) =>
{
throw new InvalidOperationException("Test exception");
};
Assert.Throws<InvalidOperationException>(() =>
publisher.RaiseEvent(new TValue(12345, 100.0)));
}
[Fact]
public void Pub_Event_HandlerWithNaNValue_ReceivesNaN()
{
var publisher = new MockPublisher();
double receivedValue = 0;
publisher.Pub += (object? sender, in TValueEventArgs args) => receivedValue = args.Value.Value;
publisher.RaiseEvent(new TValue(12345, double.NaN));
Assert.True(double.IsNaN(receivedValue));
}
[Fact]
public void Pub_Event_HandlerWithInfinityValue_ReceivesInfinity()
{
var publisher = new MockPublisher();
double receivedValue = 0;
publisher.Pub += (object? sender, in TValueEventArgs args) => receivedValue = args.Value.Value;
publisher.RaiseEvent(new TValue(12345, double.PositiveInfinity));
Assert.True(double.IsPositiveInfinity(receivedValue));
}
[Fact]
public void Pub_Event_MultipleEvents_AllReceived()
{
var publisher = new MockPublisher();
var receivedValues = new List<double>();
publisher.Pub += (object? sender, in TValueEventArgs args) => receivedValues.Add(args.Value.Value);
publisher.RaiseEvent(new TValue(12345, 100.0));
publisher.RaiseEvent(new TValue(12346, 200.0));
publisher.RaiseEvent(new TValue(12347, 300.0));
Assert.Equal(3, receivedValues.Count);
Assert.Equal(100.0, receivedValues[0]);
Assert.Equal(200.0, receivedValues[1]);
Assert.Equal(300.0, receivedValues[2]);
}
[Fact]
public void Pub_Event_SubscribeUnsubscribeMultipleTimes_Works()
{
var publisher = new MockPublisher();
int callCount = 0;
TValuePublishedHandler handler = (object? sender, in TValueEventArgs args) => callCount++;
// Subscribe multiple times
publisher.Pub += handler;
publisher.Pub += handler;
publisher.RaiseEvent(new TValue(12345, 100.0));
Assert.Equal(2, callCount); // Called twice
callCount = 0;
// Unsubscribe once
publisher.Pub -= handler;
publisher.RaiseEvent(new TValue(12346, 200.0));
Assert.Equal(1, callCount); // Called once
callCount = 0;
// Unsubscribe remaining
publisher.Pub -= handler;
publisher.RaiseEvent(new TValue(12347, 300.0));
Assert.Equal(0, callCount); // Not called
}
}