diff --git a/src/EawModinfo.Tests/MergeTests.cs b/src/EawModinfo.Tests/MergeTests.cs index c897b5d..f4fdf38 100644 --- a/src/EawModinfo.Tests/MergeTests.cs +++ b/src/EawModinfo.Tests/MergeTests.cs @@ -39,6 +39,7 @@ public void MergeInto_VariantDefinesNameOnly() Assert.Equal(mainData.Icon, newData.Icon); Assert.Equal(mainData.Summary, newData.Summary); Assert.Equal(2, newData.Languages.Count); // As stated by the specification in III.3.2, languages was not explicitly set. + Assert.True(newData.LanguagesExplicitlySet); Assert.Equal(LanguageInfo.Default, newData.Languages.First()); Assert.Equal(2, newData.Dependencies.Count); Assert.Equal("bla", newData.Dependencies[0].Identifier); @@ -89,7 +90,8 @@ public void MergeInto_VariantDefinesAll() Assert.Equal(variantData.Name, newData.Name); Assert.Equal(variantData.Icon, newData.Icon); Assert.Equal(variantData.Summary, newData.Summary); - Assert.Equal(2, newData.Languages.Count()); + Assert.Equal(2, newData.Languages.Count); + Assert.True(newData.LanguagesExplicitlySet); Assert.Equal(2, newData.Dependencies.Count); Assert.Equal("bar", newData.Dependencies[0].Identifier); Assert.NotNull(newData.SteamData); @@ -172,6 +174,7 @@ internal class InvalidModinfo : IModinfo public IDictionary Custom => null!; public ISteamData? SteamData => null; public IReadOnlyCollection Languages => null!; + public bool LanguagesExplicitlySet => false; public string ToJson() => string.Empty; public void ToJson(Stream stream) diff --git a/src/EawModinfo.Tests/ModinfoDataTest.cs b/src/EawModinfo.Tests/ModinfoDataTest.cs index e5c6954..946243a 100644 --- a/src/EawModinfo.Tests/ModinfoDataTest.cs +++ b/src/EawModinfo.Tests/ModinfoDataTest.cs @@ -128,11 +128,13 @@ public void Parse_WithOneLanguage() var modinfo = ModinfoData.Parse(data); Assert.Equal("My Mod Name", modinfo.Name); Assert.Single(modinfo.Languages); + Assert.True(modinfo.LanguagesExplicitlySet); modinfo = ModinfoData.Parse(new MemoryStream(Encoding.UTF8.GetBytes(data))); Assert.Equal("My Mod Name", modinfo.Name); Assert.Null(modinfo.Version); Assert.Null(modinfo.SteamData); + Assert.True(modinfo.LanguagesExplicitlySet); } [Fact] @@ -155,12 +157,14 @@ public void Parse_WithManyLanguages() var modinfo = ModinfoData.Parse(data); Assert.Equal("My Mod Name", modinfo.Name); - Assert.Equal(2, modinfo.Languages.Count()); + Assert.Equal(2, modinfo.Languages.Count); + Assert.True(modinfo.LanguagesExplicitlySet); modinfo = ModinfoData.Parse(new MemoryStream(Encoding.UTF8.GetBytes(data))); Assert.Equal("My Mod Name", modinfo.Name); Assert.Null(modinfo.Version); Assert.Null(modinfo.SteamData); + Assert.True(modinfo.LanguagesExplicitlySet); } [Fact] @@ -184,10 +188,12 @@ public void Parse_WithDuplicateLanguage() var modinfo = ModinfoData.Parse(data); Assert.Equal("My Mod Name", modinfo.Name); Assert.Single(modinfo.Languages); + Assert.True(modinfo.LanguagesExplicitlySet); modinfo = ModinfoData.Parse(new MemoryStream(Encoding.UTF8.GetBytes(data))); Assert.Equal("My Mod Name", modinfo.Name); Assert.Single(modinfo.Languages); + Assert.True(modinfo.LanguagesExplicitlySet); } [Fact] @@ -212,10 +218,12 @@ public void Parse_WithDuplicateLanguage2() var modinfo = ModinfoData.Parse(data); Assert.Equal("My Mod Name", modinfo.Name); Assert.Single(modinfo.Languages); + Assert.True(modinfo.LanguagesExplicitlySet); modinfo = ModinfoData.Parse(new MemoryStream(Encoding.UTF8.GetBytes(data))); Assert.Equal("My Mod Name", modinfo.Name); Assert.Single(modinfo.Languages); + Assert.True(modinfo.LanguagesExplicitlySet); } [Fact] @@ -233,12 +241,14 @@ public void Parse_WithoutLanguage() Assert.Single(modinfo.Languages); Assert.Equal("en", modinfo.Languages.ElementAt(0).Code); Assert.Equal(LanguageSupportLevel.FullLocalized, modinfo.Languages.ElementAt(0).Support); + Assert.False(modinfo.LanguagesExplicitlySet); modinfo = ModinfoData.Parse(new MemoryStream(Encoding.UTF8.GetBytes(data))); Assert.Equal("My Mod Name", modinfo.Name); Assert.Single(modinfo.Languages); Assert.Equal("en", modinfo.Languages.ElementAt(0).Code); Assert.Equal(LanguageSupportLevel.FullLocalized, modinfo.Languages.ElementAt(0).Support); + Assert.False(modinfo.LanguagesExplicitlySet); } [Fact] @@ -255,11 +265,13 @@ public void Parse_WithEmptyLanguage() var modinfo = ModinfoData.Parse(data); Assert.Equal("My Mod Name", modinfo.Name); Assert.Single(modinfo.Languages); + Assert.False(modinfo.LanguagesExplicitlySet); modinfo = ModinfoData.Parse(new MemoryStream(Encoding.UTF8.GetBytes(data))); Assert.Equal("My Mod Name", modinfo.Name); Assert.Null(modinfo.Version); Assert.Null(modinfo.SteamData); + Assert.False(modinfo.LanguagesExplicitlySet); } [Fact] @@ -804,6 +816,8 @@ public void ToJson_Full() }, SteamData = new SteamData("123", "folder", SteamWorkshopVisibility.Public, "Test", ["FOC"]) }; + + Assert.True(modinfo.LanguagesExplicitlySet); var data = modinfo.ToJson(); output.WriteLine(data); @@ -856,6 +870,7 @@ public void ToJson_CustomDefaultLanguageOnly() new LanguageInfo("en", 0), } }; + Assert.True(modinfo.LanguagesExplicitlySet); var data = modinfo.ToJson(); Assert.DoesNotContain(@"""languages""", data); output.WriteLine(data); @@ -874,6 +889,8 @@ public void ToJson_DefaultOnlyLanguage() LanguageInfo.Default } }; + Assert.True(modinfo.LanguagesExplicitlySet); + var data = modinfo.ToJson(); Assert.DoesNotContain(@"""languages""", data); output.WriteLine(data); @@ -952,6 +969,7 @@ public void Ctor_Copy() Assert.Equal(SteamWorkshopVisibility.Public, modinfo.SteamData.Visibility); Assert.Equal("Test", modinfo.SteamData.Title); Assert.Equivalent(new List{"FOC"}, modinfo.SteamData.Tags, true); + Assert.True(modinfo.LanguagesExplicitlySet); var other = new ModinfoData(modinfo); @@ -965,6 +983,7 @@ public void Ctor_Copy() Assert.Equal(modinfo.SteamData.Visibility, other.SteamData.Visibility); Assert.Equal(modinfo.SteamData.Title, other.SteamData.Title); Assert.Equivalent(modinfo.SteamData.Tags, other.SteamData.Tags, true); + Assert.True(other.LanguagesExplicitlySet); } [Fact] @@ -973,14 +992,17 @@ public void Ctor_EmptyLanguage_ShouldFallbackToDefault() var modinfo = new ModinfoData("name") { Languages = [] }; var lang = Assert.Single(modinfo.Languages); Assert.Equal(LanguageInfo.Default, lang); + Assert.False(modinfo.LanguagesExplicitlySet); var newInfo = new ModinfoData(modinfo); lang = Assert.Single(newInfo.Languages); Assert.Equal(LanguageInfo.Default, lang); + Assert.False(modinfo.LanguagesExplicitlySet); var newParsed = ModinfoData.Parse(newInfo.ToJson()); lang = Assert.Single(newParsed.Languages); Assert.Equal(LanguageInfo.Default, lang); + Assert.False(modinfo.LanguagesExplicitlySet); } [Fact] @@ -1037,6 +1059,7 @@ public void ToJsonFromJson() Assert.Equal(modinfo.Summary, other.Summary); Assert.Equal(modinfo.Icon, other.Icon); Assert.Equal(modinfo.Languages, other.Languages); + Assert.True(other.LanguagesExplicitlySet); Assert.Equal(modinfo.SteamData.Id, other.SteamData!.Id); Assert.Equal(modinfo.SteamData.ContentFolder, other.SteamData.ContentFolder); Assert.Equal(modinfo.SteamData.Visibility, other.SteamData.Visibility); @@ -1072,6 +1095,7 @@ public void Ctor_FromIdentity() Assert.Equal([new ModReference("1", ModType.Default), new ModReference("2", ModType.Workshops, SemVersionRange.Parse("*"))], modinfo.Dependencies.ToList()); Assert.Equivalent(new Dictionary(), modinfo.Custom, true); Assert.Equal([LanguageInfo.Default], modinfo.Languages); + Assert.False(modinfo.LanguagesExplicitlySet); Assert.Null(modinfo.Icon); Assert.Null(modinfo.SteamData); Assert.Null(modinfo.Summary); diff --git a/src/EawModinfo.Tests/VariantModinfoFileTest.cs b/src/EawModinfo.Tests/VariantModinfoFileTest.cs index 38fefea..d231aa4 100644 --- a/src/EawModinfo.Tests/VariantModinfoFileTest.cs +++ b/src/EawModinfo.Tests/VariantModinfoFileTest.cs @@ -136,6 +136,7 @@ private async Task AssertMergeDataFromMainIntoVariant(ModinfoVariantFile variant Assert.Equal(SemVersion.ParsedFrom(1, 1, 1, "BETA"), data.Version); Assert.Single(data.Custom); Assert.Equal(2, data.Languages.Count); + Assert.True(data.LanguagesExplicitlySet); } [Fact] @@ -169,5 +170,6 @@ public void MergeMainIntoVariant_WhereVariantSetsLanguageExplicitly() var variant = variantFile.GetModinfo(); Assert.Single(variant.Languages); + Assert.True(variant.LanguagesExplicitlySet); } } \ No newline at end of file diff --git a/src/EawModinfo/EawModinfo.csproj b/src/EawModinfo/EawModinfo.csproj index 25745cf..5020b83 100644 --- a/src/EawModinfo/EawModinfo.csproj +++ b/src/EawModinfo/EawModinfo.csproj @@ -50,11 +50,11 @@ - + - + diff --git a/src/EawModinfo/Model/Json/JsonModinfoData.cs b/src/EawModinfo/Model/Json/JsonModinfoData.cs index 9fc66aa..d7e6836 100644 --- a/src/EawModinfo/Model/Json/JsonModinfoData.cs +++ b/src/EawModinfo/Model/Json/JsonModinfoData.cs @@ -95,6 +95,9 @@ public IReadOnlyCollection Languages } } + [JsonIgnore] + public bool LanguagesExplicitlySet => !ReferenceEquals(Languages, ModinfoData.UnsetLanguages); + /// [JsonPropertyName("custom")] public IDictionary Custom { get; set; } diff --git a/src/EawModinfo/Model/ModinfoData.cs b/src/EawModinfo/Model/ModinfoData.cs index 1c38e65..e82b030 100644 --- a/src/EawModinfo/Model/ModinfoData.cs +++ b/src/EawModinfo/Model/ModinfoData.cs @@ -68,6 +68,9 @@ public IReadOnlyCollection Languages } } + /// + public bool LanguagesExplicitlySet => !ReferenceEquals(Languages, UnsetLanguages); + /// /// Initializes a new instance of the class with a given name. /// @@ -110,7 +113,7 @@ public ModinfoData(IModinfo modinfo) SteamData = modinfo.SteamData != null ? new SteamData(modinfo.SteamData) : null; Custom = new Dictionary(modinfo.Custom); - if (ReferenceEquals(modinfo.Languages, UnsetLanguages) || modinfo.Languages.Count == 0) + if (!modinfo.LanguagesExplicitlySet || modinfo.Languages.Count == 0) return; Languages = modinfo.Languages.Select(x => new LanguageInfo(x)).Distinct().ToList(); } diff --git a/src/EawModinfo/Spec/IModiInfo.cs b/src/EawModinfo/Spec/IModiInfo.cs index b432c99..e1c24d5 100644 --- a/src/EawModinfo/Spec/IModiInfo.cs +++ b/src/EawModinfo/Spec/IModiInfo.cs @@ -35,4 +35,10 @@ public interface IModinfo : IModIdentity, IConvertibleToJson /// If no other language infos are provided, a default language info gets returned. The default language info is English - FullLocalized. /// IReadOnlyCollection Languages { get; } + + /// + /// Returns if was explicitly set, + /// or is the default (English - FullLocalized) was implicitly applied. + /// + bool LanguagesExplicitlySet { get; } } \ No newline at end of file diff --git a/src/EawModinfo/Utilities/ModInfoDataUtilities.cs b/src/EawModinfo/Utilities/ModInfoDataUtilities.cs index 32c01ce..64b7d31 100644 --- a/src/EawModinfo/Utilities/ModInfoDataUtilities.cs +++ b/src/EawModinfo/Utilities/ModInfoDataUtilities.cs @@ -70,7 +70,7 @@ private static ModinfoData MergeFrom(IModinfo current, IModinfo target) dependencies = new DependencyList(target.Dependencies); var languages = current.Languages; - if (!ReferenceEquals(target.Languages, ModinfoData.UnsetLanguages)) + if (target.LanguagesExplicitlySet) languages = target.Languages.Select(x => (ILanguageInfo)new LanguageInfo(x)).Distinct().ToList(); return new ModinfoData(name) diff --git a/version.json b/version.json index 828c52d..6d3fef8 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "6.0", + "version": "6.1", "publicReleaseRefSpec": [ "^refs/heads/master$" ],