2.0协议完善加简单交管配置

This commit is contained in:
ykkokluo
2026-08-14 09:49:23 +08:00
parent a28bc68e23
commit 1e780c2b65
51 changed files with 4013 additions and 393 deletions
@@ -0,0 +1,164 @@
using StandardScene.Magnetic.Protocol;
using StandardScene.Magnetic.Tasking;
using System.Collections.Generic;
using Xunit;
namespace StandardScene.Magnetic.Tests.Tasking
{
public class Fass2ControlAreaGateTests
{
[Fact]
public void Resolve_WithoutArea_UsesCurrentSite()
{
var info = Fass2ControlAreaGate.Resolve(new Fass2SiteActionData(), 17);
Assert.Equal(new[] { 17 }, info.AreaSiteIds);
Assert.Equal("17", info.AreaId);
Assert.Equal(1, info.Capacity);
Assert.Equal(Fass2TaskBuilder.StartStopControlStart, info.ReleaseStartStop);
}
[Fact]
public void Resolve_ParsesSiteArray_AndReleasePass()
{
var info = Fass2ControlAreaGate.Resolve(new Fass2SiteActionData
{
ControlArea = "[10, 11, 12]",
ControlCapacity = 2,
ControlReleaseStartStop = Fass2TaskBuilder.StartStopPass
}, 8);
Assert.Equal(new[] { 10, 11, 12 }, info.AreaSiteIds);
Assert.Equal("10,11,12", info.AreaId);
Assert.Equal(2, info.Capacity);
Assert.Equal(Fass2TaskBuilder.StartStopPass, info.ReleaseStartStop);
}
[Fact]
public void ParseSiteIds_CommaAndSemicolon()
{
var ids = Fass2ControlAreaGate.ParseSiteIds("10;11|12", 8);
Assert.Equal(new[] { 10, 11, 12 }, ids);
}
[Fact]
public void LimitWindow_StopsAtFirstUnreleasedControlStop()
{
var nodes = new[]
{
Node(1, Fass2TaskBuilder.StartStopPass),
Node(2, Fass2TaskBuilder.StartStopControlStop),
Node(3, Fass2TaskBuilder.StartStopPass),
Node(4, Fass2TaskBuilder.StartStopPass)
};
var count = Fass2ControlAreaGate.LimitWindowCount(nodes, 0, 4, releasedIndex: -1);
Assert.Equal(2, count);
}
[Fact]
public void LimitWindow_AfterRelease_IncludesFollowingNodes()
{
var nodes = new[]
{
Node(1, Fass2TaskBuilder.StartStopPass),
Node(2, Fass2TaskBuilder.StartStopControlStart),
Node(3, Fass2TaskBuilder.StartStopPass)
};
var count = Fass2ControlAreaGate.LimitWindowCount(nodes, 1, 3, releasedIndex: 1);
Assert.Equal(2, count);
}
[Fact]
public void Evaluate_ExcludesSelf_AllowsFirstCar()
{
var area = Area(1, 10, 11);
var occupancies = new List<Fass2ControlOccupancy>
{
new Fass2ControlOccupancy(1, new[] { 10, 11 })
};
var check = Fass2ControlAreaGate.Evaluate(1, area, occupancies);
Assert.True(check.CanRelease);
Assert.Equal(0, check.OthersInArea);
}
[Fact]
public void Evaluate_OtherCarOnListedSite_EqualsCapacity_Blocks()
{
var area = Area(1, 10, 11);
var occupancies = new List<Fass2ControlOccupancy>
{
new Fass2ControlOccupancy(1, new[] { 8 }),
new Fass2ControlOccupancy(2, new[] { 11 })
};
var check = Fass2ControlAreaGate.Evaluate(1, area, occupancies);
Assert.False(check.CanRelease);
Assert.Equal(1, check.OthersInArea);
Assert.Contains("capacity=1", check.Reason);
}
[Fact]
public void Evaluate_OtherCarOutsideList_DoesNotBlock()
{
var area = Area(1, 10, 11);
var occupancies = new List<Fass2ControlOccupancy>
{
new Fass2ControlOccupancy(2, new[] { 99 })
};
var check = Fass2ControlAreaGate.Evaluate(1, area, occupancies);
Assert.True(check.CanRelease);
Assert.Equal(0, check.OthersInArea);
}
[Fact]
public void Evaluate_CapacityTwo_AllowsSecondCar()
{
var area = Area(2, 10, 11);
var occupancies = new List<Fass2ControlOccupancy>
{
new Fass2ControlOccupancy(1, new[] { 10 }),
new Fass2ControlOccupancy(2, new[] { 11 })
};
var check = Fass2ControlAreaGate.Evaluate(2, area, occupancies);
Assert.True(check.CanRelease);
Assert.Equal(1, check.OthersInArea);
}
[Fact]
public void ActionResolver_ControlStop_IsNeverComplete()
{
var expected = Node(5, Fass2TaskBuilder.StartStopControlStop);
var actual = Node(5, Fass2TaskBuilder.StartStopControlStop);
Assert.True(Fass2ActionResolver.RequiresActionWait(expected));
Assert.False(Fass2ActionResolver.IsStationActionComplete(expected, actual, vehicleState: 2));
}
private static Fass2ControlAreaInfo Area(int capacity, params int[] siteIds)
{
return new Fass2ControlAreaInfo
{
AreaSiteIds = siteIds,
AreaId = string.Join(",", siteIds),
Capacity = capacity,
ReleaseStartStop = 11
};
}
private static Fass2NodeMessage Node(ushort id, byte startStop)
{
return new Fass2NodeMessage { Node = id, StartStop = startStop };
}
}
}