Files
XplorePlane/XplorePlane.Tests/ViewModels/SnapshotManagerViewModelTests.cs
T
2026-05-18 09:38:29 +08:00

161 lines
7.7 KiB
C#

using Moq;
using System;
using System.Linq;
using System.Windows.Threading;
using Xunit;
using XP.Common.Logging.Interfaces;
using XplorePlane.Models;
using XplorePlane.Services.AppState;
using XplorePlane.ViewModels.Debug;
namespace XplorePlane.Tests.ViewModels
{
public class SnapshotManagerViewModelTests
{
private readonly Mock<IAppStateService> _mockAppStateService;
private readonly Mock<ILoggerService> _mockLoggerService;
private readonly Mock<ILoggerService> _mockLogger;
private readonly Dispatcher _dispatcher;
public SnapshotManagerViewModelTests()
{
_mockAppStateService = new Mock<IAppStateService>();
_mockLoggerService = new Mock<ILoggerService>();
_mockLogger = new Mock<ILoggerService>();
_mockLoggerService.Setup(x => x.ForModule<SnapshotManagerViewModel>()).Returns(_mockLogger.Object);
// Create a dispatcher for the current thread
_dispatcher = Dispatcher.CurrentDispatcher;
}
[Fact]
public void UpdateSnapshotDetails_WhenSnapshotSelected_ShouldPopulateSnapshotDetails()
{
// Arrange
var viewModel = new SnapshotManagerViewModel(_mockAppStateService.Object, _mockLoggerService.Object, _dispatcher);
var snapshot = new StateSnapshot
{
Id = Guid.NewGuid(),
Timestamp = DateTime.Now,
MotionState = new MotionState(
StageX: 100.5,
StageY: 200.3,
SourceZ: 300.1,
DetectorZ: 400.2,
DetectorSwing: 45.0,
FDD: 1000.0,
StageXSpeed: 10.0,
StageYSpeed: 20.0,
SourceZSpeed: 30.0,
DetectorZSpeed: 40.0,
DetectorSwingSpeed: 5.0,
FDDSpeed: 50.0,
StageRotation: 0.0,
FixtureRotation: 0.0,
FOD: 500.0,
Magnification: 2.0,
StageRotationSpeed: 0.0,
FixtureRotationSpeed: 0.0
),
RaySourceState = new RaySourceState(IsOn: true, Voltage: 160.0, Power: 8.0),
DetectorState = new DetectorState(IsConnected: true, IsAcquiring: false, FrameRate: 30.0, Resolution: "1920x1080"),
SystemState = new SystemState(OperationMode: OperationMode.Idle, HasError: false, ErrorMessage: ""),
CameraState = new CameraState(IsConnected: true, IsStreaming: false, CurrentFrame: null, Width: 1920, Height: 1080, FrameRate: 30.0),
LinkedViewState = new LinkedViewState(TargetPosition: new PhysicalPosition(0, 0, 0), IsExecuting: false, LastRequestTime: DateTime.Now),
RecipeExecutionState = new RecipeExecutionState(CurrentStepIndex: 0, TotalSteps: 10, Status: RecipeExecutionStatus.Idle, CurrentRecipeName: "Test Recipe"),
CalibrationMatrix = new CalibrationMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1)
};
var snapshotViewModel = new SnapshotViewModel { Snapshot = snapshot };
// Act
viewModel.SelectedSnapshot = snapshotViewModel;
// Assert
Assert.NotEmpty(viewModel.SnapshotDetails);
Assert.Equal(8, viewModel.SnapshotDetails.Count); // Should have 8 root nodes (one for each state type)
// Verify MotionState node exists and has children
var motionStateNode = viewModel.SnapshotDetails.FirstOrDefault(n => n.Name == "MotionState");
Assert.NotNull(motionStateNode);
Assert.NotEmpty(motionStateNode.Children);
// Verify specific field values
var stageXNode = motionStateNode.Children.FirstOrDefault(c => c.Name == "StageX");
Assert.NotNull(stageXNode);
Assert.Equal("100.50", stageXNode.Value);
// Verify RaySourceState node exists
var raySourceNode = viewModel.SnapshotDetails.FirstOrDefault(n => n.Name == "RaySourceState");
Assert.NotNull(raySourceNode);
Assert.NotEmpty(raySourceNode.Children);
}
[Fact]
public void UpdateSnapshotDetails_WhenNoSnapshotSelected_ShouldClearSnapshotDetails()
{
// Arrange
var viewModel = new SnapshotManagerViewModel(_mockAppStateService.Object, _mockLoggerService.Object, _dispatcher);
// Add a snapshot first
var snapshot = new StateSnapshot
{
Id = Guid.NewGuid(),
Timestamp = DateTime.Now,
MotionState = new MotionState(100, 200, 300, 400, 45, 1000, 10, 20, 30, 40, 5, 50, 0, 0, 500, 2, 0, 0),
RaySourceState = new RaySourceState(true, 160, 8),
DetectorState = new DetectorState(true, false, 30, "1920x1080"),
SystemState = new SystemState(OperationMode.Idle, false, ""),
CameraState = new CameraState(true, false, null, 1920, 1080, 30),
LinkedViewState = new LinkedViewState(new PhysicalPosition(0, 0, 0), false, DateTime.Now),
RecipeExecutionState = new RecipeExecutionState(0, 10, RecipeExecutionStatus.Idle, "Test"),
CalibrationMatrix = new CalibrationMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1)
};
viewModel.SelectedSnapshot = new SnapshotViewModel { Snapshot = snapshot };
Assert.NotEmpty(viewModel.SnapshotDetails);
// Act - Deselect snapshot
viewModel.SelectedSnapshot = null;
// Assert
Assert.Empty(viewModel.SnapshotDetails);
}
[Fact]
public void CaptureSnapshot_ShouldCreateSnapshotAndSelectIt()
{
// Arrange
var motionState = new MotionState(100, 200, 300, 400, 45, 1000, 10, 20, 30, 40, 5, 50, 0, 0, 500, 2, 0, 0);
var raySourceState = new RaySourceState(true, 160, 8);
var detectorState = new DetectorState(true, false, 30, "1920x1080");
var systemState = new SystemState(OperationMode.Idle, false, "");
var cameraState = new CameraState(true, false, null, 1920, 1080, 30);
var linkedViewState = new LinkedViewState(new PhysicalPosition(0, 0, 0), false, DateTime.Now);
var recipeState = new RecipeExecutionState(0, 10, RecipeExecutionStatus.Idle, "Test");
var calibMatrix = new CalibrationMatrix(1, 0, 0, 0, 1, 0, 0, 0, 1);
_mockAppStateService.Setup(x => x.MotionState).Returns(motionState);
_mockAppStateService.Setup(x => x.RaySourceState).Returns(raySourceState);
_mockAppStateService.Setup(x => x.DetectorState).Returns(detectorState);
_mockAppStateService.Setup(x => x.SystemState).Returns(systemState);
_mockAppStateService.Setup(x => x.CameraState).Returns(cameraState);
_mockAppStateService.Setup(x => x.LinkedViewState).Returns(linkedViewState);
_mockAppStateService.Setup(x => x.RecipeExecutionState).Returns(recipeState);
_mockAppStateService.Setup(x => x.CalibrationMatrix).Returns(calibMatrix);
var viewModel = new SnapshotManagerViewModel(_mockAppStateService.Object, _mockLoggerService.Object, _dispatcher);
// Act
viewModel.CaptureSnapshot();
// Assert
Assert.Single(viewModel.Snapshots);
Assert.NotNull(viewModel.SelectedSnapshot);
Assert.Equal(viewModel.Snapshots[0], viewModel.SelectedSnapshot);
Assert.NotEmpty(viewModel.SnapshotDetails); // Details should be populated for selected snapshot
}
}
}