public async Task Build_WithoutLinkerAndCompression_IsIncremental() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/p:BlazorWebAssemblyEnableLinking=false"); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; // Act var compressedFilesFolder = Path.Combine(project.IntermediateOutputDirectory, "compressed"); var thumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); // Assert for (var i = 0; i < 3; i++) { result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/p:BlazorWebAssemblyEnableLinking=false"); Assert.BuildPassed(result); var newThumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); Assert.Equal(thumbPrint.Count, newThumbPrint.Count); for (var j = 0; j < thumbPrint.Count; j++) { Assert.Equal(thumbPrint[j], newThumbPrint[j]); } } }
public async Task Build_WithBlazorEnableTimeZoneSupportDisabled_DoesNotCopyTimeZoneInfo() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Release"; project.AddProjectFileContent( @" <PropertyGroup> <BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport> </PropertyGroup>"); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); var bootJsonData = ReadBootJsonData(result, bootJsonPath); var runtime = bootJsonData.resources.runtime.Keys; Assert.Contains("dotnet.wasm", runtime); Assert.DoesNotContain("dotnet.timezones.dat", runtime); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm"); Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.timezones.dat"); }
public async Task Build_WithoutLinkerAndCompression_UpdatesFilesWhenSourcesChange() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/p:BlazorWebAssemblyEnableLinking=false"); // Act var mainAppDll = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); var mainAppCompressedDll = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll.gz"); var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); var programFile = Path.Combine(project.DirectoryPath, "Program.cs"); var programFileContents = File.ReadAllText(programFile); File.WriteAllText(programFile, programFileContents.Replace("args", "arguments")); // Assert result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/p:BlazorWebAssemblyEnableLinking=false"); Assert.BuildPassed(result); var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint); Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint); }
public async Task Build_ProducesBootJsonDataWithExpectedContent() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Debug"; var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); var bootJsonData = ReadBootJsonData(result, bootJsonPath); var runtime = bootJsonData.resources.runtime.Keys; Assert.Contains(DotNetJsFileName, runtime); Assert.Contains("dotnet.wasm", runtime); Assert.Contains("dotnet.timezones.dat", runtime); var assemblies = bootJsonData.resources.assembly.Keys; Assert.Contains("standalone.dll", assemblies); Assert.Contains("RazorClassLibrary.dll", assemblies); Assert.Contains("Microsoft.Extensions.Logging.Abstractions.dll", assemblies); var pdb = bootJsonData.resources.pdb.Keys; Assert.Contains("standalone.pdb", pdb); Assert.Contains("RazorClassLibrary.pdb", pdb); Assert.Null(bootJsonData.resources.satelliteResources); }
public async Task Build_SatelliteAssembliesAreCopiedToBuildOutput() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); project.AddProjectFileContent( @" <PropertyGroup> <DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants> </PropertyGroup> <ItemGroup> <ProjectReference Include=""..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"" /> </ItemGroup>"); var resxfileInProject = Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"); File.Move(resxfileInProject, Path.Combine(project.DirectoryPath, "Resource.ja.resx")); var result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/restore"); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "classlibrarywithsatelliteassemblies.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); Assert.FileContains(result, bootJsonPath, "\"Microsoft.CodeAnalysis.CSharp.dll\""); Assert.FileContains(result, bootJsonPath, "\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); }
public async Task Build_InRelease_Works() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Release"; var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", DotNetJsFileName); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.timezones.dat"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.pdb"); Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.pdb"); var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "standalone.StaticWebAssets.xml"); Assert.FileContains(result, staticWebAssets, Path.Combine("netstandard2.1", "wwwroot")); }
public async Task Publish_SatelliteAssemblies_AreCopiedToBuildOutput() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); project.AddProjectFileContent( @" <PropertyGroup> <DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants> </PropertyGroup> <ItemGroup> <ProjectReference Include=""..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"" /> </ItemGroup>"); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args : "/restore"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. var bootJsonPath = Path.Combine(blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileContains(result, bootJsonPath, "\"Microsoft.CodeAnalysis.CSharp.dll\""); Assert.FileContains(result, bootJsonPath, "\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); VerifyBootManifestHashes(result, blazorPublishDirectory); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); }
public async Task Build_WithLinker_IsIncremental() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; // Act var thumbPrint = FileThumbPrint.CreateFolderThumbprint(project, project.BuildOutputDirectory); // Assert for (var i = 0; i < 3; i++) { result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var newThumbPrint = FileThumbPrint.CreateFolderThumbprint(project, project.BuildOutputDirectory); Assert.Equal(thumbPrint.Count, newThumbPrint.Count); for (var j = 0; j < thumbPrint.Count; j++) { Assert.Equal(thumbPrint[j], newThumbPrint[j]); } } }
public async Task Publish_DeterministicAcrossBuilds_WhenNoSourcesChange() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args : "/bl:initial.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js"); Assert.BuildPassed(result); var publishOutputDirectory = project.PublishOutputDirectory; var serviceWorkerFile = Assert.FileExists(result, publishOutputDirectory, "wwwroot", "serviceworkers", "my-service-worker.js"); var version = File.ReadAllLines(serviceWorkerFile).Last(); var match = Regex.Match(version, "\\/\\* Manifest version: (.{8}) \\*\\/"); Assert.True(match.Success); Assert.Equal(2, match.Groups.Count); Assert.NotNull(match.Groups[1].Value); var capture = match.Groups[1].Value; // Act && Assert var updatedResult = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args : "/bl:updated.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js"); Assert.BuildPassed(result); var updatedVersion = File.ReadAllLines(serviceWorkerFile).Last(); var updatedMatch = Regex.Match(updatedVersion, "\\/\\* Manifest version: (.{8}) \\*\\/"); Assert.True(updatedMatch.Success); Assert.Equal(2, updatedMatch.Groups.Count); Assert.NotNull(updatedMatch.Groups[1].Value); var updatedCapture = updatedMatch.Groups[1].Value; Assert.Equal(capture, updatedCapture); }
// Regression test for https://github.com/dotnet/aspnetcore/issues/18752 public async Task Publish_HostedApp_WithLinkOnBuildFalse_Works() { // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; AddSiblingProjectFileContent(project, @" <PropertyGroup> <BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking> </PropertyGroup>"); // VS builds projects individually and then a publish with BuildDependencies=false, but building the main project is a close enough approximation for this test. var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build"); Assert.BuildPassed(result); // Publish result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:BuildDependencies=false"); var publishDirectory = project.PublishOutputDirectory; // Make sure the main project exists Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); // Verification for https://github.com/dotnet/aspnetcore/issues/19926. Verify binaries for projects // referenced by the Hosted project appear in the publish directory Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll"); Assert.FileExists(result, publishDirectory, "standalone.dll"); var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "RazorClassLibrary.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify static web assets from referenced projects are copied. Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); VerifyBootManifestHashes(result, blazorPublishDirectory); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); }
public async Task Publish_HostedApp_WithLinkOnBuildTrue_Works() { // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); AddSiblingProjectFileContent(project, @" <PropertyGroup> <BlazorWebAssemblyEnableLinking>true</BlazorWebAssemblyEnableLinking> </PropertyGroup>"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; // Make sure the main project exists Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll"); var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. // Verify project references appear as static web assets Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "RazorClassLibrary.dll"); // Also verify project references to the server project appear in the publish output Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll"); // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify static web assets from referenced projects are copied. Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); VerifyBootManifestHashes(result, blazorPublishDirectory); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); }
public async Task Build_SatelliteAssembliesFileIsPreserved() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); File.Move(Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"), Path.Combine(project.DirectoryPath, "Resource.ja.resx")); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var satelliteAssemblyCacheFile = Path.Combine(project.IntermediateOutputDirectory, "blazor", "blazor.satelliteasm.props"); var satelliteAssemblyFile = Path.Combine(project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "ja", "standalone.resources.dll"); var bootJson = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); // Assert for (var i = 0; i < 3; i++) { result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); Verify(); } // Assert - incremental builds with BuildingProject=false for (var i = 0; i < 3; i++) { result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/p:BuildingProject=false"); Assert.BuildPassed(result); Verify(); } void Verify() { Assert.FileExists(result, satelliteAssemblyCacheFile); Assert.FileExists(result, satelliteAssemblyFile); var bootJsonFile = JsonSerializer.Deserialize <GenerateBlazorBootJson.BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); var satelliteResources = bootJsonFile.resources.satelliteResources; var kvp = Assert.Single(satelliteResources); Assert.Equal("ja", kvp.Key); Assert.Equal("ja/standalone.resources.dll", Assert.Single(kvp.Value).Key); } }
public async Task Publish_WithDefaultSettings_Works() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new [] { "razorclasslibrary", "LinkBaseToWebRoot" }); project.Configuration = "Debug"; var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. // Verify referenced static web assets Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css"); // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify link item assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "js", "LinkedScript.js"); var cssFile = Assert.FileExists(result, blazorPublishDirectory, "css", "app.css"); Assert.FileContains(result, cssFile, ".publish"); Assert.FileDoesNotExist(result, "dist", "Fake-License.txt"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); Assert.FileCountEquals(result, 1, publishDirectory, "*", SearchOption.TopDirectoryOnly); VerifyBootManifestHashes(result, blazorPublishDirectory); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); // When publishing without linker, we expect to have collation information present in mscorlib.dll Assert.AssemblyContainsResource(result, Path.Combine(blazorPublishDirectory, "_framework", "_bin", "mscorlib.dll"), "collation.cjkCHS.bin"); }
public async Task Publish_WithNoBuild_Works() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build"); Assert.BuildPassed(result); result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:NoBuild=true"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify static web assets from referenced projects are copied. Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css"); // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); VerifyBootManifestHashes(result, blazorPublishDirectory); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); VerifyCompression(result, blazorPublishDirectory); }
public async Task Publish_HostedApp_VisualStudio() { // Simulates publishing the same way VS does by setting BuildProjectReferences=false. // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; project.Configuration = "Release"; var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build", "/p:BuildInsideVisualStudio=true"); Assert.BuildPassed(result); result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:BuildProjectReferences=false /p:BuildInsideVisualStudio=true"); var publishDirectory = project.PublishOutputDirectory; // Make sure the main project exists Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "wasm", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "standalone.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify static web assets from referenced projects are copied. Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); VerifyBootManifestHashes(result, blazorPublishDirectory); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); }
public async Task Build_SatelliteAssembliesFileIsDeleted_IfAllSatelliteFilesAreRemoved() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); File.Move(Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"), Path.Combine(project.DirectoryPath, "Resource.ja.resx")); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var satelliteAssemblyCacheFile = Path.Combine(project.IntermediateOutputDirectory, "blazor", "blazor.satelliteasm.props"); var satelliteAssemblyFile = Path.Combine(project.BuildOutputDirectory, "wwwroot", "_framework", "_bin", "ja", "standalone.resources.dll"); var bootJson = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); Assert.FileExists(result, satelliteAssemblyCacheFile); Assert.FileExists(result, satelliteAssemblyFile); var bootJsonFile = JsonSerializer.Deserialize <GenerateBlazorBootJson.BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); var satelliteResources = bootJsonFile.resources.satelliteResources; var kvp = Assert.Single(satelliteResources); Assert.Equal("ja", kvp.Key); Assert.Equal("ja/standalone.resources.dll", Assert.Single(kvp.Value).Key); File.Delete(Path.Combine(project.DirectoryPath, "Resource.ja.resx")); result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); Assert.FileDoesNotExist(result, satelliteAssemblyCacheFile); bootJsonFile = JsonSerializer.Deserialize <GenerateBlazorBootJson.BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); satelliteResources = bootJsonFile.resources.satelliteResources; Assert.Null(satelliteResources); }
public async Task Publish_WithExistingWebConfig_Works() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "LinkBaseToWebRoot" }); project.Configuration = "Release"; var webConfigContents = "test webconfig contents"; AddFileToProject(project, "web.config", webConfigContents); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); Assert.FileContains(result, Path.Combine(publishDirectory, "web.config"), webConfigContents); }
public async Task Publish_LinkerEnabledAndBlazorWebAssemblyPreserveCollationDataSet_CollationInformationIsPreserved() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Release"; project.AddProjectFileContent( @"<PropertyGroup> <BlazorWebAssemblyPreserveCollationData>false</BlazorWebAssemblyPreserveCollationData> </PropertyGroup>"); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); // When publishing with BlazorWebAssemblyPreserveCollationData=false, collation information should be stripped out. Assert.AssemblyDoesNotContainResource(result, Path.Combine(blazorPublishDirectory, "_framework", "_bin", "mscorlib.dll"), "collation.cjkCHS.bin"); }
public async Task Build_Hosted_Works() { // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; var path = Path.GetFullPath(Path.Combine(project.SolutionPath, "standalone", "bin", project.Configuration, "netstandard2.1", "standalone.dll")); Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "blazorhosted.StaticWebAssets.xml"); Assert.FileContains(result, staticWebAssets, Path.Combine("netstandard2.1", "wwwroot")); Assert.FileContains(result, staticWebAssets, Path.Combine("razorclasslibrary", "wwwroot")); Assert.FileContains(result, staticWebAssets, Path.Combine("standalone", "wwwroot")); }
public async Task Build_WithI8NOption_CopiesI8NAssembliesWithLinkerEnabled() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Debug"; project.AddProjectFileContent( @" <PropertyGroup> <BlazorWebAssemblyEnableLinking>true</BlazorWebAssemblyEnableLinking> <BlazorWebAssemblyI18NAssemblies>other</BlazorWebAssemblyI18NAssemblies> </PropertyGroup>"); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "I18N.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "I18N.Other.dll"); Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "I18N.West.dll"); }
public async Task Build_CompressesAllFrameworkFiles() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; var extensions = new[] { ".dll", ".js", ".pdb", ".wasm", ".map", ".json", ".dat" }; // Act var compressedFilesPath = Path.Combine( project.DirectoryPath, project.IntermediateOutputDirectory, "compressed", "_framework"); var compressedFiles = Directory.EnumerateFiles( compressedFilesPath, "*", SearchOption.AllDirectories) .Where(f => Path.GetExtension(f) == ".gz") .Select(f => Path.GetRelativePath(compressedFilesPath, f[0..^ 3]))
public async Task Build_WithCustomOutputPath_Works() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); project.AddDirectoryBuildContent( @"<PropertyGroup> <BaseOutputPath>$(MSBuildThisFileDirectory)build\bin\</BaseOutputPath> <BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)build\obj\</BaseIntermediateOutputPath> </PropertyGroup>"); var result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/restore"); Assert.BuildPassed(result); var compressedFilesPath = Path.Combine( project.DirectoryPath, "build", project.IntermediateOutputDirectory, "compressed"); Assert.True(Directory.Exists(compressedFilesPath)); }
public async Task Build_ServiceWorkerAssetsManifest_Works() { // Arrange var expectedExtensions = new[] { ".dll", ".pdb", ".js", ".wasm" }; using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/p:ServiceWorkerAssetsManifest=service-worker-assets.js"); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm"); Assert.FileCountEquals(result, 1, Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "wasm"), "dotnet.*.js"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "standalone.StaticWebAssets.xml"); Assert.FileContains(result, staticWebAssets, Path.Combine("netstandard2.1", "wwwroot")); var serviceWorkerAssetsManifest = Assert.FileExists(result, buildOutputDirectory, "wwwroot", "service-worker-assets.js"); // Trim prefix 'self.assetsManifest = ' and suffix ';' var manifestContents = File.ReadAllText(serviceWorkerAssetsManifest).TrimEnd()[22..^ 1]; var manifestContentsJson = JsonDocument.Parse(manifestContents); Assert.True(manifestContentsJson.RootElement.TryGetProperty("assets", out var assets)); Assert.Equal(JsonValueKind.Array, assets.ValueKind); var entries = assets.EnumerateArray().Select(e => e.GetProperty("url").GetString()).OrderBy(e => e).ToArray(); Assert.All(entries, e => expectedExtensions.Contains(Path.GetExtension(e))); }
public async Task Publish_LazyLoadExplicitAssembly_Debug_Works() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Debug"; project.AddProjectFileContent( @" <ItemGroup> <BlazorWebAssemblyLazyLoad Include='RazorClassLibrary.dll' /> </ItemGroup> "); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); var publishDirectory = project.PublishOutputDirectory; // Verify that a blazor.boot.json file has been created Assert.FileExists(result, publishDirectory, "wwwroot", "_framework", "blazor.boot.json"); // And that the assembly is in the output Assert.FileExists(result, publishDirectory, "wwwroot", "_framework", "_bin", "RazorClassLibrary.dll"); var bootJson = ReadBootJsonData(result, Path.Combine(publishDirectory, "wwwroot", "_framework", "blazor.boot.json")); // And that it has been labelled as a dynamic assembly in the boot.json var dynamicAssemblies = bootJson.resources.dynamicAssembly; var assemblies = bootJson.resources.assembly; Assert.NotNull(dynamicAssemblies); Assert.Contains("RazorClassLibrary.dll", dynamicAssemblies.Keys); Assert.DoesNotContain("RazorClassLibrary.dll", assemblies.Keys); // App assembly should not be lazy loaded Assert.DoesNotContain("standalone.dll", dynamicAssemblies.Keys); Assert.Contains("standalone.dll", assemblies.Keys); }
public async Task Build_WithLinkOnBuildDisabled_Works() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); project.AddProjectFileContent( @"<PropertyGroup> <BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking> </PropertyGroup>"); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", DotNetJsFileName); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.timezones.dat"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "standalone.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. }
public async Task Publish_HostedApp_VisualStudio_WithSatelliteAssemblies() { // Simulates publishing the same way VS does by setting BuildProjectReferences=false. // Arrange var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); project.TargetFramework = TestFacts.DefaultNetCoreTargetFramework; project.Configuration = "Release"; var standaloneProjectDirectory = Path.Combine(project.DirectoryPath, "..", "standalone"); // Setup the standalone app to have it's own satellite assemblies as well as transitively imported satellite assemblies. var resxfileInProject = Path.Combine(standaloneProjectDirectory, "Resources.ja.resx.txt"); File.Move(resxfileInProject, Path.Combine(standaloneProjectDirectory, "Resource.ja.resx")); var standaloneProjFile = Path.Combine(standaloneProjectDirectory, "standalone.csproj"); var existing = File.ReadAllText(standaloneProjFile); var updatedContent = @" <PropertyGroup> <DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants> </PropertyGroup> <ItemGroup> <ProjectReference Include=""..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"" /> </ItemGroup>"; var updated = existing.Replace("<!-- Test Placeholder -->", updatedContent); File.WriteAllText(standaloneProjFile, updated); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build", $"/restore"); Assert.BuildPassed(result); result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:BuildProjectReferences=false"); var publishDirectory = project.PublishOutputDirectory; // Make sure the main project exists Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "ja", "standalone.resources.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.resources.dll"); var bootJson = Path.Combine(project.DirectoryPath, blazorPublishDirectory, "_framework", "blazor.boot.json"); var bootJsonFile = JsonSerializer.Deserialize <GenerateBlazorBootJson.BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); var satelliteResources = bootJsonFile.resources.satelliteResources; Assert.Contains("es-ES", satelliteResources.Keys); Assert.Contains("es-ES/classlibrarywithsatelliteassemblies.resources.dll", satelliteResources["es-ES"].Keys); Assert.Contains("fr", satelliteResources.Keys); Assert.Contains("fr/Microsoft.CodeAnalysis.CSharp.resources.dll", satelliteResources["fr"].Keys); Assert.Contains("ja", satelliteResources.Keys); Assert.Contains("ja/standalone.resources.dll", satelliteResources["ja"].Keys); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); }