diff options
Diffstat (limited to 'src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs')
-rw-r--r-- | src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs b/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs index 101f4c21..6f8c8b9b 100644 --- a/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs +++ b/src/SMAPI.ModBuildConfig.Analyzer.Tests/NetFieldAnalyzerTests.cs @@ -59,7 +59,7 @@ 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("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")] // ↓ implicit conversion [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")] @@ -79,20 +79,24 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests [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.netIntField != 42);", 24, "obj.netIntField", "NetInt", "int")] // ↓ implicit conversion for parent field [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")] + [TestCase("Item item = new Item(); object list = item.netList;", 38, "item.netList", "NetList", "object")] // ↓ NetList field converted to a non-interface type + [TestCase("Item item = new Item(); object list = item.netCollection;", 38, "item.netCollection", "NetCollection", "object")] + [TestCase("Item item = new Item(); int x = (int)item.netIntField;", 32, "item.netIntField", "NetInt", "int")] // ↓ explicit conversion to invalid type + [TestCase("Item item = new Item(); int x = item.netRefField as object;", 32, "item.netRefField", "NetRef", "object")] public void AvoidImplicitNetFieldComparisons_RaisesDiagnostic(string codeText, int column, string expression, string fromType, string toType) { // arrange string code = NetFieldAnalyzerTests.SampleProgram.Replace("{{test-code}}", codeText); DiagnosticResult expected = new DiagnosticResult { - Id = "SMAPI001", - Message = $"This implicitly converts '{expression}' from {fromType} to {toType}, but {fromType} has unintuitive implicit conversion rules. Consider comparing against the actual value instead to avoid bugs. See https://smapi.io/buildmsg/smapi001 for details.", + Id = "AvoidImplicitNetFieldCast", + Message = $"This implicitly converts '{expression}' from {fromType} to {toType}, but {fromType} has unintuitive implicit conversion rules. Consider comparing against the actual value instead to avoid bugs. See https://smapi.io/buildmsg/avoid-implicit-net-field-cast for details.", Severity = DiagnosticSeverity.Warning, Locations = new[] { new DiagnosticResultLocation("Test0.cs", NetFieldAnalyzerTests.SampleCodeLine, NetFieldAnalyzerTests.SampleCodeColumn + column) } }; @@ -101,6 +105,22 @@ 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("Item item = new Item(); System.Collections.IEnumerable list = farmer.eventsSeen;")] + [TestCase("Item item = new Item(); System.Collections.Generic.IEnumerable<int> list = farmer.netList;")] + [TestCase("Item item = new Item(); System.Collections.Generic.IList<int> list = farmer.netList;")] + [TestCase("Item item = new Item(); System.Collections.Generic.ICollection<int> list = farmer.netCollection;")] + [TestCase("Item item = new Item(); 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> @@ -117,8 +137,8 @@ namespace SMAPI.ModBuildConfig.Analyzer.Tests string code = NetFieldAnalyzerTests.SampleProgram.Replace("{{test-code}}", codeText); DiagnosticResult expected = new DiagnosticResult { - Id = "SMAPI002", - Message = $"'{expression}' is a {netType} field; consider using the {suggestedProperty} property instead. See https://smapi.io/buildmsg/smapi002 for details.", + Id = "AvoidNetField", + Message = $"'{expression}' is a {netType} field; consider using the {suggestedProperty} property instead. See https://smapi.io/buildmsg/avoid-net-field for details.", Severity = DiagnosticSeverity.Warning, Locations = new[] { new DiagnosticResultLocation("Test0.cs", NetFieldAnalyzerTests.SampleCodeLine, NetFieldAnalyzerTests.SampleCodeColumn + column) } }; |