diff options
4 files changed, 51 insertions, 29 deletions
diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetRef.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetRef.cs index 714c4a8d..be2459cc 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetRef.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/Netcode/NetRef.cs @@ -2,5 +2,5 @@ namespace Netcode { /// <summary>A simplified version of Stardew Valley's <c>Netcode.NetRef</c> for unit testing.</summary> - public class NetRef : NetFieldBase<object, NetRef> { } + public class NetRef<T> : NetFieldBase<T, NetRef<T>> where T : class { } } diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Item.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Item.cs index 88723a56..386767d7 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Item.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Item.cs @@ -7,12 +7,18 @@ namespace StardewValley public class Item { /// <summary>A net int field with an equivalent non-net <c>Category</c> property.</summary> - public NetInt category { get; } = new NetInt { Value = 42 }; + public readonly NetInt category = new NetInt { Value = 42 }; - /// <summary>A net int field with no equivalent non-net property.</summary> - public NetInt type { get; } = new NetInt { Value = 42 }; + /// <summary>A generic net int field with no equivalent non-net property.</summary> + public readonly NetInt netIntField = new NetInt { Value = 42 }; - /// <summary>A net reference field.</summary> - public NetRef refField { get; } = null; + /// <summary>A generic net ref field with no equivalent non-net property.</summary> + public readonly NetRef<object> netRefField = new NetRef<object>(); + + /// <summary>A generic net int property with no equivalent non-net property.</summary> + public NetInt netIntProperty = new NetInt { Value = 42 }; + + /// <summary>A generic net ref property with no equivalent non-net property.</summary> + public NetRef<object> netRefProperty { get; } = new NetRef<object>(); } } diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Object.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Object.cs index 498c38c1..3dd66a6d 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Object.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/Mock/StardewValley/Object.cs @@ -1,6 +1,12 @@ -// ReSharper disable CheckNamespace -- matches Stardew Valley's code +// ReSharper disable CheckNamespace, InconsistentNaming -- matches Stardew Valley's code +using Netcode; + namespace StardewValley { /// <summary>A simplified version of Stardew Valley's <c>StardewValley.Object</c> class for unit testing.</summary> - public class Object : Item { } + public class Object : Item + { + /// <summary>A net int field with an equivalent non-net property.</summary> + public NetInt type = new NetInt { Value = 42 }; + } } diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/UnitTests.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/UnitTests.cs index c12bb839..51e0b059 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/UnitTests.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/UnitTests.cs @@ -26,21 +26,14 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests { public void Entry() { - Item item = null; - SObject obj = null; - - // this line should raise diagnostics {{test-code}} - - // these lines should not - if (item.type.Value != 42); } } } "; /// <summary>The line number where the unit tested code is injected into <see cref="SampleProgram"/>.</summary> - private const int SampleCodeLine = 17; + private const int SampleCodeLine = 13; /// <summary>The column number where the unit tested code is injected into <see cref="SampleProgram"/>.</summary> private const int SampleCodeColumn = 25; @@ -66,15 +59,32 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests /// <param name="expression">The expression which should be reported.</param> /// <param name="fromType">The source type name which should be reported.</param> /// <param name="toType">The target type name which should be reported.</param> - [TestCase("if (item.type < 42);", 4, "item.type", "NetInt", "int")] - [TestCase("if (item.type <= 42);", 4, "item.type", "NetInt", "int")] - [TestCase("if (item.type > 42);", 4, "item.type", "NetInt", "int")] - [TestCase("if (item.type >= 42);", 4, "item.type", "NetInt", "int")] - [TestCase("if (item.type == 42);", 4, "item.type", "NetInt", "int")] - [TestCase("if (item.type != 42);", 4, "item.type", "NetInt", "int")] - [TestCase("if (item.refField != null);", 4, "item.refField", "NetRef", "object")] - [TestCase("if (item?.type != 42);", 4, "item?.type", "NetInt", "int")] - [TestCase("if (obj.type != 42);", 4, "obj.type", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntField < 42);", 22, "item.netIntField", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntField <= 42);", 22, "item.netIntField", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntField > 42);", 22, "item.netIntField", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntField >= 42);", 22, "item.netIntField", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntField == 42);", 22, "item.netIntField", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntField != 42);", 22, "item.netIntField", "NetInt", "int")] + [TestCase("Item item = null; if (item?.netIntField != 42);", 22, "item?.netIntField", "NetInt", "int")] + [TestCase("Item item = null; if (item?.netIntField != null);", 22, "item?.netIntField", "NetInt", "object")] + [TestCase("Item item = null; if (item.netIntProperty < 42);", 22, "item.netIntProperty", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntProperty <= 42);", 22, "item.netIntProperty", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntProperty > 42);", 22, "item.netIntProperty", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntProperty >= 42);", 22, "item.netIntProperty", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntProperty == 42);", 22, "item.netIntProperty", "NetInt", "int")] + [TestCase("Item item = null; if (item.netIntProperty != 42);", 22, "item.netIntProperty", "NetInt", "int")] + [TestCase("Item item = null; if (item?.netIntProperty != 42);", 22, "item?.netIntProperty", "NetInt", "int")] + [TestCase("Item item = null; if (item?.netIntProperty != null);", 22, "item?.netIntProperty", "NetInt", "object")] + [TestCase("Item item = null; if (item.netRefField == null);", 22, "item.netRefField", "NetRef", "object")] + [TestCase("Item item = null; if (item.netRefField != null);", 22, "item.netRefField", "NetRef", "object")] + [TestCase("Item item = null; if (item.netRefProperty == null);", 22, "item.netRefProperty", "NetRef", "object")] + [TestCase("Item item = null; if (item.netRefProperty != null);", 22, "item.netRefProperty", "NetRef", "object")] + [TestCase("SObject obj = null; if (obj.netIntField != 42);", 24, "obj.netIntField", "NetInt", "int")] // ↓ same as above, but inherited from base class + [TestCase("SObject obj = null; if (obj.netIntProperty != 42);", 24, "obj.netIntProperty", "NetInt", "int")] + [TestCase("SObject obj = null; if (obj.netRefField == null);", 24, "obj.netRefField", "NetRef", "object")] + [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")] public void AvoidImplicitNetFieldComparisons_RaisesDiagnostic(string codeText, int column, string expression, string fromType, string toType) { // arrange @@ -97,10 +107,10 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests /// <param name="expression">The expression which should be reported.</param> /// <param name="netType">The net type name which should be reported.</param> /// <param name="suggestedProperty">The suggested property name which should be reported.</param> - [TestCase("int category = item.category;", 15, "item.category", "NetInt", "Category")] - [TestCase("int category = (item).category;", 15, "(item).category", "NetInt", "Category")] - [TestCase("int category = ((Item)item).category;", 15, "((Item)item).category", "NetInt", "Category")] - [TestCase("int category = obj.category;", 15, "obj.category", "NetInt", "Category")] + [TestCase("Item item = null; int category = item.category;", 33, "item.category", "NetInt", "Category")] + [TestCase("Item item = null; int category = (item).category;", 33, "(item).category", "NetInt", "Category")] + [TestCase("Item item = null; int category = ((Item)item).category;", 33, "((Item)item).category", "NetInt", "Category")] + [TestCase("SObject obj = null; int category = obj.category;", 35, "obj.category", "NetInt", "Category")] public void AvoidNetFields_RaisesDiagnostic(string codeText, int column, string expression, string netType, string suggestedProperty) { // arrange |