diff --git a/README.md b/README.md index acb68ba4..e266306c 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ The following is on my roadmap for future updates: ### Prerequisites -OpenTracker is a .NET 8.0 application. You will be required to install a .NET runtime version 8.0 or greater. You can find it at this link: https://dotnet.microsoft.com/download/dotnet +OpenTracker is a .NET 10.0 application. You will be required to install a .NET runtime version 10.0 or greater. You can find it at this link: https://dotnet.microsoft.com/download/dotnet ### Windows diff --git a/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/GetDeviceInfoRequest.cs b/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/GetDeviceInfoRequest.cs index e1491bed..6b928f0b 100644 --- a/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/GetDeviceInfoRequest.cs +++ b/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/GetDeviceInfoRequest.cs @@ -1,10 +1,9 @@ -using System; using System.Collections.Generic; using System.Threading; using Newtonsoft.Json; using OpenTracker.Models.AutoTracking.SNESConnectors.Socket; +using OpenTracker.Models.Exceptions; using OpenTracker.Models.Logging; -using LogLevel = OpenTracker.Models.Logging.LogLevel; namespace OpenTracker.Models.AutoTracking.SNESConnectors.Requests { @@ -34,8 +33,7 @@ public override IEnumerable ProcessResponseAndReturnResults(IMessageEven if (!deserialized!.TryGetValue("Results", out var results)) { - throw new Exception( - $"Request \'{Description}\' is invalid and does not contain a \'Results\' key."); + throw new InvalidRequestResponseException(Description, "Results"); } Logger.Debug("Request \'{Description}\' response successfully deserialized", diff --git a/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/GetDevicesRequest.cs b/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/GetDevicesRequest.cs index 227f41b0..8d81b3de 100644 --- a/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/GetDevicesRequest.cs +++ b/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/GetDevicesRequest.cs @@ -3,8 +3,8 @@ using System.Threading; using Newtonsoft.Json; using OpenTracker.Models.AutoTracking.SNESConnectors.Socket; +using OpenTracker.Models.Exceptions; using OpenTracker.Models.Logging; -using LogLevel = OpenTracker.Models.Logging.LogLevel; namespace OpenTracker.Models.AutoTracking.SNESConnectors.Requests { @@ -34,8 +34,7 @@ public override IEnumerable ProcessResponseAndReturnResults(IMessageEven if (!deserialized!.TryGetValue("Results", out var results)) { - throw new Exception( - $"Request \'{Description}\' is invalid and does not contain a \'Results\' key."); + throw new InvalidRequestResponseException(Description, "Results"); } Logger.Debug("Request \'{Description}\' response successfully deserialized", diff --git a/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/RegisterNameRequest.cs b/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/RegisterNameRequest.cs index e96ecec9..06ae0969 100644 --- a/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/RegisterNameRequest.cs +++ b/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/RegisterNameRequest.cs @@ -3,7 +3,6 @@ using System.Threading; using OpenTracker.Models.AutoTracking.SNESConnectors.Socket; using OpenTracker.Models.Logging; -using WebSocketSharp; namespace OpenTracker.Models.AutoTracking.SNESConnectors.Requests { diff --git a/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/RequestBase.cs b/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/RequestBase.cs index a535ad5a..6db257d5 100644 --- a/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/RequestBase.cs +++ b/src/OpenTracker.Models/AutoTracking/SNESConnectors/Requests/RequestBase.cs @@ -3,7 +3,6 @@ using Newtonsoft.Json; using OpenTracker.Models.AutoTracking.SNESConnectors.Socket; using OpenTracker.Models.Logging; -using LogLevel = OpenTracker.Models.Logging.LogLevel; namespace OpenTracker.Models.AutoTracking.SNESConnectors.Requests { diff --git a/src/OpenTracker.Models/Exceptions/InvalidRequestResponseException.cs b/src/OpenTracker.Models/Exceptions/InvalidRequestResponseException.cs new file mode 100644 index 00000000..16b51101 --- /dev/null +++ b/src/OpenTracker.Models/Exceptions/InvalidRequestResponseException.cs @@ -0,0 +1,16 @@ +using System; + +namespace OpenTracker.Models.Exceptions; + +public class InvalidRequestResponseException : Exception +{ + public string RequestDescription { get; } + public string MissingKey { get; } + + public InvalidRequestResponseException(string requestDescription, string missingKey) + : base($"Request '{requestDescription}' is invalid and does not contain a '{missingKey}' key.") + { + RequestDescription = requestDescription; + MissingKey = missingKey; + } +} \ No newline at end of file diff --git a/src/OpenTracker.Models/OpenTracker.Models.csproj b/src/OpenTracker.Models/OpenTracker.Models.csproj index 5b669df5..8c6ec6bf 100644 --- a/src/OpenTracker.Models/OpenTracker.Models.csproj +++ b/src/OpenTracker.Models/OpenTracker.Models.csproj @@ -1,20 +1,20 @@  - net8.0 + net10.0 enable 1.8.7 latest - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + diff --git a/src/OpenTracker.Utils/OpenTracker.Utils.csproj b/src/OpenTracker.Utils/OpenTracker.Utils.csproj index 4707db4f..cb36b90d 100644 --- a/src/OpenTracker.Utils/OpenTracker.Utils.csproj +++ b/src/OpenTracker.Utils/OpenTracker.Utils.csproj @@ -1,22 +1,22 @@ - net8.0 + net10.0 enable 1.8.5 latest - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/src/OpenTracker.Utils/ViewLocator.cs b/src/OpenTracker.Utils/ViewLocator.cs index aa6ea41d..dec10973 100644 --- a/src/OpenTracker.Utils/ViewLocator.cs +++ b/src/OpenTracker.Utils/ViewLocator.cs @@ -11,8 +11,11 @@ public class ViewLocator : IDataTemplate public static bool SupportsRecycling => false; - public IControl Build(object data) + public Control? Build(object? data) { + if (data == null) + return null; + var assembly = Assembly.GetEntryAssembly() ?? throw new NullReferenceException(); var viewTypes = assembly.GetTypes(); @@ -29,7 +32,7 @@ public IControl Build(object data) } } - public bool Match(object data) + public bool Match(object? data) { return data is ViewModelBase; } diff --git a/src/OpenTracker/App.axaml b/src/OpenTracker/App.axaml index 2e0071ad..25789cce 100644 --- a/src/OpenTracker/App.axaml +++ b/src/OpenTracker/App.axaml @@ -8,9 +8,8 @@ - - - + + diff --git a/src/OpenTracker/Views/Menus/TopMenu.axaml.cs b/src/OpenTracker/Views/Menus/TopMenu.axaml.cs index 6865bbb4..39dd7caa 100644 --- a/src/OpenTracker/Views/Menus/TopMenu.axaml.cs +++ b/src/OpenTracker/Views/Menus/TopMenu.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.Menus { - public class TopMenu : UserControl + public partial class TopMenu : UserControl { public TopMenu() { diff --git a/src/OpenTracker/Views/ModeSettings.axaml.cs b/src/OpenTracker/Views/ModeSettings.axaml.cs index 299c57c9..2de50190 100644 --- a/src/OpenTracker/Views/ModeSettings.axaml.cs +++ b/src/OpenTracker/Views/ModeSettings.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views { - public class ModeSettings : UserControl + public partial class ModeSettings : UserControl { public ModeSettings() { diff --git a/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNote.axaml.cs b/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNote.axaml.cs index 06c86254..b03544d2 100644 --- a/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNote.axaml.cs +++ b/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNote.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.PinnedLocations.Notes { - public class PinnedLocationNote : UserControl + public partial class PinnedLocationNote : UserControl { public PinnedLocationNote() { diff --git a/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNoteArea.axaml b/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNoteArea.axaml index d5516169..ce95a423 100644 --- a/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNoteArea.axaml +++ b/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNoteArea.axaml @@ -12,7 +12,7 @@ - + diff --git a/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNoteArea.axaml.cs b/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNoteArea.axaml.cs index 76266df4..c5d72b7c 100644 --- a/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNoteArea.axaml.cs +++ b/src/OpenTracker/Views/PinnedLocations/Notes/PinnedLocationNoteArea.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.PinnedLocations.Notes { - public class PinnedLocationNoteArea : UserControl + public partial class PinnedLocationNoteArea : UserControl { public PinnedLocationNoteArea() { diff --git a/src/OpenTracker/Views/PinnedLocations/PinnedLocation.axaml b/src/OpenTracker/Views/PinnedLocations/PinnedLocation.axaml index c50ece7c..35c54325 100644 --- a/src/OpenTracker/Views/PinnedLocations/PinnedLocation.axaml +++ b/src/OpenTracker/Views/PinnedLocations/PinnedLocation.axaml @@ -38,7 +38,7 @@ - + diff --git a/src/OpenTracker/Views/PinnedLocations/PinnedLocation.axaml.cs b/src/OpenTracker/Views/PinnedLocations/PinnedLocation.axaml.cs index f32c285b..ffe4586a 100644 --- a/src/OpenTracker/Views/PinnedLocations/PinnedLocation.axaml.cs +++ b/src/OpenTracker/Views/PinnedLocations/PinnedLocation.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.PinnedLocations { - public class PinnedLocation : UserControl + public partial class PinnedLocation : UserControl { public PinnedLocation() { diff --git a/src/OpenTracker/Views/PinnedLocations/PinnedLocationsPanel.axaml b/src/OpenTracker/Views/PinnedLocations/PinnedLocationsPanel.axaml index ba090c43..59243023 100644 --- a/src/OpenTracker/Views/PinnedLocations/PinnedLocationsPanel.axaml +++ b/src/OpenTracker/Views/PinnedLocations/PinnedLocationsPanel.axaml @@ -9,7 +9,7 @@ - + diff --git a/src/OpenTracker/Views/PinnedLocations/PinnedLocationsPanel.axaml.cs b/src/OpenTracker/Views/PinnedLocations/PinnedLocationsPanel.axaml.cs index 84d19717..c8249a37 100644 --- a/src/OpenTracker/Views/PinnedLocations/PinnedLocationsPanel.axaml.cs +++ b/src/OpenTracker/Views/PinnedLocations/PinnedLocationsPanel.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.PinnedLocations { - public class PinnedLocationsPanel : UserControl + public partial class PinnedLocationsPanel : UserControl { public PinnedLocationsPanel() { diff --git a/src/OpenTracker/Views/PinnedLocations/Sections/BossSectionIcon.axaml.cs b/src/OpenTracker/Views/PinnedLocations/Sections/BossSectionIcon.axaml.cs index e8788a55..eedc308d 100644 --- a/src/OpenTracker/Views/PinnedLocations/Sections/BossSectionIcon.axaml.cs +++ b/src/OpenTracker/Views/PinnedLocations/Sections/BossSectionIcon.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.PinnedLocations.Sections { - public class BossSectionIcon : UserControl + public partial class BossSectionIcon : UserControl { public BossSectionIcon() { diff --git a/src/OpenTracker/Views/PinnedLocations/Sections/MarkingSectionIcon.axaml.cs b/src/OpenTracker/Views/PinnedLocations/Sections/MarkingSectionIcon.axaml.cs index 9b0f97f2..4f44c225 100644 --- a/src/OpenTracker/Views/PinnedLocations/Sections/MarkingSectionIcon.axaml.cs +++ b/src/OpenTracker/Views/PinnedLocations/Sections/MarkingSectionIcon.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.PinnedLocations.Sections { - public class MarkingSectionIcon : UserControl + public partial class MarkingSectionIcon : UserControl { public MarkingSectionIcon() { diff --git a/src/OpenTracker/Views/PinnedLocations/Sections/PrizeSectionIcon.axaml.cs b/src/OpenTracker/Views/PinnedLocations/Sections/PrizeSectionIcon.axaml.cs index a8c70d00..b652e171 100644 --- a/src/OpenTracker/Views/PinnedLocations/Sections/PrizeSectionIcon.axaml.cs +++ b/src/OpenTracker/Views/PinnedLocations/Sections/PrizeSectionIcon.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.PinnedLocations.Sections { - public class PrizeSectionIcon : UserControl + public partial class PrizeSectionIcon : UserControl { public PrizeSectionIcon() { diff --git a/src/OpenTracker/Views/PinnedLocations/Sections/Section.axaml b/src/OpenTracker/Views/PinnedLocations/Sections/Section.axaml index 7b9a884f..e5bced02 100644 --- a/src/OpenTracker/Views/PinnedLocations/Sections/Section.axaml +++ b/src/OpenTracker/Views/PinnedLocations/Sections/Section.axaml @@ -33,7 +33,7 @@ - + diff --git a/src/OpenTracker/Views/PinnedLocations/Sections/Section.axaml.cs b/src/OpenTracker/Views/PinnedLocations/Sections/Section.axaml.cs index bc713f96..d9dc9135 100644 --- a/src/OpenTracker/Views/PinnedLocations/Sections/Section.axaml.cs +++ b/src/OpenTracker/Views/PinnedLocations/Sections/Section.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.PinnedLocations.Sections { - public class Section : UserControl + public partial class Section : UserControl { public Section() { diff --git a/src/OpenTracker/Views/PinnedLocations/Sections/SectionIcon.axaml.cs b/src/OpenTracker/Views/PinnedLocations/Sections/SectionIcon.axaml.cs index 26105b4f..b41ffd27 100644 --- a/src/OpenTracker/Views/PinnedLocations/Sections/SectionIcon.axaml.cs +++ b/src/OpenTracker/Views/PinnedLocations/Sections/SectionIcon.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.PinnedLocations.Sections { - public class SectionIcon : UserControl + public partial class SectionIcon : UserControl { public SectionIcon() { diff --git a/src/OpenTracker/Views/SequenceBreaks/SequenceBreakControl.axaml.cs b/src/OpenTracker/Views/SequenceBreaks/SequenceBreakControl.axaml.cs index efa79aba..e55c8aef 100644 --- a/src/OpenTracker/Views/SequenceBreaks/SequenceBreakControl.axaml.cs +++ b/src/OpenTracker/Views/SequenceBreaks/SequenceBreakControl.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.SequenceBreaks { - public class SequenceBreakControl : UserControl + public partial class SequenceBreakControl : UserControl { public SequenceBreakControl() { diff --git a/src/OpenTracker/Views/StatusBar.axaml.cs b/src/OpenTracker/Views/StatusBar.axaml.cs index 441b495c..57158815 100644 --- a/src/OpenTracker/Views/StatusBar.axaml.cs +++ b/src/OpenTracker/Views/StatusBar.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views { - public class StatusBar : UserControl + public partial class StatusBar : UserControl { public StatusBar() { diff --git a/src/OpenTracker/Views/ToolTips/MapLocationToolTip.axaml b/src/OpenTracker/Views/ToolTips/MapLocationToolTip.axaml index 671db213..bd7d8e51 100644 --- a/src/OpenTracker/Views/ToolTips/MapLocationToolTip.axaml +++ b/src/OpenTracker/Views/ToolTips/MapLocationToolTip.axaml @@ -25,7 +25,7 @@ - + diff --git a/src/OpenTracker/Views/ToolTips/MapLocationToolTip.axaml.cs b/src/OpenTracker/Views/ToolTips/MapLocationToolTip.axaml.cs index 9261d45e..8443f8b8 100644 --- a/src/OpenTracker/Views/ToolTips/MapLocationToolTip.axaml.cs +++ b/src/OpenTracker/Views/ToolTips/MapLocationToolTip.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.ToolTips { - public class MapLocationToolTip : UserControl + public partial class MapLocationToolTip : UserControl { public MapLocationToolTip() { diff --git a/src/OpenTracker/Views/ToolTips/MapLocationToolTipMarking.axaml.cs b/src/OpenTracker/Views/ToolTips/MapLocationToolTipMarking.axaml.cs index 21c24136..e389157b 100644 --- a/src/OpenTracker/Views/ToolTips/MapLocationToolTipMarking.axaml.cs +++ b/src/OpenTracker/Views/ToolTips/MapLocationToolTipMarking.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.ToolTips { - public class MapLocationToolTipMarking : UserControl + public partial class MapLocationToolTipMarking : UserControl { public MapLocationToolTipMarking() { diff --git a/src/OpenTracker/Views/UIPanels/UIPanel.axaml.cs b/src/OpenTracker/Views/UIPanels/UIPanel.axaml.cs index 8c6b7d65..e923ca77 100644 --- a/src/OpenTracker/Views/UIPanels/UIPanel.axaml.cs +++ b/src/OpenTracker/Views/UIPanels/UIPanel.axaml.cs @@ -3,7 +3,7 @@ namespace OpenTracker.Views.UIPanels { - public class UIPanel : UserControl + public partial class UIPanel : UserControl { public UIPanel() { diff --git a/tests/OpenTracker.UnitTests/Models/Dungeons/Nodes/Factories/SPDungeonNodeFactoryTests.cs b/tests/OpenTracker.UnitTests/Models/Dungeons/Nodes/Factories/SPDungeonNodeFactoryTests.cs index 87c7ef52..5ca80ce4 100644 --- a/tests/OpenTracker.UnitTests/Models/Dungeons/Nodes/Factories/SPDungeonNodeFactoryTests.cs +++ b/tests/OpenTracker.UnitTests/Models/Dungeons/Nodes/Factories/SPDungeonNodeFactoryTests.cs @@ -77,6 +77,7 @@ private static void PopulateExpectedValues() ExpectedEntryValues.Clear(); ExpectedNoRequirementValues.Clear(); ExpectedBossValues.Clear(); + ExpectedComplexValues.Clear(); ExpectedItemValues.Clear(); ExpectedKeyDoorValues.Clear(); @@ -250,7 +251,8 @@ public void PopulateNodeConnections_ShouldCreateExpectedEntryConnections( var connections = new List(); _sut.PopulateNodeConnections(dungeonData, id, node, connections); - Assert.Contains(_entryFactoryCalls, x => x == _overworldNodes[fromNodeID]); + Assert.True(_entryFactoryCalls.Contains(_overworldNodes[fromNodeID]), + $"Expected entry factory to be called with overworld node {fromNodeID}"); } public static IEnumerable PopulateNodeConnections_ShouldCreateExpectedEntryConnectionsData() @@ -270,10 +272,16 @@ public void PopulateNodeConnections_ShouldCreateExpectedNoRequirementConnections var dungeonData = Substitute.For(); var node = Substitute.For(); var connections = new List(); + + // Configure the substitute to return consistent node instances + var expectedNode = Substitute.For(); + dungeonData.Nodes[fromNodeID].Returns(expectedNode); + _sut.PopulateNodeConnections(dungeonData, id, node, connections); - Assert.Contains(_connectionFactoryCalls, x => - x.fromNode == dungeonData.Nodes[fromNodeID] && x.requirement == null); + Assert.True(_connectionFactoryCalls.Any(x => + x.fromNode == expectedNode && x.requirement == null), + $"Expected connection from {fromNodeID} with no requirement for node {id}"); } public static IEnumerable PopulateNodeConnections_ShouldCreateExpectedNoRequirementConnectionsData() @@ -293,10 +301,17 @@ public void PopulateNodeConnections_ShouldCreateExpectedBossConnections( var dungeonData = Substitute.For(); var node = Substitute.For(); var connections = new List(); + + // Configure the substitute to return consistent node instances + var expectedNode = Substitute.For(); + dungeonData.Nodes[fromNodeID].Returns(expectedNode); + _sut.PopulateNodeConnections(dungeonData, id, node, connections); - Assert.Contains(_connectionFactoryCalls, x => - x.fromNode == dungeonData.Nodes[fromNodeID] && x.requirement == _bossRequirements[bossID]); + Assert.True(_connectionFactoryCalls.Any(x => + x.fromNode == expectedNode && + ReferenceEquals(x.requirement, _bossRequirements[bossID])), + $"Expected boss connection from {fromNodeID} with boss {bossID} for node {id}"); } public static IEnumerable PopulateNodeConnections_ShouldCreateExpectedBossConnectionsData() @@ -315,10 +330,17 @@ public void PopulateNodeConnections_ShouldCreateExpectedComplexConnections( var dungeonData = Substitute.For(); var node = Substitute.For(); var connections = new List(); + + // Configure the substitute to return consistent node instances + var expectedNode = Substitute.For(); + dungeonData.Nodes[fromNodeID].Returns(expectedNode); + _sut.PopulateNodeConnections(dungeonData, id, node, connections); - Assert.Contains(_connectionFactoryCalls, x => - x.fromNode == dungeonData.Nodes[fromNodeID] && x.requirement == _complexRequirements[requirementType]); + Assert.True(_connectionFactoryCalls.Any(x => + x.fromNode == expectedNode && + ReferenceEquals(x.requirement, _complexRequirements[requirementType])), + $"Expected complex connection from {fromNodeID} with type {requirementType} for node {id}"); } public static IEnumerable PopulateNodeConnections_ShouldCreateExpectedComplexConnectionsData() @@ -338,10 +360,17 @@ public void PopulateNodeConnections_ShouldCreateExpectedItemConnections( var dungeonData = Substitute.For(); var node = Substitute.For(); var connections = new List(); + + // Configure the substitute to return consistent node instances + var expectedNode = Substitute.For(); + dungeonData.Nodes[fromNodeID].Returns(expectedNode); + _sut.PopulateNodeConnections(dungeonData, id, node, connections); - Assert.Contains(_connectionFactoryCalls, x => - x.fromNode == dungeonData.Nodes[fromNodeID] && x.requirement == _itemRequirements[(type, count)]); + Assert.True(_connectionFactoryCalls.Any(x => + x.fromNode == expectedNode && + ReferenceEquals(x.requirement, _itemRequirements[(type, count)])), + $"Expected item connection from {fromNodeID} requiring {type}x{count} for node {id}"); } public static IEnumerable PopulateNodeConnections_ShouldCreateExpectedItemConnectionsData() @@ -360,11 +389,17 @@ public void PopulateNodeConnections_ShouldCreateExpectedKeyDoorConnections( var dungeonData = Substitute.For(); var node = Substitute.For(); var connections = new List(); + + // Configure the substitute to return consistent node instances + var expectedNode = Substitute.For(); + dungeonData.Nodes[fromNodeID].Returns(expectedNode); + _sut.PopulateNodeConnections(dungeonData, id, node, connections); - Assert.Contains(_connectionFactoryCalls, x => - x.fromNode == dungeonData.Nodes[fromNodeID] && - x.requirement == dungeonData.KeyDoors[keyDoor].Requirement); + Assert.True(_connectionFactoryCalls.Any(x => + x.fromNode == expectedNode && + ReferenceEquals(x.requirement, dungeonData.KeyDoors[keyDoor].Requirement)), + $"Expected key door connection from {fromNodeID} with door {keyDoor} for node {id}"); } public static IEnumerable PopulateNodeConnections_ShouldCreateExpectedKeyDoorConnectionsData() diff --git a/tests/OpenTracker.UnitTests/OpenTracker.UnitTests.csproj b/tests/OpenTracker.UnitTests/OpenTracker.UnitTests.csproj index 7c245294..0a52d729 100644 --- a/tests/OpenTracker.UnitTests/OpenTracker.UnitTests.csproj +++ b/tests/OpenTracker.UnitTests/OpenTracker.UnitTests.csproj @@ -1,25 +1,25 @@  - net8.0 + net10.0 enable latest - - - - + + + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive