171 lines
6.8 KiB
C#
171 lines
6.8 KiB
C#
using System;
|
|
using XplorePlane.Models;
|
|
using Xunit;
|
|
using Xunit.Abstractions;
|
|
|
|
namespace XplorePlane.Tests.Models
|
|
{
|
|
public class StateModelsTests
|
|
{
|
|
private readonly ITestOutputHelper _output;
|
|
|
|
public StateModelsTests(ITestOutputHelper output)
|
|
{
|
|
_output = output;
|
|
}
|
|
|
|
// ── Default Value Tests ───────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void MotionState_Default_AllZeros()
|
|
{
|
|
var state = MotionState.Default;
|
|
_output.WriteLine($"MotionState.Default: XM={state.XM}, YM={state.YM}, ZT={state.ZT}, ZD={state.ZD}, TiltD={state.TiltD}, Dist={state.Dist}");
|
|
_output.WriteLine($" Speeds: XM={state.XMSpeed}, YM={state.YMSpeed}, ZT={state.ZTSpeed}, ZD={state.ZDSpeed}, TiltD={state.TiltDSpeed}, Dist={state.DistSpeed}");
|
|
|
|
Assert.Equal(0, state.XM);
|
|
Assert.Equal(0, state.YM);
|
|
Assert.Equal(0, state.ZT);
|
|
Assert.Equal(0, state.ZD);
|
|
Assert.Equal(0, state.TiltD);
|
|
Assert.Equal(0, state.Dist);
|
|
Assert.Equal(0, state.XMSpeed);
|
|
Assert.Equal(0, state.YMSpeed);
|
|
Assert.Equal(0, state.ZTSpeed);
|
|
Assert.Equal(0, state.ZDSpeed);
|
|
Assert.Equal(0, state.TiltDSpeed);
|
|
Assert.Equal(0, state.DistSpeed);
|
|
}
|
|
|
|
[Fact]
|
|
public void RaySourceState_Default_IsOffAndZeros()
|
|
{
|
|
var state = RaySourceState.Default;
|
|
_output.WriteLine($"RaySourceState.Default: IsOn={state.IsOn}, Voltage={state.Voltage}, Power={state.Power}");
|
|
|
|
Assert.False(state.IsOn);
|
|
Assert.Equal(0, state.Voltage);
|
|
Assert.Equal(0, state.Power);
|
|
}
|
|
|
|
[Fact]
|
|
public void DetectorState_Default_DisconnectedAndZeros()
|
|
{
|
|
var state = DetectorState.Default;
|
|
_output.WriteLine($"DetectorState.Default: IsConnected={state.IsConnected}, IsAcquiring={state.IsAcquiring}, FrameRate={state.FrameRate}, Resolution='{state.Resolution}'");
|
|
|
|
Assert.False(state.IsConnected);
|
|
Assert.False(state.IsAcquiring);
|
|
Assert.Equal(0, state.FrameRate);
|
|
Assert.Equal(string.Empty, state.Resolution);
|
|
}
|
|
|
|
[Fact]
|
|
public void SystemState_Default_IdleNoError()
|
|
{
|
|
var state = SystemState.Default;
|
|
_output.WriteLine($"SystemState.Default: OperationMode={state.OperationMode}, HasError={state.HasError}, ErrorMessage='{state.ErrorMessage}'");
|
|
|
|
Assert.Equal(OperationMode.Idle, state.OperationMode);
|
|
Assert.False(state.HasError);
|
|
Assert.Equal(string.Empty, state.ErrorMessage);
|
|
}
|
|
|
|
[Fact]
|
|
public void CameraState_Default_DisconnectedAndZeros()
|
|
{
|
|
var state = CameraState.Default;
|
|
_output.WriteLine($"CameraState.Default: IsConnected={state.IsConnected}, IsStreaming={state.IsStreaming}, CurrentFrame={state.CurrentFrame}, Width={state.Width}, Height={state.Height}, FrameRate={state.FrameRate}");
|
|
|
|
Assert.False(state.IsConnected);
|
|
Assert.False(state.IsStreaming);
|
|
Assert.Null(state.CurrentFrame);
|
|
Assert.Equal(0, state.Width);
|
|
Assert.Equal(0, state.Height);
|
|
Assert.Equal(0, state.FrameRate);
|
|
}
|
|
|
|
[Fact]
|
|
public void LinkedViewState_Default_ZeroPositionNotExecuting()
|
|
{
|
|
var state = LinkedViewState.Default;
|
|
_output.WriteLine($"LinkedViewState.Default: TargetPosition=({state.TargetPosition.X}, {state.TargetPosition.Y}, {state.TargetPosition.Z}), IsExecuting={state.IsExecuting}, LastRequestTime={state.LastRequestTime}");
|
|
|
|
Assert.Equal(0, state.TargetPosition.X);
|
|
Assert.Equal(0, state.TargetPosition.Y);
|
|
Assert.Equal(0, state.TargetPosition.Z);
|
|
Assert.False(state.IsExecuting);
|
|
Assert.Equal(DateTime.MinValue, state.LastRequestTime);
|
|
}
|
|
|
|
[Fact]
|
|
public void RecipeExecutionState_Default_IdleAndZeros()
|
|
{
|
|
var state = RecipeExecutionState.Default;
|
|
_output.WriteLine($"RecipeExecutionState.Default: CurrentStepIndex={state.CurrentStepIndex}, TotalSteps={state.TotalSteps}, Status={state.Status}, CurrentRecipeName='{state.CurrentRecipeName}'");
|
|
|
|
Assert.Equal(0, state.CurrentStepIndex);
|
|
Assert.Equal(0, state.TotalSteps);
|
|
Assert.Equal(RecipeExecutionStatus.Idle, state.Status);
|
|
Assert.Equal(string.Empty, state.CurrentRecipeName);
|
|
}
|
|
|
|
// ── Immutability Test ─────────────────────────────────────────
|
|
|
|
[Fact]
|
|
public void MotionState_WithExpression_ProducesNewInstance()
|
|
{
|
|
var original = MotionState.Default;
|
|
var modified = original with { XM = 100 };
|
|
_output.WriteLine($"Original.XM={original.XM}, Modified.XM={modified.XM}, SameRef={ReferenceEquals(original, modified)}");
|
|
|
|
// New instance is different from original
|
|
Assert.NotSame(original, modified);
|
|
Assert.Equal(100, modified.XM);
|
|
|
|
// Original is unchanged
|
|
Assert.Equal(0, original.XM);
|
|
}
|
|
|
|
// ── CalibrationMatrix Transform Tests ─────────────────────────
|
|
|
|
[Fact]
|
|
public void CalibrationMatrix_Transform_CorrectCalculation()
|
|
{
|
|
// Known matrix: scaling X by 2, Y by 3, with offsets
|
|
var matrix = new CalibrationMatrix(
|
|
M11: 2, M12: 0, M13: 10,
|
|
M21: 0, M22: 3, M23: 20,
|
|
M31: 0, M32: 0, M33: 0
|
|
);
|
|
|
|
var (x, y, z) = matrix.Transform(pixelX: 5, pixelY: 8);
|
|
_output.WriteLine($"Matrix Transform(5, 8): x={x}, y={y}, z={z} (expected: 20, 44, 0)");
|
|
|
|
// x = 2*5 + 0*8 + 10 = 20
|
|
Assert.Equal(20, x);
|
|
// y = 0*5 + 3*8 + 20 = 44
|
|
Assert.Equal(44, y);
|
|
// z = 0*5 + 0*8 + 0 = 0
|
|
Assert.Equal(0, z);
|
|
}
|
|
|
|
[Fact]
|
|
public void CalibrationMatrix_Transform_IdentityMatrix()
|
|
{
|
|
// Identity-like matrix: should return (pixelX, pixelY, 0) approximately
|
|
var identity = new CalibrationMatrix(
|
|
M11: 1, M12: 0, M13: 0,
|
|
M21: 0, M22: 1, M23: 0,
|
|
M31: 0, M32: 0, M33: 0
|
|
);
|
|
|
|
var (x, y, z) = identity.Transform(pixelX: 42.5, pixelY: 99.1);
|
|
_output.WriteLine($"Identity Transform(42.5, 99.1): x={x}, y={y}, z={z}");
|
|
|
|
Assert.Equal(42.5, x, precision: 10);
|
|
Assert.Equal(99.1, y, precision: 10);
|
|
Assert.Equal(0, z, precision: 10);
|
|
}
|
|
}
|
|
} |