|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
using System.Text.Json;
using Microsoft.AspNetCore.StaticWebAssets.Tasks;
using Microsoft.NET.Sdk.WebAssembly;
namespace Microsoft.NET.Sdk.BlazorWebAssembly.Tests
{
public class WasmBuildIntegrationTest(ITestOutputHelper log) : BlazorWasmBaselineTests(log, GenerateBaselines)
{
private static string customIcuFilename = "icudt_custom.dat";
private static string fullIcuFilename = "icudt.dat";
private static string[] icuShardFilenames = new string[] {
"icudt_EFIGS.dat",
"icudt_CJK.dat",
"icudt_no_CJK.dat"
};
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void BuildMinimal_Works()
{
// Arrange
// Minimal has no project references, service worker etc. This is pretty close to the project template.
var testAsset = "BlazorWasmMinimal";
var testInstance = CreateAspNetSdkTestAsset(testAsset)
.WithProjectChanges((p, doc) =>
{
var itemGroup = new XElement("PropertyGroup");
var fingerprintAssets = new XElement("WasmFingerprintAssets", false);
itemGroup.Add(fingerprintAssets);
doc.Root.Add(itemGroup);
});
File.WriteAllText(Path.Combine(testInstance.TestRoot, "App.razor.css"), "h1 { font-size: 16px; }");
var build = CreateBuildCommand(testInstance);
ExecuteCommand(build)
.Should()
.Pass();
var buildOutputDirectory = build.GetOutputDirectory(DefaultTfm).ToString();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName)).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm.gz")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazorwasm-minimal.wasm")).Should().Exist();
}
[RequiresMSBuildVersionTheory("17.12", Reason = "Needs System.Text.Json 8.0.5")]
[InlineData("blazor")]
[InlineData("blazor spaces")]
public void Build_Works(string identifier)
{
// Arrange
var testAppName = "BlazorWasmWithLibrary";
var testInstance = CreateAspNetSdkTestAsset(testAppName, identifier: identifier)
.WithProjectChanges((path, doc) =>
{
var itemGroup = new XElement("PropertyGroup");
var fingerprintAssets = new XElement("WasmFingerprintAssets", false);
itemGroup.Add(fingerprintAssets);
doc.Root.Add(itemGroup);
});
var buildCommand = CreateBuildCommand(testInstance, "blazorwasm");
ExecuteCommand(buildCommand)
.Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName)).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm.gz")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazorwasm.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.Text.Json.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.Text.Json.wasm.gz")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.wasm.gz")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazorwasm.pdb")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "RazorClassLibrary.pdb")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "RazorClassLibrary.wasm")).Should().Exist();
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_Works_WithLibraryUsingHintPath()
{
// Arrange
var testAppName = "BlazorWasmWithLibrary";
var testInstance = CreateAspNetSdkTestAsset(testAppName);
testInstance.WithProjectChanges((project, document) =>
{
if (Path.GetFileNameWithoutExtension(project) == "blazorwasm")
{
document.Root.Add(new XElement("PropertyGroup",
new XElement("WasmFingerprintAssets", false)));
var reference = document
.Descendants()
.Single(e =>
e.Name == "ProjectReference" &&
e.Attribute("Include").Value == @"..\razorclasslibrary\RazorClassLibrary.csproj");
reference.Name = "Reference";
reference.Add(new XElement(
"HintPath",
Path.Combine("..", "razorclasslibrary", "bin", "Debug", ToolsetInfo.CurrentTargetFramework, "RazorClassLibrary.dll")));
}
});
var buildLibraryCommand = CreateBuildCommand(testInstance, "razorclasslibrary");
ExecuteCommand(buildLibraryCommand)
.Should().Pass();
var buildCommand = CreateBuildCommand(testInstance, "blazorwasm");
ExecuteCommand(buildCommand)
.Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName)).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm.gz")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazorwasm.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.Text.Json.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.Text.Json.wasm.gz")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.wasm.gz")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazorwasm.pdb")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "RazorClassLibrary.pdb")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "RazorClassLibrary.wasm")).Should().Exist();
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_InRelease_Works()
{
// Arrange
var testAppName = "BlazorWasmWithLibrary";
var testInstance = CreateAspNetSdkTestAsset(testAppName)
.WithProjectChanges((p, doc) =>
{
if (Path.GetFileName(p) == "blazorwasm.csproj")
{
var itemGroup = new XElement("PropertyGroup");
var fingerprintAssets = new XElement("WasmFingerprintAssets", false);
itemGroup.Add(fingerprintAssets);
doc.Root.Add(itemGroup);
}
});
var buildCommand = CreateBuildCommand(testInstance, "blazorwasm");
ExecuteCommand(buildCommand, "/p:Configuration=Release")
.Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm, "Release").ToString();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName)).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm.gz")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazorwasm.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.Text.Json.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.Text.Json.wasm.gz")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "System.wasm.gz")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazorwasm.pdb")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "RazorClassLibrary.pdb")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "RazorClassLibrary.wasm")).Should().Exist();
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_ProducesBootJsonDataWithExpectedContent()
{
// Arrange
var testAppName = "BlazorWasmWithLibrary";
var testInstance = CreateAspNetSdkTestAsset(testAppName)
.WithProjectChanges((p, doc) =>
{
if (Path.GetFileName(p) == "blazorwasm.csproj")
{
var itemGroup = new XElement("PropertyGroup");
var fingerprintAssets = new XElement("WasmFingerprintAssets", false);
itemGroup.Add(fingerprintAssets);
doc.Root.Add(itemGroup);
}
});
var wwwroot = Path.Combine(testInstance.TestRoot, "blazorwasm", "wwwroot");
File.WriteAllText(Path.Combine(wwwroot, "appsettings.json"), "Default settings");
File.WriteAllText(Path.Combine(wwwroot, "appsettings.development.json"), "Development settings");
var buildCommand = CreateBuildCommand(testInstance, "blazorwasm");
ExecuteCommand(buildCommand)
.Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName);
var bootJsonData = ReadBootJsonData(bootJsonPath);
bootJsonData.resources.wasmNative.Should().ContainKey("dotnet.native.wasm");
var assemblies = bootJsonData.resources.assembly;
assemblies.Should().ContainKey("blazorwasm.wasm");
assemblies.Should().ContainKey("RazorClassLibrary.wasm");
assemblies.Should().ContainKey("System.Text.Json.wasm");
var pdb = bootJsonData.resources.pdb;
pdb.Should().ContainKey("blazorwasm.pdb");
pdb.Should().ContainKey("RazorClassLibrary.pdb");
bootJsonData.resources.satelliteResources.Should().BeNull();
bootJsonData.config.Should().Contain("../appsettings.json");
bootJsonData.config.Should().Contain("../appsettings.development.json");
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_InRelease_ProducesBootJsonDataWithExpectedContent()
{
// Arrange
var testAppName = "BlazorWasmWithLibrary";
var testInstance = CreateAspNetSdkTestAsset(testAppName)
.WithProjectChanges((p, doc) =>
{
if (Path.GetFileName(p) == "blazorwasm.csproj")
{
var itemGroup = new XElement("PropertyGroup");
var fingerprintAssets = new XElement("WasmFingerprintAssets", false);
itemGroup.Add(fingerprintAssets);
doc.Root.Add(itemGroup);
}
});
var wwwroot = Path.Combine(testInstance.TestRoot, "blazorwasm", "wwwroot");
File.WriteAllText(Path.Combine(wwwroot, "appsettings.json"), "Default settings");
File.WriteAllText(Path.Combine(wwwroot, "appsettings.development.json"), "Development settings");
var buildCommand = CreateBuildCommand(testInstance, "blazorwasm");
ExecuteCommand(buildCommand, "/p:Configuration=Release")
.Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm, "Release").ToString();
var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName);
var bootJsonData = ReadBootJsonData(bootJsonPath);
bootJsonData.resources.wasmNative.Should().ContainKey("dotnet.native.wasm");
var assemblies = bootJsonData.resources.assembly;
assemblies.Should().ContainKey("blazorwasm.wasm");
assemblies.Should().ContainKey("RazorClassLibrary.wasm");
assemblies.Should().ContainKey("System.Text.Json.wasm");
var pdb = bootJsonData.resources.pdb;
pdb.Should().ContainKey("blazorwasm.pdb");
pdb.Should().ContainKey("RazorClassLibrary.pdb");
bootJsonData.resources.satelliteResources.Should().BeNull();
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_WithBlazorEnableTimeZoneSupportDisabled_DoesNotCopyTimeZoneInfo()
{
// Arrange
var testAppName = "BlazorWasmWithLibrary";
var testInstance = CreateAspNetSdkTestAsset(testAppName);
testInstance.WithProjectChanges((project) =>
{
var ns = project.Root.Name.Namespace;
var itemGroup = new XElement(ns + "PropertyGroup");
itemGroup.Add(new XElement("BlazorEnableTimeZoneSupport", false));
itemGroup.Add(new XElement("WasmFingerprintAssets", false));
project.Root.Add(itemGroup);
});
var buildCommand = CreateBuildCommand(testInstance, "blazorwasm");
ExecuteCommand(buildCommand)
.Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName);
var bootJsonData = ReadBootJsonData(bootJsonPath);
bootJsonData.resources.wasmNative.Should().ContainKey("dotnet.native.wasm");
bootJsonData.resources.runtime.Should().BeNull();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.timezones.blat")).Should().NotExist();
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_WithInvariantGlobalizationEnabled_DoesNotCopyGlobalizationData()
{
// Arrange
var testAppName = "BlazorWasmMinimal";
var testInstance = CreateAspNetSdkTestAsset(testAppName);
testInstance.WithProjectChanges((project) =>
{
var ns = project.Root.Name.Namespace;
var itemGroup = new XElement(ns + "PropertyGroup");
itemGroup.Add(new XElement("InvariantGlobalization", true));
itemGroup.Add(new XElement("WasmFingerprintAssets", false));
project.Root.Add(itemGroup);
});
var buildCommand = CreateBuildCommand(testInstance);
ExecuteCommand(buildCommand)
.Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName);
var bootJsonData = ReadBootJsonData(bootJsonPath);
bootJsonData.globalizationMode.Should().Be("invariant");
bootJsonData.resources.wasmNative.Should().ContainKey("dotnet.native.wasm");
bootJsonData.resources.icu.Should().BeNull();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", fullIcuFilename)).Should().NotExist();
foreach (var shardFilename in icuShardFilenames)
{
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", shardFilename)).Should().NotExist();
}
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Publish_WithInvariantGlobalizationEnabled_DoesNotCopyGlobalizationData()
{
// Arrange
var testAppName = "BlazorHosted";
var testInstance = CreateAspNetSdkTestAsset(testAppName);
testInstance.WithProjectChanges((project) =>
{
var ns = project.Root.Name.Namespace;
var itemGroup = new XElement(ns + "PropertyGroup");
itemGroup.Add(new XElement("InvariantGlobalization", true));
itemGroup.Add(new XElement("WasmFingerprintAssets", false));
project.Root.Add(itemGroup);
});
var publishCommand = CreatePublishCommand(testInstance, "blazorhosted");
ExecuteCommand(publishCommand)
.Should().Pass();
var publishOutputDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString();
var bootJsonPath = Path.Combine(publishOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName);
var bootJsonData = ReadBootJsonData(bootJsonPath);
bootJsonData.globalizationMode.Should().Be("invariant");
bootJsonData.resources.wasmNative.Should().ContainKey("dotnet.native.wasm");
bootJsonData.resources.icu.Should().BeNull();
new FileInfo(Path.Combine(publishOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(publishOutputDirectory, "wwwroot", "_framework", fullIcuFilename)).Should().NotExist();
foreach (var shardFilename in icuShardFilenames)
{
new FileInfo(Path.Combine(publishOutputDirectory, "wwwroot", "_framework", shardFilename)).Should().NotExist();
}
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_WithBlazorWebAssemblyLoadCustomGlobalizationData_SetsGlobalizationMode()
{
// Arrange
var testAppName = "BlazorWasmMinimal";
var testInstance = CreateAspNetSdkTestAsset(testAppName);
testInstance.WithProjectChanges((project) =>
{
var ns = project.Root.Name.Namespace;
var itemGroup = new XElement(ns + "PropertyGroup");
itemGroup.Add(new XElement("BlazorIcuDataFileName", customIcuFilename));
itemGroup.Add(new XElement("WasmFingerprintAssets", false));
project.Root.Add(itemGroup);
});
var buildCommand = CreateBuildCommand(testInstance);
ExecuteCommand(buildCommand)
.Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName);
var bootJsonData = ReadBootJsonData(bootJsonPath);
bootJsonData.globalizationMode.Should().Be("custom");
bootJsonData.resources.wasmNative.Should().ContainKey("dotnet.native.wasm");
bootJsonData.resources.icu.Should().ContainKey(customIcuFilename);
bootJsonData.resources.icu.Should().NotContainKey(fullIcuFilename);
foreach (var shardFilename in icuShardFilenames)
{
bootJsonData.resources.icu.Should().NotContainKey(shardFilename);
}
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", customIcuFilename)).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", fullIcuFilename)).Should().NotExist();
foreach (var shardFilename in icuShardFilenames)
{
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", shardFilename)).Should().NotExist();
}
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Publish_WithBlazorWebAssemblyLoadCustomGlobalizationData_SetsGlobalizationMode()
{
var testAppName = "BlazorHosted";
var testInstance = CreateAspNetSdkTestAsset(testAppName);
testInstance.WithProjectChanges((project) =>
{
var ns = project.Root.Name.Namespace;
var itemGroup = new XElement(ns + "PropertyGroup");
itemGroup.Add(new XElement("BlazorIcuDataFileName", customIcuFilename));
itemGroup.Add(new XElement("WasmFingerprintAssets", false));
project.Root.Add(itemGroup);
});
var publishCommand = CreatePublishCommand(testInstance, "blazorhosted");
ExecuteCommand(publishCommand)
.Should().Pass();
var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString();
var bootJsonPath = Path.Combine(publishDirectory, "wwwroot", "_framework", WasmBootConfigFileName);
var bootJsonData = ReadBootJsonData(bootJsonPath);
bootJsonData.globalizationMode.Should().Be("custom");
bootJsonData.resources.wasmNative.Should().ContainKey("dotnet.native.wasm");
bootJsonData.resources.icu.Should().ContainKey(customIcuFilename);
bootJsonData.resources.icu.Should().NotContainKey(fullIcuFilename);
foreach (var shardFilename in icuShardFilenames)
{
bootJsonData.resources.icu.Should().NotContainKey(shardFilename);
}
new FileInfo(Path.Combine(publishDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(publishDirectory, "wwwroot", "_framework", customIcuFilename)).Should().Exist();
new FileInfo(Path.Combine(publishDirectory, "wwwroot", "_framework", fullIcuFilename)).Should().NotExist();
foreach (var shardFilename in icuShardFilenames)
{
new FileInfo(Path.Combine(publishDirectory, "wwwroot", "_framework", shardFilename)).Should().NotExist();
}
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_WithBlazorWebAssemblyLoadAllGlobalizationData_SetsICUDataMode()
{
// Arrange
var testAppName = "BlazorWasmMinimal";
var testInstance = CreateAspNetSdkTestAsset(testAppName);
testInstance.WithProjectChanges((project) =>
{
var ns = project.Root.Name.Namespace;
var itemGroup = new XElement(ns + "PropertyGroup");
itemGroup.Add(new XElement("BlazorWebAssemblyLoadAllGlobalizationData", true));
itemGroup.Add(new XElement("WasmFingerprintAssets", false));
project.Root.Add(itemGroup);
});
var buildCommand = CreateBuildCommand(testInstance);
ExecuteCommand(buildCommand)
.Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName);
var bootJsonData = ReadBootJsonData(bootJsonPath);
bootJsonData.globalizationMode.Should().Be("all");
bootJsonData.resources.wasmNative.Should().ContainKey("dotnet.native.wasm");
bootJsonData.resources.icu.Should().ContainKey(fullIcuFilename);
foreach (var shardFilename in icuShardFilenames)
{
bootJsonData.resources.icu.Should().NotContainKey(shardFilename);
}
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", fullIcuFilename)).Should().Exist();
foreach (var shardFilename in icuShardFilenames)
{
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", shardFilename)).Should().NotExist();
}
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Publish_WithBlazorWebAssemblyLoadAllGlobalizationData_SetsGlobalizationMode()
{
// Arrange
var testAppName = "BlazorHosted";
var testInstance = CreateAspNetSdkTestAsset(testAppName);
testInstance.WithProjectChanges((project) =>
{
var ns = project.Root.Name.Namespace;
var itemGroup = new XElement(ns + "PropertyGroup");
itemGroup.Add(new XElement("BlazorWebAssemblyLoadAllGlobalizationData", true));
itemGroup.Add(new XElement("WasmFingerprintAssets", false));
project.Root.Add(itemGroup);
});
var publishCommand = CreatePublishCommand(testInstance, "blazorhosted");
ExecuteCommand(publishCommand)
.Should().Pass();
var publishDirectory = publishCommand.GetOutputDirectory(DefaultTfm).ToString();
var bootJsonPath = Path.Combine(publishDirectory, "wwwroot", "_framework", WasmBootConfigFileName);
var bootJsonData = ReadBootJsonData(bootJsonPath);
bootJsonData.globalizationMode.Should().Be("all");
bootJsonData.resources.wasmNative.Should().ContainKey("dotnet.native.wasm");
bootJsonData.resources.icu.Should().ContainKey(fullIcuFilename);
foreach (var shardFilename in icuShardFilenames)
{
bootJsonData.resources.icu.Should().NotContainKey(shardFilename);
}
new FileInfo(Path.Combine(publishDirectory, "wwwroot", "_framework", "dotnet.native.wasm")).Should().Exist();
new FileInfo(Path.Combine(publishDirectory, "wwwroot", "_framework", fullIcuFilename)).Should().Exist();
foreach (var shardFilename in icuShardFilenames)
{
new FileInfo(Path.Combine(publishDirectory, "wwwroot", "_framework", shardFilename)).Should().NotExist();
}
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_Hosted_Works()
{
// Arrange
var testAppName = "BlazorHosted";
var testInstance = CreateAspNetSdkTestAsset(testAppName);
var buildCommand = CreateBuildCommand(testInstance, "blazorhosted");
ExecuteCommand(buildCommand).Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
new FileInfo(Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "_bin", "blazorwasm.wasm")).Should().NotExist();
}
[Fact]
public void Build_SatelliteAssembliesAreCopiedToBuildOutput()
{
// Arrange
var testAppName = "BlazorWasmWithLibrary";
ProjectDirectory = CreateAspNetSdkTestAsset(testAppName);
ProjectDirectory.WithProjectChanges((path, project) =>
{
if (path.Contains("blazorwasm"))
{
var ns = project.Root.Name.Namespace;
var propertyGroup = new XElement(ns + "PropertyGroup");
propertyGroup.Add(new XElement("DefineConstants", @"$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies"));
propertyGroup.Add(new XElement("WasmFingerprintAssets", false));
var itemGroup = new XElement(ns + "ItemGroup");
itemGroup.Add(new XElement("ProjectReference", new XAttribute("Include", @"..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj")));
project.Root.Add(propertyGroup);
project.Root.Add(itemGroup);
}
});
var resxfileInProject = Path.Combine(ProjectDirectory.TestRoot, "blazorwasm", "Resources.ja.resx.txt");
File.Move(resxfileInProject, Path.Combine(ProjectDirectory.TestRoot, "blazorwasm", "Resource.ja.resx"));
var buildCommand = CreateBuildCommand(ProjectDirectory, "blazorwasm");
ExecuteCommand(buildCommand).Should().Pass();
var outputPath = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
var intermediateOutputPath = buildCommand.GetIntermediateDirectory(DefaultTfm).ToString();
// GenerateStaticWebAssetsManifest should generate the manifest file.
var path = Path.Combine(intermediateOutputPath, "staticwebassets.build.json");
new FileInfo(path).Should().Exist();
var manifest = StaticWebAssetsManifest.FromJsonBytes(File.ReadAllBytes(path));
AssertManifest(manifest, LoadBuildManifest());
// GenerateStaticWebAssetsManifest should copy the file to the output folder.
var finalPath = Path.Combine(outputPath, "blazorwasm.staticwebassets.runtime.json");
new FileInfo(finalPath).Should().Exist();
AssertBuildAssets(
manifest,
outputPath,
intermediateOutputPath);
new FileInfo(Path.Combine(outputPath, "wwwroot", "_framework", "blazorwasm.wasm")).Should().Exist();
new FileInfo(Path.Combine(outputPath, "wwwroot", "_framework", "classlibrarywithsatelliteassemblies.wasm")).Should().Exist();
new FileInfo(Path.Combine(outputPath, "wwwroot", "_framework", "Microsoft.CodeAnalysis.CSharp.wasm")).Should().Exist();
new FileInfo(Path.Combine(outputPath, "wwwroot", "_framework", "fr", "Microsoft.CodeAnalysis.CSharp.resources.wasm")).Should().Exist();
var bootJsonPath = new FileInfo(Path.Combine(outputPath, "wwwroot", "_framework", WasmBootConfigFileName));
bootJsonPath.Should().Contain("\"Microsoft.CodeAnalysis.CSharp.wasm\"");
bootJsonPath.Should().Contain("\"fr\"");
bootJsonPath.Should().Contain("\"Microsoft.CodeAnalysis.CSharp.resources.wasm\"");
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_WithCustomOutputPath_Works()
{
var testAppName = "BlazorWasmWithLibrary";
var testInstance = CreateAspNetSdkTestAsset(testAppName);
testInstance.WithProjectChanges((path, project) =>
{
if (path.Contains("blazorwasm"))
{
var ns = project.Root.Name.Namespace;
var propertyGroup = new XElement(ns + "PropertyGroup");
propertyGroup.Add(new XElement("BaseOutputPath", @"$(MSBuildThisFileDirectory)build\bin\"));
propertyGroup.Add(new XElement("BaseIntermediateOutputPath", @"$(MSBuildThisFileDirectory)build\obj\"));
project.Root.Add(propertyGroup);
}
});
var buildCommand = CreateBuildCommand(testInstance, "blazorwasm");
ExecuteCommand(buildCommand).Should().Pass();
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_WithTransitiveReference_Works()
{
// Regression test for https://github.com/dotnet/aspnetcore/issues/37574.
var testInstance = CreateAspNetSdkTestAsset("BlazorWasmWithLibrary");
var buildCommand = CreateBuildCommand(testInstance, "classlibrarywithsatelliteassemblies");
ExecuteCommand(buildCommand).Should().Pass();
var referenceAssemblyPath = new FileInfo(Path.Combine(
buildCommand.GetOutputDirectory(DefaultTfm).ToString(),
"classlibrarywithsatelliteassemblies.dll"));
referenceAssemblyPath.Should().Exist();
testInstance.WithProjectChanges((path, project) =>
{
if (path.Contains("blazorwasm.csproj"))
{
var propertyGroup = new XElement(project.Root.Name.Namespace + "PropertyGroup");
propertyGroup.Add(new XElement("WasmFingerprintAssets", false));
project.Root.Add(propertyGroup);
}
if (path.Contains("razorclasslibrary"))
{
var ns = project.Root.Name.Namespace;
// <ItemGroup>
// <Reference Include="classlibrarywithsatelliteassemblies" HintPath="$Path\classlibrarywithsatelliteassemblies.wasm" />
// </ItemGroup>
var itemGroup = new XElement(ns + "ItemGroup",
new XElement(ns + "Reference",
new XAttribute("Include", "classlibrarywithsatelliteassemblies"),
new XAttribute("HintPath", referenceAssemblyPath)));
project.Root.Add(itemGroup);
}
});
// Ensure a compile time reference exists between the project and the assembly added as a reference. This is required for
// the assembly to be resolved by the "app" as part of RAR
File.WriteAllText(Path.Combine(testInstance.Path, "razorclasslibrary", "TestReference.cs"),
@"
public class TestReference
{
public void Method() => System.GC.KeepAlive(typeof(classlibrarywithsatelliteassemblies.Class1));
}");
buildCommand = CreateBuildCommand(testInstance, "blazorwasm");
ExecuteCommand(buildCommand).Should().Pass();
// Assert
var outputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
var fileInWwwroot = new FileInfo(Path.Combine(outputDirectory, "wwwroot", "_framework", "classlibrarywithsatelliteassemblies.wasm"));
fileInWwwroot.Should().Exist();
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Restore_WithRuntime_Works()
{
var testInstance = CreateAspNetSdkTestAsset("BlazorHosted");
var nugetRestorePath = Path.Combine(testInstance.TestRoot, ".nuget");
new DotnetRestoreCommand(Log, "-bl:msbuild-restore.binlog", "-r", "linux-x64")
.WithWorkingDirectory(Path.Combine(testInstance.TestRoot, "blazorhosted"))
.WithEnvironmentVariable("NUGET_PACKAGES", nugetRestorePath)
.Execute()
.Should().Pass();
new DirectoryInfo(Path.Combine(nugetRestorePath, "microsoft.netcore.app.runtime.mono.linux-x64"))
.Should().NotExist();
}
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_WithReference_Works()
{
// Regression test for https://github.com/dotnet/aspnetcore/issues/37574.
var testInstance = CreateAspNetSdkTestAsset("BlazorWasmWithLibrary")
.WithProjectChanges((path, project) =>
{
if (path.Contains("blazorwasm.csproj"))
{
var ns = project.Root.Name.Namespace;
var propertyGroup = new XElement(ns + "PropertyGroup");
propertyGroup.Add(new XElement("WasmFingerprintAssets", false));
project.Root.Add(propertyGroup);
}
});
var buildCommand = CreateBuildCommand(testInstance, "classlibrarywithsatelliteassemblies");
ExecuteCommand(buildCommand).Should().Pass();
var referenceAssemblyPath = new FileInfo(Path.Combine(
buildCommand.GetOutputDirectory(DefaultTfm).ToString(),
"classlibrarywithsatelliteassemblies.dll"));
referenceAssemblyPath.Should().Exist();
testInstance.WithProjectChanges((path, project) =>
{
if (path.Contains("blazorwasm"))
{
var ns = project.Root.Name.Namespace;
// <ItemGroup>
// <Reference Include="classlibrarywithsatelliteassemblies" HintPath="$Path\classlibrarywithsatelliteassemblies.wasm" />
// </ItemGroup>
var itemGroup = new XElement(ns + "ItemGroup",
new XElement(ns + "Reference",
new XAttribute("Include", "classlibrarywithsatelliteassemblies"),
new XAttribute("HintPath", referenceAssemblyPath)));
project.Root.Add(itemGroup);
var propertyGroup = new XElement(ns + "PropertyGroup");
propertyGroup.Add(new XElement("WasmFingerprintAssets", false));
project.Root.Add(propertyGroup);
}
});
// Ensure a compile time reference exists between the project and the assembly added as a reference. This is required for
// the assembly to be resolved by the "app" as part of RAR
File.WriteAllText(Path.Combine(testInstance.Path, "blazorwasm", "TestReference.cs"),
@"
public class TestReference
{
public void Method() => System.GC.KeepAlive(typeof(classlibrarywithsatelliteassemblies.Class1));
}");
buildCommand = CreateBuildCommand(testInstance, "blazorwasm");
ExecuteCommand(buildCommand).Should().Pass();
// Assert
var outputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
var fileInWwwroot = new FileInfo(Path.Combine(outputDirectory, "wwwroot", "_framework", "classlibrarywithsatelliteassemblies.wasm"));
fileInWwwroot.Should().Exist();
}
[RequiresMSBuildVersionTheory("17.12", Reason = "Needs System.Text.Json 8.0.5")]
[InlineData(true)]
[InlineData(false)]
[InlineData(null)]
public void Build_WithJiterpreter(bool? value)
=> BuildWasmMinimalAndValidateBootConfig(new[] { ("BlazorWebAssemblyJiterpreter", value?.ToString()) }, b =>
{
if (value != null)
{
b.runtimeOptions.Should().NotBeNull();
b.runtimeOptions.Length.Should().Be(3);
}
else
{
b.runtimeOptions.Should().BeNull();
}
});
[RequiresMSBuildVersionFact("17.12", Reason = "Needs System.Text.Json 8.0.5")]
public void Build_WithJiterpreter_Advanced()
=> BuildWasmMinimalAndValidateBootConfig(new[] { ("BlazorWebAssemblyJiterpreter", "true"), ("BlazorWebAssemblyRuntimeOptions", "--no-jiterpreter-interp-entry-enabled") }, b =>
{
b.runtimeOptions.Should().NotBeNull();
b.runtimeOptions.Length.Should().Be(3);
b.runtimeOptions.Should().Contain("--no-jiterpreter-interp-entry-enabled");
b.runtimeOptions.Should().NotContain("--jiterpreter-interp-entry-enabled");
b.runtimeOptions.Should().Contain("--jiterpreter-traces-enabled");
b.runtimeOptions.Should().Contain("--jiterpreter-jit-call-enabled");
});
private void BuildWasmMinimalAndValidateBootConfig((string name, string value)[] properties, Action<BootJsonData> validateBootConfig)
{
var testAppName = "BlazorWasmMinimal";
var testInstance = CreateAspNetSdkTestAsset(testAppName, identifier: string.Join("-", properties.Select(p => p.name + p.value ?? "null")));
foreach (var property in properties)
{
if (property.value != null)
{
testInstance.WithProjectChanges((project) =>
{
var ns = project.Root.Name.Namespace;
var itemGroup = new XElement(ns + "PropertyGroup");
itemGroup.Add(new XElement(property.name, property.value));
project.Root.Add(itemGroup);
});
}
}
var buildCommand = CreateBuildCommand(testInstance);
ExecuteCommand(buildCommand)
.Should().Pass();
var buildOutputDirectory = buildCommand.GetOutputDirectory(DefaultTfm).ToString();
var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", WasmBootConfigFileName);
var bootJsonData = ReadBootJsonData(bootJsonPath);
validateBootConfig(bootJsonData);
}
private static BootJsonData ReadBootJsonData(string path)
{
return BootJsonDataLoader.ParseBootData(path);
}
}
}
|