From 8c43c8d3ccd17393d4dedec5639314415acfaf1f Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 1 Aug 2023 11:54:25 +0000 Subject: [PATCH 01/17] Fix the logic + add simple tests. --- ...rosoft.NET.Sdk.WebAssembly.Browser.targets | 14 ++- .../Blazor/BlazorBuildOptions.cs | 4 +- .../Blazor/BlazorWasmProjectProvider.cs | 6 +- .../wasm/Wasm.Build.Tests/Blazor/IcuTests.cs | 95 +++++++++++++++++++ .../Common/GlobalizationMode.cs | 2 +- .../Wasm.Build.Tests/ProjectProviderBase.cs | 5 +- .../AssetsComputingHelper.cs | 4 + .../ComputeWasmBuildAssets.cs | 8 +- .../ComputeWasmPublishAssets.cs | 8 +- .../GenerateWasmBootJson.cs | 4 +- 10 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs diff --git a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets index 593825f84be8e3..981c48a65a7f30 100644 --- a/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets +++ b/src/mono/nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets @@ -163,15 +163,17 @@ Copyright (c) .NET Foundation. All rights reserved. + false - <_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(InvariantGlobalization)' != 'true'">$(BlazorWebAssemblyLoadAllGlobalizationData) + <_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(InvariantGlobalization)' != 'true' AND '$(HybridGlobalization)' != 'true'">$(BlazorWebAssemblyLoadAllGlobalizationData) <_BlazorWebAssemblyLoadAllGlobalizationData Condition="'$(_BlazorWebAssemblyLoadAllGlobalizationData)' == ''">false - <_IsHybridGlobalization Condition="'$(InvariantGlobalization)' != 'true' AND '$(HybridGlobalization)' == 'true'"> + <_IsHybridGlobalization>$(HybridGlobalization) + <_IsHybridGlobalization Condition="'$(InvariantGlobalization)' == 'true' OR '$(HybridGlobalization)' == ''">false <_BlazorIcuDataFileName Condition="'$(InvariantGlobalization)' != 'true' AND '$(BlazorWebAssemblyLoadAllGlobalizationData)' != 'true' AND '$(HybridGlobalization)' != 'true'">$(BlazorIcuDataFileName) <_LoadCustomIcuData>false <_LoadCustomIcuData Condition="'$(_BlazorIcuDataFileName)' != ''">true @@ -240,6 +242,8 @@ Copyright (c) .NET Foundation. All rights reserved. ProjectSatelliteAssemblies="@(IntermediateSatelliteAssembliesWithTargetPath)" TimeZoneSupport="$(_BlazorEnableTimeZoneSupport)" InvariantGlobalization="$(_WasmInvariantGlobalization)" + HybridGlobalization="$(_IsHybridGlobalization)" + LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" DotNetJsVersion="$(_WasmRuntimePackVersion)" CopySymbols="$(_WasmCopyOutputSymbolsToOutputDirectory)" OutputPath="$(OutputPath)" @@ -366,7 +370,7 @@ Copyright (c) .NET Foundation. All rights reserved. InvariantGlobalization="$(InvariantGlobalization)" LoadCustomIcuData="$(_LoadCustomIcuData)" IsHybridGlobalization="$(_IsHybridGlobalization)" - LoadAllICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" + LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" StartupMemoryCache="$(_BlazorWebAssemblyStartupMemoryCache)" Jiterpreter="$(_BlazorWebAssemblyJiterpreter)" RuntimeOptions="$(_BlazorWebAssemblyRuntimeOptions)" @@ -414,6 +418,8 @@ Copyright (c) .NET Foundation. All rights reserved. PublishPath="$(PublishDir)" WasmAotAssets="@(WasmNativeAsset)" InvariantGlobalization="$(_WasmInvariantGlobalization)" + HybridGlobalization="$(_IsHybridGlobalization)" + LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" CopySymbols="$(CopyOutputSymbolsToPublishDirectory)" ExistingAssets="@(_WasmPublishPrefilteredAssets)" DotNetJsVersion="$(_WasmRuntimePackVersion)" @@ -557,7 +563,7 @@ Copyright (c) .NET Foundation. All rights reserved. InvariantGlobalization="$(InvariantGlobalization)" LoadCustomIcuData="$(_LoadCustomIcuData)" IsHybridGlobalization="$(_IsHybridGlobalization)" - LoadAllICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" + LoadFullICUData="$(_BlazorWebAssemblyLoadAllGlobalizationData)" StartupMemoryCache="$(_BlazorWebAssemblyStartupMemoryCache)" Jiterpreter="$(_BlazorWebAssemblyJiterpreter)" RuntimeOptions="$(_BlazorWebAssemblyRuntimeOptions)" diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs index 46c736e670acec..f0ff78729b81bd 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs @@ -15,5 +15,7 @@ public record BlazorBuildOptions bool WarnAsError = true, bool ExpectRelinkDirWhenPublishing = false, bool ExpectFingerprintOnDotnetJs = false, - RuntimeVariant RuntimeType = RuntimeVariant.SingleThreaded + RuntimeVariant RuntimeType = RuntimeVariant.SingleThreaded, + GlobalizationMode GlobalizationMode = GlobalizationMode.Default, + string PredefinedIcudt = "" ); diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmProjectProvider.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmProjectProvider.cs index f29e99fd568bc7..6ae7c8c4380dbc 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmProjectProvider.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmProjectProvider.cs @@ -19,12 +19,12 @@ public void AssertBundle(BlazorBuildOptions options) IsPublish: options.IsPublish, TargetFramework: options.TargetFramework, BinFrameworkDir: FindBinFrameworkDir(options.Config, options.IsPublish, options.TargetFramework), - GlobalizationMode: GlobalizationMode.Default, - PredefinedIcudt: null, + GlobalizationMode: options.GlobalizationMode, + PredefinedIcudt: options.PredefinedIcudt, ExpectFingerprintOnDotnetJs: options.ExpectFingerprintOnDotnetJs, ExpectedFileType: options.ExpectedFileType, RuntimeType: options.RuntimeType, - AssertIcuAssets: false, // FIXME: this is broken right now + AssertIcuAssets: true, AssertSymbolsFile: false // FIXME: not supported yet )); } diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs new file mode 100644 index 00000000000000..8a98abc3cb8721 --- /dev/null +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs @@ -0,0 +1,95 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using Xunit; +using Xunit.Abstractions; +using Xunit.Sdk; +using System.Collections.Generic; + +#nullable enable + +namespace Wasm.Build.Tests.Blazor; + +// these tests only check if correct ICU files got copied +public class IcuTests : BlazorWasmTestBase +{ + public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) {} + + string getRandomNameWithoutDots => Path.GetRandomFileName().Replace(".", ""); + + [Theory] + [InlineData("Debug", false)] + [InlineData("Debug", true)] + [InlineData("Release", false)] + [InlineData("Release", true)] + public void HybridWithInvariant(string config, bool invariant) + { + string id = $"blz_hybrid_{config}_{getRandomNameWithoutDots}"; + string projectFile = CreateProjectWithNativeReference(id); + AddItemsPropertiesToProject( + projectFile, + extraProperties: + $"true{invariant}"); + + (CommandResult res, string logPath) = BlazorBuild( + new BlazorBuildOptions( + id, + config, + WarnAsError: false, + GlobalizationMode: invariant ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid + )); + if (invariant) + Assert.Contains("$(HybridGlobalization) has no effect when $(InvariantGlobalization) is set to true.", res.Output); + } + + [Theory] + [InlineData("Debug", false)] + [InlineData("Debug", true)] + [InlineData("Release", false)] + [InlineData("Release", true)] + public void HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) + { + string id = $"blz_hybrid_{config}_{getRandomNameWithoutDots}"; + string projectFile = CreateProjectWithNativeReference(id); + AddItemsPropertiesToProject(projectFile, extraProperties: + $"true{fullIcu}"); + + (CommandResult res, string logPath) = BlazorBuild( + new BlazorBuildOptions( + id, + config, + WarnAsError: false, + GlobalizationMode: GlobalizationMode.Hybrid + )); + if (fullIcu) + Assert.Contains("$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(HybridGlobalization) is set to true.", res.Output); + } + + + [Theory] + [InlineData("Debug", false)] + [InlineData("Debug", true)] + [InlineData("Release", false)] + [InlineData("Release", true)] + public void FullIcuFromRuntimePackWithInvariant(string config, bool invariant) + { + string id = $"blz_hybrid_{config}_{getRandomNameWithoutDots}"; + string projectFile = CreateProjectWithNativeReference(id); + AddItemsPropertiesToProject(projectFile, extraProperties: + $"true{invariant}"); + + (CommandResult res, string logPath) = BlazorBuild( + new BlazorBuildOptions( + id, + config, + WarnAsError: false, + GlobalizationMode: invariant ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu + )); + + if (invariant) + Assert.Contains("$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(InvariantGlobalization) is set to true.", res.Output); + } +} \ No newline at end of file diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs b/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs index 29fee6d77db442..cf66ef0fcc41c8 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Common/GlobalizationMode.cs @@ -9,6 +9,6 @@ public enum GlobalizationMode Default, // chosen based on locale Invariant, // no icu FullIcu, // full icu data: icudt.dat is loaded - PredefinedIcu, // user set WasmIcuDataFileName value and we are loading that file + PredefinedIcu, // user set WasmIcuDataFileName/BlazorIcuDataFileName value and we are loading that file Hybrid // reduced icu, missing data is provided by platform-native functions (web api for wasm) }; diff --git a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs index 99d624b78ef55c..d1debcdd70270e 100644 --- a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs @@ -55,7 +55,7 @@ public IReadOnlyDictionary AssertBasicBundle(AssertBundl // icu if (assertOptions.AssertIcuAssets) { - _testOutput.WriteLine("Skipping asserting icu assets"); + _testOutput.WriteLine("Starting icu assets assert"); AssertIcuAssets(assertOptions); } @@ -348,6 +348,7 @@ public static void AssertDotNetJsSymbols(AssertBundleOptionsBase assertOptions) public void AssertIcuAssets(AssertBundleOptionsBase assertOptions) { List expected = new(); + _testOutput.WriteLine($"AssertIcuAssets: {assertOptions.GlobalizationMode}"); switch (assertOptions.GlobalizationMode) { case GlobalizationMode.Invariant: @@ -374,6 +375,8 @@ public void AssertIcuAssets(AssertBundleOptionsBase assertOptions) default: throw new NotImplementedException($"Unknown {nameof(assertOptions.GlobalizationMode)} = {assertOptions.GlobalizationMode}"); } + foreach (var e in expected) + _testOutput.WriteLine($"e: {e}"); IEnumerable actual = Directory.EnumerateFiles(assertOptions.BinFrameworkDir, "icudt*dat"); AssertFilesOnDisk(expected, actual); diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs index 445f427e02fafa..8682c57a04c3dc 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs @@ -29,6 +29,8 @@ public static bool ShouldFilterCandidate( ITaskItem candidate, bool timezoneSupport, bool invariantGlobalization, + bool hybridGlobalization, + bool loadFullICUData, bool copySymbols, string customIcuCandidateFilename, bool enableThreads, @@ -53,6 +55,8 @@ public static bool ShouldFilterCandidate( ".props" when fromMonoPackage => "extension is .props is not supported.", ".blat" when !timezoneSupport => "timezone support is not enabled.", ".dat" when invariantGlobalization && fileName.StartsWith("icudt") => "invariant globalization is enabled", + ".dat" when loadFullICUData && fileName != "icudt" => "full ICU data is enabled", + ".dat" when hybridGlobalization && fileName != "icudt_hybrid" => "hybrid globalization is enabled", ".dat" when !string.IsNullOrEmpty(customIcuCandidateFilename) && fileName != customIcuCandidateFilename => "custom icu file will be used instead of icu from the runtime pack", ".json" when fromMonoPackage && (fileName == "emcc-props" || fileName == "package") => $"{fileName}{extension} is not used by Blazor", ".ts" when fromMonoPackage && fileName == "dotnet.d" => "dotnet type definition is not used by Blazor", diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs index ba25c5103c4d5d..36cccd45704096 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs @@ -43,6 +43,12 @@ public class ComputeWasmBuildAssets : Task [Required] public bool InvariantGlobalization { get; set; } + [Required] + public bool HybridGlobalization { get; set; } + + [Required] + public bool LoadFullICUData { get; set; } + [Required] public bool CopySymbols { get; set; } @@ -86,7 +92,7 @@ public override bool Execute() for (int i = 0; i < Candidates.Length; i++) { var candidate = Candidates[i]; - if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) + if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, HybridGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) { Log.LogMessage(MessageImportance.Low, "Skipping asset '{0}' because '{1}'", candidate.ItemSpec, reason); filesToRemove.Add(candidate); diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs index df269f565e1d7d..429addedfd555e 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmPublishAssets.cs @@ -43,6 +43,12 @@ public class ComputeWasmPublishAssets : Task [Required] public bool InvariantGlobalization { get; set; } + [Required] + public bool HybridGlobalization { get; set; } + + [Required] + public bool LoadFullICUData { get; set; } + [Required] public bool CopySymbols { get; set; } @@ -577,7 +583,7 @@ private void GroupResolvedFilesToPublish( foreach (var candidate in resolvedFilesToPublish) { #pragma warning disable CA1864 // Prefer the 'IDictionary.TryAdd(TKey, TValue)' method. Dictionary.TryAdd() not available in .Net framework. - if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) + if (AssetsComputingHelper.ShouldFilterCandidate(candidate, TimeZoneSupport, InvariantGlobalization, HybridGlobalization, LoadFullICUData, CopySymbols, customIcuCandidateFilename, EnableThreads, EmitSourceMap, out var reason)) { Log.LogMessage(MessageImportance.Low, "Skipping asset '{0}' because '{1}'", candidate.ItemSpec, reason); if (!resolvedFilesToPublishToRemove.ContainsKey(candidate.ItemSpec)) diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs index dfa897ca3bbcff..ef42b6fa952f10 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs @@ -41,7 +41,7 @@ public class GenerateWasmBootJson : Task [Required] public bool CacheBootResources { get; set; } - public bool LoadAllICUData { get; set; } + public bool LoadFullICUData { get; set; } public bool IsHybridGlobalization { get; set; } @@ -386,7 +386,7 @@ private GlobalizationMode GetGlobalizationMode() return GlobalizationMode.Invariant; else if (IsHybridGlobalization) return GlobalizationMode.Hybrid; - else if (LoadAllICUData) + else if (LoadFullICUData) return GlobalizationMode.All; else if (LoadCustomIcuData) return GlobalizationMode.Custom; From bd1c709b82e24fe92bf609002dd15c2e176cad4e Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 2 Aug 2023 07:50:23 +0000 Subject: [PATCH 02/17] Fix non-icu-sharding tests. --- src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs | 2 +- .../AssetsComputingHelper.cs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs index f0ff78729b81bd..ba953eb86fd00f 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorBuildOptions.cs @@ -16,6 +16,6 @@ public record BlazorBuildOptions bool ExpectRelinkDirWhenPublishing = false, bool ExpectFingerprintOnDotnetJs = false, RuntimeVariant RuntimeType = RuntimeVariant.SingleThreaded, - GlobalizationMode GlobalizationMode = GlobalizationMode.Default, + GlobalizationMode GlobalizationMode = GlobalizationMode.Sharded, string PredefinedIcudt = "" ); diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs index 8682c57a04c3dc..3f3c1a4fc10afd 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs @@ -58,6 +58,7 @@ public static bool ShouldFilterCandidate( ".dat" when loadFullICUData && fileName != "icudt" => "full ICU data is enabled", ".dat" when hybridGlobalization && fileName != "icudt_hybrid" => "hybrid globalization is enabled", ".dat" when !string.IsNullOrEmpty(customIcuCandidateFilename) && fileName != customIcuCandidateFilename => "custom icu file will be used instead of icu from the runtime pack", + ".dat" when IsDefaultIcuMode() && (fileName != "icudt_EFIGS" && fileName != "icudt_CJK" && fileName != "icudt_no_CJK") => "automatic icu shard selection, based on application culture, is enabled", ".json" when fromMonoPackage && (fileName == "emcc-props" || fileName == "package") => $"{fileName}{extension} is not used by Blazor", ".ts" when fromMonoPackage && fileName == "dotnet.d" => "dotnet type definition is not used by Blazor", ".map" when !emitSourceMap && fromMonoPackage && (fileName == "dotnet.js" || fileName == "dotnet.runtime.js") => "source map file is not published", @@ -69,6 +70,11 @@ public static bool ShouldFilterCandidate( }; return reason != null; + + bool IsDefaultIcuMode() + { + return !invariantGlobalization && !loadFullICUData && !hybridGlobalization && string.IsNullOrEmpty(customIcuCandidateFilename); + } } private static bool IsFromMonoPackage(ITaskItem candidate) From ce43251ca22ccd7c846d6ed4edb2541d376acc48 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 2 Aug 2023 09:15:24 +0000 Subject: [PATCH 03/17] Split ICU WBT file - it was running long on CI. --- .../Wasm.Build.Tests/Common/IcuTestsHelper.cs | 102 ++++++++++ .../wasm/Wasm.Build.Tests/IcuShardingTests.cs | 190 +----------------- src/mono/wasm/Wasm.Build.Tests/IcuTests.cs | 104 ++++++++++ 3 files changed, 216 insertions(+), 180 deletions(-) create mode 100644 src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs create mode 100644 src/mono/wasm/Wasm.Build.Tests/IcuTests.cs diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs b/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs new file mode 100644 index 00000000000000..6c3e5e574a122c --- /dev/null +++ b/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs @@ -0,0 +1,102 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using Xunit; +using Xunit.Abstractions; +using Xunit.Sdk; +using System.Collections.Generic; + +#nullable enable + +namespace Wasm.Build.Tests; + +public record SundayNames { + public static string English = "Sunday"; + public static string French = "dimanche"; + public static string Spanish = "domingo"; + public static string Chinese = "星期日"; + public static string Japanese = "日曜日"; + public static string Slovak = "nedeľa"; +} + +public static class IcuTestsHelper +{ + // custom file contains only locales "cy-GB", "is-IS", "bs-BA", "lb-LU" and fallback locale: "en-US": + public static string CustomIcuPath = Path.Combine(BuildEnvironment.TestAssetsPath, "icudt_custom.dat"); + + private const string FallbackSundayNameEnUS = "Sunday"; + + public static readonly string CustomIcuTestedLocales = $@"new Locale[] {{ + new Locale(""cy-GB"", ""Dydd Sul""), new Locale(""is-IS"", ""sunnudagur""), new Locale(""bs-BA"", ""nedjelja""), new Locale(""lb-LU"", ""Sonndeg""), + new Locale(""fr-FR"", null), new Locale(""hr-HR"", null), new Locale(""ko-KR"", null) + }}"; + public static string GetEfigsTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + new Locale(""en-US"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""es-ES"", ""{SundayNames.Spanish}""), + new Locale(""pl-PL"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""cs-CZ"", ""{fallbackSundayName}"") + }}"; + public static string GetCjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}""), new Locale(""ja-JP"", ""{SundayNames.Japanese}""), + new Locale(""fr-FR"", ""{fallbackSundayName}""), new Locale(""hr-HR"", ""{fallbackSundayName}""), new Locale(""it-IT"", ""{fallbackSundayName}"") + }}"; + public static string GetNocjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + new Locale(""en-AU"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), + new Locale(""ja-JP"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""zh-CN"", ""{fallbackSundayName}"") + }}"; + public static readonly string FullIcuTestedLocales = $@"new Locale[] {{ + new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}"") + }}"; + + public static string GetProgramText(string testedLocales, bool onlyPredefinedCultures=false, string fallbackSundayName=FallbackSundayNameEnUS) => $@" + #nullable enable + + using System; + using System.Globalization; + + Console.WriteLine($""Current culture: '{{CultureInfo.CurrentCulture.Name}}'""); + + string fallbackSundayName = ""{fallbackSundayName}""; + bool onlyPredefinedCultures = {(onlyPredefinedCultures ? "true" : "false")}; + Locale[] localesToTest = {testedLocales}; + + bool fail = false; + foreach (var testLocale in localesToTest) + {{ + bool expectMissing = string.IsNullOrEmpty(testLocale.SundayName); + bool ctorShouldFail = expectMissing && onlyPredefinedCultures; + CultureInfo culture; + + try + {{ + culture = new CultureInfo(testLocale.Code); + if (ctorShouldFail) + {{ + Console.WriteLine($""CultureInfo..ctor did not throw an exception for {{testLocale.Code}} as was expected.""); + fail = true; + continue; + }} + }} + catch(CultureNotFoundException cnfe) when (ctorShouldFail && cnfe.Message.Contains($""{{testLocale.Code}} is an invalid culture identifier."")) + {{ + Console.WriteLine($""{{testLocale.Code}}: Success. .ctor failed as expected.""); + continue; + }} + + string expectedSundayName = (expectMissing && !onlyPredefinedCultures) + ? fallbackSundayName + : testLocale.SundayName; + var actualLocalizedSundayName = culture.DateTimeFormat.GetDayName(new DateTime(2000,01,02).DayOfWeek); + if (expectedSundayName != actualLocalizedSundayName) + {{ + Console.WriteLine($""Error: incorrect localized value for Sunday in locale {{testLocale.Code}}. Expected '{{expectedSundayName}}' but got '{{actualLocalizedSundayName}}'.""); + fail = true; + continue; + }} + Console.WriteLine($""{{testLocale.Code}}: Success. Sunday name: {{actualLocalizedSundayName}}""); + }} + return fail ? -1 : 42; + + public record Locale(string Code, string? SundayName); + "; +} diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs index 4da328f69ee2fb..65d5482ba36a8d 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs @@ -17,44 +17,11 @@ public class IcuShardingTests : TestMainJsTestBase public IcuShardingTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : base(output, buildContext) { } - // custom file contains only locales "cy-GB", "is-IS", "bs-BA", "lb-LU" and fallback locale: "en-US": - private static string s_customIcuPath = Path.Combine(BuildEnvironment.TestAssetsPath, "icudt_custom.dat"); - public record SundayNames { - public static string English = "Sunday"; - public static string French = "dimanche"; - public static string Spanish = "domingo"; - public static string Chinese = "星期日"; - public static string Japanese = "日曜日"; - public static string Slovak = "nedeľa"; - } - - private const string FallbackSundayNameEnUS = "Sunday"; - - private static readonly string s_customIcuTestedLocales = $@"new Locale[] {{ - new Locale(""cy-GB"", ""Dydd Sul""), new Locale(""is-IS"", ""sunnudagur""), new Locale(""bs-BA"", ""nedjelja""), new Locale(""lb-LU"", ""Sonndeg""), - new Locale(""fr-FR"", null), new Locale(""hr-HR"", null), new Locale(""ko-KR"", null) - }}"; - private static string GetEfigsTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ - new Locale(""en-US"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""es-ES"", ""{SundayNames.Spanish}""), - new Locale(""pl-PL"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""cs-CZ"", ""{fallbackSundayName}"") - }}"; - private static string GetCjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ - new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}""), new Locale(""ja-JP"", ""{SundayNames.Japanese}""), - new Locale(""fr-FR"", ""{fallbackSundayName}""), new Locale(""hr-HR"", ""{fallbackSundayName}""), new Locale(""it-IT"", ""{fallbackSundayName}"") - }}"; - private static string GetNocjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ - new Locale(""en-AU"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), - new Locale(""ja-JP"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""zh-CN"", ""{fallbackSundayName}"") - }}"; - private static readonly string s_fullIcuTestedLocales = $@"new Locale[] {{ - new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}"") - }}"; - public static IEnumerable IcuExpectedAndMissingCustomShardTestData(bool aot, RunHost host) => ConfigWithAOTData(aot) .Multiply( - new object[] { s_customIcuPath, s_customIcuTestedLocales, false }, - new object[] { s_customIcuPath, s_customIcuTestedLocales, true }) + new object[] { IcuTestsHelper.CustomIcuPath, IcuTestsHelper.CustomIcuTestedLocales, false }, + new object[] { IcuTestsHelper.CustomIcuPath, IcuTestsHelper.CustomIcuTestedLocales, true }) .WithRunHosts(host) .UnwrapItemsAsArrays(); @@ -65,92 +32,21 @@ private static string GetNocjkTestedLocales(string fallbackSundayName=FallbackSu $@"new Locale[] {{ new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), new Locale(""xx-yy"", null) }}" }, - new object[] { "icudt_EFIGS.dat", GetEfigsTestedLocales() }, - new object[] { "icudt_CJK.dat", GetCjkTestedLocales() }, - new object[] { "icudt_no_CJK.dat", GetNocjkTestedLocales() }) + new object[] { "icudt_EFIGS.dat", IcuTestsHelper.GetEfigsTestedLocales() }, + new object[] { "icudt_CJK.dat", IcuTestsHelper.GetCjkTestedLocales() }, + new object[] { "icudt_no_CJK.dat", IcuTestsHelper.GetNocjkTestedLocales() }) .WithRunHosts(host) .UnwrapItemsAsArrays(); public static IEnumerable IcuExpectedAndMissingAutomaticShardTestData(bool aot) => ConfigWithAOTData(aot) .Multiply( - new object[] { "fr-FR", GetEfigsTestedLocales(SundayNames.French)}, - new object[] { "ja-JP", GetCjkTestedLocales(SundayNames.Japanese) }, - new object[] { "sk-SK", GetNocjkTestedLocales(SundayNames.Slovak) }) + new object[] { "fr-FR", IcuTestsHelper.GetEfigsTestedLocales(SundayNames.French)}, + new object[] { "ja-JP", IcuTestsHelper.GetCjkTestedLocales(SundayNames.Japanese) }, + new object[] { "sk-SK", IcuTestsHelper.GetNocjkTestedLocales(SundayNames.Slovak) }) .WithRunHosts(BuildTestBase.s_hostsForOSLocaleSensitiveTests) .UnwrapItemsAsArrays(); - public static IEnumerable FullIcuWithInvariantTestData(bool aot, RunHost host) - => ConfigWithAOTData(aot) - .Multiply( - // in invariant mode, all locales should be missing - new object[] { true, true, "Array.Empty()" }, - new object[] { true, false, "Array.Empty()" }, - new object[] { false, false, GetEfigsTestedLocales() }, - new object[] { false, true, s_fullIcuTestedLocales}) - .WithRunHosts(host) - .UnwrapItemsAsArrays(); - - public static IEnumerable FullIcuWithICustomIcuTestData(bool aot, RunHost host) - => ConfigWithAOTData(aot) - .Multiply( - new object[] { true }, - new object[] { false }) - .WithRunHosts(host) - .UnwrapItemsAsArrays(); - - private static string GetProgramText(string testedLocales, bool onlyPredefinedCultures=false, string fallbackSundayName=FallbackSundayNameEnUS) => $@" - #nullable enable - - using System; - using System.Globalization; - - Console.WriteLine($""Current culture: '{{CultureInfo.CurrentCulture.Name}}'""); - - string fallbackSundayName = ""{fallbackSundayName}""; - bool onlyPredefinedCultures = {(onlyPredefinedCultures ? "true" : "false")}; - Locale[] localesToTest = {testedLocales}; - - bool fail = false; - foreach (var testLocale in localesToTest) - {{ - bool expectMissing = string.IsNullOrEmpty(testLocale.SundayName); - bool ctorShouldFail = expectMissing && onlyPredefinedCultures; - CultureInfo culture; - - try - {{ - culture = new CultureInfo(testLocale.Code); - if (ctorShouldFail) - {{ - Console.WriteLine($""CultureInfo..ctor did not throw an exception for {{testLocale.Code}} as was expected.""); - fail = true; - continue; - }} - }} - catch(CultureNotFoundException cnfe) when (ctorShouldFail && cnfe.Message.Contains($""{{testLocale.Code}} is an invalid culture identifier."")) - {{ - Console.WriteLine($""{{testLocale.Code}}: Success. .ctor failed as expected.""); - continue; - }} - - string expectedSundayName = (expectMissing && !onlyPredefinedCultures) - ? fallbackSundayName - : testLocale.SundayName; - var actualLocalizedSundayName = culture.DateTimeFormat.GetDayName(new DateTime(2000,01,02).DayOfWeek); - if (expectedSundayName != actualLocalizedSundayName) - {{ - Console.WriteLine($""Error: incorrect localized value for Sunday in locale {{testLocale.Code}}. Expected '{{expectedSundayName}}' but got '{{actualLocalizedSundayName}}'.""); - fail = true; - continue; - }} - Console.WriteLine($""{{testLocale.Code}}: Success. Sunday name: {{actualLocalizedSundayName}}""); - }} - return fail ? -1 : 42; - - public record Locale(string Code, string? SundayName); - "; - private void TestIcuShards(BuildArgs buildArgs, string shardName, string testedLocales, RunHost host, string id, bool onlyPredefinedCultures=false) { string projectName = $"shard_{Path.GetFileName(shardName)}_{buildArgs.Config}_{buildArgs.AOT}"; @@ -162,7 +58,7 @@ private void TestIcuShards(BuildArgs buildArgs, string shardName, string testedL $"{shardName}"; buildArgs = ExpandBuildArgs(buildArgs, extraProperties: extraProperties); - string programText = GetProgramText(testedLocales, onlyPredefinedCultures); + string programText = IcuTestsHelper.GetProgramText(testedLocales, onlyPredefinedCultures); _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); (_, string output) = BuildProject(buildArgs, id: id, @@ -198,7 +94,7 @@ public void AutomaticShardSelectionDependingOnEnvLocale(BuildArgs buildArgs, str buildArgs = buildArgs with { ProjectName = projectName }; buildArgs = ExpandBuildArgs(buildArgs); - string programText = GetProgramText(testedLocales); + string programText = IcuTestsHelper.GetProgramText(testedLocales); _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); (_, string output) = BuildProject(buildArgs, id: id, @@ -207,70 +103,4 @@ public void AutomaticShardSelectionDependingOnEnvLocale(BuildArgs buildArgs, str DotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack)); string runOutput = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id, environmentLocale: environmentLocale); } - - [Theory] - [MemberData(nameof(FullIcuWithInvariantTestData), parameters: new object[] { false, RunHost.NodeJS | RunHost.Chrome })] - [MemberData(nameof(FullIcuWithInvariantTestData), parameters: new object[] { true, RunHost.NodeJS | RunHost.Chrome })] - public void FullIcuFromRuntimePackWithInvariant(BuildArgs buildArgs, bool invariant, bool fullIcu, string testedLocales, RunHost host, string id) - { - string projectName = $"fullIcuInvariant_{fullIcu}_{invariant}_{buildArgs.Config}_{buildArgs.AOT}"; - bool dotnetWasmFromRuntimePack = !(buildArgs.AOT || buildArgs.Config == "Release"); - - buildArgs = buildArgs with { ProjectName = projectName }; - buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"{invariant}{fullIcu}"); - - string programText = GetProgramText(testedLocales); - _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); - (_, string output) = BuildProject(buildArgs, - id: id, - new BuildProjectOptions( - InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText), - DotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, - GlobalizationMode: invariant ? GlobalizationMode.Invariant : fullIcu ? GlobalizationMode.FullIcu : GlobalizationMode.Sharded)); - - string runOutput = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id); - } - - [Theory] - [MemberData(nameof(FullIcuWithICustomIcuTestData), parameters: new object[] { false, RunHost.NodeJS | RunHost.Chrome })] - [MemberData(nameof(FullIcuWithICustomIcuTestData), parameters: new object[] { true, RunHost.NodeJS | RunHost.Chrome })] - public void FullIcuFromRuntimePackWithCustomIcu(BuildArgs buildArgs, bool fullIcu, RunHost host, string id) - { - string projectName = $"fullIcuCustom_{fullIcu}_{buildArgs.Config}_{buildArgs.AOT}"; - bool dotnetWasmFromRuntimePack = !(buildArgs.AOT || buildArgs.Config == "Release"); - - buildArgs = buildArgs with { ProjectName = projectName }; - buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"{s_customIcuPath}{fullIcu}"); - - string testedLocales = fullIcu ? s_fullIcuTestedLocales : s_customIcuTestedLocales; - string programText = GetProgramText(testedLocales); - _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); - (_, string output) = BuildProject(buildArgs, - id: id, - new BuildProjectOptions( - InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText), - DotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, - GlobalizationMode: fullIcu ? GlobalizationMode.FullIcu : GlobalizationMode.PredefinedIcu, - PredefinedIcudt: fullIcu ? "" : s_customIcuPath)); - if (fullIcu) - Assert.Contains("$(WasmIcuDataFileName) has no effect when $(WasmIncludeFullIcuData) is set to true.", output); - - string runOutput = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id); - } - - [Theory] - [BuildAndRun(host: RunHost.None)] - public void NonExistingCustomFileAssertError(BuildArgs buildArgs, string id) - { - string projectName = $"invalidCustomIcu_{buildArgs.Config}_{buildArgs.AOT}"; - buildArgs = buildArgs with { ProjectName = projectName }; - buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"nonexisting.dat"); - - (_, string output) = BuildProject(buildArgs, - id: id, - new BuildProjectOptions( - InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42), - ExpectSuccess: false)); - Assert.Contains("File in location $(WasmIcuDataFileName)=nonexisting.dat cannot be found neither when used as absolute path nor a relative runtime pack path.", output); - } } diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs new file mode 100644 index 00000000000000..92071dfcbae2aa --- /dev/null +++ b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs @@ -0,0 +1,104 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using Xunit; +using Xunit.Abstractions; +using Xunit.Sdk; +using System.Collections.Generic; + +#nullable enable + +namespace Wasm.Build.Tests; + +public class IcuTests : TestMainJsTestBase +{ + public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) { } + + public static IEnumerable FullIcuWithInvariantTestData(bool aot, RunHost host) + => ConfigWithAOTData(aot) + .Multiply( + // in invariant mode, all locales should be missing + new object[] { true, true, "Array.Empty()" }, + new object[] { true, false, "Array.Empty()" }, + new object[] { false, false, IcuTestsHelper.GetEfigsTestedLocales() }, + new object[] { false, true, IcuTestsHelper.FullIcuTestedLocales}) + .WithRunHosts(host) + .UnwrapItemsAsArrays(); + + public static IEnumerable FullIcuWithICustomIcuTestData(bool aot, RunHost host) + => ConfigWithAOTData(aot) + .Multiply( + new object[] { true }, + new object[] { false }) + .WithRunHosts(host) + .UnwrapItemsAsArrays(); + + [Theory] + [MemberData(nameof(FullIcuWithInvariantTestData), parameters: new object[] { false, RunHost.NodeJS | RunHost.Chrome })] + [MemberData(nameof(FullIcuWithInvariantTestData), parameters: new object[] { true, RunHost.NodeJS | RunHost.Chrome })] + public void FullIcuFromRuntimePackWithInvariant(BuildArgs buildArgs, bool invariant, bool fullIcu, string testedLocales, RunHost host, string id) + { + string projectName = $"fullIcuInvariant_{fullIcu}_{invariant}_{buildArgs.Config}_{buildArgs.AOT}"; + bool dotnetWasmFromRuntimePack = !(buildArgs.AOT || buildArgs.Config == "Release"); + + buildArgs = buildArgs with { ProjectName = projectName }; + buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"{invariant}{fullIcu}"); + + string programText = IcuTestsHelper.GetProgramText(testedLocales); + _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); + (_, string output) = BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText), + DotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, + GlobalizationMode: invariant ? GlobalizationMode.Invariant : fullIcu ? GlobalizationMode.FullIcu : GlobalizationMode.Sharded)); + + string runOutput = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id); + } + + [Theory] + [MemberData(nameof(FullIcuWithICustomIcuTestData), parameters: new object[] { false, RunHost.NodeJS | RunHost.Chrome })] + [MemberData(nameof(FullIcuWithICustomIcuTestData), parameters: new object[] { true, RunHost.NodeJS | RunHost.Chrome })] + public void FullIcuFromRuntimePackWithCustomIcu(BuildArgs buildArgs, bool fullIcu, RunHost host, string id) + { + string projectName = $"fullIcuCustom_{fullIcu}_{buildArgs.Config}_{buildArgs.AOT}"; + bool dotnetWasmFromRuntimePack = !(buildArgs.AOT || buildArgs.Config == "Release"); + + buildArgs = buildArgs with { ProjectName = projectName }; + buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"{IcuTestsHelper.CustomIcuPath}{fullIcu}"); + + string testedLocales = fullIcu ? IcuTestsHelper.FullIcuTestedLocales : IcuTestsHelper.CustomIcuTestedLocales; + string programText = IcuTestsHelper.GetProgramText(testedLocales); + _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); + (_, string output) = BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText), + DotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, + GlobalizationMode: fullIcu ? GlobalizationMode.FullIcu : GlobalizationMode.PredefinedIcu, + PredefinedIcudt: fullIcu ? "" : IcuTestsHelper.CustomIcuPath)); + if (fullIcu) + Assert.Contains("$(WasmIcuDataFileName) has no effect when $(WasmIncludeFullIcuData) is set to true.", output); + + string runOutput = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id); + } + + [Theory] + [BuildAndRun(host: RunHost.None)] + public void NonExistingCustomFileAssertError(BuildArgs buildArgs, string id) + { + string projectName = $"invalidCustomIcu_{buildArgs.Config}_{buildArgs.AOT}"; + buildArgs = buildArgs with { ProjectName = projectName }; + buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"nonexisting.dat"); + + (_, string output) = BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42), + ExpectSuccess: false)); + Assert.Contains("File in location $(WasmIcuDataFileName)=nonexisting.dat cannot be found neither when used as absolute path nor a relative runtime pack path.", output); + } +} From 0ec214ac453fb91a87ff91a0071bd7e7851f5d78 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 2 Aug 2023 11:33:11 +0000 Subject: [PATCH 04/17] Add new wbt files to CI jobs. --- eng/testing/scenarios/BuildWasmAppsJobsList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eng/testing/scenarios/BuildWasmAppsJobsList.txt b/eng/testing/scenarios/BuildWasmAppsJobsList.txt index cc16b81fa55b70..a4573ad805591d 100644 --- a/eng/testing/scenarios/BuildWasmAppsJobsList.txt +++ b/eng/testing/scenarios/BuildWasmAppsJobsList.txt @@ -11,10 +11,12 @@ Wasm.Build.Tests.Blazor.MiscTests Wasm.Build.Tests.Blazor.MiscTests2 Wasm.Build.Tests.Blazor.NativeTests Wasm.Build.Tests.Blazor.NoopNativeRebuildTest +Wasm.Build.Tests.Blazor.IcuTests Wasm.Build.Tests.BuildPublishTests Wasm.Build.Tests.ConfigSrcTests Wasm.Build.Tests.HybridGlobalizationTests Wasm.Build.Tests.IcuShardingTests +Wasm.Build.Tests.IcuTests Wasm.Build.Tests.InvariantGlobalizationTests Wasm.Build.Tests.InvariantTimezoneTests Wasm.Build.Tests.MainWithArgsTests From 2ad38f06c899a25a2cc649c105fab0fc7817aca5 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 2 Aug 2023 14:51:34 +0000 Subject: [PATCH 05/17] Split sharding wbt into classes ~equal no. of test cases. --- .../Blazor/BlazorWasmTestBase.cs | 2 + .../Wasm.Build.Tests/Common/IcuTestsBase.cs | 125 ++++++++++++++ .../Wasm.Build.Tests/Common/IcuTestsHelper.cs | 156 +++++++++--------- .../wasm/Wasm.Build.Tests/IcuShardingTests.cs | 57 +------ .../Wasm.Build.Tests/IcuShardingTests2.cs | 39 +++++ src/mono/wasm/Wasm.Build.Tests/IcuTests.cs | 12 +- 6 files changed, 254 insertions(+), 137 deletions(-) create mode 100644 src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsBase.cs create mode 100644 src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs index 82ce0dd906123e..ee005a6e2b4204 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs @@ -216,4 +216,6 @@ void OnErrorMessage(string msg) public string FindBlazorBinFrameworkDir(string config, bool forPublish, string framework = DefaultTargetFrameworkForBlazor) => _provider.FindBinFrameworkDir(config: config, forPublish: forPublish, framework: framework); + + public string GetRandomNameWithoutDots() => Path.GetRandomFileName().Replace(".", ""); } diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsBase.cs b/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsBase.cs new file mode 100644 index 00000000000000..74f0a32e86926b --- /dev/null +++ b/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsBase.cs @@ -0,0 +1,125 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace Wasm.Build.Tests; + +public abstract class IcuTestsBase : TestMainJsTestBase +{ + public IcuTestsBase(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) { } + + public record SundayNames + { + public static string English = "Sunday"; + public static string French = "dimanche"; + public static string Spanish = "domingo"; + public static string Chinese = "星期日"; + public static string Japanese = "日曜日"; + public static string Slovak = "nedeľa"; + } + + public readonly string CustomIcuPath = Path.Combine(BuildEnvironment.TestAssetsPath, "icudt_custom.dat"); + + private const string FallbackSundayNameEnUS = "Sunday"; + + public static readonly string CustomIcuTestedLocales = $@"new Locale[] {{ + new Locale(""cy-GB"", ""Dydd Sul""), new Locale(""is-IS"", ""sunnudagur""), new Locale(""bs-BA"", ""nedjelja""), new Locale(""lb-LU"", ""Sonndeg""), + new Locale(""fr-FR"", null), new Locale(""hr-HR"", null), new Locale(""ko-KR"", null) + }}"; + public static string GetEfigsTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + new Locale(""en-US"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""es-ES"", ""{SundayNames.Spanish}""), + new Locale(""pl-PL"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""cs-CZ"", ""{fallbackSundayName}"") + }}"; + public static string GetCjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}""), new Locale(""ja-JP"", ""{SundayNames.Japanese}""), + new Locale(""fr-FR"", ""{fallbackSundayName}""), new Locale(""hr-HR"", ""{fallbackSundayName}""), new Locale(""it-IT"", ""{fallbackSundayName}"") + }}"; + public static string GetNocjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + new Locale(""en-AU"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), + new Locale(""ja-JP"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""zh-CN"", ""{fallbackSundayName}"") + }}"; + public static readonly string FullIcuTestedLocales = $@"new Locale[] {{ + new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}"") + }}"; + + public string GetProgramText(string testedLocales, bool onlyPredefinedCultures=false, string fallbackSundayName=FallbackSundayNameEnUS) => $@" + #nullable enable + + using System; + using System.Globalization; + + Console.WriteLine($""Current culture: '{{CultureInfo.CurrentCulture.Name}}'""); + + string fallbackSundayName = ""{fallbackSundayName}""; + bool onlyPredefinedCultures = {(onlyPredefinedCultures ? "true" : "false")}; + Locale[] localesToTest = {testedLocales}; + + bool fail = false; + foreach (var testLocale in localesToTest) + {{ + bool expectMissing = string.IsNullOrEmpty(testLocale.SundayName); + bool ctorShouldFail = expectMissing && onlyPredefinedCultures; + CultureInfo culture; + + try + {{ + culture = new CultureInfo(testLocale.Code); + if (ctorShouldFail) + {{ + Console.WriteLine($""CultureInfo..ctor did not throw an exception for {{testLocale.Code}} as was expected.""); + fail = true; + continue; + }} + }} + catch(CultureNotFoundException cnfe) when (ctorShouldFail && cnfe.Message.Contains($""{{testLocale.Code}} is an invalid culture identifier."")) + {{ + Console.WriteLine($""{{testLocale.Code}}: Success. .ctor failed as expected.""); + continue; + }} + + string expectedSundayName = (expectMissing && !onlyPredefinedCultures) + ? fallbackSundayName + : testLocale.SundayName; + var actualLocalizedSundayName = culture.DateTimeFormat.GetDayName(new DateTime(2000,01,02).DayOfWeek); + if (expectedSundayName != actualLocalizedSundayName) + {{ + Console.WriteLine($""Error: incorrect localized value for Sunday in locale {{testLocale.Code}}. Expected '{{expectedSundayName}}' but got '{{actualLocalizedSundayName}}'.""); + fail = true; + continue; + }} + Console.WriteLine($""{{testLocale.Code}}: Success. Sunday name: {{actualLocalizedSundayName}}""); + }} + return fail ? -1 : 42; + + public record Locale(string Code, string? SundayName); + "; + + public void TestIcuShards(BuildArgs buildArgs, string shardName, string testedLocales, RunHost host, string id, bool onlyPredefinedCultures=false) + { + string projectName = $"shard_{Path.GetFileName(shardName)}_{buildArgs.Config}_{buildArgs.AOT}"; + bool dotnetWasmFromRuntimePack = !(buildArgs.AOT || buildArgs.Config == "Release"); + + buildArgs = buildArgs with { ProjectName = projectName }; + string extraProperties = onlyPredefinedCultures ? + $"{shardName}true" : + $"{shardName}"; + buildArgs = ExpandBuildArgs(buildArgs, extraProperties: extraProperties); + + string programText = GetProgramText(testedLocales, onlyPredefinedCultures); + _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); + (_, string output) = BuildProject(buildArgs, + id: id, + new BuildProjectOptions( + InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText), + DotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, + GlobalizationMode: GlobalizationMode.PredefinedIcu, + PredefinedIcudt: shardName)); + + string runOutput = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id); + } +} \ No newline at end of file diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs b/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs index 6c3e5e574a122c..672a156578cc1f 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs @@ -12,91 +12,85 @@ namespace Wasm.Build.Tests; -public record SundayNames { - public static string English = "Sunday"; - public static string French = "dimanche"; - public static string Spanish = "domingo"; - public static string Chinese = "星期日"; - public static string Japanese = "日曜日"; - public static string Slovak = "nedeľa"; -} + public static class IcuTestsHelper { // custom file contains only locales "cy-GB", "is-IS", "bs-BA", "lb-LU" and fallback locale: "en-US": public static string CustomIcuPath = Path.Combine(BuildEnvironment.TestAssetsPath, "icudt_custom.dat"); - private const string FallbackSundayNameEnUS = "Sunday"; - - public static readonly string CustomIcuTestedLocales = $@"new Locale[] {{ - new Locale(""cy-GB"", ""Dydd Sul""), new Locale(""is-IS"", ""sunnudagur""), new Locale(""bs-BA"", ""nedjelja""), new Locale(""lb-LU"", ""Sonndeg""), - new Locale(""fr-FR"", null), new Locale(""hr-HR"", null), new Locale(""ko-KR"", null) - }}"; - public static string GetEfigsTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ - new Locale(""en-US"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""es-ES"", ""{SundayNames.Spanish}""), - new Locale(""pl-PL"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""cs-CZ"", ""{fallbackSundayName}"") - }}"; - public static string GetCjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ - new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}""), new Locale(""ja-JP"", ""{SundayNames.Japanese}""), - new Locale(""fr-FR"", ""{fallbackSundayName}""), new Locale(""hr-HR"", ""{fallbackSundayName}""), new Locale(""it-IT"", ""{fallbackSundayName}"") - }}"; - public static string GetNocjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ - new Locale(""en-AU"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), - new Locale(""ja-JP"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""zh-CN"", ""{fallbackSundayName}"") - }}"; - public static readonly string FullIcuTestedLocales = $@"new Locale[] {{ - new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}"") - }}"; - - public static string GetProgramText(string testedLocales, bool onlyPredefinedCultures=false, string fallbackSundayName=FallbackSundayNameEnUS) => $@" - #nullable enable - - using System; - using System.Globalization; - - Console.WriteLine($""Current culture: '{{CultureInfo.CurrentCulture.Name}}'""); - - string fallbackSundayName = ""{fallbackSundayName}""; - bool onlyPredefinedCultures = {(onlyPredefinedCultures ? "true" : "false")}; - Locale[] localesToTest = {testedLocales}; - - bool fail = false; - foreach (var testLocale in localesToTest) - {{ - bool expectMissing = string.IsNullOrEmpty(testLocale.SundayName); - bool ctorShouldFail = expectMissing && onlyPredefinedCultures; - CultureInfo culture; - - try - {{ - culture = new CultureInfo(testLocale.Code); - if (ctorShouldFail) - {{ - Console.WriteLine($""CultureInfo..ctor did not throw an exception for {{testLocale.Code}} as was expected.""); - fail = true; - continue; - }} - }} - catch(CultureNotFoundException cnfe) when (ctorShouldFail && cnfe.Message.Contains($""{{testLocale.Code}} is an invalid culture identifier."")) - {{ - Console.WriteLine($""{{testLocale.Code}}: Success. .ctor failed as expected.""); - continue; - }} - - string expectedSundayName = (expectMissing && !onlyPredefinedCultures) - ? fallbackSundayName - : testLocale.SundayName; - var actualLocalizedSundayName = culture.DateTimeFormat.GetDayName(new DateTime(2000,01,02).DayOfWeek); - if (expectedSundayName != actualLocalizedSundayName) - {{ - Console.WriteLine($""Error: incorrect localized value for Sunday in locale {{testLocale.Code}}. Expected '{{expectedSundayName}}' but got '{{actualLocalizedSundayName}}'.""); - fail = true; - continue; - }} - Console.WriteLine($""{{testLocale.Code}}: Success. Sunday name: {{actualLocalizedSundayName}}""); - }} - return fail ? -1 : 42; - - public record Locale(string Code, string? SundayName); - "; + // private const string FallbackSundayNameEnUS = "Sunday"; + + // public static readonly string CustomIcuTestedLocales = $@"new Locale[] {{ + // new Locale(""cy-GB"", ""Dydd Sul""), new Locale(""is-IS"", ""sunnudagur""), new Locale(""bs-BA"", ""nedjelja""), new Locale(""lb-LU"", ""Sonndeg""), + // new Locale(""fr-FR"", null), new Locale(""hr-HR"", null), new Locale(""ko-KR"", null) + // }}"; + // public static string GetEfigsTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + // new Locale(""en-US"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""es-ES"", ""{SundayNames.Spanish}""), + // new Locale(""pl-PL"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""cs-CZ"", ""{fallbackSundayName}"") + // }}"; + // public static string GetCjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + // new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}""), new Locale(""ja-JP"", ""{SundayNames.Japanese}""), + // new Locale(""fr-FR"", ""{fallbackSundayName}""), new Locale(""hr-HR"", ""{fallbackSundayName}""), new Locale(""it-IT"", ""{fallbackSundayName}"") + // }}"; + // public static string GetNocjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + // new Locale(""en-AU"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), + // new Locale(""ja-JP"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""zh-CN"", ""{fallbackSundayName}"") + // }}"; + // public static readonly string FullIcuTestedLocales = $@"new Locale[] {{ + // new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}"") + // }}"; + + // public static string GetProgramText(string testedLocales, bool onlyPredefinedCultures=false, string fallbackSundayName=FallbackSundayNameEnUS) => $@" + // #nullable enable + + // using System; + // using System.Globalization; + + // Console.WriteLine($""Current culture: '{{CultureInfo.CurrentCulture.Name}}'""); + + // string fallbackSundayName = ""{fallbackSundayName}""; + // bool onlyPredefinedCultures = {(onlyPredefinedCultures ? "true" : "false")}; + // Locale[] localesToTest = {testedLocales}; + + // bool fail = false; + // foreach (var testLocale in localesToTest) + // {{ + // bool expectMissing = string.IsNullOrEmpty(testLocale.SundayName); + // bool ctorShouldFail = expectMissing && onlyPredefinedCultures; + // CultureInfo culture; + + // try + // {{ + // culture = new CultureInfo(testLocale.Code); + // if (ctorShouldFail) + // {{ + // Console.WriteLine($""CultureInfo..ctor did not throw an exception for {{testLocale.Code}} as was expected.""); + // fail = true; + // continue; + // }} + // }} + // catch(CultureNotFoundException cnfe) when (ctorShouldFail && cnfe.Message.Contains($""{{testLocale.Code}} is an invalid culture identifier."")) + // {{ + // Console.WriteLine($""{{testLocale.Code}}: Success. .ctor failed as expected.""); + // continue; + // }} + + // string expectedSundayName = (expectMissing && !onlyPredefinedCultures) + // ? fallbackSundayName + // : testLocale.SundayName; + // var actualLocalizedSundayName = culture.DateTimeFormat.GetDayName(new DateTime(2000,01,02).DayOfWeek); + // if (expectedSundayName != actualLocalizedSundayName) + // {{ + // Console.WriteLine($""Error: incorrect localized value for Sunday in locale {{testLocale.Code}}. Expected '{{expectedSundayName}}' but got '{{actualLocalizedSundayName}}'.""); + // fail = true; + // continue; + // }} + // Console.WriteLine($""{{testLocale.Code}}: Success. Sunday name: {{actualLocalizedSundayName}}""); + // }} + // return fail ? -1 : 42; + + // public record Locale(string Code, string? SundayName); + // "; + // } } diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs index 65d5482ba36a8d..fc60fe3281ab31 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs @@ -12,7 +12,7 @@ namespace Wasm.Build.Tests; -public class IcuShardingTests : TestMainJsTestBase +public class IcuShardingTests : IcuTestsBase { public IcuShardingTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : base(output, buildContext) { } @@ -20,69 +20,26 @@ public IcuShardingTests(ITestOutputHelper output, SharedBuildPerTestClassFixture public static IEnumerable IcuExpectedAndMissingCustomShardTestData(bool aot, RunHost host) => ConfigWithAOTData(aot) .Multiply( - new object[] { IcuTestsHelper.CustomIcuPath, IcuTestsHelper.CustomIcuTestedLocales, false }, - new object[] { IcuTestsHelper.CustomIcuPath, IcuTestsHelper.CustomIcuTestedLocales, true }) - .WithRunHosts(host) - .UnwrapItemsAsArrays(); - - public static IEnumerable IcuExpectedAndMissingShardFromRuntimePackTestData(bool aot, RunHost host) - => ConfigWithAOTData(aot) - .Multiply( - new object[] { "icudt.dat", - $@"new Locale[] {{ - new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), - new Locale(""xx-yy"", null) }}" }, - new object[] { "icudt_EFIGS.dat", IcuTestsHelper.GetEfigsTestedLocales() }, - new object[] { "icudt_CJK.dat", IcuTestsHelper.GetCjkTestedLocales() }, - new object[] { "icudt_no_CJK.dat", IcuTestsHelper.GetNocjkTestedLocales() }) + new object[] { IcuTestsHelper.CustomIcuPath, CustomIcuTestedLocales, false }, + new object[] { IcuTestsHelper.CustomIcuPath, CustomIcuTestedLocales, true }) .WithRunHosts(host) .UnwrapItemsAsArrays(); public static IEnumerable IcuExpectedAndMissingAutomaticShardTestData(bool aot) => ConfigWithAOTData(aot) .Multiply( - new object[] { "fr-FR", IcuTestsHelper.GetEfigsTestedLocales(SundayNames.French)}, - new object[] { "ja-JP", IcuTestsHelper.GetCjkTestedLocales(SundayNames.Japanese) }, - new object[] { "sk-SK", IcuTestsHelper.GetNocjkTestedLocales(SundayNames.Slovak) }) + new object[] { "fr-FR", GetEfigsTestedLocales(SundayNames.French)}, + new object[] { "ja-JP", GetCjkTestedLocales(SundayNames.Japanese) }, + new object[] { "sk-SK", GetNocjkTestedLocales(SundayNames.Slovak) }) .WithRunHosts(BuildTestBase.s_hostsForOSLocaleSensitiveTests) .UnwrapItemsAsArrays(); - private void TestIcuShards(BuildArgs buildArgs, string shardName, string testedLocales, RunHost host, string id, bool onlyPredefinedCultures=false) - { - string projectName = $"shard_{Path.GetFileName(shardName)}_{buildArgs.Config}_{buildArgs.AOT}"; - bool dotnetWasmFromRuntimePack = !(buildArgs.AOT || buildArgs.Config == "Release"); - - buildArgs = buildArgs with { ProjectName = projectName }; - string extraProperties = onlyPredefinedCultures ? - $"{shardName}true" : - $"{shardName}"; - buildArgs = ExpandBuildArgs(buildArgs, extraProperties: extraProperties); - - string programText = IcuTestsHelper.GetProgramText(testedLocales, onlyPredefinedCultures); - _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); - (_, string output) = BuildProject(buildArgs, - id: id, - new BuildProjectOptions( - InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText), - DotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, - GlobalizationMode: GlobalizationMode.PredefinedIcu, - PredefinedIcudt: shardName)); - - string runOutput = RunAndTestWasmApp(buildArgs, buildDir: _projectDir, expectedExitCode: 42, host: host, id: id); - } - [Theory] [MemberData(nameof(IcuExpectedAndMissingCustomShardTestData), parameters: new object[] { false, RunHost.NodeJS | RunHost.Chrome })] [MemberData(nameof(IcuExpectedAndMissingCustomShardTestData), parameters: new object[] { true, RunHost.NodeJS | RunHost.Chrome })] public void CustomIcuShard(BuildArgs buildArgs, string shardName, string testedLocales, bool onlyPredefinedCultures, RunHost host, string id) => TestIcuShards(buildArgs, shardName, testedLocales, host, id, onlyPredefinedCultures); - [Theory] - [MemberData(nameof(IcuExpectedAndMissingShardFromRuntimePackTestData), parameters: new object[] { false,RunHost.NodeJS | RunHost.Chrome })] - [MemberData(nameof(IcuExpectedAndMissingShardFromRuntimePackTestData), parameters: new object[] { true, RunHost.NodeJS | RunHost.Chrome })] - public void DefaultAvailableIcuShardsFromRuntimePack(BuildArgs buildArgs, string shardName, string testedLocales, RunHost host, string id) => - TestIcuShards(buildArgs, shardName, testedLocales, host, id); - [Theory] [MemberData(nameof(IcuExpectedAndMissingAutomaticShardTestData), parameters: new object[] { false })] [MemberData(nameof(IcuExpectedAndMissingAutomaticShardTestData), parameters: new object[] { true })] @@ -94,7 +51,7 @@ public void AutomaticShardSelectionDependingOnEnvLocale(BuildArgs buildArgs, str buildArgs = buildArgs with { ProjectName = projectName }; buildArgs = ExpandBuildArgs(buildArgs); - string programText = IcuTestsHelper.GetProgramText(testedLocales); + string programText = GetProgramText(testedLocales); _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); (_, string output) = BuildProject(buildArgs, id: id, diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs new file mode 100644 index 00000000000000..b120e872d1dab2 --- /dev/null +++ b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.IO; +using Xunit; +using Xunit.Abstractions; +using Xunit.Sdk; +using System.Collections.Generic; + +#nullable enable + +namespace Wasm.Build.Tests; + +public class IcuShardingTests3 : IcuTestsBase +{ + public IcuShardingTests3(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) { } + + public static IEnumerable IcuExpectedAndMissingShardFromRuntimePackTestData(bool aot, RunHost host) + => ConfigWithAOTData(aot) + .Multiply( + new object[] { "icudt.dat", + $@"new Locale[] {{ + new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), + new Locale(""xx-yy"", null) }}" }, + new object[] { "icudt_EFIGS.dat", GetEfigsTestedLocales() }, + new object[] { "icudt_CJK.dat", GetCjkTestedLocales() }, + new object[] { "icudt_no_CJK.dat", GetNocjkTestedLocales() }) + .WithRunHosts(host) + .UnwrapItemsAsArrays(); + + + [Theory] + [MemberData(nameof(IcuExpectedAndMissingShardFromRuntimePackTestData), parameters: new object[] { false, RunHost.NodeJS | RunHost.Chrome })] + [MemberData(nameof(IcuExpectedAndMissingShardFromRuntimePackTestData), parameters: new object[] { true, RunHost.NodeJS | RunHost.Chrome })] + public void DefaultAvailableIcuShardsFromRuntimePack(BuildArgs buildArgs, string shardName, string testedLocales, RunHost host, string id) => + TestIcuShards(buildArgs, shardName, testedLocales, host, id); +} diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs index 92071dfcbae2aa..1a6c0677df255e 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs @@ -12,7 +12,7 @@ namespace Wasm.Build.Tests; -public class IcuTests : TestMainJsTestBase +public class IcuTests : IcuTestsBase { public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : base(output, buildContext) { } @@ -23,8 +23,8 @@ public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildCo // in invariant mode, all locales should be missing new object[] { true, true, "Array.Empty()" }, new object[] { true, false, "Array.Empty()" }, - new object[] { false, false, IcuTestsHelper.GetEfigsTestedLocales() }, - new object[] { false, true, IcuTestsHelper.FullIcuTestedLocales}) + new object[] { false, false, GetEfigsTestedLocales() }, + new object[] { false, true, FullIcuTestedLocales}) .WithRunHosts(host) .UnwrapItemsAsArrays(); @@ -47,7 +47,7 @@ public void FullIcuFromRuntimePackWithInvariant(BuildArgs buildArgs, bool invari buildArgs = buildArgs with { ProjectName = projectName }; buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"{invariant}{fullIcu}"); - string programText = IcuTestsHelper.GetProgramText(testedLocales); + string programText = GetProgramText(testedLocales); _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); (_, string output) = BuildProject(buildArgs, id: id, @@ -70,8 +70,8 @@ public void FullIcuFromRuntimePackWithCustomIcu(BuildArgs buildArgs, bool fullIc buildArgs = buildArgs with { ProjectName = projectName }; buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"{IcuTestsHelper.CustomIcuPath}{fullIcu}"); - string testedLocales = fullIcu ? IcuTestsHelper.FullIcuTestedLocales : IcuTestsHelper.CustomIcuTestedLocales; - string programText = IcuTestsHelper.GetProgramText(testedLocales); + string testedLocales = fullIcu ? FullIcuTestedLocales : CustomIcuTestedLocales; + string programText = GetProgramText(testedLocales); _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); (_, string output) = BuildProject(buildArgs, id: id, From 15add5e328761ddfe38749b8c1aba0b23369d681 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 2 Aug 2023 14:52:21 +0000 Subject: [PATCH 06/17] And update job list. --- eng/testing/scenarios/BuildWasmAppsJobsList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/testing/scenarios/BuildWasmAppsJobsList.txt b/eng/testing/scenarios/BuildWasmAppsJobsList.txt index a4573ad805591d..24e6b711205e02 100644 --- a/eng/testing/scenarios/BuildWasmAppsJobsList.txt +++ b/eng/testing/scenarios/BuildWasmAppsJobsList.txt @@ -16,6 +16,7 @@ Wasm.Build.Tests.BuildPublishTests Wasm.Build.Tests.ConfigSrcTests Wasm.Build.Tests.HybridGlobalizationTests Wasm.Build.Tests.IcuShardingTests +Wasm.Build.Tests.IcuShardingTests2 Wasm.Build.Tests.IcuTests Wasm.Build.Tests.InvariantGlobalizationTests Wasm.Build.Tests.InvariantTimezoneTests From 40bfb79b8237f4738fb34acf17e38022e91965da Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:02:00 +0000 Subject: [PATCH 07/17] Fix `File sizes don't match for dotnet.native.wasm`. --- src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs index 8a98abc3cb8721..f5e14790a6dc3c 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs @@ -39,7 +39,8 @@ public void HybridWithInvariant(string config, bool invariant) id, config, WarnAsError: false, - GlobalizationMode: invariant ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid + GlobalizationMode: invariant ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid, + ExpectedFileType: NativeFilesType.Relinked )); if (invariant) Assert.Contains("$(HybridGlobalization) has no effect when $(InvariantGlobalization) is set to true.", res.Output); @@ -62,7 +63,8 @@ public void HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) id, config, WarnAsError: false, - GlobalizationMode: GlobalizationMode.Hybrid + GlobalizationMode: GlobalizationMode.Hybrid, + ExpectedFileType: NativeFilesType.Relinked )); if (fullIcu) Assert.Contains("$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(HybridGlobalization) is set to true.", res.Output); @@ -86,7 +88,8 @@ public void FullIcuFromRuntimePackWithInvariant(string config, bool invariant) id, config, WarnAsError: false, - GlobalizationMode: invariant ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu + GlobalizationMode: invariant ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu, + ExpectedFileType: NativeFilesType.Relinked )); if (invariant) From 1c552f7525301dfedc64ebcdf2fc7e9b9b1e80cc Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:37:45 +0000 Subject: [PATCH 08/17] Move file to fix class not found. --- src/mono/wasm/Wasm.Build.Tests/{Common => }/IcuTestsBase.cs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/mono/wasm/Wasm.Build.Tests/{Common => }/IcuTestsBase.cs (100%) diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsBase.cs b/src/mono/wasm/Wasm.Build.Tests/IcuTestsBase.cs similarity index 100% rename from src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsBase.cs rename to src/mono/wasm/Wasm.Build.Tests/IcuTestsBase.cs From 07dbf00c129f378a6fb1a39780624fcb88650b7b Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Thu, 3 Aug 2023 11:28:05 +0000 Subject: [PATCH 09/17] Cleanup. --- .../Wasm.Build.Tests/Common/IcuTestsHelper.cs | 79 +------------------ .../Wasm.Build.Tests/IcuShardingTests2.cs | 4 +- src/mono/wasm/Wasm.Build.Tests/IcuTests.cs | 17 +++- .../Wasm.Build.Tests/ProjectProviderBase.cs | 3 - 4 files changed, 16 insertions(+), 87 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs b/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs index 672a156578cc1f..5d87b8c7dbe5fd 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs @@ -12,85 +12,8 @@ namespace Wasm.Build.Tests; - - public static class IcuTestsHelper { // custom file contains only locales "cy-GB", "is-IS", "bs-BA", "lb-LU" and fallback locale: "en-US": public static string CustomIcuPath = Path.Combine(BuildEnvironment.TestAssetsPath, "icudt_custom.dat"); - - // private const string FallbackSundayNameEnUS = "Sunday"; - - // public static readonly string CustomIcuTestedLocales = $@"new Locale[] {{ - // new Locale(""cy-GB"", ""Dydd Sul""), new Locale(""is-IS"", ""sunnudagur""), new Locale(""bs-BA"", ""nedjelja""), new Locale(""lb-LU"", ""Sonndeg""), - // new Locale(""fr-FR"", null), new Locale(""hr-HR"", null), new Locale(""ko-KR"", null) - // }}"; - // public static string GetEfigsTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ - // new Locale(""en-US"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""es-ES"", ""{SundayNames.Spanish}""), - // new Locale(""pl-PL"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""cs-CZ"", ""{fallbackSundayName}"") - // }}"; - // public static string GetCjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ - // new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}""), new Locale(""ja-JP"", ""{SundayNames.Japanese}""), - // new Locale(""fr-FR"", ""{fallbackSundayName}""), new Locale(""hr-HR"", ""{fallbackSundayName}""), new Locale(""it-IT"", ""{fallbackSundayName}"") - // }}"; - // public static string GetNocjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ - // new Locale(""en-AU"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), - // new Locale(""ja-JP"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""zh-CN"", ""{fallbackSundayName}"") - // }}"; - // public static readonly string FullIcuTestedLocales = $@"new Locale[] {{ - // new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}"") - // }}"; - - // public static string GetProgramText(string testedLocales, bool onlyPredefinedCultures=false, string fallbackSundayName=FallbackSundayNameEnUS) => $@" - // #nullable enable - - // using System; - // using System.Globalization; - - // Console.WriteLine($""Current culture: '{{CultureInfo.CurrentCulture.Name}}'""); - - // string fallbackSundayName = ""{fallbackSundayName}""; - // bool onlyPredefinedCultures = {(onlyPredefinedCultures ? "true" : "false")}; - // Locale[] localesToTest = {testedLocales}; - - // bool fail = false; - // foreach (var testLocale in localesToTest) - // {{ - // bool expectMissing = string.IsNullOrEmpty(testLocale.SundayName); - // bool ctorShouldFail = expectMissing && onlyPredefinedCultures; - // CultureInfo culture; - - // try - // {{ - // culture = new CultureInfo(testLocale.Code); - // if (ctorShouldFail) - // {{ - // Console.WriteLine($""CultureInfo..ctor did not throw an exception for {{testLocale.Code}} as was expected.""); - // fail = true; - // continue; - // }} - // }} - // catch(CultureNotFoundException cnfe) when (ctorShouldFail && cnfe.Message.Contains($""{{testLocale.Code}} is an invalid culture identifier."")) - // {{ - // Console.WriteLine($""{{testLocale.Code}}: Success. .ctor failed as expected.""); - // continue; - // }} - - // string expectedSundayName = (expectMissing && !onlyPredefinedCultures) - // ? fallbackSundayName - // : testLocale.SundayName; - // var actualLocalizedSundayName = culture.DateTimeFormat.GetDayName(new DateTime(2000,01,02).DayOfWeek); - // if (expectedSundayName != actualLocalizedSundayName) - // {{ - // Console.WriteLine($""Error: incorrect localized value for Sunday in locale {{testLocale.Code}}. Expected '{{expectedSundayName}}' but got '{{actualLocalizedSundayName}}'.""); - // fail = true; - // continue; - // }} - // Console.WriteLine($""{{testLocale.Code}}: Success. Sunday name: {{actualLocalizedSundayName}}""); - // }} - // return fail ? -1 : 42; - - // public record Locale(string Code, string? SundayName); - // "; - // } -} +} \ No newline at end of file diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs index b120e872d1dab2..9b116cbb871dd7 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs @@ -12,9 +12,9 @@ namespace Wasm.Build.Tests; -public class IcuShardingTests3 : IcuTestsBase +public class IcuShardingTests2 : IcuTestsBase { - public IcuShardingTests3(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + public IcuShardingTests2(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : base(output, buildContext) { } public static IEnumerable IcuExpectedAndMissingShardFromRuntimePackTestData(bool aot, RunHost host) diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs index 1a6c0677df255e..cfd40231cc9b77 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs @@ -87,18 +87,27 @@ public void FullIcuFromRuntimePackWithCustomIcu(BuildArgs buildArgs, bool fullIc } [Theory] - [BuildAndRun(host: RunHost.None)] - public void NonExistingCustomFileAssertError(BuildArgs buildArgs, string id) + [BuildAndRun(host: RunHost.None, parameters: new object[] { "icudtNonExisting.dat", true })] + [BuildAndRun(host: RunHost.None, parameters: new object[] { "incorrectName.dat", false })] + public void NonExistingCustomFileAssertError(BuildArgs buildArgs, string customFileName, bool isFilenameCorrect, string id) { string projectName = $"invalidCustomIcu_{buildArgs.Config}_{buildArgs.AOT}"; buildArgs = buildArgs with { ProjectName = projectName }; - buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"nonexisting.dat"); + string customIcu = Path.Combine(BuildEnvironment.TestAssetsPath, customFileName); + buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"{customIcu}"); (_, string output) = BuildProject(buildArgs, id: id, new BuildProjectOptions( InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), s_mainReturns42), ExpectSuccess: false)); - Assert.Contains("File in location $(WasmIcuDataFileName)=nonexisting.dat cannot be found neither when used as absolute path nor a relative runtime pack path.", output); + if (isFilenameCorrect) + { + Assert.Contains($"File in location $(WasmIcuDataFileName)={customIcu} cannot be found neither when used as absolute path nor a relative runtime pack path.", output); + } + else + { + Assert.Contains($"Custom ICU file name in path $(WasmIcuDataFileName)={customIcu} has to start with 'icudt'.", output); + } } } diff --git a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs index 5d8436a6b647d7..82fac06b647314 100644 --- a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs @@ -348,7 +348,6 @@ public static void AssertDotNetJsSymbols(AssertBundleOptionsBase assertOptions) public void AssertIcuAssets(AssertBundleOptionsBase assertOptions) { List expected = new(); - _testOutput.WriteLine($"AssertIcuAssets: {assertOptions.GlobalizationMode}"); switch (assertOptions.GlobalizationMode) { case GlobalizationMode.Invariant: @@ -375,8 +374,6 @@ public void AssertIcuAssets(AssertBundleOptionsBase assertOptions) default: throw new NotImplementedException($"Unknown {nameof(assertOptions.GlobalizationMode)} = {assertOptions.GlobalizationMode}"); } - foreach (var e in expected) - _testOutput.WriteLine($"e: {e}"); IEnumerable actual = Directory.EnumerateFiles(assertOptions.BinFrameworkDir, "icudt*dat"); AssertFilesOnDisk(expected, actual); From df5a6e811abebcd6232b8e41c4a210f58bc4c765 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Thu, 3 Aug 2023 13:20:55 +0000 Subject: [PATCH 10/17] Propagate warning update. --- src/mono/wasm/Wasm.Build.Tests/IcuTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs index cfd40231cc9b77..8c410362596255 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs @@ -107,7 +107,7 @@ public void NonExistingCustomFileAssertError(BuildArgs buildArgs, string customF } else { - Assert.Contains($"Custom ICU file name in path $(WasmIcuDataFileName)={customIcu} has to start with 'icudt'.", output); + Assert.Contains($"Custom ICU file name in path $(WasmIcuDataFileName)={customIcu} must start with 'icudt'.", output); } } } From f57367bec0cbab2fcdbf53593be31c06083b6c26 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Fri, 4 Aug 2023 10:37:02 +0000 Subject: [PATCH 11/17] @radical's suggestions. --- .../wasm/Wasm.Build.Tests/Blazor/IcuTests.cs | 8 +++---- .../Wasm.Build.Tests/Common/IcuTestsHelper.cs | 19 ---------------- .../wasm/Wasm.Build.Tests/IcuShardingTests.cs | 4 ++-- src/mono/wasm/Wasm.Build.Tests/IcuTests.cs | 8 +++---- .../wasm/Wasm.Build.Tests/IcuTestsBase.cs | 22 ++++++++++--------- .../Wasm.Build.Tests/ProjectProviderBase.cs | 5 ++++- .../AssetsComputingHelper.cs | 18 ++++++++++----- 7 files changed, 38 insertions(+), 46 deletions(-) delete mode 100644 src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs index f5e14790a6dc3c..f1b6ebad237bfe 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs @@ -18,8 +18,6 @@ public class IcuTests : BlazorWasmTestBase public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : base(output, buildContext) {} - string getRandomNameWithoutDots => Path.GetRandomFileName().Replace(".", ""); - [Theory] [InlineData("Debug", false)] [InlineData("Debug", true)] @@ -27,7 +25,7 @@ public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildCo [InlineData("Release", true)] public void HybridWithInvariant(string config, bool invariant) { - string id = $"blz_hybrid_{config}_{getRandomNameWithoutDots}"; + string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; string projectFile = CreateProjectWithNativeReference(id); AddItemsPropertiesToProject( projectFile, @@ -53,7 +51,7 @@ public void HybridWithInvariant(string config, bool invariant) [InlineData("Release", true)] public void HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) { - string id = $"blz_hybrid_{config}_{getRandomNameWithoutDots}"; + string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; string projectFile = CreateProjectWithNativeReference(id); AddItemsPropertiesToProject(projectFile, extraProperties: $"true{fullIcu}"); @@ -78,7 +76,7 @@ public void HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) [InlineData("Release", true)] public void FullIcuFromRuntimePackWithInvariant(string config, bool invariant) { - string id = $"blz_hybrid_{config}_{getRandomNameWithoutDots}"; + string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; string projectFile = CreateProjectWithNativeReference(id); AddItemsPropertiesToProject(projectFile, extraProperties: $"true{invariant}"); diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs b/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs deleted file mode 100644 index 5d87b8c7dbe5fd..00000000000000 --- a/src/mono/wasm/Wasm.Build.Tests/Common/IcuTestsHelper.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.IO; -using Xunit; -using Xunit.Abstractions; -using Xunit.Sdk; -using System.Collections.Generic; - -#nullable enable - -namespace Wasm.Build.Tests; - -public static class IcuTestsHelper -{ - // custom file contains only locales "cy-GB", "is-IS", "bs-BA", "lb-LU" and fallback locale: "en-US": - public static string CustomIcuPath = Path.Combine(BuildEnvironment.TestAssetsPath, "icudt_custom.dat"); -} \ No newline at end of file diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs index fc60fe3281ab31..62b0dbdf3ea3f6 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs @@ -20,8 +20,8 @@ public IcuShardingTests(ITestOutputHelper output, SharedBuildPerTestClassFixture public static IEnumerable IcuExpectedAndMissingCustomShardTestData(bool aot, RunHost host) => ConfigWithAOTData(aot) .Multiply( - new object[] { IcuTestsHelper.CustomIcuPath, CustomIcuTestedLocales, false }, - new object[] { IcuTestsHelper.CustomIcuPath, CustomIcuTestedLocales, true }) + new object[] { CustomIcuPath, CustomIcuTestedLocales, false }, + new object[] { CustomIcuPath, CustomIcuTestedLocales, true }) .WithRunHosts(host) .UnwrapItemsAsArrays(); diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs index 8c410362596255..8482e923078cd6 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs @@ -24,7 +24,7 @@ public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildCo new object[] { true, true, "Array.Empty()" }, new object[] { true, false, "Array.Empty()" }, new object[] { false, false, GetEfigsTestedLocales() }, - new object[] { false, true, FullIcuTestedLocales}) + new object[] { false, true, s_fullIcuTestedLocales}) .WithRunHosts(host) .UnwrapItemsAsArrays(); @@ -68,9 +68,9 @@ public void FullIcuFromRuntimePackWithCustomIcu(BuildArgs buildArgs, bool fullIc bool dotnetWasmFromRuntimePack = !(buildArgs.AOT || buildArgs.Config == "Release"); buildArgs = buildArgs with { ProjectName = projectName }; - buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"{IcuTestsHelper.CustomIcuPath}{fullIcu}"); + buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"{CustomIcuPath}{fullIcu}"); - string testedLocales = fullIcu ? FullIcuTestedLocales : CustomIcuTestedLocales; + string testedLocales = fullIcu ? s_fullIcuTestedLocales : CustomIcuTestedLocales; string programText = GetProgramText(testedLocales); _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); (_, string output) = BuildProject(buildArgs, @@ -79,7 +79,7 @@ public void FullIcuFromRuntimePackWithCustomIcu(BuildArgs buildArgs, bool fullIc InitProject: () => File.WriteAllText(Path.Combine(_projectDir!, "Program.cs"), programText), DotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack, GlobalizationMode: fullIcu ? GlobalizationMode.FullIcu : GlobalizationMode.PredefinedIcu, - PredefinedIcudt: fullIcu ? "" : IcuTestsHelper.CustomIcuPath)); + PredefinedIcudt: fullIcu ? "" : CustomIcuPath)); if (fullIcu) Assert.Contains("$(WasmIcuDataFileName) has no effect when $(WasmIncludeFullIcuData) is set to true.", output); diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuTestsBase.cs b/src/mono/wasm/Wasm.Build.Tests/IcuTestsBase.cs index 74f0a32e86926b..e89f5558d1c3ad 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuTestsBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuTestsBase.cs @@ -13,7 +13,7 @@ public abstract class IcuTestsBase : TestMainJsTestBase public IcuTestsBase(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) : base(output, buildContext) { } - public record SundayNames + protected record SundayNames { public static string English = "Sunday"; public static string French = "dimanche"; @@ -23,31 +23,33 @@ public record SundayNames public static string Slovak = "nedeľa"; } - public readonly string CustomIcuPath = Path.Combine(BuildEnvironment.TestAssetsPath, "icudt_custom.dat"); + protected string GetRandomNameWithoutDots => Path.GetRandomFileName().Replace(".", ""); - private const string FallbackSundayNameEnUS = "Sunday"; + public static readonly string CustomIcuPath = Path.Combine(BuildEnvironment.TestAssetsPath, "icudt_custom.dat"); - public static readonly string CustomIcuTestedLocales = $@"new Locale[] {{ + private const string _fallbackSundayNameEnUS = "Sunday"; + + protected static readonly string CustomIcuTestedLocales = $@"new Locale[] {{ new Locale(""cy-GB"", ""Dydd Sul""), new Locale(""is-IS"", ""sunnudagur""), new Locale(""bs-BA"", ""nedjelja""), new Locale(""lb-LU"", ""Sonndeg""), new Locale(""fr-FR"", null), new Locale(""hr-HR"", null), new Locale(""ko-KR"", null) }}"; - public static string GetEfigsTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + protected static string GetEfigsTestedLocales(string fallbackSundayName=_fallbackSundayNameEnUS) => $@"new Locale[] {{ new Locale(""en-US"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""es-ES"", ""{SundayNames.Spanish}""), new Locale(""pl-PL"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""cs-CZ"", ""{fallbackSundayName}"") }}"; - public static string GetCjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + protected static string GetCjkTestedLocales(string fallbackSundayName=_fallbackSundayNameEnUS) => $@"new Locale[] {{ new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}""), new Locale(""ja-JP"", ""{SundayNames.Japanese}""), new Locale(""fr-FR"", ""{fallbackSundayName}""), new Locale(""hr-HR"", ""{fallbackSundayName}""), new Locale(""it-IT"", ""{fallbackSundayName}"") }}"; - public static string GetNocjkTestedLocales(string fallbackSundayName=FallbackSundayNameEnUS) => $@"new Locale[] {{ + protected static string GetNocjkTestedLocales(string fallbackSundayName=_fallbackSundayNameEnUS) => $@"new Locale[] {{ new Locale(""en-AU"", ""{SundayNames.English}""), new Locale(""fr-FR"", ""{SundayNames.French}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), new Locale(""ja-JP"", ""{fallbackSundayName}""), new Locale(""ko-KR"", ""{fallbackSundayName}""), new Locale(""zh-CN"", ""{fallbackSundayName}"") }}"; - public static readonly string FullIcuTestedLocales = $@"new Locale[] {{ + protected static readonly string s_fullIcuTestedLocales = $@"new Locale[] {{ new Locale(""en-GB"", ""{SundayNames.English}""), new Locale(""sk-SK"", ""{SundayNames.Slovak}""), new Locale(""zh-CN"", ""{SundayNames.Chinese}"") }}"; - public string GetProgramText(string testedLocales, bool onlyPredefinedCultures=false, string fallbackSundayName=FallbackSundayNameEnUS) => $@" + protected string GetProgramText(string testedLocales, bool onlyPredefinedCultures=false, string fallbackSundayName=_fallbackSundayNameEnUS) => $@" #nullable enable using System; @@ -99,7 +101,7 @@ public string GetProgramText(string testedLocales, bool onlyPredefinedCultures=f public record Locale(string Code, string? SundayName); "; - public void TestIcuShards(BuildArgs buildArgs, string shardName, string testedLocales, RunHost host, string id, bool onlyPredefinedCultures=false) + protected void TestIcuShards(BuildArgs buildArgs, string shardName, string testedLocales, RunHost host, string id, bool onlyPredefinedCultures=false) { string projectName = $"shard_{Path.GetFileName(shardName)}_{buildArgs.Config}_{buildArgs.AOT}"; bool dotnetWasmFromRuntimePack = !(buildArgs.AOT || buildArgs.Config == "Release"); diff --git a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs index 82fac06b647314..16f4a79f8226f6 100644 --- a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs @@ -55,9 +55,12 @@ public IReadOnlyDictionary AssertBasicBundle(AssertBundl // icu if (assertOptions.AssertIcuAssets) { - _testOutput.WriteLine("Starting icu assets assert"); AssertIcuAssets(assertOptions); } + else + { + _testOutput.WriteLine("Skipping asserting icu assets"); + } // symbols if (assertOptions.AssertSymbolsFile) diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs index 3f3c1a4fc10afd..44f192d9a32d6a 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/AssetsComputingHelper.cs @@ -25,6 +25,13 @@ public class AssetsComputingHelper "dotnet.runtime" }; + private static readonly string[] icuShardsFromRuntimePack = new[] + { + "icudt_EFIGS", + "icudt_CJK", + "icudt_no_CJK" + }; + public static bool ShouldFilterCandidate( ITaskItem candidate, bool timezoneSupport, @@ -58,7 +65,7 @@ public static bool ShouldFilterCandidate( ".dat" when loadFullICUData && fileName != "icudt" => "full ICU data is enabled", ".dat" when hybridGlobalization && fileName != "icudt_hybrid" => "hybrid globalization is enabled", ".dat" when !string.IsNullOrEmpty(customIcuCandidateFilename) && fileName != customIcuCandidateFilename => "custom icu file will be used instead of icu from the runtime pack", - ".dat" when IsDefaultIcuMode() && (fileName != "icudt_EFIGS" && fileName != "icudt_CJK" && fileName != "icudt_no_CJK") => "automatic icu shard selection, based on application culture, is enabled", + ".dat" when IsDefaultIcuMode() && !(icuShardsFromRuntimePack.Any(f => f == fileName)) => "automatic icu shard selection, based on application culture, is enabled", ".json" when fromMonoPackage && (fileName == "emcc-props" || fileName == "package") => $"{fileName}{extension} is not used by Blazor", ".ts" when fromMonoPackage && fileName == "dotnet.d" => "dotnet type definition is not used by Blazor", ".map" when !emitSourceMap && fromMonoPackage && (fileName == "dotnet.js" || fileName == "dotnet.runtime.js") => "source map file is not published", @@ -71,10 +78,11 @@ public static bool ShouldFilterCandidate( return reason != null; - bool IsDefaultIcuMode() - { - return !invariantGlobalization && !loadFullICUData && !hybridGlobalization && string.IsNullOrEmpty(customIcuCandidateFilename); - } + bool IsDefaultIcuMode() => + !invariantGlobalization && + !loadFullICUData && + !hybridGlobalization && + string.IsNullOrEmpty(customIcuCandidateFilename); } private static bool IsFromMonoPackage(ITaskItem candidate) From bafc86f9f64387a53236cb4436f948459ff7295d Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Mon, 7 Aug 2023 07:53:50 +0000 Subject: [PATCH 12/17] Build fix. --- src/mono/wasm/Wasm.Build.Tests/IcuTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs index 5ab0288e2cea23..c7a18a4dce742e 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs @@ -70,7 +70,7 @@ public void FullIcuFromRuntimePackWithCustomIcu(BuildArgs buildArgs, bool fullIc buildArgs = buildArgs with { ProjectName = projectName }; buildArgs = ExpandBuildArgs(buildArgs, extraProperties: $"{s_customIcuPath}{fullIcu}"); - string testedLocales = fullIcu ? s_fullIcuTestedLocales : CustomIcuTestedLocales; + string testedLocales = fullIcu ? s_fullIcuTestedLocales : s_customIcuTestedLocales; string programText = GetProgramText(testedLocales); _testOutput.WriteLine($"----- Program: -----{Environment.NewLine}{programText}{Environment.NewLine}-------"); (_, string output) = BuildProject(buildArgs, From 9497ffa37533317e0a450804ada9d5d5cc1994cf Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Mon, 7 Aug 2023 07:53:58 +0000 Subject: [PATCH 13/17] Null test cases. --- .../wasm/Wasm.Build.Tests/Blazor/IcuTests.cs | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs index f1b6ebad237bfe..f224cb620284fe 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs @@ -21,26 +21,28 @@ public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildCo [Theory] [InlineData("Debug", false)] [InlineData("Debug", true)] + [InlineData("Debug", null)] [InlineData("Release", false)] [InlineData("Release", true)] - public void HybridWithInvariant(string config, bool invariant) + [InlineData("Release", null)] + public void HybridWithInvariant(string config, bool? invariant) { string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; string projectFile = CreateProjectWithNativeReference(id); - AddItemsPropertiesToProject( - projectFile, - extraProperties: - $"true{invariant}"); + string extraProperties = "true"; + if (invariant != null) + extraProperties += $"{invariant}"; + AddItemsPropertiesToProject(projectFile, extraProperties: extraProperties); (CommandResult res, string logPath) = BlazorBuild( new BlazorBuildOptions( id, config, WarnAsError: false, - GlobalizationMode: invariant ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid, + GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid, ExpectedFileType: NativeFilesType.Relinked )); - if (invariant) + if (invariant == true) Assert.Contains("$(HybridGlobalization) has no effect when $(InvariantGlobalization) is set to true.", res.Output); } @@ -72,25 +74,29 @@ public void HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) [Theory] [InlineData("Debug", false)] [InlineData("Debug", true)] + [InlineData("Debug", null)] [InlineData("Release", false)] [InlineData("Release", true)] - public void FullIcuFromRuntimePackWithInvariant(string config, bool invariant) + [InlineData("Release", null)] + public void FullIcuFromRuntimePackWithInvariant(string config, bool? invariant) { string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; - string projectFile = CreateProjectWithNativeReference(id); - AddItemsPropertiesToProject(projectFile, extraProperties: - $"true{invariant}"); + string projectFile = CreateProjectWithNativeReference(id); + string extraProperties = "true"; + if (invariant != null) + extraProperties += $"{invariant}"; + AddItemsPropertiesToProject(projectFile, extraProperties: extraProperties); (CommandResult res, string logPath) = BlazorBuild( new BlazorBuildOptions( id, config, WarnAsError: false, - GlobalizationMode: invariant ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu, + GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu, ExpectedFileType: NativeFilesType.Relinked )); - if (invariant) + if (invariant == true) Assert.Contains("$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(InvariantGlobalization) is set to true.", res.Output); } } \ No newline at end of file From 3e1ebc12f8efe1465f3b8a0343854dd7d304548e Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 8 Aug 2023 07:54:45 +0000 Subject: [PATCH 14/17] Add running the apps. --- .../wasm/Wasm.Build.Tests/Blazor/IcuTests.cs | 44 ++++++++++++++++--- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs index f224cb620284fe..3d01f2a9f40154 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs @@ -7,6 +7,7 @@ using Xunit.Abstractions; using Xunit.Sdk; using System.Collections.Generic; +using System.Threading.Tasks; #nullable enable @@ -25,7 +26,7 @@ public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildCo [InlineData("Release", false)] [InlineData("Release", true)] [InlineData("Release", null)] - public void HybridWithInvariant(string config, bool? invariant) + public async Task HybridWithInvariant(string config, bool? invariant) { string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; string projectFile = CreateProjectWithNativeReference(id); @@ -42,8 +43,18 @@ public void HybridWithInvariant(string config, bool? invariant) GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid, ExpectedFileType: NativeFilesType.Relinked )); + + string warning = "$(HybridGlobalization) has no effect when $(InvariantGlobalization) is set to true."; if (invariant == true) - Assert.Contains("$(HybridGlobalization) has no effect when $(InvariantGlobalization) is set to true.", res.Output); + { + Assert.Contains(warning, res.Output); + } + else + { + Assert.DoesNotContain(warning, res.Output); + } + + await BlazorRunForBuildWithDotnetRun(new BlazorRunOptions() { Config = config }); } [Theory] @@ -51,7 +62,7 @@ public void HybridWithInvariant(string config, bool? invariant) [InlineData("Debug", true)] [InlineData("Release", false)] [InlineData("Release", true)] - public void HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) + public async Task HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) { string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; string projectFile = CreateProjectWithNativeReference(id); @@ -66,8 +77,18 @@ public void HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) GlobalizationMode: GlobalizationMode.Hybrid, ExpectedFileType: NativeFilesType.Relinked )); + + string warning = "$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(HybridGlobalization) is set to true."; if (fullIcu) - Assert.Contains("$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(HybridGlobalization) is set to true.", res.Output); + { + Assert.Contains(warning, res.Output); + } + else + { + Assert.DoesNotContain(warning, res.Output); + } + + await BlazorRunForBuildWithDotnetRun(new BlazorRunOptions() { Config = config }); } @@ -78,7 +99,7 @@ public void HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) [InlineData("Release", false)] [InlineData("Release", true)] [InlineData("Release", null)] - public void FullIcuFromRuntimePackWithInvariant(string config, bool? invariant) + public async Task FullIcuFromRuntimePackWithInvariant(string config, bool? invariant) { string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; string projectFile = CreateProjectWithNativeReference(id); @@ -95,8 +116,17 @@ public void FullIcuFromRuntimePackWithInvariant(string config, bool? invariant) GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu, ExpectedFileType: NativeFilesType.Relinked )); - + + string warning = "$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(InvariantGlobalization) is set to true."; if (invariant == true) - Assert.Contains("$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(InvariantGlobalization) is set to true.", res.Output); + { + Assert.Contains(warning, res.Output); + } + else + { + Assert.DoesNotContain(warning, res.Output); + } + + await BlazorRunForBuildWithDotnetRun(new BlazorRunOptions() { Config = config }); } } \ No newline at end of file From c135c0e28a64a4aac5c35a1edc3a6a6b03fabe47 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 8 Aug 2023 16:09:01 +0000 Subject: [PATCH 15/17] @radical's feedback --- .../Blazor/BlazorWasmTestBase.cs | 2 -- .../wasm/Wasm.Build.Tests/Blazor/IcuTests.cs | 25 +++++++++++-------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs index 518ceac360e64b..bfebc6eac4145b 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs @@ -216,6 +216,4 @@ void OnErrorMessage(string msg) public string FindBlazorBinFrameworkDir(string config, bool forPublish, string framework = DefaultTargetFrameworkForBlazor) => _provider.FindBinFrameworkDir(config: config, forPublish: forPublish, framework: framework); - - public string GetRandomNameWithoutDots() => Path.GetRandomFileName().Replace(".", ""); } diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs index 3d01f2a9f40154..27a7001aebb646 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs @@ -28,8 +28,8 @@ public IcuTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildCo [InlineData("Release", null)] public async Task HybridWithInvariant(string config, bool? invariant) { - string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; - string projectFile = CreateProjectWithNativeReference(id); + string id = $"blz_hybrid_{config}_{GetRandomId()}"; + string projectFile = CreateBlazorWasmTemplateProject(id); string extraProperties = "true"; if (invariant != null) extraProperties += $"{invariant}"; @@ -60,14 +60,18 @@ public async Task HybridWithInvariant(string config, bool? invariant) [Theory] [InlineData("Debug", false)] [InlineData("Debug", true)] + [InlineData("Debug", null)] [InlineData("Release", false)] [InlineData("Release", true)] - public async Task HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) + [InlineData("Release", null)] + public async Task HybridWithFullIcuFromRuntimePack(string config, bool? fullIcu) { - string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; - string projectFile = CreateProjectWithNativeReference(id); - AddItemsPropertiesToProject(projectFile, extraProperties: - $"true{fullIcu}"); + string id = $"blz_hybrid_{config}_{GetRandomId()}"; + string projectFile = CreateBlazorWasmTemplateProject(id); + string extraProperties = "true"; + if (fullIcu != null) + extraProperties += $"{fullIcu}"; + AddItemsPropertiesToProject(projectFile, extraProperties: extraProperties); (CommandResult res, string logPath) = BlazorBuild( new BlazorBuildOptions( @@ -79,7 +83,7 @@ public async Task HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) )); string warning = "$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(HybridGlobalization) is set to true."; - if (fullIcu) + if (fullIcu == true) { Assert.Contains(warning, res.Output); } @@ -91,7 +95,6 @@ public async Task HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) await BlazorRunForBuildWithDotnetRun(new BlazorRunOptions() { Config = config }); } - [Theory] [InlineData("Debug", false)] [InlineData("Debug", true)] @@ -101,8 +104,8 @@ public async Task HybridWithFullIcuFromRuntimePack(string config, bool fullIcu) [InlineData("Release", null)] public async Task FullIcuFromRuntimePackWithInvariant(string config, bool? invariant) { - string id = $"blz_hybrid_{config}_{GetRandomNameWithoutDots()}"; - string projectFile = CreateProjectWithNativeReference(id); + string id = $"blz_hybrid_{config}_{GetRandomId()}"; + string projectFile = CreateBlazorWasmTemplateProject(id); string extraProperties = "true"; if (invariant != null) extraProperties += $"{invariant}"; From 6470ff5f526691619875542ca10cdcdebe8ae6a4 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 9 Aug 2023 11:34:41 +0000 Subject: [PATCH 16/17] Changing type of template required update in options. --- src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs index 27a7001aebb646..ee1f4ecab310ea 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs @@ -40,8 +40,7 @@ public async Task HybridWithInvariant(string config, bool? invariant) id, config, WarnAsError: false, - GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid, - ExpectedFileType: NativeFilesType.Relinked + GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid )); string warning = "$(HybridGlobalization) has no effect when $(InvariantGlobalization) is set to true."; @@ -78,8 +77,7 @@ public async Task HybridWithFullIcuFromRuntimePack(string config, bool? fullIcu) id, config, WarnAsError: false, - GlobalizationMode: GlobalizationMode.Hybrid, - ExpectedFileType: NativeFilesType.Relinked + GlobalizationMode: GlobalizationMode.Hybrid )); string warning = "$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(HybridGlobalization) is set to true."; @@ -116,8 +114,7 @@ public async Task FullIcuFromRuntimePackWithInvariant(string config, bool? invar id, config, WarnAsError: false, - GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu, - ExpectedFileType: NativeFilesType.Relinked + GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu )); string warning = "$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(InvariantGlobalization) is set to true."; From cf1545cc8bc482812545b8adf04d29c8b0266ede Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 9 Aug 2023 13:59:57 +0000 Subject: [PATCH 17/17] Fix "file sizes don't match for dotnet.native.wasm". --- src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs index ee1f4ecab310ea..728eb96386b2ec 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/IcuTests.cs @@ -40,7 +40,8 @@ public async Task HybridWithInvariant(string config, bool? invariant) id, config, WarnAsError: false, - GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid + GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.Hybrid, + ExpectedFileType: invariant == true ? NativeFilesType.Relinked : NativeFilesType.FromRuntimePack )); string warning = "$(HybridGlobalization) has no effect when $(InvariantGlobalization) is set to true."; @@ -114,7 +115,8 @@ public async Task FullIcuFromRuntimePackWithInvariant(string config, bool? invar id, config, WarnAsError: false, - GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu + GlobalizationMode: invariant == true ? GlobalizationMode.Invariant : GlobalizationMode.FullIcu, + ExpectedFileType: invariant == true ? NativeFilesType.Relinked : NativeFilesType.FromRuntimePack )); string warning = "$(BlazorWebAssemblyLoadAllGlobalizationData) has no effect when $(InvariantGlobalization) is set to true.";