using Xunit; using WIDESEAWCS_S7Simulator.Core.Memory; namespace WIDESEAWCS_S7Simulator.UnitTests.Memory { public class MRegionTests { [Fact] public void Constructor_WithValidSize_CreatesRegion() { // Arrange & Act var region = new MRegion(1024); // Assert Assert.Equal("M", region.RegionType); Assert.Equal(1024, region.Size); } [Fact] public void Read_WithinBounds_ReturnsData() { // Arrange var region = new MRegion(1024); var testData = new byte[] { 0x12, 0x34, 0x56, 0x78 }; region.Write(0, testData); // Act var result = region.Read(0, 4); // Assert Assert.Equal(testData, result); } [Fact] public void Read_OutOfBounds_ThrowsArgumentOutOfRange() { // Arrange var region = new MRegion(100); // Act & Assert Assert.Throws(() => region.Read(0, 101)); } [Fact] public void Write_WithinBounds_WritesData() { // Arrange var region = new MRegion(1024); var testData = new byte[] { 0xAA, 0xBB, 0xCC, 0xDD }; // Act region.Write(100, testData); var result = region.Read(100, 4); // Assert Assert.Equal(testData, result); } [Fact] public void Write_OutOfBounds_ThrowsArgumentOutOfRange() { // Arrange var region = new MRegion(100); var testData = new byte[] { 0x01, 0x02 }; // Act & Assert Assert.Throws(() => region.Write(99, testData)); } [Fact] public void ReadBit_ValidBit_ReturnsCorrectValue() { // Arrange var region = new MRegion(1024); region.Write(0, new byte[] { 0xFF }); // 所有位为1 // Act var result = region.ReadBit(0, 0); // Assert Assert.True(result); } [Fact] public void WriteBit_ValidBit_SetsCorrectValue() { // Arrange var region = new MRegion(1024); // Act region.WriteBit(0, 3, true); var result = region.ReadBit(0, 3); // Assert Assert.True(result); } [Fact] public void WriteBit_InvalidBitOffset_ThrowsArgumentOutOfRange() { // Arrange var region = new MRegion(1024); // Act & Assert Assert.Throws(() => region.WriteBit(0, 8, true)); } [Fact] public void Clear_ZerosAllMemory() { // Arrange var region = new MRegion(100); region.Write(0, new byte[] { 0xFF, 0xFF, 0xFF }); // Act region.Clear(); var result = region.Read(0, 3); // Assert Assert.Equal(new byte[] { 0, 0, 0 }, result); } [Fact] public void ConcurrentReadWrite_ThreadSafe() { // Arrange var region = new MRegion(1024); var exceptions = new System.Collections.Concurrent.ConcurrentBag(); var cts = new CancellationTokenSource(); cts.CancelAfter(1000); // 1秒后取消 // Act var writeTask = Task.Run(() => { try { var data = new byte[] { 0xAA, 0xBB }; while (!cts.Token.IsCancellationRequested) { region.Write(0, data); } } catch (Exception ex) { exceptions.Add(ex); } }, cts.Token); var readTask = Task.Run(() => { try { while (!cts.Token.IsCancellationRequested) { region.Read(0, 2); } } catch (Exception ex) { exceptions.Add(ex); } }, cts.Token); Task.WaitAll(writeTask, readTask); // Assert Assert.Empty(exceptions); } } }