summaryrefslogtreecommitdiff
path: root/src/SMAPI.ModBuildConfig.Analyzer.Tests/ObsoleteFieldAnalyzerTests.cs
blob: fa9235a3f81ae8f1b3e8a86428bd401538a538ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using NUnit.Framework;
using SMAPI.ModBuildConfig.Analyzer.Tests.Framework;
using StardewModdingAPI.ModBuildConfig.Analyzer;

namespace SMAPI.ModBuildConfig.Analyzer.Tests
{
    /// <summary>Unit tests for <see cref="ObsoleteFieldAnalyzer"/>.</summary>
    [TestFixture]
    public class ObsoleteFieldAnalyzerTests : DiagnosticVerifier
    {
        /*********
        ** Fields
        *********/
        /// <summary>Sample C# mod code, with a {{test-code}} placeholder for the code in the Entry method to test.</summary>
        const string SampleProgram = @"
            using System;
            using StardewValley;
            using Netcode;
            using SObject = StardewValley.Object;

            namespace SampleMod
            {
                class ModEntry
                {
                    public void Entry()
                    {
                        {{test-code}}
                    }
                }
            }
        ";

        /// <summary>The line number where the unit tested code is injected into <see cref="SampleProgram"/>.</summary>
        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;


        /*********
        ** Unit tests
        *********/
        /// <summary>Test that no diagnostics are raised for an empty code block.</summary>
        [TestCase]
        public void EmptyCode_HasNoDiagnostics()
        {
            // arrange
            string test = @"";

            // assert
            this.VerifyCSharpDiagnostic(test);
        }

        /// <summary>Test that the expected diagnostic message is raised for an obsolete field reference.</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>
        /// <param name="oldName">The old field name which should be reported.</param>
        /// <param name="newName">The new field name which should be reported.</param>
        [TestCase("var x = new Farmer().friendships;", 8, "StardewValley.Farmer.friendships", "friendshipData")]
        [TestCase("var x = new Farmer()?.friendships;", 8, "StardewValley.Farmer.friendships", "friendshipData")]
        public void AvoidObsoleteField_RaisesDiagnostic(string codeText, int column, string oldName, string newName)
        {
            // arrange
            string code = ObsoleteFieldAnalyzerTests.SampleProgram.Replace("{{test-code}}", codeText);
            DiagnosticResult expected = new DiagnosticResult
            {
                Id = "AvoidObsoleteField",
                Message = $"The '{oldName}' field is obsolete and should be replaced with '{newName}'. See https://smapi.io/buildmsg/avoid-obsolete-field for details.",
                Severity = DiagnosticSeverity.Warning,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", ObsoleteFieldAnalyzerTests.SampleCodeLine, ObsoleteFieldAnalyzerTests.SampleCodeColumn + column) }
            };

            // assert
            this.VerifyCSharpDiagnostic(code, expected);
        }


        /*********
        ** Helpers
        *********/
        /// <summary>Get the analyzer being tested.</summary>
        protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer()
        {
            return new ObsoleteFieldAnalyzer();
        }
    }
}