From 3431f486a2ef93e86d8923c1a4651644110df81b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 29 Jan 2022 18:15:42 -0500 Subject: normalize season names in SDate constructor --- src/SMAPI.Tests/Utilities/SDateTests.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/SMAPI.Tests/Utilities') diff --git a/src/SMAPI.Tests/Utilities/SDateTests.cs b/src/SMAPI.Tests/Utilities/SDateTests.cs index 0461952e..374f4921 100644 --- a/src/SMAPI.Tests/Utilities/SDateTests.cs +++ b/src/SMAPI.Tests/Utilities/SDateTests.cs @@ -16,9 +16,12 @@ namespace SMAPI.Tests.Utilities /********* ** Fields *********/ - /// All valid seasons. + /// The valid seasons. private static readonly string[] ValidSeasons = { "spring", "summer", "fall", "winter" }; + /// Sample user inputs for season names. + private static readonly string[] SampleSeasonValues = SDateTests.ValidSeasons.Concat(new[] { " WIntEr " }).ToArray(); + /// All valid days of a month. private static readonly int[] ValidDays = Enumerable.Range(1, 28).ToArray(); @@ -55,19 +58,18 @@ namespace SMAPI.Tests.Utilities ** Constructor ****/ [Test(Description = "Assert that the constructor sets the expected values for all valid dates.")] - public void Constructor_SetsExpectedValues([ValueSource(nameof(SDateTests.ValidSeasons))] string season, [ValueSource(nameof(SDateTests.ValidDays))] int day, [Values(1, 2, 100)] int year) + public void Constructor_SetsExpectedValues([ValueSource(nameof(SDateTests.SampleSeasonValues))] string season, [ValueSource(nameof(SDateTests.ValidDays))] int day, [Values(1, 2, 100)] int year) { // act SDate date = new SDate(day, season, year); // assert Assert.AreEqual(day, date.Day); - Assert.AreEqual(season, date.Season); + Assert.AreEqual(season.Trim().ToLowerInvariant(), date.Season); Assert.AreEqual(year, date.Year); } [Test(Description = "Assert that the constructor throws an exception if the values are invalid.")] - [TestCase(01, "Spring", 1)] // seasons are case-sensitive [TestCase(01, "springs", 1)] // invalid season name [TestCase(-1, "spring", 1)] // day < 0 [TestCase(0, "spring", 1)] // day zero -- cgit From a593eda30f82af474887d91458b0e9158f66fefc Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 6 Apr 2022 18:24:59 -0400 Subject: use target-typed new --- src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs | 22 +++++++++++----------- src/SMAPI.Tests/Utilities/SDateTests.cs | 4 ++-- src/SMAPI.Tests/Utilities/SemanticVersionTests.cs | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src/SMAPI.Tests/Utilities') diff --git a/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs b/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs index ab4c2618..94819c2e 100644 --- a/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs +++ b/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs @@ -14,7 +14,7 @@ namespace SMAPI.Tests.Utilities /// Sample paths used in unit tests. public static readonly SamplePath[] SamplePaths = { // Windows absolute path - new SamplePath + new() { OriginalPath = @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley", @@ -26,7 +26,7 @@ namespace SMAPI.Tests.Utilities }, // Windows absolute path (with trailing slash) - new SamplePath + new() { OriginalPath = @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley\", @@ -38,7 +38,7 @@ namespace SMAPI.Tests.Utilities }, // Windows relative path - new SamplePath + new() { OriginalPath = @"Content\Characters\Dialogue\Abigail", @@ -50,7 +50,7 @@ namespace SMAPI.Tests.Utilities }, // Windows relative path (with directory climbing) - new SamplePath + new() { OriginalPath = @"..\..\Content", @@ -62,7 +62,7 @@ namespace SMAPI.Tests.Utilities }, // Windows UNC path - new SamplePath + new() { OriginalPath = @"\\unc\path", @@ -74,7 +74,7 @@ namespace SMAPI.Tests.Utilities }, // Linux absolute path - new SamplePath + new() { OriginalPath = @"/home/.steam/steam/steamapps/common/Stardew Valley", @@ -86,7 +86,7 @@ namespace SMAPI.Tests.Utilities }, // Linux absolute path (with trailing slash) - new SamplePath + new() { OriginalPath = @"/home/.steam/steam/steamapps/common/Stardew Valley/", @@ -98,7 +98,7 @@ namespace SMAPI.Tests.Utilities }, // Linux absolute path (with ~) - new SamplePath + new() { OriginalPath = @"~/.steam/steam/steamapps/common/Stardew Valley", @@ -110,7 +110,7 @@ namespace SMAPI.Tests.Utilities }, // Linux relative path - new SamplePath + new() { OriginalPath = @"Content/Characters/Dialogue/Abigail", @@ -122,7 +122,7 @@ namespace SMAPI.Tests.Utilities }, // Linux relative path (with directory climbing) - new SamplePath + new() { OriginalPath = @"../../Content", @@ -134,7 +134,7 @@ namespace SMAPI.Tests.Utilities }, // Mixed directory separators - new SamplePath + new() { OriginalPath = @"C:\some/mixed\path/separators", diff --git a/src/SMAPI.Tests/Utilities/SDateTests.cs b/src/SMAPI.Tests/Utilities/SDateTests.cs index 374f4921..886f25cd 100644 --- a/src/SMAPI.Tests/Utilities/SDateTests.cs +++ b/src/SMAPI.Tests/Utilities/SDateTests.cs @@ -61,7 +61,7 @@ namespace SMAPI.Tests.Utilities public void Constructor_SetsExpectedValues([ValueSource(nameof(SDateTests.SampleSeasonValues))] string season, [ValueSource(nameof(SDateTests.ValidDays))] int day, [Values(1, 2, 100)] int year) { // act - SDate date = new SDate(day, season, year); + SDate date = new(day, season, year); // assert Assert.AreEqual(day, date.Day); @@ -254,7 +254,7 @@ namespace SMAPI.Tests.Utilities { foreach (int day in SDateTests.ValidDays) { - SDate date = new SDate(day, season, year); + SDate date = new(day, season, year); int hash = date.GetHashCode(); if (hashes.TryGetValue(hash, out SDate otherDate)) Assert.Fail($"Received identical hash code {hash} for dates {otherDate} and {date}."); diff --git a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs index ac4ef39b..c8270373 100644 --- a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs +++ b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs @@ -395,7 +395,7 @@ namespace SMAPI.Tests.Utilities public void GameVersion(string versionStr) { // act - GameVersion version = new GameVersion(versionStr); + GameVersion version = new(versionStr); // assert Assert.AreEqual(versionStr, version.ToString(), "The game version did not round-trip to the same value."); -- cgit From b6c8cfc28b2c94e6dc3cb07d3058371dd6775e70 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 6 Apr 2022 18:24:59 -0400 Subject: simplify 'is not' patterns --- src/SMAPI.Tests/Utilities/SemanticVersionTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SMAPI.Tests/Utilities') diff --git a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs index c8270373..142c9814 100644 --- a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs +++ b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs @@ -455,7 +455,7 @@ namespace SMAPI.Tests.Utilities TestContext.WriteLine($"Exception thrown:\n{ex}"); return; } - catch (Exception ex) when (!(ex is AssertionException)) + catch (Exception ex) when (ex is not AssertionException) { TestContext.WriteLine($"Exception thrown:\n{ex}"); Assert.Fail(message ?? $"Didn't throw the expected exception; expected {typeof(T).FullName}, got {ex.GetType().FullName}."); -- cgit From 2e7c233f6c9bf6430672b39f970a3324deba79dd Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 6 Apr 2022 21:48:55 -0400 Subject: enable nullable annotations by default (#837) This adds `#nullable disable` to all existing code (except where null is impossible like enum files), so it can be migrated incrementally. --- src/SMAPI.Tests/Utilities/KeybindListTests.cs | 2 ++ src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs | 2 ++ src/SMAPI.Tests/Utilities/SDateTests.cs | 2 ++ src/SMAPI.Tests/Utilities/SemanticVersionTests.cs | 2 ++ 4 files changed, 8 insertions(+) (limited to 'src/SMAPI.Tests/Utilities') diff --git a/src/SMAPI.Tests/Utilities/KeybindListTests.cs b/src/SMAPI.Tests/Utilities/KeybindListTests.cs index 0bd6ec17..f5c156c4 100644 --- a/src/SMAPI.Tests/Utilities/KeybindListTests.cs +++ b/src/SMAPI.Tests/Utilities/KeybindListTests.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using NUnit.Framework; diff --git a/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs b/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs index 94819c2e..ae2cc6ce 100644 --- a/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs +++ b/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs @@ -1,3 +1,5 @@ +#nullable disable + using System.IO; using NUnit.Framework; using StardewModdingAPI.Toolkit.Utilities; diff --git a/src/SMAPI.Tests/Utilities/SDateTests.cs b/src/SMAPI.Tests/Utilities/SDateTests.cs index 886f25cd..a4a36828 100644 --- a/src/SMAPI.Tests/Utilities/SDateTests.cs +++ b/src/SMAPI.Tests/Utilities/SDateTests.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; diff --git a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs index 142c9814..66181ea6 100644 --- a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs +++ b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json; -- cgit From d1a7194bf604ac9f960c45de0c82e6eaddd5ff5a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 6 Apr 2022 23:47:12 -0400 Subject: allow null values in ISemanticVersion compare methods (#837) --- src/SMAPI.Tests/Utilities/SemanticVersionTests.cs | 39 +++++++++++++++++------ 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'src/SMAPI.Tests/Utilities') diff --git a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs index 66181ea6..599ac839 100644 --- a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs +++ b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs @@ -219,11 +219,16 @@ namespace SMAPI.Tests.Utilities [TestCase("1.0-beta.2", "1.0-beta.1", ExpectedResult = 1)] [TestCase("1.0-beta.10", "1.0-beta.2", ExpectedResult = 1)] [TestCase("1.0-beta-10", "1.0-beta-2", ExpectedResult = 1)] + + // null + [TestCase("1.0.0", null, ExpectedResult = 1)] // null is always less than any value per CompareTo remarks public int CompareTo(string versionStrA, string versionStrB) { // arrange ISemanticVersion versionA = new SemanticVersion(versionStrA); - ISemanticVersion versionB = new SemanticVersion(versionStrB); + ISemanticVersion versionB = versionStrB != null + ? new SemanticVersion(versionStrB) + : null; // assert return versionA.CompareTo(versionB); @@ -262,14 +267,19 @@ namespace SMAPI.Tests.Utilities [TestCase("1.0-beta.2", "1.0-beta.1", ExpectedResult = false)] [TestCase("1.0-beta.10", "1.0-beta.2", ExpectedResult = false)] [TestCase("1.0-beta-10", "1.0-beta-2", ExpectedResult = false)] + + // null + [TestCase("1.0.0", null, ExpectedResult = false)] // null is always less than any value per CompareTo remarks public bool IsOlderThan(string versionStrA, string versionStrB) { // arrange ISemanticVersion versionA = new SemanticVersion(versionStrA); - ISemanticVersion versionB = new SemanticVersion(versionStrB); + ISemanticVersion versionB = versionStrB != null + ? new SemanticVersion(versionStrB) + : null; // assert - Assert.AreEqual(versionA.IsOlderThan(versionB), versionA.IsOlderThan(versionB.ToString()), "The two signatures returned different results."); + Assert.AreEqual(versionA.IsOlderThan(versionB), versionA.IsOlderThan(versionB?.ToString()), "The two signatures returned different results."); return versionA.IsOlderThan(versionB); } @@ -306,14 +316,19 @@ namespace SMAPI.Tests.Utilities [TestCase("1.0-beta.2", "1.0-beta.1", ExpectedResult = true)] [TestCase("1.0-beta.10", "1.0-beta.2", ExpectedResult = true)] [TestCase("1.0-beta-10", "1.0-beta-2", ExpectedResult = true)] + + // null + [TestCase("1.0.0", null, ExpectedResult = true)] // null is always less than any value per CompareTo remarks public bool IsNewerThan(string versionStrA, string versionStrB) { // arrange ISemanticVersion versionA = new SemanticVersion(versionStrA); - ISemanticVersion versionB = new SemanticVersion(versionStrB); + ISemanticVersion versionB = versionStrB != null + ? new SemanticVersion(versionStrB) + : null; // assert - Assert.AreEqual(versionA.IsNewerThan(versionB), versionA.IsNewerThan(versionB.ToString()), "The two signatures returned different results."); + Assert.AreEqual(versionA.IsNewerThan(versionB), versionA.IsNewerThan(versionB?.ToString()), "The two signatures returned different results."); return versionA.IsNewerThan(versionB); } @@ -324,7 +339,7 @@ namespace SMAPI.Tests.Utilities /// The main version. /// The lower version number. /// The upper version number. - [Test(Description = "Assert that version.IsNewerThan returns the expected value.")] + [Test(Description = "Assert that version.IsBetween returns the expected value.")] // is between [TestCase("0.5.7-beta.3", "0.5.7-beta.3", "0.5.7-beta.3", ExpectedResult = true)] [TestCase("1.0", "1.0", "1.1", ExpectedResult = true)] @@ -332,6 +347,7 @@ namespace SMAPI.Tests.Utilities [TestCase("1.0", "0.5", "1.1", ExpectedResult = true)] [TestCase("1.0-beta.2", "1.0-beta.1", "1.0-beta.3", ExpectedResult = true)] [TestCase("1.0-beta-2", "1.0-beta-1", "1.0-beta-3", ExpectedResult = true)] + [TestCase("1.0.0", null, "1.0.0", ExpectedResult = true)] // null is always less than any value per CompareTo remarks // is not between [TestCase("1.0-beta", "1.0", "1.1", ExpectedResult = false)] @@ -339,15 +355,20 @@ namespace SMAPI.Tests.Utilities [TestCase("1.0-beta.2", "1.1", "1.0", ExpectedResult = false)] [TestCase("1.0-beta.2", "1.0-beta.10", "1.0-beta.3", ExpectedResult = false)] [TestCase("1.0-beta-2", "1.0-beta-10", "1.0-beta-3", ExpectedResult = false)] + [TestCase("1.0.0", "1.0.0", null, ExpectedResult = false)] // null is always less than any value per CompareTo remarks public bool IsBetween(string versionStr, string lowerStr, string upperStr) { // arrange - ISemanticVersion lower = new SemanticVersion(lowerStr); - ISemanticVersion upper = new SemanticVersion(upperStr); + ISemanticVersion lower = lowerStr != null + ? new SemanticVersion(lowerStr) + : null; + ISemanticVersion upper = upperStr != null + ? new SemanticVersion(upperStr) + : null; ISemanticVersion version = new SemanticVersion(versionStr); // assert - Assert.AreEqual(version.IsBetween(lower, upper), version.IsBetween(lower.ToString(), upper.ToString()), "The two signatures returned different results."); + Assert.AreEqual(version.IsBetween(lower, upper), version.IsBetween(lower?.ToString(), upper?.ToString()), "The two signatures returned different results."); return version.IsBetween(lower, upper); } -- cgit From ab6cf45b03073f324c46f9e93a98e3342a1bdff7 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 7 Apr 2022 00:56:00 -0400 Subject: enable nullable annotations for semantic versions (#837) --- src/SMAPI.Tests/Utilities/SemanticVersionTests.cs | 35 +++++++++++------------ 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'src/SMAPI.Tests/Utilities') diff --git a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs index 599ac839..fedadba6 100644 --- a/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs +++ b/src/SMAPI.Tests/Utilities/SemanticVersionTests.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json; @@ -63,10 +61,10 @@ namespace SMAPI.Tests.Utilities [TestCase("apple")] [TestCase("-apple")] [TestCase("-5")] - public void Constructor_FromString_WithInvalidValues(string input) + public void Constructor_FromString_WithInvalidValues(string? input) { if (input == null) - this.AssertAndLogException(() => new SemanticVersion(input)); + this.AssertAndLogException(() => new SemanticVersion(input!)); else this.AssertAndLogException(() => new SemanticVersion(input)); } @@ -93,7 +91,7 @@ namespace SMAPI.Tests.Utilities [TestCase("1.2.3.4-some-tag.4 ")] public void Constructor_FromString_Standard_DisallowsNonStandardVersion(string input) { - Assert.Throws(() => new SemanticVersion(input)); + Assert.Throws(() => _ = new SemanticVersion(input)); } /// Assert the parsed version when constructed from standard parts. @@ -112,7 +110,7 @@ namespace SMAPI.Tests.Utilities [TestCase(1, 2, 3, "some-tag.4 ", null, ExpectedResult = "1.2.3-some-tag.4")] [TestCase(1, 2, 3, "some-tag.4 ", "build.004", ExpectedResult = "1.2.3-some-tag.4+build.004")] [TestCase(1, 2, 0, null, "3.4.5-build.004", ExpectedResult = "1.2.0+3.4.5-build.004")] - public string Constructor_FromParts(int major, int minor, int patch, string prerelease, string build) + public string Constructor_FromParts(int major, int minor, int patch, string? prerelease, string? build) { // act ISemanticVersion version = new SemanticVersion(major, minor, patch, prerelease, build); @@ -222,11 +220,11 @@ namespace SMAPI.Tests.Utilities // null [TestCase("1.0.0", null, ExpectedResult = 1)] // null is always less than any value per CompareTo remarks - public int CompareTo(string versionStrA, string versionStrB) + public int CompareTo(string versionStrA, string? versionStrB) { // arrange ISemanticVersion versionA = new SemanticVersion(versionStrA); - ISemanticVersion versionB = versionStrB != null + ISemanticVersion? versionB = versionStrB != null ? new SemanticVersion(versionStrB) : null; @@ -270,11 +268,11 @@ namespace SMAPI.Tests.Utilities // null [TestCase("1.0.0", null, ExpectedResult = false)] // null is always less than any value per CompareTo remarks - public bool IsOlderThan(string versionStrA, string versionStrB) + public bool IsOlderThan(string versionStrA, string? versionStrB) { // arrange ISemanticVersion versionA = new SemanticVersion(versionStrA); - ISemanticVersion versionB = versionStrB != null + ISemanticVersion? versionB = versionStrB != null ? new SemanticVersion(versionStrB) : null; @@ -319,11 +317,11 @@ namespace SMAPI.Tests.Utilities // null [TestCase("1.0.0", null, ExpectedResult = true)] // null is always less than any value per CompareTo remarks - public bool IsNewerThan(string versionStrA, string versionStrB) + public bool IsNewerThan(string versionStrA, string? versionStrB) { // arrange ISemanticVersion versionA = new SemanticVersion(versionStrA); - ISemanticVersion versionB = versionStrB != null + ISemanticVersion? versionB = versionStrB != null ? new SemanticVersion(versionStrB) : null; @@ -356,13 +354,13 @@ namespace SMAPI.Tests.Utilities [TestCase("1.0-beta.2", "1.0-beta.10", "1.0-beta.3", ExpectedResult = false)] [TestCase("1.0-beta-2", "1.0-beta-10", "1.0-beta-3", ExpectedResult = false)] [TestCase("1.0.0", "1.0.0", null, ExpectedResult = false)] // null is always less than any value per CompareTo remarks - public bool IsBetween(string versionStr, string lowerStr, string upperStr) + public bool IsBetween(string versionStr, string? lowerStr, string? upperStr) { // arrange - ISemanticVersion lower = lowerStr != null + ISemanticVersion? lower = lowerStr != null ? new SemanticVersion(lowerStr) : null; - ISemanticVersion upper = upperStr != null + ISemanticVersion? upper = upperStr != null ? new SemanticVersion(upperStr) : null; ISemanticVersion version = new SemanticVersion(versionStr); @@ -436,7 +434,7 @@ namespace SMAPI.Tests.Utilities /// The prerelease tag. /// The build metadata. /// Whether the version should be marked as non-standard. - private void AssertParts(ISemanticVersion version, int major, int minor, int patch, string prerelease, string build, bool nonStandard) + private void AssertParts(ISemanticVersion version, int major, int minor, int patch, string? prerelease, string? build, bool nonStandard) { Assert.AreEqual(major, version.MajorVersion, "The major version doesn't match."); Assert.AreEqual(minor, version.MinorVersion, "The minor version doesn't match."); @@ -449,9 +447,8 @@ namespace SMAPI.Tests.Utilities /// Assert that the expected exception type is thrown, and log the action output and thrown exception. /// The expected exception type. /// The action which may throw the exception. - /// The message to log if the expected exception isn't thrown. [SuppressMessage("ReSharper", "UnusedParameter.Local", Justification = "The message argument is deliberately only used in precondition checks since this is an assertion method.")] - private void AssertAndLogException(Func action, string message = null) + private void AssertAndLogException(Func action) where T : Exception { this.AssertAndLogException(() => @@ -466,7 +463,7 @@ namespace SMAPI.Tests.Utilities /// The action which may throw the exception. /// The message to log if the expected exception isn't thrown. [SuppressMessage("ReSharper", "UnusedParameter.Local", Justification = "The message argument is deliberately only used in precondition checks since this is an assertion method.")] - private void AssertAndLogException(Action action, string message = null) + private void AssertAndLogException(Action action, string? message = null) where T : Exception { try -- cgit From 5f7a92a74592a53529890eebb1ee9fe519afd92f Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 12 Apr 2022 20:52:01 -0400 Subject: enable nullable annotations in unit tests (#837) --- src/SMAPI.Tests/Utilities/KeybindListTests.cs | 12 +- src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs | 183 +++++++++++------------- src/SMAPI.Tests/Utilities/SDateTests.cs | 19 ++- 3 files changed, 101 insertions(+), 113 deletions(-) (limited to 'src/SMAPI.Tests/Utilities') diff --git a/src/SMAPI.Tests/Utilities/KeybindListTests.cs b/src/SMAPI.Tests/Utilities/KeybindListTests.cs index f5c156c4..060c93ed 100644 --- a/src/SMAPI.Tests/Utilities/KeybindListTests.cs +++ b/src/SMAPI.Tests/Utilities/KeybindListTests.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Collections.Generic; using NUnit.Framework; @@ -46,7 +44,7 @@ namespace SMAPI.Tests.Utilities [TestCase(",", ExpectedResult = "None")] [TestCase("A,", ExpectedResult = "A")] [TestCase(",A", ExpectedResult = "A")] - public string TryParse_MultiValues(string input) + public string TryParse_MultiValues(string? input) { // act bool success = KeybindList.TryParse(input, out KeybindList parsed, out string[] errors); @@ -100,13 +98,15 @@ namespace SMAPI.Tests.Utilities public SButtonState GetState(string input, string stateMap) { // act - bool success = KeybindList.TryParse(input, out KeybindList parsed, out string[] errors); + bool success = KeybindList.TryParse(input, out KeybindList? parsed, out string[] errors); if (success && parsed?.Keybinds != null) { - foreach (var keybind in parsed.Keybinds) + foreach (Keybind? keybind in parsed.Keybinds) + { #pragma warning disable 618 // method is marked obsolete because it should only be used in unit tests keybind.GetButtonState = key => this.GetStateFromMap(key, stateMap); #pragma warning restore 618 + } } // assert @@ -114,7 +114,7 @@ namespace SMAPI.Tests.Utilities Assert.IsNotNull(parsed, "The parsed result should not be null."); Assert.IsNotNull(errors, message: "The errors should never be null."); Assert.IsEmpty(errors, message: "The input bindings incorrectly reported errors."); - return parsed.GetState(); + return parsed!.GetState(); } diff --git a/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs b/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs index ae2cc6ce..3219d89d 100644 --- a/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs +++ b/src/SMAPI.Tests/Utilities/PathUtilitiesTests.cs @@ -1,5 +1,4 @@ -#nullable disable - +using System.Diagnostics.CodeAnalysis; using System.IO; using NUnit.Framework; using StardewModdingAPI.Toolkit.Utilities; @@ -8,6 +7,7 @@ namespace SMAPI.Tests.Utilities { /// Unit tests for . [TestFixture] + [SuppressMessage("ReSharper", "StringLiteralTypo", Justification = "These are standard game install paths.")] internal class PathUtilitiesTests { /********* @@ -16,136 +16,125 @@ namespace SMAPI.Tests.Utilities /// Sample paths used in unit tests. public static readonly SamplePath[] SamplePaths = { // Windows absolute path - new() - { - OriginalPath = @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley", + new( + OriginalPath: @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley", - Segments = new[] { "C:", "Program Files (x86)", "Steam", "steamapps", "common", "Stardew Valley" }, - SegmentsLimit3 = new [] { "C:", "Program Files (x86)", @"Steam\steamapps\common\Stardew Valley" }, + Segments: new[] { "C:", "Program Files (x86)", "Steam", "steamapps", "common", "Stardew Valley" }, + SegmentsLimit3: new [] { "C:", "Program Files (x86)", @"Steam\steamapps\common\Stardew Valley" }, - NormalizedOnWindows = @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley", - NormalizedOnUnix = @"C:/Program Files (x86)/Steam/steamapps/common/Stardew Valley" - }, + NormalizedOnWindows: @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley", + NormalizedOnUnix: @"C:/Program Files (x86)/Steam/steamapps/common/Stardew Valley" + ), // Windows absolute path (with trailing slash) - new() - { - OriginalPath = @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley\", + new( + OriginalPath: @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley\", - Segments = new[] { "C:", "Program Files (x86)", "Steam", "steamapps", "common", "Stardew Valley" }, - SegmentsLimit3 = new [] { "C:", "Program Files (x86)", @"Steam\steamapps\common\Stardew Valley\" }, + Segments: new[] { "C:", "Program Files (x86)", "Steam", "steamapps", "common", "Stardew Valley" }, + SegmentsLimit3: new [] { "C:", "Program Files (x86)", @"Steam\steamapps\common\Stardew Valley\" }, - NormalizedOnWindows = @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley\", - NormalizedOnUnix = @"C:/Program Files (x86)/Steam/steamapps/common/Stardew Valley/" - }, + NormalizedOnWindows: @"C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley\", + NormalizedOnUnix: @"C:/Program Files (x86)/Steam/steamapps/common/Stardew Valley/" + ), // Windows relative path - new() - { - OriginalPath = @"Content\Characters\Dialogue\Abigail", + new( + OriginalPath: @"Content\Characters\Dialogue\Abigail", - Segments = new [] { "Content", "Characters", "Dialogue", "Abigail" }, - SegmentsLimit3 = new [] { "Content", "Characters", @"Dialogue\Abigail" }, + Segments: new [] { "Content", "Characters", "Dialogue", "Abigail" }, + SegmentsLimit3: new [] { "Content", "Characters", @"Dialogue\Abigail" }, - NormalizedOnWindows = @"Content\Characters\Dialogue\Abigail", - NormalizedOnUnix = @"Content/Characters/Dialogue/Abigail" - }, + NormalizedOnWindows: @"Content\Characters\Dialogue\Abigail", + NormalizedOnUnix: @"Content/Characters/Dialogue/Abigail" + ), // Windows relative path (with directory climbing) - new() - { - OriginalPath = @"..\..\Content", + new( + OriginalPath: @"..\..\Content", - Segments = new [] { "..", "..", "Content" }, - SegmentsLimit3 = new [] { "..", "..", "Content" }, + Segments: new [] { "..", "..", "Content" }, + SegmentsLimit3: new [] { "..", "..", "Content" }, - NormalizedOnWindows = @"..\..\Content", - NormalizedOnUnix = @"../../Content" - }, + NormalizedOnWindows: @"..\..\Content", + NormalizedOnUnix: @"../../Content" + ), // Windows UNC path - new() - { - OriginalPath = @"\\unc\path", + new( + OriginalPath: @"\\unc\path", - Segments = new [] { "unc", "path" }, - SegmentsLimit3 = new [] { "unc", "path" }, + Segments: new [] { "unc", "path" }, + SegmentsLimit3: new [] { "unc", "path" }, - NormalizedOnWindows = @"\\unc\path", - NormalizedOnUnix = "/unc/path" // there's no good way to normalize this on Unix since UNC paths aren't supported; path normalization is meant for asset names anyway, so this test only ensures it returns some sort of sane value - }, + NormalizedOnWindows: @"\\unc\path", + NormalizedOnUnix: "/unc/path" // there's no good way to normalize this on Unix since UNC paths aren't supported; path normalization is meant for asset names anyway, so this test only ensures it returns some sort of sane value + ), // Linux absolute path - new() - { - OriginalPath = @"/home/.steam/steam/steamapps/common/Stardew Valley", + new( + OriginalPath: @"/home/.steam/steam/steamapps/common/Stardew Valley", - Segments = new [] { "home", ".steam", "steam", "steamapps", "common", "Stardew Valley" }, - SegmentsLimit3 = new [] { "home", ".steam", "steam/steamapps/common/Stardew Valley" }, + Segments: new [] { "home", ".steam", "steam", "steamapps", "common", "Stardew Valley" }, + SegmentsLimit3: new [] { "home", ".steam", "steam/steamapps/common/Stardew Valley" }, - NormalizedOnWindows = @"\home\.steam\steam\steamapps\common\Stardew Valley", - NormalizedOnUnix = @"/home/.steam/steam/steamapps/common/Stardew Valley" - }, + NormalizedOnWindows: @"\home\.steam\steam\steamapps\common\Stardew Valley", + NormalizedOnUnix: @"/home/.steam/steam/steamapps/common/Stardew Valley" + ), // Linux absolute path (with trailing slash) - new() - { - OriginalPath = @"/home/.steam/steam/steamapps/common/Stardew Valley/", + new( + OriginalPath: @"/home/.steam/steam/steamapps/common/Stardew Valley/", - Segments = new [] { "home", ".steam", "steam", "steamapps", "common", "Stardew Valley" }, - SegmentsLimit3 = new [] { "home", ".steam", "steam/steamapps/common/Stardew Valley/" }, + Segments: new [] { "home", ".steam", "steam", "steamapps", "common", "Stardew Valley" }, + SegmentsLimit3: new [] { "home", ".steam", "steam/steamapps/common/Stardew Valley/" }, - NormalizedOnWindows = @"\home\.steam\steam\steamapps\common\Stardew Valley\", - NormalizedOnUnix = @"/home/.steam/steam/steamapps/common/Stardew Valley/" - }, + NormalizedOnWindows: @"\home\.steam\steam\steamapps\common\Stardew Valley\", + NormalizedOnUnix: @"/home/.steam/steam/steamapps/common/Stardew Valley/" + ), // Linux absolute path (with ~) - new() - { - OriginalPath = @"~/.steam/steam/steamapps/common/Stardew Valley", + new( + OriginalPath: @"~/.steam/steam/steamapps/common/Stardew Valley", - Segments = new [] { "~", ".steam", "steam", "steamapps", "common", "Stardew Valley" }, - SegmentsLimit3 = new [] { "~", ".steam", "steam/steamapps/common/Stardew Valley" }, + Segments: new [] { "~", ".steam", "steam", "steamapps", "common", "Stardew Valley" }, + SegmentsLimit3: new [] { "~", ".steam", "steam/steamapps/common/Stardew Valley" }, - NormalizedOnWindows = @"~\.steam\steam\steamapps\common\Stardew Valley", - NormalizedOnUnix = @"~/.steam/steam/steamapps/common/Stardew Valley" - }, + NormalizedOnWindows: @"~\.steam\steam\steamapps\common\Stardew Valley", + NormalizedOnUnix: @"~/.steam/steam/steamapps/common/Stardew Valley" + ), // Linux relative path - new() - { - OriginalPath = @"Content/Characters/Dialogue/Abigail", + new( + OriginalPath: @"Content/Characters/Dialogue/Abigail", - Segments = new [] { "Content", "Characters", "Dialogue", "Abigail" }, - SegmentsLimit3 = new [] { "Content", "Characters", "Dialogue/Abigail" }, + Segments: new [] { "Content", "Characters", "Dialogue", "Abigail" }, + SegmentsLimit3: new [] { "Content", "Characters", "Dialogue/Abigail" }, - NormalizedOnWindows = @"Content\Characters\Dialogue\Abigail", - NormalizedOnUnix = @"Content/Characters/Dialogue/Abigail" - }, + NormalizedOnWindows: @"Content\Characters\Dialogue\Abigail", + NormalizedOnUnix: @"Content/Characters/Dialogue/Abigail" + ), // Linux relative path (with directory climbing) - new() - { - OriginalPath = @"../../Content", + new( + OriginalPath: @"../../Content", - Segments = new [] { "..", "..", "Content" }, - SegmentsLimit3 = new [] { "..", "..", "Content" }, + Segments: new [] { "..", "..", "Content" }, + SegmentsLimit3: new [] { "..", "..", "Content" }, - NormalizedOnWindows = @"..\..\Content", - NormalizedOnUnix = @"../../Content" - }, + NormalizedOnWindows: @"..\..\Content", + NormalizedOnUnix: @"../../Content" + ), // Mixed directory separators - new() - { - OriginalPath = @"C:\some/mixed\path/separators", + new( + OriginalPath: @"C:\some/mixed\path/separators", - Segments = new [] { "C:", "some", "mixed", "path", "separators" }, - SegmentsLimit3 = new [] { "C:", "some", @"mixed\path/separators" }, + Segments: new [] { "C:", "some", "mixed", "path", "separators" }, + SegmentsLimit3: new [] { "C:", "some", @"mixed\path/separators" }, - NormalizedOnWindows = @"C:\some\mixed\path\separators", - NormalizedOnUnix = @"C:/some/mixed/path/separators" - }, + NormalizedOnWindows: @"C:\some\mixed\path\separators", + NormalizedOnUnix: @"C:/some/mixed/path/separators" + ) }; @@ -283,14 +272,14 @@ namespace SMAPI.Tests.Utilities /********* ** Private classes *********/ - public class SamplePath + /// A sample path in multiple formats. + /// The original path to pass to the . + /// The normalized path segments. + /// The normalized path segments, if we stop segmenting after the second one. + /// The normalized form on Windows. + /// The normalized form on Linux or macOS. + public record SamplePath(string OriginalPath, string[] Segments, string[] SegmentsLimit3, string NormalizedOnWindows, string NormalizedOnUnix) { - public string OriginalPath { get; set; } - public string[] Segments { get; set; } - public string[] SegmentsLimit3 { get; set; } - public string NormalizedOnWindows { get; set; } - public string NormalizedOnUnix { get; set; } - public override string ToString() { return this.OriginalPath; diff --git a/src/SMAPI.Tests/Utilities/SDateTests.cs b/src/SMAPI.Tests/Utilities/SDateTests.cs index a4a36828..b9c3d202 100644 --- a/src/SMAPI.Tests/Utilities/SDateTests.cs +++ b/src/SMAPI.Tests/Utilities/SDateTests.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -258,7 +256,7 @@ namespace SMAPI.Tests.Utilities { SDate date = new(day, season, year); int hash = date.GetHashCode(); - if (hashes.TryGetValue(hash, out SDate otherDate)) + if (hashes.TryGetValue(hash, out SDate? otherDate)) Assert.Fail($"Received identical hash code {hash} for dates {otherDate} and {date}."); if (hash < lastHash) Assert.Fail($"Received smaller hash code for date {date} ({hash}) relative to {hashes[lastHash]} ({lastHash})."); @@ -298,7 +296,7 @@ namespace SMAPI.Tests.Utilities [TestCase(Dates.Now, Dates.NextDay, ExpectedResult = false)] [TestCase(Dates.Now, Dates.NextMonth, ExpectedResult = false)] [TestCase(Dates.Now, Dates.NextYear, ExpectedResult = false)] - public bool Operators_Equals(string now, string other) + public bool Operators_Equals(string? now, string other) { return this.GetDate(now) == this.GetDate(other); } @@ -312,7 +310,7 @@ namespace SMAPI.Tests.Utilities [TestCase(Dates.Now, Dates.NextDay, ExpectedResult = true)] [TestCase(Dates.Now, Dates.NextMonth, ExpectedResult = true)] [TestCase(Dates.Now, Dates.NextYear, ExpectedResult = true)] - public bool Operators_NotEquals(string now, string other) + public bool Operators_NotEquals(string? now, string other) { return this.GetDate(now) != this.GetDate(other); } @@ -326,7 +324,7 @@ namespace SMAPI.Tests.Utilities [TestCase(Dates.Now, Dates.NextDay, ExpectedResult = true)] [TestCase(Dates.Now, Dates.NextMonth, ExpectedResult = true)] [TestCase(Dates.Now, Dates.NextYear, ExpectedResult = true)] - public bool Operators_LessThan(string now, string other) + public bool Operators_LessThan(string? now, string other) { return this.GetDate(now) < this.GetDate(other); } @@ -340,7 +338,7 @@ namespace SMAPI.Tests.Utilities [TestCase(Dates.Now, Dates.NextDay, ExpectedResult = true)] [TestCase(Dates.Now, Dates.NextMonth, ExpectedResult = true)] [TestCase(Dates.Now, Dates.NextYear, ExpectedResult = true)] - public bool Operators_LessThanOrEqual(string now, string other) + public bool Operators_LessThanOrEqual(string? now, string other) { return this.GetDate(now) <= this.GetDate(other); } @@ -354,7 +352,7 @@ namespace SMAPI.Tests.Utilities [TestCase(Dates.Now, Dates.NextDay, ExpectedResult = false)] [TestCase(Dates.Now, Dates.NextMonth, ExpectedResult = false)] [TestCase(Dates.Now, Dates.NextYear, ExpectedResult = false)] - public bool Operators_MoreThan(string now, string other) + public bool Operators_MoreThan(string? now, string other) { return this.GetDate(now) > this.GetDate(other); } @@ -368,7 +366,7 @@ namespace SMAPI.Tests.Utilities [TestCase(Dates.Now, Dates.NextDay, ExpectedResult = false)] [TestCase(Dates.Now, Dates.NextMonth, ExpectedResult = false)] [TestCase(Dates.Now, Dates.NextYear, ExpectedResult = false)] - public bool Operators_MoreThanOrEqual(string now, string other) + public bool Operators_MoreThanOrEqual(string? now, string other) { return this.GetDate(now) > this.GetDate(other); } @@ -379,7 +377,8 @@ namespace SMAPI.Tests.Utilities *********/ /// Convert a string date into a game date, to make unit tests easier to read. /// The date string like "dd MMMM yy". - private SDate GetDate(string dateStr) + [return: NotNullIfNotNull("dateStr")] + private SDate? GetDate(string? dateStr) { if (dateStr == null) return null; -- cgit From 4adf8611131a5d86b15f017a42a0366837d14528 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 13 Apr 2022 21:07:43 -0400 Subject: enable nullable annotations in the rest of SMAPI core (#837) --- src/SMAPI.Tests/Utilities/KeybindListTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/SMAPI.Tests/Utilities') diff --git a/src/SMAPI.Tests/Utilities/KeybindListTests.cs b/src/SMAPI.Tests/Utilities/KeybindListTests.cs index 060c93ed..c4c086de 100644 --- a/src/SMAPI.Tests/Utilities/KeybindListTests.cs +++ b/src/SMAPI.Tests/Utilities/KeybindListTests.cs @@ -21,12 +21,12 @@ namespace SMAPI.Tests.Utilities public void TryParse_SimpleValue(SButton button) { // act - bool success = KeybindList.TryParse($"{button}", out KeybindList parsed, out string[] errors); + bool success = KeybindList.TryParse($"{button}", out KeybindList? parsed, out string[] errors); // assert Assert.IsTrue(success, "Parsing unexpectedly failed."); Assert.IsNotNull(parsed, "The parsed result should not be null."); - Assert.AreEqual(parsed.ToString(), $"{button}"); + Assert.AreEqual(parsed!.ToString(), $"{button}"); Assert.IsNotNull(errors, message: "The errors should never be null."); Assert.IsEmpty(errors, message: "The input bindings incorrectly reported errors."); } @@ -47,14 +47,14 @@ namespace SMAPI.Tests.Utilities public string TryParse_MultiValues(string? input) { // act - bool success = KeybindList.TryParse(input, out KeybindList parsed, out string[] errors); + bool success = KeybindList.TryParse(input, out KeybindList? parsed, out string[] errors); // assert Assert.IsTrue(success, "Parsing unexpectedly failed."); Assert.IsNotNull(parsed, "The parsed result should not be null."); Assert.IsNotNull(errors, message: "The errors should never be null."); Assert.IsEmpty(errors, message: "The input bindings incorrectly reported errors."); - return parsed.ToString(); + return parsed!.ToString(); } /// Assert invalid values are rejected. @@ -67,7 +67,7 @@ namespace SMAPI.Tests.Utilities public void TryParse_InvalidValues(string input, string expectedError) { // act - bool success = KeybindList.TryParse(input, out KeybindList parsed, out string[] errors); + bool success = KeybindList.TryParse(input, out KeybindList? parsed, out string[] errors); // assert Assert.IsFalse(success, "Parsing unexpectedly succeeded."); -- cgit