Group all 69 projects into category subfolders under src/ and tests/ so the Rider Solution Explorer mirrors the module structure. Folders: Core, Server, Drivers (with a nested Driver CLIs subfolder), Client, Tooling. - Move every project folder on disk with git mv (history preserved as renames). - Recompute relative paths in 57 .csproj files: cross-category ProjectReferences, the lib/ HintPath+None refs in Driver.Historian.Wonderware, and the external mxaccessgw refs in Driver.Galaxy and its test project. - Rebuild ZB.MOM.WW.OtOpcUa.slnx with nested solution folders. - Re-prefix project paths in functional scripts (e2e, compliance, smoke SQL, integration, install). Build green (0 errors); unit tests pass. Docs left for a separate pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
101 lines
3.5 KiB
C#
101 lines
3.5 KiB
C#
using Shouldly;
|
|
using Xunit;
|
|
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions.Tests.Alarms;
|
|
|
|
/// <summary>
|
|
/// Contract tests for the <see cref="AlarmConditionInfo"/> record extension added in PR 2.1.
|
|
/// Five sub-attribute references (InAlarmRef, PriorityRef, DescAttrNameRef, AckedRef,
|
|
/// AckMsgWriteRef) carry the driver-side tag references the server-level alarm-condition
|
|
/// service uses to subscribe to live alarm-state attributes and route ack writes.
|
|
/// </summary>
|
|
public sealed class AlarmConditionInfoTests
|
|
{
|
|
[Fact]
|
|
public void LegacyThreeArgConstructor_StillCompiles_AndDefaultsRefsToNull()
|
|
{
|
|
var info = new AlarmConditionInfo(
|
|
SourceName: "Tank.HiHi",
|
|
InitialSeverity: AlarmSeverity.High,
|
|
InitialDescription: "High-high alarm");
|
|
|
|
info.SourceName.ShouldBe("Tank.HiHi");
|
|
info.InitialSeverity.ShouldBe(AlarmSeverity.High);
|
|
info.InitialDescription.ShouldBe("High-high alarm");
|
|
info.InAlarmRef.ShouldBeNull();
|
|
info.PriorityRef.ShouldBeNull();
|
|
info.DescAttrNameRef.ShouldBeNull();
|
|
info.AckedRef.ShouldBeNull();
|
|
info.AckMsgWriteRef.ShouldBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void FullConstructor_PopulatesAllFiveSubAttributeRefs()
|
|
{
|
|
var info = new AlarmConditionInfo(
|
|
SourceName: "Tank1.HiAlarm",
|
|
InitialSeverity: AlarmSeverity.Medium,
|
|
InitialDescription: "Tank level high",
|
|
InAlarmRef: "Tank1.HiAlarm.InAlarm",
|
|
PriorityRef: "Tank1.HiAlarm.Priority",
|
|
DescAttrNameRef: "Tank1.HiAlarm.DescAttrName",
|
|
AckedRef: "Tank1.HiAlarm.Acked",
|
|
AckMsgWriteRef: "Tank1.HiAlarm.AckMsg");
|
|
|
|
info.InAlarmRef.ShouldBe("Tank1.HiAlarm.InAlarm");
|
|
info.PriorityRef.ShouldBe("Tank1.HiAlarm.Priority");
|
|
info.DescAttrNameRef.ShouldBe("Tank1.HiAlarm.DescAttrName");
|
|
info.AckedRef.ShouldBe("Tank1.HiAlarm.Acked");
|
|
info.AckMsgWriteRef.ShouldBe("Tank1.HiAlarm.AckMsg");
|
|
}
|
|
|
|
[Fact]
|
|
public void RecordEquality_ComparesAllEightFields()
|
|
{
|
|
var a = new AlarmConditionInfo(
|
|
"T.Alarm", AlarmSeverity.Low, "desc",
|
|
"T.Alarm.InAlarm", "T.Alarm.Priority", "T.Alarm.DescAttrName",
|
|
"T.Alarm.Acked", "T.Alarm.AckMsg");
|
|
|
|
var b = new AlarmConditionInfo(
|
|
"T.Alarm", AlarmSeverity.Low, "desc",
|
|
"T.Alarm.InAlarm", "T.Alarm.Priority", "T.Alarm.DescAttrName",
|
|
"T.Alarm.Acked", "T.Alarm.AckMsg");
|
|
|
|
a.ShouldBe(b);
|
|
}
|
|
|
|
[Fact]
|
|
public void RecordEquality_DistinctWhenAnyRefDiffers()
|
|
{
|
|
var baseInfo = new AlarmConditionInfo(
|
|
"T.Alarm", AlarmSeverity.Low, "desc",
|
|
InAlarmRef: "T.Alarm.InAlarm");
|
|
|
|
var differingAckRef = baseInfo with { AckedRef = "T.Alarm.Acked" };
|
|
|
|
baseInfo.ShouldNotBe(differingAckRef);
|
|
}
|
|
|
|
[Fact]
|
|
public void WithExpression_AllowsPartialUpdates()
|
|
{
|
|
var legacy = new AlarmConditionInfo("S", AlarmSeverity.Medium, null);
|
|
|
|
var enriched = legacy with
|
|
{
|
|
InAlarmRef = "S.InAlarm",
|
|
AckedRef = "S.Acked",
|
|
AckMsgWriteRef = "S.AckMsg",
|
|
};
|
|
|
|
enriched.SourceName.ShouldBe("S");
|
|
enriched.InAlarmRef.ShouldBe("S.InAlarm");
|
|
enriched.PriorityRef.ShouldBeNull();
|
|
enriched.DescAttrNameRef.ShouldBeNull();
|
|
enriched.AckedRef.ShouldBe("S.Acked");
|
|
enriched.AckMsgWriteRef.ShouldBe("S.AckMsg");
|
|
}
|
|
}
|