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 Publish_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, "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 static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify referenced static web assets Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, blazorPublishDirectory, "_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_WithLinkerAndCompression_UpdatesFilesWhenSourcesChange() { // Arrange using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); 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 blazorBootJson = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); var blazorBootJsonThumbPrint = FileThumbPrint.Create(blazorBootJson); var blazorBootJsonCompressed = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json.gz"); var blazorBootJsonCompressedThumbPrint = FileThumbPrint.Create(blazorBootJsonCompressed); // Act var programFile = Path.Combine(project.DirectoryPath, "Program.cs"); var programFileContents = File.ReadAllText(programFile); File.WriteAllText(programFile, programFileContents.Replace("args", "arguments")); result = await MSBuildProcessManager.DotnetMSBuild(project); // Assert Assert.BuildPassed(result); var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); var newBlazorBootJsonThumbPrint = FileThumbPrint.Create(blazorBootJson); var newBlazorBootJsonCompressedThumbPrint = FileThumbPrint.Create(blazorBootJsonCompressed); Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint); Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint); Assert.NotEqual(blazorBootJsonThumbPrint, newBlazorBootJsonThumbPrint); Assert.NotEqual(blazorBootJsonCompressedThumbPrint, newBlazorBootJsonCompressedThumbPrint); }
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_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_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_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_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 static Task <MSBuildResult> DotnetMSBuild( ProjectDirectory project, string target = "Build", string args = null) { var buildArgumentList = new List <string> { // Disable node-reuse. We don't want msbuild processes to stick around // once the test is completed. "/nr:false", // Always generate a bin log for debugging purposes "/bl", }; buildArgumentList.Add($"/t:{target}"); buildArgumentList.Add($"/p:Configuration={project.Configuration}"); buildArgumentList.Add($"/p:BlazorBuildConfiguration={ProjectDirectory.TestProjectConfiguration}"); buildArgumentList.Add(args); var buildArguments = string.Join(" ", buildArgumentList); return(MSBuildProcessManager.RunProcessAsync(project, buildArguments)); }
private static void AddFileToProject(ProjectDirectory project, string filename, string content) { var path = Path.Combine(project.DirectoryPath, filename); File.WriteAllText(path, content); }
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"); }