|
| 1 | +using System.Collections.Generic; |
| 2 | +using System.Linq; |
| 3 | +using NUnit.Framework; |
| 4 | +using StardewModdingAPI; |
| 5 | +using StardewModdingAPI.Toolkit.Framework.Clients.Wiki; |
| 6 | + |
| 7 | +namespace SMAPI.Tests.WikiClient |
| 8 | +{ |
| 9 | + /// <summary>Unit tests for <see cref="ChangeDescriptor"/>.</summary> |
| 10 | + [TestFixture] |
| 11 | + internal class ChangeDescriptorTests |
| 12 | + { |
| 13 | + /********* |
| 14 | + ** Unit tests |
| 15 | + *********/ |
| 16 | + /**** |
| 17 | + ** Constructor |
| 18 | + ****/ |
| 19 | + [Test(Description = "Assert that Parse sets the expected values for valid and invalid descriptors.")] |
| 20 | + public void Parse_SetsExpectedValues_Raw() |
| 21 | + { |
| 22 | + // arrange |
| 23 | + string rawDescriptor = "-Nexus:2400, -B, XX → YY, Nexus:451,+A, XXX → YYY, invalidA →, → invalidB"; |
| 24 | + string[] expectedAdd = new[] { "Nexus:451", "A" }; |
| 25 | + string[] expectedRemove = new[] { "Nexus:2400", "B" }; |
| 26 | + IDictionary<string, string> expectedReplace = new Dictionary<string, string> |
| 27 | + { |
| 28 | + ["XX"] = "YY", |
| 29 | + ["XXX"] = "YYY" |
| 30 | + }; |
| 31 | + string[] expectedErrors = new[] |
| 32 | + { |
| 33 | + "Failed parsing ' invalidA →': can't map to a blank value. Use the '-value' format to remove a value.", |
| 34 | + "Failed parsing ' → invalidB': can't map from a blank old value. Use the '+value' format to add a value." |
| 35 | + }; |
| 36 | + |
| 37 | + // act |
| 38 | + ChangeDescriptor parsed = ChangeDescriptor.Parse(rawDescriptor, out string[] errors); |
| 39 | + |
| 40 | + // assert |
| 41 | + Assert.That(parsed.Add, Is.EquivalentTo(expectedAdd), $"{nameof(parsed.Add)} doesn't match the expected value."); |
| 42 | + Assert.That(parsed.Remove, Is.EquivalentTo(expectedRemove), $"{nameof(parsed.Replace)} doesn't match the expected value."); |
| 43 | + Assert.That(parsed.Replace, Is.EquivalentTo(expectedReplace), $"{nameof(parsed.Replace)} doesn't match the expected value."); |
| 44 | + Assert.That(errors, Is.EquivalentTo(expectedErrors), $"{nameof(errors)} doesn't match the expected value."); |
| 45 | + } |
| 46 | + |
| 47 | + [Test(Description = "Assert that Parse sets the expected values for descriptors when a format callback is specified.")] |
| 48 | + public void Parse_SetsExpectedValues_Formatted() |
| 49 | + { |
| 50 | + // arrange |
| 51 | + string rawDescriptor = "-1.0.1, -2.0-beta, 1.00 → 1.0, 1.0.0,+2.0-beta.15, 2.0 → 2.0-beta, invalidA →, → invalidB"; |
| 52 | + string[] expectedAdd = new[] { "1.0.0", "2.0.0-beta.15" }; |
| 53 | + string[] expectedRemove = new[] { "1.0.1", "2.0.0-beta" }; |
| 54 | + IDictionary<string, string> expectedReplace = new Dictionary<string, string> |
| 55 | + { |
| 56 | + ["1.00"] = "1.0.0", |
| 57 | + ["2.0.0"] = "2.0.0-beta" |
| 58 | + }; |
| 59 | + string[] expectedErrors = new[] |
| 60 | + { |
| 61 | + "Failed parsing ' invalidA →': can't map to a blank value. Use the '-value' format to remove a value.", |
| 62 | + "Failed parsing ' → invalidB': can't map from a blank old value. Use the '+value' format to add a value." |
| 63 | + }; |
| 64 | + |
| 65 | + // act |
| 66 | + ChangeDescriptor parsed = ChangeDescriptor.Parse( |
| 67 | + rawDescriptor, |
| 68 | + out string[] errors, |
| 69 | + formatValue: raw => SemanticVersion.TryParse(raw, out ISemanticVersion version) |
| 70 | + ? version.ToString() |
| 71 | + : raw |
| 72 | + ); |
| 73 | + |
| 74 | + // assert |
| 75 | + Assert.That(parsed.Add, Is.EquivalentTo(expectedAdd), $"{nameof(parsed.Add)} doesn't match the expected value."); |
| 76 | + Assert.That(parsed.Remove, Is.EquivalentTo(expectedRemove), $"{nameof(parsed.Replace)} doesn't match the expected value."); |
| 77 | + Assert.That(parsed.Replace, Is.EquivalentTo(expectedReplace), $"{nameof(parsed.Replace)} doesn't match the expected value."); |
| 78 | + Assert.That(errors, Is.EquivalentTo(expectedErrors), $"{nameof(errors)} doesn't match the expected value."); |
| 79 | + } |
| 80 | + |
| 81 | + [Test(Description = "Assert that Apply returns the expected value for the given descriptor.")] |
| 82 | + |
| 83 | + // null input |
| 84 | + [TestCase(null, "", ExpectedResult = null)] |
| 85 | + [TestCase(null, "+Nexus:2400", ExpectedResult = "Nexus:2400")] |
| 86 | + [TestCase(null, "-Nexus:2400", ExpectedResult = null)] |
| 87 | + |
| 88 | + // blank input |
| 89 | + [TestCase("", null, ExpectedResult = "")] |
| 90 | + [TestCase("", "", ExpectedResult = "")] |
| 91 | + |
| 92 | + // add value |
| 93 | + [TestCase("", "+Nexus:2400", ExpectedResult = "Nexus:2400")] |
| 94 | + [TestCase("Nexus:2400", "+Nexus:2400", ExpectedResult = "Nexus:2400")] |
| 95 | + [TestCase("Nexus:2400", "Nexus:2400", ExpectedResult = "Nexus:2400")] |
| 96 | + [TestCase("Nexus:2400", "+Nexus:2401", ExpectedResult = "Nexus:2400, Nexus:2401")] |
| 97 | + [TestCase("Nexus:2400", "Nexus:2401", ExpectedResult = "Nexus:2400, Nexus:2401")] |
| 98 | + |
| 99 | + // remove value |
| 100 | + [TestCase("", "-Nexus:2400", ExpectedResult = "")] |
| 101 | + [TestCase("Nexus:2400", "-Nexus:2400", ExpectedResult = "")] |
| 102 | + [TestCase("Nexus:2400", "-Nexus:2401", ExpectedResult = "Nexus:2400")] |
| 103 | + |
| 104 | + // replace value |
| 105 | + [TestCase("", "Nexus:2400 → Nexus:2401", ExpectedResult = "")] |
| 106 | + [TestCase("Nexus:2400", "Nexus:2400 → Nexus:2401", ExpectedResult = "Nexus:2401")] |
| 107 | + [TestCase("Nexus:1", "Nexus: 2400 → Nexus: 2401", ExpectedResult = "Nexus:1")] |
| 108 | + |
| 109 | + // complex strings |
| 110 | + [TestCase("", "+Nexus:A, Nexus:B, -Chucklefish:14, Nexus:2400 → Nexus:2401, Nexus:A→Nexus:B", ExpectedResult = "Nexus:A, Nexus:B")] |
| 111 | + [TestCase("Nexus:2400", "+Nexus:A, Nexus:B, -Chucklefish:14, Nexus:2400 → Nexus:2401, Nexus:A→Nexus:B", ExpectedResult = "Nexus:2401, Nexus:A, Nexus:B")] |
| 112 | + [TestCase("Nexus:2400, Nexus:2401, Nexus:B,Chucklefish:14", "+Nexus:A, Nexus:B, -Chucklefish:14, Nexus:2400 → Nexus:2401, Nexus:A→Nexus:B", ExpectedResult = "Nexus:2401, Nexus:2401, Nexus:B, Nexus:A")] |
| 113 | + public string Apply_Raw(string input, string descriptor) |
| 114 | + { |
| 115 | + var parsed = ChangeDescriptor.Parse(descriptor, out string[] errors); |
| 116 | + |
| 117 | + Assert.IsEmpty(errors, "Parsing the descriptor failed."); |
| 118 | + |
| 119 | + return parsed.ApplyToCopy(input); |
| 120 | + } |
| 121 | + |
| 122 | + [Test(Description = "Assert that ToString returns the expected normalized descriptors.")] |
| 123 | + [TestCase(null, ExpectedResult = "")] |
| 124 | + [TestCase("", ExpectedResult = "")] |
| 125 | + [TestCase("+ Nexus:2400", ExpectedResult = "+Nexus:2400")] |
| 126 | + [TestCase(" Nexus:2400 ", ExpectedResult = "+Nexus:2400")] |
| 127 | + [TestCase("-Nexus:2400", ExpectedResult = "-Nexus:2400")] |
| 128 | + [TestCase(" Nexus:2400 →Nexus:2401 ", ExpectedResult = "Nexus:2400 → Nexus:2401")] |
| 129 | + [TestCase("+Nexus:A, Nexus:B, -Chucklefish:14, Nexus:2400 → Nexus:2401, Nexus:A→Nexus:B", ExpectedResult = "+Nexus:A, +Nexus:B, -Chucklefish:14, Nexus:2400 → Nexus:2401, Nexus:A → Nexus:B")] |
| 130 | + public string ToString(string descriptor) |
| 131 | + { |
| 132 | + var parsed = ChangeDescriptor.Parse(descriptor, out string[] errors); |
| 133 | + |
| 134 | + Assert.IsEmpty(errors, "Parsing the descriptor failed."); |
| 135 | + |
| 136 | + return parsed.ToString(); |
| 137 | + } |
| 138 | + } |
| 139 | +} |
0 commit comments