camera-restore: - IEngineStateProvider.SetCamera 반사 쓰기 (HmegDirectStateProvider) - POST /camera/restore (BridgeHttpServer, StateRouter) - Recorder --sidecar-url + camera_snapshot 캡처 - UiaPlayerHost.TryRestoreCamera, PlayerEngine 재생 전 복원 - 149 tests LauncherUI (#15): - Sidecar URL 체크박스 + 입력란 (녹화/재생 모두 연동) - 재생 속도 슬라이더 (0.25x~4.0x, 기본 1.0x) - 빌드 타임스탬프 타이틀바 표시 - 녹화 완료 후 RecordNameBox 초기화 - UiAnalysisWindow 추가 PlayerEngine (#15): - CancellationToken 지원 (중단 버튼 동작) - Focus 스텝 early return (no-op, issue #11) - Type/Drag unresolvable UIA path fallback - SpeedMultiplier 옵션 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
95 lines
3.3 KiB
C#
95 lines
3.3 KiB
C#
using Recordingtest.Bridge;
|
|
using Recordingtest.Sut.EgBim.PluginHost;
|
|
using Xunit;
|
|
|
|
namespace Recordingtest.Sut.EgBim.PluginHost.Tests;
|
|
|
|
public class ChainedEngineStateProviderTests
|
|
{
|
|
private sealed class ScriptedProvider : IEngineStateProvider
|
|
{
|
|
public IReadOnlyList<string> SelectedIds = Array.Empty<string>();
|
|
public CameraSnapshot Camera = new(
|
|
new double[] { 0, 0, 0 },
|
|
new double[] { 0, 0, 0 },
|
|
new double[] { 0, 0, 1 },
|
|
45.0);
|
|
public SceneSnapshot Scene = new(0, null);
|
|
public bool Render = true;
|
|
|
|
public IReadOnlyList<string> GetSelectedIds() => SelectedIds;
|
|
public CameraSnapshot GetCamera() => Camera;
|
|
public SceneSnapshot GetScene() => Scene;
|
|
public bool GetRenderComplete() => Render;
|
|
public void SetCamera(CameraSnapshot snapshot) { /* tracked if needed */ }
|
|
}
|
|
|
|
[Fact]
|
|
public void Selection_Primary_NonEmpty_Wins()
|
|
{
|
|
var p = new ScriptedProvider { SelectedIds = new[] { "a" } };
|
|
var f = new ScriptedProvider { SelectedIds = new[] { "fallback" } };
|
|
var c = new ChainedEngineStateProvider(p, f);
|
|
Assert.Equal(new[] { "a" }, c.GetSelectedIds());
|
|
}
|
|
|
|
[Fact]
|
|
public void Selection_Primary_Empty_Falls_Through()
|
|
{
|
|
var p = new ScriptedProvider();
|
|
var f = new ScriptedProvider { SelectedIds = new[] { "fallback" } };
|
|
var c = new ChainedEngineStateProvider(p, f);
|
|
Assert.Equal(new[] { "fallback" }, c.GetSelectedIds());
|
|
}
|
|
|
|
[Fact]
|
|
public void Camera_Primary_Default_Falls_Through()
|
|
{
|
|
var p = new ScriptedProvider();
|
|
var fc = new CameraSnapshot(new double[] { 1, 2, 3 }, new double[] { 4, 5, 6 }, new double[] { 0, 0, 1 }, 60);
|
|
var f = new ScriptedProvider { Camera = fc };
|
|
var c = new ChainedEngineStateProvider(p, f);
|
|
Assert.Equal(60.0, c.GetCamera().Fov);
|
|
}
|
|
|
|
[Fact]
|
|
public void Camera_Primary_NonDefault_Wins()
|
|
{
|
|
var pc = new CameraSnapshot(new double[] { 1, 0, 0 }, new double[] { 0, 0, 0 }, new double[] { 0, 0, 1 }, 30);
|
|
var p = new ScriptedProvider { Camera = pc };
|
|
var f = new ScriptedProvider();
|
|
var c = new ChainedEngineStateProvider(p, f);
|
|
Assert.Equal(30.0, c.GetCamera().Fov);
|
|
}
|
|
|
|
[Fact]
|
|
public void Scene_Primary_Empty_Falls_Through()
|
|
{
|
|
var p = new ScriptedProvider();
|
|
var f = new ScriptedProvider { Scene = new(7, "x.hmeg") };
|
|
var c = new ChainedEngineStateProvider(p, f);
|
|
var s = c.GetScene();
|
|
Assert.Equal(7, s.ObjectCount);
|
|
Assert.Equal("x.hmeg", s.DocumentPath);
|
|
}
|
|
|
|
[Fact]
|
|
public void Scene_Primary_Has_Path_Wins_Even_With_Zero_Objects()
|
|
{
|
|
var p = new ScriptedProvider { Scene = new(0, "primary.hmeg") };
|
|
var f = new ScriptedProvider { Scene = new(99, "fallback.hmeg") };
|
|
var c = new ChainedEngineStateProvider(p, f);
|
|
var s = c.GetScene();
|
|
Assert.Equal("primary.hmeg", s.DocumentPath);
|
|
}
|
|
|
|
[Fact]
|
|
public void Render_Primary_Always_Wins()
|
|
{
|
|
var p = new ScriptedProvider { Render = false };
|
|
var f = new ScriptedProvider { Render = true };
|
|
var c = new ChainedEngineStateProvider(p, f);
|
|
Assert.False(c.GetRenderComplete());
|
|
}
|
|
}
|