summaryrefslogtreecommitdiff
path: root/src/SMAPI.ModBuildConfig.Analyzer.Tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI.ModBuildConfig.Analyzer.Tests')
-rw-r--r--src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetList.cs9
-rw-r--r--src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetObjectList.cs6
-rw-r--r--src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs11
-rw-r--r--src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs19
4 files changed, 43 insertions, 2 deletions
diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetList.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetList.cs
new file mode 100644
index 00000000..1699f71c
--- /dev/null
+++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetList.cs
@@ -0,0 +1,9 @@
+// ReSharper disable CheckNamespace -- matches Stardew Valley's code
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Netcode
+{
+ /// <summary>A simplified version of Stardew Valley's <c>Netcode.NetObjectList</c> for unit testing.</summary>
+ public class NetList<T> : List<T>, IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable { }
+}
diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetObjectList.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetObjectList.cs
new file mode 100644
index 00000000..7814e7d6
--- /dev/null
+++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetObjectList.cs
@@ -0,0 +1,6 @@
+// ReSharper disable CheckNamespace -- matches Stardew Valley's code
+namespace Netcode
+{
+ /// <summary>A simplified version of Stardew Valley's <c>Netcode.NetObjectList</c> for unit testing.</summary>
+ public class NetObjectList<T> : NetList<T> { }
+}
diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs
index e0f0e30c..54e91682 100644
--- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs
+++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Farmer.cs
@@ -1,11 +1,20 @@
// ReSharper disable CheckNamespace, InconsistentNaming -- matches Stardew Valley's code
+#pragma warning disable 649 // (never assigned) -- only used to test type conversions
using System.Collections.Generic;
+using Netcode;
namespace StardewValley
{
/// <summary>A simplified version of Stardew Valley's <c>StardewValley.Farmer</c> class for unit testing.</summary>
internal class Farmer
{
- public IDictionary<string, int[]> friendships;
+ /// <summary>A sample field which should be replaced with a different property.</summary>
+ public readonly IDictionary<string, int[]> friendships;
+
+ /// <summary>A sample net list.</summary>
+ public readonly NetList<int> eventsSeen;
+
+ /// <summary>A sample net object list.</summary>
+ public readonly NetObjectList<int> netObjectList;
}
}
diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs
index 79ce9263..15bcadcd 100644
--- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs
+++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs
@@ -19,6 +19,7 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests
using StardewValley;
using Netcode;
using SObject = StardewValley.Object;
+ using SFarmer = StardewValley.Farmer;
namespace SampleMod
{
@@ -33,7 +34,7 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests
";
/// <summary>The line number where the unit tested code is injected into <see cref="SampleProgram"/>.</summary>
- private const int SampleCodeLine = 13;
+ private const int SampleCodeLine = 14;
/// <summary>The column number where the unit tested code is injected into <see cref="SampleProgram"/>.</summary>
private const int SampleCodeColumn = 25;
@@ -85,6 +86,7 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests
[TestCase("SObject obj = null; if (obj.netRefField != null);", 24, "obj.netRefField", "NetRef", "object")]
[TestCase("SObject obj = null; if (obj.netRefProperty == null);", 24, "obj.netRefProperty", "NetRef", "object")]
[TestCase("SObject obj = null; if (obj.netRefProperty != null);", 24, "obj.netRefProperty", "NetRef", "object")]
+ [TestCase("SFarmer farmer = new SFarmer(); object list = farmer.eventsSeen;", 46, "farmer.eventsSeen", "NetList", "object")] // ↓ NetList field converted to a non-interface type
public void AvoidImplicitNetFieldComparisons_RaisesDiagnostic(string codeText, int column, string expression, string fromType, string toType)
{
// arrange
@@ -101,6 +103,21 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests
this.VerifyCSharpDiagnostic(code, expected);
}
+ /// <summary>Test that the net field analyzer doesn't raise any warnings for safe member access.</summary>
+ /// <param name="codeText">The code line to test.</param>
+ [TestCase("SFarmer farmer = new SFarmer(); System.Collections.IEnumerable list = farmer.eventsSeen;")]
+ [TestCase("SFarmer farmer = new SFarmer(); System.Collections.Generic.IEnumerable<int> list = farmer.eventsSeen;")]
+ [TestCase("SFarmer farmer = new SFarmer(); System.Collections.Generic.IList<int> list = farmer.eventsSeen;")]
+ [TestCase("SFarmer farmer = new SFarmer(); System.Collections.Generic.IList<int> list = farmer.netObjectList;")] // subclass of NetList
+ public void AvoidImplicitNetFieldComparisons_AllowsSafeAccess(string codeText)
+ {
+ // arrange
+ string code = NetFieldAnalyzerTests.SampleProgram.Replace("{{test-code}}", codeText);
+
+ // assert
+ this.VerifyCSharpDiagnostic(code);
+ }
+
/// <summary>Test that the expected diagnostic message is raised for avoidable net field references.</summary>
/// <param name="codeText">The code line to test.</param>
/// <param name="column">The column within the code line where the diagnostic message should be reported.</param>