- T11 路径编辑(PathEditingAutomationTests):删除点/更新位置/正交化/去环 - T12 路径导出(ExportImportRoundTripAutomationTests):XML/JSON 导出→导入回环 - T13 播放控制(AnimationPlaybackControlAutomationTests):pause 验证帧停止/resume 前进 - T14 批量队列(BatchQueueAutomationTests):队列添加/计数递增 - T15 路径分析(PathAnalysisAutomationTests):评分结构验证 - 服务端新增 5 端点:export-route-file/edit-route/animation-playback-control/batch-queue-add/analyze-path - 产品 bug 修复:PathDatabase.CollisionResults 表已废弃→GetCollisionCount 改查 CollisionReports、 SaveCollisions 异常保护;路径编辑真删点走 PathRoute.RemovePoint(RemovePathPoint 仅 3D 标记) 验证:集成测试 24/24 通过,完整集 74.6s(15fps/5s 动画)
102 lines
5.4 KiB
C#
102 lines
5.4 KiB
C#
using System;
|
||
using System.IO;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||
using Newtonsoft.Json.Linq;
|
||
|
||
namespace NavisworksTransport.UnitTests.Integration
|
||
{
|
||
/// <summary>
|
||
/// 路径编辑集成测试(覆盖计划 T11)。
|
||
///
|
||
/// 验证 PathPlanningManager 编辑链路:
|
||
/// - 删除路径点(remove-point:点数递减)
|
||
/// - 更新路径点位置(update-point:坐标更新)
|
||
/// - 正交化(orthogonalize)
|
||
/// - 去除矩形环(remove-loops)
|
||
///
|
||
/// 使用独立导入的临时路径,避免影响标准测试路径。
|
||
/// </summary>
|
||
[TestClass]
|
||
[TestCategory("NavisworksIntegration")]
|
||
public class PathEditingAutomationTests
|
||
{
|
||
private const string RouteName = "路径编辑_测试";
|
||
|
||
[TestMethod]
|
||
[Timeout(120000)]
|
||
public async Task EditRoute_RemoveUpdateOrthogonalize_Work()
|
||
{
|
||
using (var client = new NavisworksTestAutomationClient())
|
||
{
|
||
await client.EnsureServiceReadyAsync(TimeSpan.FromSeconds(90)).ConfigureAwait(false);
|
||
|
||
string tempDir = Path.Combine(Path.GetTempPath(), "NavisworksTransportIntegrationTests", Guid.NewGuid().ToString("N"));
|
||
Directory.CreateDirectory(tempDir);
|
||
try
|
||
{
|
||
// 1. 导入 3 点测试路径
|
||
string filePath = Path.Combine(tempDir, "edit-route.json");
|
||
File.WriteAllText(filePath, BuildEditRouteJson(), new UTF8Encoding(false));
|
||
JObject importResponse = await client.ImportRouteFileAsync(filePath, overwrite: true).ConfigureAwait(false);
|
||
Assert.IsTrue(importResponse.Value<bool>("ok"), "导入编辑路径失败: " + (string)importResponse["error"]);
|
||
Assert.AreEqual(3, (int)((JArray)importResponse["data"]["routes"])[0]["pointCount"], "初始点数应为 3");
|
||
|
||
// 2. 删除中间点(index=1)
|
||
JObject removeResponse = await client.EditRouteAsync("remove-point", RouteName, pointIndex: 1).ConfigureAwait(false);
|
||
Assert.IsTrue(removeResponse.Value<bool>("ok"), "删除路径点失败: " + (string)removeResponse["error"]);
|
||
Assert.AreEqual(2, (int)removeResponse["data"]["pointCount"], "删除后点数应为 2");
|
||
|
||
// 3. 更新起点位置
|
||
JObject updateResponse = await client.EditRouteAsync(
|
||
"update-point", RouteName,
|
||
pointIndex: 0, x: -204.608, y: 14.833, z: 20.0).ConfigureAwait(false);
|
||
Assert.IsTrue(updateResponse.Value<bool>("ok"), "更新路径点失败: " + (string)updateResponse["error"]);
|
||
JArray updatedPoints = (JArray)updateResponse["data"]["points"];
|
||
JObject updatedStart = (JObject)updatedPoints[0]["position"];
|
||
Assert.AreEqual(20.0, (double)updatedStart["z"], 1e-2, "更新后的 Z 坐标不匹配");
|
||
|
||
// 4. 正交化
|
||
JObject orthogonalizeResponse = await client.EditRouteAsync("orthogonalize", RouteName).ConfigureAwait(false);
|
||
Assert.IsTrue(orthogonalizeResponse.Value<bool>("ok"), "正交化失败: " + (string)orthogonalizeResponse["error"]);
|
||
Assert.IsTrue((int)orthogonalizeResponse["data"]["pointCount"] >= 2, "正交化后点数应 >= 2");
|
||
|
||
// 5. 去除矩形环
|
||
JObject removeLoopsResponse = await client.EditRouteAsync("remove-loops", RouteName).ConfigureAwait(false);
|
||
Assert.IsTrue(removeLoopsResponse.Value<bool>("ok"), "去除矩形环失败: " + (string)removeLoopsResponse["error"]);
|
||
}
|
||
finally
|
||
{
|
||
SafeDelete(tempDir);
|
||
}
|
||
}
|
||
}
|
||
|
||
private static string BuildEditRouteJson()
|
||
{
|
||
return string.Format(
|
||
System.Globalization.CultureInfo.InvariantCulture,
|
||
@"{{""PathPlanningData"":{{""version"":""1.0"",""generator"":""integration-test"",""timestamp"":""2026-08-04T21:30:00"",""ProjectInfo"":{{""name"":""test"",""description"":""test"",""units"":""meters"",""coordinateSystem"":""Global""}},""Routes"":[{{""id"":""edit-route-{0}"",""name"":""{1}"",""description"":"""",""pathType"":""Ground"",""totalLength"":20.0,""objectLimits"":{{""maxLength"":0,""maxWidth"":0,""maxHeight"":0,""safetyMargin"":0}},""gridSize"":1.0,""liftHeight"":0.0,""created"":""2026-08-04T21:30:00"",""points"":[{{""id"":""er-p1"",""name"":""start"",""type"":""StartPoint"",""index"":0,""x"":-204.608,""y"":14.833,""z"":19.250,""created"":""2026-08-04T21:30:00""}},{{""id"":""er-p2"",""name"":""mid"",""type"":""WayPoint"",""index"":1,""x"":-206.608,""y"":14.833,""z"":18.250,""created"":""2026-08-04T21:30:00""}},{{""id"":""er-p3"",""name"":""end"",""type"":""EndPoint"",""index"":2,""x"":-208.608,""y"":14.833,""z"":17.250,""created"":""2026-08-04T21:30:00""}}]}}]}}}}",
|
||
Guid.NewGuid().ToString("N"),
|
||
RouteName);
|
||
}
|
||
|
||
private static void SafeDelete(string directory)
|
||
{
|
||
if (!Directory.Exists(directory))
|
||
{
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
Directory.Delete(directory, true);
|
||
}
|
||
catch
|
||
{
|
||
}
|
||
}
|
||
}
|
||
}
|