diff --git a/.azure/pipelines/ci.yml b/.azure/pipelines/ci.yml index db4461e991..87d067bb56 100644 --- a/.azure/pipelines/ci.yml +++ b/.azure/pipelines/ci.yml @@ -7,9 +7,9 @@ trigger: batch: true branches: include: - - blazor-wasm - master - release/* + - internal/release/3.* # Run PR validation on all branches pr: @@ -80,18 +80,11 @@ variables: value: test - name: _PublishArgs value: '' -<<<<<<< HEAD -======= - # used for post-build phases, internal builds only - - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - - group: DotNet-AspNet-SDLValidation-Params ->>>>>>> bbafecc0535e1de3264845e51ea8b3d18eb3ca61 stages: - stage: build displayName: Build jobs: -<<<<<<< HEAD # Code check - ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: - template: jobs/default-build.yml @@ -116,8 +109,6 @@ stages: publishOnError: true includeForks: true -======= ->>>>>>> bbafecc0535e1de3264845e51ea8b3d18eb3ca61 # Build Windows (x64/x86) - template: jobs/default-build.yml parameters: @@ -151,13 +142,12 @@ stages: -arch x64 -pack -all - -NoBuildNative + -buildNative /bl:artifacts/log/build.x64.binlog $(_BuildArgs) $(_InternalRuntimeDownloadArgs) displayName: Build x64 -<<<<<<< HEAD # Build the x86 shared framework # TODO: make it possible to build for one Windows architecture at a time # This is going to actually build x86 native assets. See https://github.com/aspnet/AspNetCore/issues/7196 @@ -183,8 +173,6 @@ stages: $(_InternalRuntimeDownloadArgs) displayName: Build SiteExtension -======= ->>>>>>> bbafecc0535e1de3264845e51ea8b3d18eb3ca61 # This runs code-signing on all packages, zips, and jar files as defined in build/CodeSign.targets. If https://github.com/dotnet/arcade/issues/1957 is resolved, # consider running code-signing inline with the other previous steps. # Sign check is disabled because it is run in a separate step below, after installers are built. @@ -212,6 +200,16 @@ stages: /p:PublishInstallerBaseVersion=true displayName: Build Installers + # A few files must also go to the VS package feed. + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: NuGetCommand@2 + displayName: Push Visual Studio packages + inputs: + command: push + packagesToPush: 'artifacts/packages/**/VS.Redist.Common.AspNetCore.*.nupkg' + nuGetFeedType: external + publishFeedCredentials: 'DevDiv - VS package feed' + artifacts: - name: Windows_Logs path: artifacts/log/ @@ -220,7 +218,6 @@ stages: - name: Windows_Packages path: artifacts/packages/ -<<<<<<< HEAD # Build Windows ARM - template: jobs/default-build.yml parameters: @@ -515,8 +512,6 @@ stages: parameters: inputName: Linux_musl_arm64 -======= ->>>>>>> bbafecc0535e1de3264845e51ea8b3d18eb3ca61 # Test jobs - template: jobs/default-build.yml parameters: @@ -661,7 +656,6 @@ stages: publishOnError: true includeForks: true -<<<<<<< HEAD # Source build - job: Source_Build displayName: 'Test: Linux Source Build' @@ -720,17 +714,23 @@ stages: artifactType: Container parallel: true -======= ->>>>>>> bbafecc0535e1de3264845e51ea8b3d18eb3ca61 # Publish to the BAR - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - template: /eng/common/templates/job/publish-build-assets.yml parameters: dependsOn: - Windows_build + - Windows_arm_build + - CodeSign_Xplat_MacOS_x64 + - CodeSign_Xplat_Linux_x64 + - CodeSign_Xplat_Linux_arm + - CodeSign_Xplat_Linux_arm64 + - CodeSign_Xplat_Linux_musl_x64 + - CodeSign_Xplat_Linux_musl_arm64 # In addition to the dependencies above, ensure the build was successful overall. - Linux_Test - MacOS_Test + - Source_Build - Windows_Templates_Test - Windows_Test pool: diff --git a/NuGet.config b/NuGet.config index b632b50bdf..699d9e10b1 100644 --- a/NuGet.config +++ b/NuGet.config @@ -3,32 +3,20 @@ -<<<<<<< HEAD + + -======= - - - - - - - - - - - + + + - - - ->>>>>>> bbafecc0535e1de3264845e51ea8b3d18eb3ca61 diff --git a/eng/Baseline.Designer.props b/eng/Baseline.Designer.props index 78f2952da7..00294a106f 100644 --- a/eng/Baseline.Designer.props +++ b/eng/Baseline.Designer.props @@ -18,6 +18,13 @@ 3.1.4 + + + 3.2.0 + + + + 3.1.4 @@ -240,6 +247,48 @@ + + + 3.2.0 + + + + + + + + + + 3.2.0 + + + + + + + 3.2.0 + + + + + 3.2.0 + + + + + + + + 3.2.0 + + + + + 3.2.0 + + + + 3.1.4 diff --git a/eng/Baseline.xml b/eng/Baseline.xml index a768d1d764..ee094c82d5 100644 --- a/eng/Baseline.xml +++ b/eng/Baseline.xml @@ -8,6 +8,7 @@ Update this list when preparing for a new patch. + @@ -36,6 +37,12 @@ Update this list when preparing for a new patch. + + + + + + diff --git a/eng/Build.props b/eng/Build.props index 6ba4d0eda6..95b9636667 100644 --- a/eng/Build.props +++ b/eng/Build.props @@ -34,8 +34,8 @@ $(RepoRoot)src\Installers\**\*.*proj; $(RepoRoot)src\SignalR\clients\ts\**\node_modules\**\*.*proj; $(RepoRoot)src\Components\Web.JS\node_modules\**\*.*proj; - $(RepoRoot)src\Components\Blazor\Build\testassets\**\*.*proj; - $(RepoRoot)src\ProjectTemplates\BlazorWasm.ProjectTemplates\content\**\*.csproj; + $(RepoRoot)src\Components\WebAssembly\Build\testassets\**\*.csproj; + $(RepoRoot)src\ProjectTemplates\ComponentsWebAssembly.ProjectTemplates\content\**\*.csproj; $(RepoRoot)src\ProjectTemplates\Web.ProjectTemplates\content\**\*.csproj; $(RepoRoot)src\ProjectTemplates\Web.ProjectTemplates\content\**\*.fsproj; $(RepoRoot)src\ProjectTemplates\Web.Spa.ProjectTemplates\content\**\*.csproj; @@ -50,11 +50,6 @@ " /> - - - $(RepoRoot)src\Components\**\*.csproj;$(RepoRoot)src\ProjectTemplates\**\*.csproj - - diff --git a/eng/Dependencies.props b/eng/Dependencies.props index 73ffdde39f..22235e50c4 100644 --- a/eng/Dependencies.props +++ b/eng/Dependencies.props @@ -92,6 +92,7 @@ and are generated based on the last package release. + @@ -122,7 +123,7 @@ and are generated based on the last package release. - + diff --git a/eng/ProjectReferences.props b/eng/ProjectReferences.props index dedf038e0b..c0ecfb2b07 100644 --- a/eng/ProjectReferences.props +++ b/eng/ProjectReferences.props @@ -55,12 +55,14 @@ - - - - - + + + + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 037cb728dc..580e6b3b36 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -9,9 +9,13 @@ --> - - https://github.com/aspnet/Blazor - 7868699de745fd30a654c798a99dc541b77b95c0 + + https://github.com/dotnet/blazor + cc449601d638ffaab58ae9487f0fd010bb178a12 + + + https://github.com/dotnet/corefx + 66409e392d64ed96e5d3a5fda712d9baf51196ed https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore-tooling diff --git a/eng/Versions.props b/eng/Versions.props index c43b1c1855..07f4eaf7ba 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,6 +10,11 @@ 1 5 0 + + 3 + 2 + 1 + @@ -19,9 +24,6 @@ false servicing Servicing - - 4 - preview$(BlazorClientPreReleasePreviewNumber) $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion) 3.1.0 @@ -30,6 +32,7 @@ true $(AspNetCoreMajorVersion).$(AspNetCoreMinorVersion).$(AspNetCorePatchVersion) + $(ComponentsWebAssemblyMajorVersion).$(ComponentsWebAssemblyMinorVersion).$(ComponentsWebAssemblyPatchVersion) $(VersionPrefix) @@ -92,12 +95,13 @@ 4.7.0 4.7.1 4.7.2 + 3.2.0 4.7.1 4.7.0 3.1.1 - 3.1.0-preview4.19605.1 + 3.2.0 3.1.4-servicing.20221.11 3.1.4-servicing.20221.11 diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 29d76cd3be..92a053bd16 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -257,7 +257,7 @@ function InitializeVisualStudioMSBuild([bool]$install, [object]$vsRequirements = if ($msbuildCmd -ne $null) { # Workaround for https://github.com/dotnet/roslyn/issues/35793 # Due to this issue $msbuildCmd.Version returns 0.0.0.0 for msbuild.exe 16.2+ - $msbuildVersion = [Version]::new((Get-Item $msbuildCmd.Path).VersionInfo.ProductVersion.Split([char[]]@('-', '+'))[0]) + $msbuildVersion = [Version]::new((Get-Item $msbuildCmd.Path).VersionInfo.ProductVersion.Split(@('-', '+'))[0]) if ($msbuildVersion -ge $vsMinVersion) { return $global:_MSBuildExe = $msbuildCmd.Path diff --git a/eng/scripts/CodeCheck.ps1 b/eng/scripts/CodeCheck.ps1 index a7baf079c8..072f55fe21 100644 --- a/eng/scripts/CodeCheck.ps1 +++ b/eng/scripts/CodeCheck.ps1 @@ -170,11 +170,10 @@ try { & $PSScriptRoot\GenerateReferenceAssemblies.ps1 -ci:$ci } - # Temporarily disable package baseline generation while we stage for publishing - # Write-Host "Re-generating package baselines" - # Invoke-Block { - # & dotnet run -p "$repoRoot/eng/tools/BaselineGenerator/" - # } + Write-Host "Re-generating package baselines" + Invoke-Block { + & dotnet run -p "$repoRoot/eng/tools/BaselineGenerator/" + } Write-Host "Run git diff to check for pending changes" diff --git a/global.json b/global.json index e0882dd64d..974708a611 100644 --- a/global.json +++ b/global.json @@ -1,16 +1,9 @@ { "sdk": { -<<<<<<< HEAD "version": "3.1.103" }, "tools": { "dotnet": "3.1.103", -======= - "version": "3.1.100" - }, - "tools": { - "dotnet": "3.1.100", ->>>>>>> bbafecc0535e1de3264845e51ea8b3d18eb3ca61 "runtimes": { "dotnet/x64": [ "$(MicrosoftNETCoreAppInternalPackageVersion)" @@ -32,12 +25,7 @@ }, "msbuild-sdks": { "Yarn.MSBuild": "1.15.2", -<<<<<<< HEAD "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.20213.4", "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.20213.4" -======= - "Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19577.5", - "Microsoft.DotNet.Helix.Sdk": "2.0.0-beta.19577.5" ->>>>>>> bbafecc0535e1de3264845e51ea8b3d18eb3ca61 } } diff --git a/src/Components/Blazor/Blazor.Version.props b/src/Components/Blazor/Blazor.Version.props deleted file mode 100644 index 123a94c1d7..0000000000 --- a/src/Components/Blazor/Blazor.Version.props +++ /dev/null @@ -1,8 +0,0 @@ - - - - 3.2.0 - preview1 - - - \ No newline at end of file diff --git a/src/Components/Blazor/Blazor/ref/Microsoft.AspNetCore.Blazor.netstandard2.1.cs b/src/Components/Blazor/Blazor/ref/Microsoft.AspNetCore.Blazor.netstandard2.1.cs deleted file mode 100644 index eb33362975..0000000000 --- a/src/Components/Blazor/Blazor/ref/Microsoft.AspNetCore.Blazor.netstandard2.1.cs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Blazor -{ - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] - public static partial class JSInteropMethods - { - [Microsoft.JSInterop.JSInvokableAttribute("NotifyLocationChanged")] - public static void NotifyLocationChanged(string uri, bool isInterceptedLink) { } - } -} -namespace Microsoft.AspNetCore.Blazor.Hosting -{ - [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public readonly partial struct RootComponentMapping - { - private readonly object _dummy; - public RootComponentMapping(System.Type componentType, string selector) { throw null; } - public System.Type ComponentType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public string Selector { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - } - public partial class RootComponentMappingCollection : System.Collections.ObjectModel.Collection - { - public RootComponentMappingCollection() { } - public void Add(System.Type componentType, string selector) { } - public void AddRange(System.Collections.Generic.IEnumerable items) { } - public void Add(string selector) where TComponent : Microsoft.AspNetCore.Components.IComponent { } - } - public sealed partial class WebAssemblyHost : System.IAsyncDisposable - { - internal WebAssemblyHost() { } - public Microsoft.Extensions.Configuration.IConfiguration Configuration { get { throw null; } } - public System.IServiceProvider Services { get { throw null; } } - [System.Diagnostics.DebuggerStepThroughAttribute] - public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } - public System.Threading.Tasks.Task RunAsync() { throw null; } - } - public sealed partial class WebAssemblyHostBuilder - { - internal WebAssemblyHostBuilder() { } - public Microsoft.Extensions.Configuration.IConfigurationBuilder Configuration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Blazor.Hosting.RootComponentMappingCollection RootComponents { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.Extensions.DependencyInjection.IServiceCollection Services { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } - public Microsoft.AspNetCore.Blazor.Hosting.WebAssemblyHost Build() { throw null; } - public static Microsoft.AspNetCore.Blazor.Hosting.WebAssemblyHostBuilder CreateDefault(string[] args = null) { throw null; } - } -} -namespace Microsoft.AspNetCore.Blazor.Http -{ - public enum FetchCredentialsOption - { - Omit = 0, - SameOrigin = 1, - Include = 2, - } - public static partial class WebAssemblyHttpMessageHandlerOptions - { - public static Microsoft.AspNetCore.Blazor.Http.FetchCredentialsOption DefaultCredentials { get { throw null; } set { } } - } -} -namespace Microsoft.AspNetCore.Blazor.Rendering -{ - public static partial class WebAssemblyEventDispatcher - { - [Microsoft.JSInterop.JSInvokableAttribute("DispatchEvent")] - public static System.Threading.Tasks.Task DispatchEvent(Microsoft.AspNetCore.Components.RenderTree.WebEventDescriptor eventDescriptor, string eventArgsJson) { throw null; } - } -} diff --git a/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyHostBuilder.cs b/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyHostBuilder.cs deleted file mode 100644 index 1d1f05dce7..0000000000 --- a/src/Components/Blazor/Blazor/src/Hosting/WebAssemblyHostBuilder.cs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using Microsoft.AspNetCore.Blazor.Services; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Routing; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Logging; -using Microsoft.JSInterop; - -namespace Microsoft.AspNetCore.Blazor.Hosting -{ - /// - /// A builder for configuring and creating a . - /// - public sealed class WebAssemblyHostBuilder - { - /// - /// Creates an instance of using the most common - /// conventions and settings. - /// - /// The argument passed to the application's main method. - /// A . - public static WebAssemblyHostBuilder CreateDefault(string[] args = default) - { - // We don't use the args for anything right now, but we want to accept them - // here so that it shows up this way in the project templates. - args ??= Array.Empty(); - var builder = new WebAssemblyHostBuilder(); - - // Right now we don't have conventions or behaviors that are specific to this method - // however, making this the default for the template allows us to add things like that - // in the future, while giving `new WebAssemblyHostBuilder` as an opt-out of opinionated - // settings. - return builder; - } - - /// - /// Creates an instance of with the minimal configuration. - /// - private WebAssemblyHostBuilder() - { - // Private right now because we don't have much reason to expose it. This can be exposed - // in the future if we want to give people a choice between CreateDefault and something - // less opinionated. - Configuration = new ConfigurationBuilder(); - RootComponents = new RootComponentMappingCollection(); - Services = new ServiceCollection(); - - InitializeDefaultServices(); - } - - /// - /// Gets an that can be used to customize the application's - /// configuration sources. - /// - public IConfigurationBuilder Configuration { get; } - - /// - /// Gets the collection of root component mappings configured for the application. - /// - public RootComponentMappingCollection RootComponents { get; } - - /// - /// Gets the service collection. - /// - public IServiceCollection Services { get; } - - /// - /// Builds a instance based on the configuration of this builder. - /// - /// A object. - public WebAssemblyHost Build() - { - // Intentionally overwrite configuration with the one we're creating. - var configuration = Configuration.Build(); - Services.AddSingleton(configuration); - - // A Blazor application always runs in a scope. Since we want to make it possible for the user - // to configure services inside *that scope* inside their startup code, we create *both* the - // service provider and the scope here. - var services = Services.BuildServiceProvider(); - var scope = services.GetRequiredService().CreateScope(); - - return new WebAssemblyHost(services, scope, configuration, RootComponents.ToArray()); - } - - private void InitializeDefaultServices() - { - Services.AddSingleton(WebAssemblyJSRuntime.Instance); - Services.AddSingleton(WebAssemblyNavigationManager.Instance); - Services.AddSingleton(WebAssemblyNavigationInterception.Instance); - Services.AddSingleton(); - Services.TryAdd(ServiceDescriptor.Singleton(typeof(ILogger<>), typeof(WebAssemblyConsoleLogger<>))); - Services.AddSingleton(s => - { - // Creating the URI helper needs to wait until the JS Runtime is initialized, so defer it. - var navigationManager = s.GetRequiredService(); - return new HttpClient - { - BaseAddress = new Uri(navigationManager.BaseUri) - }; - }); - } - } -} diff --git a/src/Components/Blazor/Blazor/src/Http/WebAssemblyHttpMessageHandlerOptions.cs b/src/Components/Blazor/Blazor/src/Http/WebAssemblyHttpMessageHandlerOptions.cs deleted file mode 100644 index bc46e4e527..0000000000 --- a/src/Components/Blazor/Blazor/src/Http/WebAssemblyHttpMessageHandlerOptions.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Reflection; - -namespace Microsoft.AspNetCore.Blazor.Http -{ - /// - /// Configures options for the WebAssembly HTTP message handler. - /// - public static class WebAssemblyHttpMessageHandlerOptions - { - /// - /// Gets or sets the default value of the 'credentials' option on outbound HTTP requests. - /// Defaults to . - /// - public static FetchCredentialsOption DefaultCredentials - { - get - { - var valueString = MonoDefaultCredentialsGetter.Value(); - var result = default(FetchCredentialsOption); - if (valueString != null) - { - Enum.TryParse(valueString, out result); - } - return result; - } - - set - { - MonoDefaultCredentialsSetter.Value(value.ToString()); - } - } - - static Func MonoWasmHttpMessageHandlerType = () - => Assembly.Load("WebAssembly.Net.Http") - .GetType("WebAssembly.Net.Http.HttpClient.WasmHttpMessageHandler"); - - static Func MonoFetchCredentialsOptionType = () - => Assembly.Load("WebAssembly.Net.Http") - .GetType("WebAssembly.Net.Http.HttpClient.FetchCredentialsOption"); - - static Lazy MonoDefaultCredentialsProperty = new Lazy( - () => MonoWasmHttpMessageHandlerType()?.GetProperty("DefaultCredentials", BindingFlags.Public | BindingFlags.Static)); - - static Lazy> MonoDefaultCredentialsGetter = new Lazy>(() => - { - return () => MonoDefaultCredentialsProperty.Value?.GetValue(null).ToString(); - }); - - static Lazy> MonoDefaultCredentialsSetter = new Lazy>(() => - { - var fetchCredentialsOptionsType = MonoFetchCredentialsOptionType(); - return value => MonoDefaultCredentialsProperty.Value?.SetValue(null, Enum.Parse(fetchCredentialsOptionsType, value)); - }); - } -} diff --git a/src/Components/Blazor/Blazor/src/JSInteropMethods.cs b/src/Components/Blazor/Blazor/src/JSInteropMethods.cs deleted file mode 100644 index 239dbb4952..0000000000 --- a/src/Components/Blazor/Blazor/src/JSInteropMethods.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.ComponentModel; -using Microsoft.AspNetCore.Blazor.Services; -using Microsoft.JSInterop; - -namespace Microsoft.AspNetCore.Blazor -{ - /// - /// Contains methods called by interop. Intended for framework use only, not supported for use in application - /// code. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public static class JSInteropMethods - { - /// - /// For framework use only. - /// - [JSInvokable(nameof(NotifyLocationChanged))] - public static void NotifyLocationChanged(string uri, bool isInterceptedLink) - { - WebAssemblyNavigationManager.Instance.SetLocation(uri, isInterceptedLink); - } - } -} diff --git a/src/Components/Blazor/Blazor/src/Microsoft.AspNetCore.Blazor.csproj b/src/Components/Blazor/Blazor/src/Microsoft.AspNetCore.Blazor.csproj deleted file mode 100644 index 3a4e98a8b7..0000000000 --- a/src/Components/Blazor/Blazor/src/Microsoft.AspNetCore.Blazor.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - netstandard2.1 - Build client-side single-page applications (SPAs) with Blazor running under WebAssembly. - false - - - - - - - - - - - - - - - - - diff --git a/src/Components/Blazor/Blazor/src/Services/WebAssemblyConsoleLogger.cs b/src/Components/Blazor/Blazor/src/Services/WebAssemblyConsoleLogger.cs deleted file mode 100644 index c86c1cf30b..0000000000 --- a/src/Components/Blazor/Blazor/src/Services/WebAssemblyConsoleLogger.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.Extensions.Logging; - -namespace Microsoft.AspNetCore.Blazor.Services -{ - internal class WebAssemblyConsoleLogger : ILogger, ILogger - { - public IDisposable BeginScope(TState state) - { - return NoOpDisposable.Instance; - } - - public bool IsEnabled(LogLevel logLevel) - { - return logLevel >= LogLevel.Warning; - } - - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) - { - var formattedMessage = formatter(state, exception); - Console.WriteLine($"[{logLevel}] {formattedMessage}"); - } - - private class NoOpDisposable : IDisposable - { - public static NoOpDisposable Instance = new NoOpDisposable(); - - public void Dispose() { } - } - } -} diff --git a/src/Components/Blazor/Blazor/src/Services/WebAssemblyJSRuntime.cs b/src/Components/Blazor/Blazor/src/Services/WebAssemblyJSRuntime.cs deleted file mode 100644 index c5404c256f..0000000000 --- a/src/Components/Blazor/Blazor/src/Services/WebAssemblyJSRuntime.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNetCore.Components; -using Mono.WebAssembly.Interop; - -namespace Microsoft.AspNetCore.Blazor.Services -{ - internal sealed class WebAssemblyJSRuntime : MonoWebAssemblyJSRuntime - { - private static readonly WebAssemblyJSRuntime _instance = new WebAssemblyJSRuntime(); - private static bool _initialized; - - public WebAssemblyJSRuntime() - { - JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter()); - } - - public static WebAssemblyJSRuntime Instance - { - get - { - if (!_initialized) - { - // This is executing in MonoWASM. Consequently we do not to have concern ourselves with thread safety. - _initialized = true; - Initialize(_instance); - } - - return _instance; - } - } - } -} diff --git a/src/Components/Blazor/Blazor/src/Services/WebAssemblyLoggerFactory.cs b/src/Components/Blazor/Blazor/src/Services/WebAssemblyLoggerFactory.cs deleted file mode 100644 index 73458387e7..0000000000 --- a/src/Components/Blazor/Blazor/src/Services/WebAssemblyLoggerFactory.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.Extensions.Logging; - -namespace Microsoft.AspNetCore.Blazor.Services -{ - internal class WebAssemblyLoggerFactory : ILoggerFactory - { - public void AddProvider(ILoggerProvider provider) - { - // No-op - } - - public ILogger CreateLogger(string categoryName) - => new WebAssemblyConsoleLogger(); - - public void Dispose() - { - // No-op - } - } -} diff --git a/src/Components/Blazor/Blazor/test/Hosting/WebAssemblyHostBuilderTest.cs b/src/Components/Blazor/Blazor/test/Hosting/WebAssemblyHostBuilderTest.cs deleted file mode 100644 index 77b6583d26..0000000000 --- a/src/Components/Blazor/Blazor/test/Hosting/WebAssemblyHostBuilderTest.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Text; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Routing; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.JSInterop; -using Xunit; - -namespace Microsoft.AspNetCore.Blazor.Hosting -{ - public class WebAssemblyHostBuilderTest - { - [Fact] - public void Build_AllowsConfiguringConfiguration() - { - // Arrange - var builder = WebAssemblyHostBuilder.CreateDefault(); - - builder.Configuration.AddInMemoryCollection(new[] - { - new KeyValuePair("key", "value"), - }); - - // Act - var host = builder.Build(); - - // Assert - Assert.Equal("value", host.Configuration["key"]); - } - - [Fact] - public void Build_AllowsConfiguringServices() - { - // Arrange - var builder = WebAssemblyHostBuilder.CreateDefault(); - - // This test also verifies that we create a scope. - builder.Services.AddScoped(); - - // Act - var host = builder.Build(); - - // Assert - Assert.NotNull(host.Services.GetRequiredService()); - } - - [Fact] - public void Build_AddsConfigurationToServices() - { - // Arrange - var builder = WebAssemblyHostBuilder.CreateDefault(); - - builder.Configuration.AddInMemoryCollection(new[] - { - new KeyValuePair("key", "value"), - }); - - // Act - var host = builder.Build(); - - // Assert - var configuration = host.Services.GetRequiredService(); - Assert.Equal("value", configuration["key"]); - } - - private static IReadOnlyList DefaultServiceTypes - { - get - { - return new Type[] - { - typeof(IJSRuntime), - typeof(NavigationManager), - typeof(INavigationInterception), - typeof(ILoggerFactory), - typeof(HttpClient), - typeof(ILogger<>), - }; - } - } - - [Fact] - public void Constructor_AddsDefaultServices() - { - // Arrange & Act - var builder = WebAssemblyHostBuilder.CreateDefault(); - - // Assert - Assert.Equal(DefaultServiceTypes.Count, builder.Services.Count); - foreach (var type in DefaultServiceTypes) - { - Assert.Single(builder.Services, d => d.ServiceType == type); - } - } - } -} diff --git a/src/Components/Blazor/Blazor/test/Microsoft.AspNetCore.Blazor.Tests.csproj b/src/Components/Blazor/Blazor/test/Microsoft.AspNetCore.Blazor.Tests.csproj deleted file mode 100644 index 40c5a5b702..0000000000 --- a/src/Components/Blazor/Blazor/test/Microsoft.AspNetCore.Blazor.Tests.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - - false - - - - - - - - - - - diff --git a/src/Components/Blazor/Build/src/Properties/AssemblyInfo.cs b/src/Components/Blazor/Build/src/Properties/AssemblyInfo.cs deleted file mode 100644 index aac42c25cc..0000000000 --- a/src/Components/Blazor/Build/src/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,3 +0,0 @@ -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Blazor.Build.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] diff --git a/src/Components/Blazor/Build/src/Tasks/GenerateBlazorBootJson.cs b/src/Components/Blazor/Build/src/Tasks/GenerateBlazorBootJson.cs deleted file mode 100644 index 1984de0a57..0000000000 --- a/src/Components/Blazor/Build/src/Tasks/GenerateBlazorBootJson.cs +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.Serialization.Json; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; - -namespace Microsoft.AspNetCore.Blazor.Build -{ - public class GenerateBlazorBootJson : Task - { - [Required] - public string AssemblyPath { get; set; } - - [Required] - public ITaskItem[] References { get; set; } - - [Required] - public bool LinkerEnabled { get; set; } - - [Required] - public string OutputPath { get; set; } - - public override bool Execute() - { - var entryAssemblyName = AssemblyName.GetAssemblyName(AssemblyPath).Name; - var assemblies = References.Select(GetUriPath).OrderBy(c => c, StringComparer.Ordinal).ToArray(); - - using var fileStream = File.Create(OutputPath); - WriteBootJson(fileStream, entryAssemblyName, assemblies, LinkerEnabled); - - return true; - - static string GetUriPath(ITaskItem item) - { - var outputPath = item.GetMetadata("RelativeOutputPath"); - if (string.IsNullOrEmpty(outputPath)) - { - outputPath = Path.GetFileName(item.ItemSpec); - } - - return outputPath.Replace('\\', '/'); - } - } - - internal static void WriteBootJson(Stream stream, string entryAssemblyName, string[] assemblies, bool linkerEnabled) - { - var data = new BootJsonData - { - entryAssembly = entryAssemblyName, - assemblies = assemblies, - linkerEnabled = linkerEnabled, - }; - - var serializer = new DataContractJsonSerializer(typeof(BootJsonData)); - serializer.WriteObject(stream, data); - } - - /// - /// Defines the structure of a Blazor boot JSON file - /// -#pragma warning disable IDE1006 // Naming Styles - public class BootJsonData - { - /// - /// Gets the name of the assembly with the application entry point - /// - public string entryAssembly { get; set; } - - /// - /// Gets the closure of assemblies to be loaded by Blazor WASM. This includes the application entry assembly. - /// - public string[] assemblies { get; set; } - - /// - /// Gets a value that determines if the linker is enabled. - /// - public bool linkerEnabled { get; set; } - } -#pragma warning restore IDE1006 // Naming Styles - } -} diff --git a/src/Components/Blazor/Build/src/build/netstandard1.0/Microsoft.AspNetCore.Blazor.Build.props b/src/Components/Blazor/Build/src/build/netstandard1.0/Microsoft.AspNetCore.Blazor.Build.props deleted file mode 100644 index f20d90334c..0000000000 --- a/src/Components/Blazor/Build/src/build/netstandard1.0/Microsoft.AspNetCore.Blazor.Build.props +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Components/Blazor/Build/src/targets/All.targets b/src/Components/Blazor/Build/src/targets/All.targets deleted file mode 100644 index 6c69e85a40..0000000000 --- a/src/Components/Blazor/Build/src/targets/All.targets +++ /dev/null @@ -1,49 +0,0 @@ - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - - - $(MSBuildThisFileDirectory)..\tools\ - <_BlazorTasksTFM Condition=" '$(MSBuildRuntimeType)' == 'Core'">netcoreapp - <_BlazorTasksTFM Condition=" '$(_BlazorTasksTFM)' == ''">netfx - $(BlazorToolsDir)$(_BlazorTasksTFM)\Microsoft.AspNetCore.Blazor.Build.Tasks.dll - - - true - - - true - - - - - - - - - $(AssemblyName).blazor.config - $(TargetDir)$(BlazorMetadataFileName) - - - - <_BlazorConfigContent Include="$(MSBuildProjectFullPath)" /> - <_BlazorConfigContent Include="$(TargetPath)" /> - <_BlazorConfigContent Include="debug:true" Condition="'$(BlazorEnableDebugging)'=='true'" /> - - - - - - - - - - diff --git a/src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.props b/src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.props deleted file mode 100644 index f49c1f8f2f..0000000000 --- a/src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.props +++ /dev/null @@ -1,20 +0,0 @@ - - - - $(MSBuildThisFileDirectory)..\tools\blazor\blazor.webassembly.js - - - - none - --disable-opt unreachablebodies --verbose --strip-security true --exclude-feature com -v false -c link -u link -b true - dist\ - $(BaseBlazorDistPath)_content\ - $(BaseBlazorDistPath)_framework\ - $(BaseBlazorRuntimeOutputPath)_bin\ - $(BaseBlazorRuntimeOutputPath)wasm\ - wwwroot\ - blazor.boot.json - <_BlazorBuiltInBclLinkerDescriptor>$(MSBuildThisFileDirectory)BuiltInBclLinkerDescriptor.xml - - - diff --git a/src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.targets b/src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.targets deleted file mode 100644 index 3c7d126561..0000000000 --- a/src/Components/Blazor/Build/src/targets/Blazor.MonoRuntime.targets +++ /dev/null @@ -1,336 +0,0 @@ - - - true - - - - - $(MonoBaseClassLibraryPath) - $(MonoBaseClassLibraryFacadesPath) - $(MonoWasmRuntimePath) - $(MonoWasmFrameworkPath) - - - - - $(DotNetWebAssemblyArtifactsRoot)\wasm-bcl\wasm\ - $(DotNetWebAssemblyBCLPath)\Facades\ - $(DotNetWebAssemblyArtifactsRoot)\builds\debug\ - $(DotNetWebAssemblyArtifactsRoot)\framework\ - - - - - - - - - - - - - - <_BlazorStatisticsOutput Include="@(BlazorOutputWithTargetPath->'%(TargetOutputPath)')" /> - - - - - - - - - - - - - - $(BlazorRuntimeWasmOutputPath)%(FileName)%(Extension) - - - $(BaseBlazorRuntimeOutputPath)%(FileName)%(Extension) - - - - - <_BlazorPackageContentOutput Include="@(BlazorPackageContentFile)" Condition="%(SourcePackage) != ''"> - $(BaseBlazorPackageContentOutputPath)%(SourcePackage)\%(RecursiveDir)\%(Filename)%(Extension) - - - - - - - - - $(IntermediateOutputPath)blazor\ - - - $(BlazorIntermediateOutputPath)linker.descriptor.xml - - <_TypeGranularityLinkerDescriptor>$(BlazorIntermediateOutputPath)linker.typegranularityconfig.xml - - - $(BlazorIntermediateOutputPath)linker/ - - - $(BlazorIntermediateOutputPath)$(BlazorBootJsonName) - - <_BlazorLinkerOutputCache>$(BlazorIntermediateOutputPath)linker.output - - <_BlazorApplicationAssembliesCacheFile>$(BlazorIntermediateOutputPath)unlinked.output - - - - <_WebAssemblyBCLFolder Include=" - $(DotNetWebAssemblyBCLPath); - $(DotNetWebAssemblyBCLFacadesPath); - $(DotNetWebAssemblyFrameworkPath)" /> - - <_WebAssemblyBCLAssembly Include="%(_WebAssemblyBCLFolder.Identity)*.dll" /> - - - - - - <_BlazorManagedRuntimeAssemby Include="@(RuntimeCopyLocalItems)" /> - - - <_BlazorUserRuntimeAssembly Include="@(ReferencePath->WithMetadataValue('CopyLocal', 'true'))" /> - <_BlazorUserRuntimeAssembly Include="@(ReferenceDependencyPaths->WithMetadataValue('CopyLocal', 'true'))" /> - - <_BlazorManagedRuntimeAssemby Include="@(_BlazorUserRuntimeAssembly)" /> - <_BlazorManagedRuntimeAssemby Include="@(IntermediateAssembly)" /> - - - - - - - - - - - <_BlazorCopyLocalPaths Include="@(ReferenceCopyLocalPaths)" /> - <_BlazorCopyLocalPaths Remove="@(_BlazorManagedRuntimeAssemby)" /> - - - true - $(BlazorRuntimeBinOutputPath)%(_BlazorCopyLocalPaths.DestinationSubDirectory)%(FileName)%(Extension) - %(_BlazorCopyLocalPaths.DestinationSubDirectory)%(FileName)%(Extension) - - - - true - $(BlazorRuntimeBinOutputPath)%(FileName)%(Extension) - %(FileName)%(Extension) - - - - - - - - - - - - - - - - - <_BlazorRuntimeCopyLocalItems Include="@(RuntimeCopyLocalItems)" /> - - - <_BlazorRuntimeCopyLocalItems IsLinkable="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('System.'))" /> - <_BlazorRuntimeCopyLocalItems IsLinkable="true" TypeGranularity="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('Microsoft.AspNetCore.'))" /> - <_BlazorRuntimeCopyLocalItems IsLinkable="true" TypeGranularity="true" Condition="$([System.String]::Copy('%(Filename)').StartsWith('Microsoft.Extensions.'))" /> - - <_BlazorAssemblyToLink Include="@(_WebAssemblyBCLAssembly)" /> - <_BlazorAssemblyToLink Include="@(_BlazorRuntimeCopyLocalItems)" Condition="'%(_BlazorRuntimeCopyLocalItems.IsLinkable)' == 'true'" /> - - <_BlazorLinkerRoot Include="@(IntermediateAssembly)" /> - <_BlazorLinkerRoot Include="@(_BlazorUserRuntimeAssembly)" /> - <_BlazorLinkerRoot Include="@(_BlazorRuntimeCopyLocalItems)" Condition="'%(_BlazorRuntimeCopyLocalItems.IsLinkable)' != 'true'" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_BlazorLinkerAdditionalOptions>-l $(MonoLinkerI18NAssemblies) $(AdditionalMonoLinkerOptions) - - - - <_OldLinkedFile Include="$(BlazorIntermediateLinkerOutputPath)*.dll" /> - <_OldLinkedFile Include="$(BlazorIntermediateLinkerOutputPath)*.pdb" /> - - - - - - - <_DotNetHostDirectory>$(NetCoreRoot) - <_DotNetHostFileName>dotnet - <_DotNetHostFileName Condition=" '$(OS)' == 'Windows_NT' ">dotnet.exe - - - - - - <_LinkerResult Include="$(BlazorIntermediateLinkerOutputPath)*.dll" /> - <_LinkerResult Include="$(BlazorIntermediateLinkerOutputPath)*.pdb" Condition="'$(BlazorEnableDebugging)' == 'true'" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_BlazorRuntimeFile Include="@(BlazorOutputWithTargetPath->WithMetadataValue('BlazorRuntimeFile', 'true'))" /> - - - - - - - - - - - diff --git a/src/Components/Blazor/Build/src/targets/Publish.targets b/src/Components/Blazor/Build/src/targets/Publish.targets deleted file mode 100644 index 7cb7e0ad23..0000000000 --- a/src/Components/Blazor/Build/src/targets/Publish.targets +++ /dev/null @@ -1,70 +0,0 @@ - - - true - $(AssemblyName)\dist\ - - - false - false - false - false - false - true - - - - - - - - - - $(BlazorPublishDistDir)$([System.String]::new(%(TargetPath)).Substring(8)) - - - - <_BlazorGCTPDI Include="%(BlazorOutputWithTargetPath.Identity)"> - $(AssemblyName)\%(TargetOutputPath) - - - - %(TargetPath) - PreserveNewest - - - - - - <_BlazorConfigPath>$(OutDir)$(AssemblyName).blazor.config - - - - <_BlazorPublishConfigContent Include="." /> - <_BlazorPublishConfigContent Include="$(AssemblyName)/" /> - - - - - - - - - - <_StandaloneWebConfigContent Include="$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)Standalone.Web.config'))"/> - - - - - - - diff --git a/src/Components/Blazor/Build/src/targets/StaticWebAssets.targets b/src/Components/Blazor/Build/src/targets/StaticWebAssets.targets deleted file mode 100644 index d547f500b1..0000000000 --- a/src/Components/Blazor/Build/src/targets/StaticWebAssets.targets +++ /dev/null @@ -1,37 +0,0 @@ - - - - - $(ResolveStaticWebAssetsInputsDependsOn); - _RemoveBlazorCurrentProjectAssetsFromStaticWebAssets; - - - - $(GetCurrentProjectStaticWebAssetsDependsOn); - _RemoveBlazorCurrentProjectAssetsFromStaticWebAssets; - - - - - - - - - - - - - - - <_StandaloneExternalPublishStaticWebAsset Include="@(_ExternalPublishStaticWebAsset)" Condition="'%(RelativePath)' != ''"> - $([MSBuild]::MakeRelative('$(MSBuildProjectDirectory)', '$([MSBuild]::NormalizePath('$([System.Text.RegularExpressions.Regex]::Replace('%(RelativePath)','^wwwroot\\?\/?(.*)','$(BlazorPublishDistDir)$1'))'))')) - - - - - - - - - diff --git a/src/Components/Blazor/Build/test/BindRazorIntegrationTest.cs b/src/Components/Blazor/Build/test/BindRazorIntegrationTest.cs deleted file mode 100644 index 1fafb9e81d..0000000000 --- a/src/Components/Blazor/Build/test/BindRazorIntegrationTest.cs +++ /dev/null @@ -1,534 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.AspNetCore.Blazor.Build.Test -{ - public class BindRazorIntegrationTest : RazorIntegrationTestBase - { - public BindRazorIntegrationTest(ITestOutputHelper output) - : base(output) - { - } - - internal override bool UseTwoPhaseCompilation => true; - - [Fact] - public void Render_BindToComponent_SpecifiesValue_WithMatchingProperties() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using System; -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase - { - [Parameter] - public int Value { get; set; } - - [Parameter] - public Action ValueChanged { get; set; } - } -}")); - - var component = CompileToComponent(@" - -@code { - public int ParentValue { get; set; } = 42; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0), - frame => AssertFrame.Attribute(frame, "Value", 42, 1), - frame => AssertFrame.Attribute(frame, "ValueChanged", typeof(Action), 2)); - } - - [Fact] - public void Render_BindToComponent_SpecifiesValue_WithoutMatchingProperties() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase, IComponent - { - Task IComponent.SetParametersAsync(ParameterView parameters) - { - return Task.CompletedTask; - } - } -}")); - - var component = CompileToComponent(@" - -@code { - public int ParentValue { get; set; } = 42; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0), - frame => AssertFrame.Attribute(frame, "Value", 42, 1), - frame => AssertFrame.Attribute(frame, "ValueChanged", typeof(EventCallback), 2)); - } - - [Fact] - public void Render_BindToComponent_SpecifiesValueAndChangeEvent_WithMatchingProperties() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using System; -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase - { - [Parameter] - public int Value { get; set; } - - [Parameter] - public Action OnChanged { get; set; } - } -}")); - - var component = CompileToComponent(@" - -@code { - public int ParentValue { get; set; } = 42; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0), - frame => AssertFrame.Attribute(frame, "Value", 42, 1), - frame => AssertFrame.Attribute(frame, "OnChanged", typeof(Action), 2)); - } - - [Fact] - public void Render_BindToComponent_SpecifiesValueAndChangeEvent_WithoutMatchingProperties() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase, IComponent - { - Task IComponent.SetParametersAsync(ParameterView parameters) - { - return Task.CompletedTask; - } - } -}")); - - var component = CompileToComponent(@" - -@code { - public int ParentValue { get; set; } = 42; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0), - frame => AssertFrame.Attribute(frame, "Value", 42, 1), - frame => AssertFrame.Attribute(frame, "OnChanged", typeof(EventCallback), 2)); - } - - [Fact] - public void Render_BindToElement_WritesAttributes() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using System; -using Microsoft.AspNetCore.Components; - -namespace Test -{ - [BindElement(""div"", null, ""myvalue"", ""myevent"")] - public static class BindAttributes - { - } -}")); - - var component = CompileToComponent(@" -
-@code { - public string ParentValue { get; set; } = ""hi""; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "div", 3, 0), - frame => AssertFrame.Attribute(frame, "myvalue", "hi", 1), - frame => AssertFrame.Attribute(frame, "myevent", typeof(EventCallback), 2)); - } - - [Fact] - public void Render_BindToElementWithSuffix_WritesAttributes() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using System; -using Microsoft.AspNetCore.Components; - -namespace Test -{ - [BindElement(""div"", ""value"", ""myvalue"", ""myevent"")] - public static class BindAttributes - { - } -}")); - - var component = CompileToComponent(@" -
-@code { - public string ParentValue { get; set; } = ""hi""; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "div", 3, 0), - frame => AssertFrame.Attribute(frame, "myvalue", "hi", 1), - frame => AssertFrame.Attribute(frame, "myevent", typeof(EventCallback), 2)); - } - - [Fact] - public void Render_BindDuplicates_ReportsDiagnostic() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using System; -using Microsoft.AspNetCore.Components; - -namespace Test -{ - [BindElement(""div"", ""value"", ""myvalue2"", ""myevent2"")] - [BindElement(""div"", ""value"", ""myvalue"", ""myevent"")] - public static class BindAttributes - { - } -}")); - - // Act - var result = CompileToCSharp(@" -
-@code { - public string ParentValue { get; set; } = ""hi""; -}"); - - // Assert - var diagnostic = Assert.Single(result.Diagnostics); - Assert.Equal("RZ9989", diagnostic.Id); - Assert.Equal( - "The attribute '@bind-value' was matched by multiple bind attributes. Duplicates:" + Environment.NewLine + - "Test.BindAttributes" + Environment.NewLine + - "Test.BindAttributes", - diagnostic.GetMessage()); - } - - [Fact] - public void Render_BuiltIn_BindToInputWithoutType_WritesAttributes() - { - // Arrange - var component = CompileToComponent(@" -@using Microsoft.AspNetCore.Components.Web - -@code { - public int ParentValue { get; set; } = 42; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "input", 3, 0), - frame => AssertFrame.Attribute(frame, "value", "42", 1), - frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 2)); - } - - [Fact] - public void Render_BuiltIn_BindToInputText_WithFormat_WritesAttributes() - { - // Arrange - var component = CompileToComponent(@" -@using Microsoft.AspNetCore.Components.Web - -@code { - public DateTime CurrentDate { get; set; } = new DateTime(2018, 1, 1); -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "input", 4, 0), - frame => AssertFrame.Attribute(frame, "type", "text", 1), - frame => AssertFrame.Attribute(frame, "value", new DateTime(2018, 1, 1).ToString("MM/dd/yyyy"), 2), - frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3)); - } - - [Fact] - public void Render_BuiltIn_BindToInputText_WithFormatFromProperty_WritesAttributes() - { - // Arrange - var component = CompileToComponent(@" -@using Microsoft.AspNetCore.Components.Web - -@code { - public DateTime CurrentDate { get; set; } = new DateTime(2018, 1, 1); - - public string Format { get; set; } = ""MM/dd/yyyy""; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "input", 4, 0), - frame => AssertFrame.Attribute(frame, "type", "text", 1), - frame => AssertFrame.Attribute(frame, "value", new DateTime(2018, 1, 1).ToString("MM/dd/yyyy"), 2), - frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3)); - } - - [Fact] - public void Render_BuiltIn_BindToInputText_WritesAttributes() - { - // Arrange - var component = CompileToComponent(@" -@using Microsoft.AspNetCore.Components.Web - -@code { - public int ParentValue { get; set; } = 42; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "input", 4, 0), - frame => AssertFrame.Attribute(frame, "type", "text", 1), - frame => AssertFrame.Attribute(frame, "value", "42", 2), - frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3)); - } - - [Fact] - public void Render_BuiltIn_BindToInputCheckbox_WritesAttributes() - { - // Arrange - var component = CompileToComponent(@" -@using Microsoft.AspNetCore.Components.Web - -@code { - public bool Enabled { get; set; } -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "input", 3, 0), - frame => AssertFrame.Attribute(frame, "type", "checkbox", 1), - frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3)); - } - - [Fact] - public void Render_BindToElementFallback_WritesAttributes() - { - // Arrange - var component = CompileToComponent(@" - -@code { - public int ParentValue { get; set; } = 42; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "input", 4, 0), - frame => AssertFrame.Attribute(frame, "type", "text", 1), - frame => AssertFrame.Attribute(frame, "value", "42", 2), - frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3)); - } - - [Fact] - public void Render_BindToElementFallback_WithFormat_WritesAttributes() - { - // Arrange - var component = CompileToComponent(@" - -@code { - public DateTime CurrentDate { get; set; } = new DateTime(2018, 1, 1); -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "input", 4, 0), - frame => AssertFrame.Attribute(frame, "type", "text", 1), - frame => AssertFrame.Attribute(frame, "value", new DateTime(2018, 1, 1).ToString("MM/dd"), 2), - frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 3)); - } - - [Fact] // Additional coverage of OrphanTagHelperLoweringPass - public void Render_BindToElementFallback_SpecifiesValueAndChangeEvent_WithCSharpAttribute() - { - // Arrange - var component = CompileToComponent(@" - -@code { - public int ParentValue { get; set; } = 42; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "input", 5, 0), - frame => AssertFrame.Attribute(frame, "type", "text", 1), - frame => AssertFrame.Attribute(frame, "visible", 2), - frame => AssertFrame.Attribute(frame, "value", "42", 3), - frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 4)); - } - - [Fact] // See https://github.com/aspnet/Blazor/issues/703 - public void Workaround_703() - { - // Arrange - var component = CompileToComponent(@" - -@code { - public int ParentValue { get; set; } = 42; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - // - // The workaround for 703 is that the value attribute MUST be after the type - // attribute. - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "input", 5, 0), - frame => AssertFrame.Attribute(frame, "type", "text", 1), - frame => AssertFrame.Attribute(frame, "visible", 2), - frame => AssertFrame.Attribute(frame, "value", "42", 3), - frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 4)); - } - - [Fact] // Additional coverage of OrphanTagHelperLoweringPass - public void Render_BindToElementFallback_SpecifiesValueAndChangeEvent_BodyContent() - { - // Arrange - var component = CompileToComponent(@" -
- @(42.ToString()) -
-@code { - public int ParentValue { get; set; } = 42; -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "div", 7, 0), - frame => AssertFrame.Attribute(frame, "value", "42", 1), - frame => AssertFrame.Attribute(frame, "onchange", typeof(EventCallback), 2), - frame => AssertFrame.MarkupWhitespace(frame, 3), - frame => AssertFrame.Element(frame, "span", 2, 4), - frame => AssertFrame.Text(frame, "42", 5), - frame => AssertFrame.MarkupWhitespace(frame, 6)); - } - - [Fact] - public void Render_BindFallback_InvalidSyntax_TooManyParts() - { - // Arrange & Act - var generated = CompileToCSharp(@" - -@code { - public string Text { get; set; } = ""text""; -}"); - - // Assert - var diagnostic = Assert.Single(generated.Diagnostics); - Assert.Equal("RZ9991", diagnostic.Id); - } - - [Fact] - public void Render_BindFallback_InvalidSyntax_TrailingDash() - { - // Arrange & Act - var generated = CompileToCSharp(@" - -@code { - public string Text { get; set; } = ""text""; -}"); - - // Assert - var diagnostic = Assert.Single(generated.Diagnostics); - Assert.Equal("RZ9991", diagnostic.Id); - } - } -} diff --git a/src/Components/Blazor/Build/test/BootJsonWriterTest.cs b/src/Components/Blazor/Build/test/BootJsonWriterTest.cs deleted file mode 100644 index 1e2d89b573..0000000000 --- a/src/Components/Blazor/Build/test/BootJsonWriterTest.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Text.Json; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Blazor.Build -{ - public class BootJsonWriterTest - { - [Fact] - public async Task ProducesJsonReferencingAssemblyAndDependencies() - { - // Arrange/Act - var assemblyReferences = new string[] { "MyApp.EntryPoint.dll", "System.Abc.dll", "MyApp.ClassLib.dll", }; - using var stream = new MemoryStream(); - - // Act - GenerateBlazorBootJson.WriteBootJson( - stream, - "MyApp.Entrypoint.dll", - assemblyReferences, - linkerEnabled: true); - - // Assert - stream.Position = 0; - using var parsedContent = await JsonDocument.ParseAsync(stream); - var rootElement = parsedContent.RootElement; - Assert.Equal("MyApp.Entrypoint.dll", rootElement.GetProperty("entryAssembly").GetString()); - var assembliesElement = rootElement.GetProperty("assemblies"); - Assert.Equal(assemblyReferences.Length, assembliesElement.GetArrayLength()); - for (var i = 0; i < assemblyReferences.Length; i++) - { - Assert.Equal(assemblyReferences[i], assembliesElement[i].GetString()); - } - Assert.True(rootElement.GetProperty("linkerEnabled").GetBoolean()); - } - } -} diff --git a/src/Components/Blazor/Build/test/BuildIntegrationTests/BuildIncrementalismTest.cs b/src/Components/Blazor/Build/test/BuildIntegrationTests/BuildIncrementalismTest.cs deleted file mode 100644 index 73d8645029..0000000000 --- a/src/Components/Blazor/Build/test/BuildIntegrationTests/BuildIncrementalismTest.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Blazor.Build -{ - public class BuildIncrementalismTest - { - [Fact] - public async Task Build_WithLinker_IsIncremental() - { - // Arrange - using var project = ProjectDirectory.Create("standalone"); - 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]); - } - } - } - } -} diff --git a/src/Components/Blazor/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs b/src/Components/Blazor/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs deleted file mode 100644 index f3148b1a0b..0000000000 --- a/src/Components/Blazor/Build/test/BuildIntegrationTests/BuildIntegrationTest.cs +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Blazor.Build -{ - public class BuildIntegrationTest - { - [Fact] - public async Task Build_WithDefaultSettings_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone"); - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "blazor.boot.json"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "wasm", "dotnet.js"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - } - - [Fact] - public async Task Build_Hosted_Works() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = "netcoreapp3.1"; - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - var blazorConfig = Path.Combine(buildOutputDirectory, "standalone.blazor.config"); - Assert.FileExists(result, blazorConfig); - - var path = Path.GetFullPath(Path.Combine(project.SolutionPath, "standalone", "bin", project.Configuration, "netstandard2.1", "standalone.dll")); - Assert.FileContains(result, blazorConfig, path); - Assert.FileDoesNotExist(result, buildOutputDirectory, "dist", "_framework", "_bin", "standalone.dll"); - } - - [Fact] - public async Task Build_WithLinkOnBuildDisabled_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone"); - project.AddProjectFileContent( -@" - false -"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "blazor.boot.json"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "wasm", "dotnet.js"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - } - - [Fact] - public async Task Build_SatelliteAssembliesAreCopiedToBuildOutput() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); - project.AddProjectFileContent( -@" - - $(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies - - - -"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/restore"); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "classlibrarywithsatelliteassemblies.dll"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. - - var bootJsonPath = Path.Combine(buildOutputDirectory, "dist", "_framework", "blazor.boot.json"); - Assert.FileContains(result, bootJsonPath, "\"Microsoft.CodeAnalysis.CSharp.dll\""); - Assert.FileContains(result, bootJsonPath, "\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); - } - - [Fact] - public async Task Build_WithBlazorLinkOnBuildFalse_SatelliteAssembliesAreCopiedToBuildOutput() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); - project.AddProjectFileContent( -@" - - false - $(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies - - - -"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, args: "/restore"); - - Assert.BuildPassed(result); - - var buildOutputDirectory = project.BuildOutputDirectory; - - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "classlibrarywithsatelliteassemblies.dll"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll"); - Assert.FileExists(result, buildOutputDirectory, "dist", "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. - - var bootJsonPath = Path.Combine(buildOutputDirectory, "dist", "_framework", "blazor.boot.json"); - Assert.FileContains(result, bootJsonPath, "\"Microsoft.CodeAnalysis.CSharp.dll\""); - Assert.FileContains(result, bootJsonPath, "\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); - } - } -} diff --git a/src/Components/Blazor/Build/test/BuildIntegrationTests/PublishIntegrationTest.cs b/src/Components/Blazor/Build/test/BuildIntegrationTests/PublishIntegrationTest.cs deleted file mode 100644 index 3556f119f4..0000000000 --- a/src/Components/Blazor/Build/test/BuildIntegrationTests/PublishIntegrationTest.cs +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; -using System.Threading.Tasks; -using Xunit; - -namespace Microsoft.AspNetCore.Blazor.Build -{ - public class PublishIntegrationTest - { - [Fact] - public async Task Publish_WithDefaultSettings_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new [] { "razorclasslibrary" }); - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - var blazorPublishDirectory = Path.Combine(publishDirectory, Path.GetFileNameWithoutExtension(project.ProjectFilePath)); - - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "wasm", "dotnet.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "_bin", "Microsoft.Extensions.Logging.Abstractions.dll"); // Verify dependencies are part of the output. - - // Verify referenced static web assets - Assert.FileExists(result, blazorPublishDirectory, "dist", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_content", "RazorClassLibrary", "styles.css"); - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "dist", "index.html"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - } - - [Fact] - 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, Path.GetFileNameWithoutExtension(project.ProjectFilePath)); - - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "wasm", "dotnet.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_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, "dist", "index.html"); - - // Verify static web assets from referenced projects are copied. - // Uncomment once https://github.com/aspnet/AspNetCore/issues/17426 is resolved. - // Assert.FileExists(result, blazorPublishDirectory, "dist", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - // Assert.FileExists(result, blazorPublishDirectory, "dist", "_content", "RazorClassLibrary", "styles.css"); - - // Verify static assets are in the publish directory - Assert.FileExists(result, blazorPublishDirectory, "dist", "index.html"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - } - - [Fact] - public async Task Publish_WithLinkOnBuildDisabled_Works() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new [] { "razorclasslibrary" }); - project.AddProjectFileContent( -@" - false -"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - var blazorPublishDirectory = Path.Combine(publishDirectory, Path.GetFileNameWithoutExtension(project.ProjectFilePath)); - - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "wasm", "dotnet.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_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, "dist", "index.html"); - - // Verify referenced static web assets - Assert.FileExists(result, blazorPublishDirectory, "dist", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_content", "RazorClassLibrary", "styles.css"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - } - - [Fact] - public async Task Publish_SatelliteAssemblies_AreCopiedToBuildOutput() - { - // Arrange - using var project = ProjectDirectory.Create("standalone", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); - project.AddProjectFileContent( -@" - - $(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies - - - -"); - - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args: "/restore"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - var blazorPublishDirectory = Path.Combine(publishDirectory, Path.GetFileNameWithoutExtension(project.ProjectFilePath)); - - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "_bin", "Microsoft.CodeAnalysis.CSharp.dll"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "_bin", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. - - var bootJsonPath = Path.Combine(blazorPublishDirectory, "dist", "_framework", "blazor.boot.json"); - Assert.FileContains(result, bootJsonPath, "\"Microsoft.CodeAnalysis.CSharp.dll\""); - Assert.FileContains(result, bootJsonPath, "\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); - } - - [Fact] - public async Task Publish_HostedApp_Works() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = "netcoreapp3.1"; - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); - - Assert.BuildPassed(result); - - var publishDirectory = project.PublishOutputDirectory; - // Make sure the main project exists - Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); - - var blazorPublishDirectory = Path.Combine(publishDirectory, "standalone"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "wasm", "dotnet.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_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, "dist", "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, "dist", "index.html"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - - var blazorConfig = Path.Combine(result.Project.DirectoryPath, publishDirectory, "standalone.blazor.config"); - var blazorConfigLines = File.ReadAllLines(blazorConfig); - Assert.Equal(".", blazorConfigLines[0]); - Assert.Equal("standalone/", blazorConfigLines[1]); - } - - [Fact] - public async Task Publish_HostedApp_WithNoBuild_Works() - { - // Arrange - using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "standalone", "razorclasslibrary", }); - project.TargetFramework = "netcoreapp3.1"; - var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build"); - - Assert.BuildPassed(result); - - result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:NoBuild=true"); - - var publishDirectory = project.PublishOutputDirectory; - // Make sure the main project exists - Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); - - var blazorPublishDirectory = Path.Combine(publishDirectory, "standalone"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "blazor.boot.json"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "blazor.webassembly.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "wasm", "dotnet.wasm"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "wasm", "dotnet.js"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_framework", "_bin", "standalone.dll"); - Assert.FileExists(result, blazorPublishDirectory, "dist", "_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, "dist", "index.html"); - - // Verify static web assets from referenced projects are copied. - // Uncomment once https://github.com/aspnet/AspNetCore/issues/17426 is resolved. - // 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, "dist", "index.html"); - - // Verify web.config - Assert.FileExists(result, publishDirectory, "web.config"); - } - } -} diff --git a/src/Components/Blazor/Build/test/ChildContentRazorIntegrationTest.cs b/src/Components/Blazor/Build/test/ChildContentRazorIntegrationTest.cs deleted file mode 100644 index 720c00fe9b..0000000000 --- a/src/Components/Blazor/Build/test/ChildContentRazorIntegrationTest.cs +++ /dev/null @@ -1,407 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Test.Helpers; -using Microsoft.CodeAnalysis.CSharp; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.AspNetCore.Blazor.Build.Test -{ - public class ChildContentRazorIntegrationTest : RazorIntegrationTestBase - { - private readonly CSharpSyntaxTree RenderChildContentComponent = Parse(@" -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Rendering; -namespace Test -{ - public class RenderChildContent : ComponentBase - { - protected override void BuildRenderTree(RenderTreeBuilder builder) - { - builder.AddContent(0, ChildContent); - } - - [Parameter] - public RenderFragment ChildContent { get; set; } - } -} -"); - - private readonly CSharpSyntaxTree RenderChildContentStringComponent = Parse(@" -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Rendering; -namespace Test -{ - public class RenderChildContentString : ComponentBase - { - protected override void BuildRenderTree(RenderTreeBuilder builder) - { - builder.AddContent(0, ChildContent, Value); - } - - [Parameter] - public RenderFragment ChildContent { get; set; } - - [Parameter] - public string Value { get; set; } - } -} -"); - - private readonly CSharpSyntaxTree RenderMultipleChildContent = Parse(@" -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Rendering; -namespace Test -{ - public class RenderMultipleChildContent : ComponentBase - { - protected override void BuildRenderTree(RenderTreeBuilder builder) - { - builder.AddContent(0, Header, Name); - builder.AddContent(1, ChildContent, Value); - builder.AddContent(2, Footer); - } - - [Parameter] - public string Name { get; set; } - - [Parameter] - public RenderFragment Header { get; set; } - - [Parameter] - public RenderFragment ChildContent { get; set; } - - [Parameter] - public RenderFragment Footer { get; set; } - - [Parameter] - public string Value { get; set; } - } -} -"); - - public ChildContentRazorIntegrationTest(ITestOutputHelper output) - : base(output) - { - } - - internal override bool UseTwoPhaseCompilation => true; - - [Fact] - public void Render_BodyChildContent() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderChildContentComponent); - - var component = CompileToComponent(@" - -
-
"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 0), - frame => AssertFrame.Attribute(frame, "ChildContent", 1), - frame => AssertFrame.Markup(frame, "\n
\n", 2)); - } - - [Fact] - public void Render_BodyChildContent_Generic() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderChildContentStringComponent); - - var component = CompileToComponent(@" - -
@context.ToLowerInvariant()
-
"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderChildContentString", 3, 0), - frame => AssertFrame.Attribute(frame, "Value", "HI", 1), - frame => AssertFrame.Attribute(frame, "ChildContent", 2), - frame => AssertFrame.MarkupWhitespace(frame, 3), - frame => AssertFrame.Element(frame, "div", 2, 4), - frame => AssertFrame.Text(frame, "hi", 5), - frame => AssertFrame.MarkupWhitespace(frame, 6)); - } - - [Fact] - public void Render_ExplicitChildContent() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderChildContentComponent); - - var component = CompileToComponent(@" - - -
-
-
"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 0), - frame => AssertFrame.Attribute(frame, "ChildContent", 1), - frame => AssertFrame.Markup(frame, "\n
\n ", 2)); - } - - [Fact] - public void Render_BodyChildContent_Recursive() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderChildContentComponent); - - var component = CompileToComponent(@" - - - -
-
-
"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 0), - frame => AssertFrame.Attribute(frame, "ChildContent", 1), - frame => AssertFrame.MarkupWhitespace(frame, 2), - frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 3), - frame => AssertFrame.Attribute(frame, "ChildContent", 4), - frame => AssertFrame.MarkupWhitespace(frame, 6), - frame => AssertFrame.Markup(frame, "\n
\n ", 5)); - } - - [Fact] - public void Render_AttributeChildContent() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderChildContentComponent); - - var component = CompileToComponent(@" -@{ RenderFragment template = (context) => @
@context.ToLowerInvariant()
; } -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 2), - frame => AssertFrame.Attribute(frame, "ChildContent", 3), - frame => AssertFrame.Element(frame, "div", 2, 0), - frame => AssertFrame.Text(frame, "hi", 1)); - } - - [Fact] - public void Render_AttributeChildContent_RenderFragmentOfString() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderChildContentStringComponent); - - var component = CompileToComponent(@" -@{ RenderFragment template = (context) => @
@context.ToLowerInvariant()
; } -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderChildContentString", 3, 2), - frame => AssertFrame.Attribute(frame, "ChildContent", 3), - frame => AssertFrame.Attribute(frame, "Value", "HI", 4), - frame => AssertFrame.Element(frame, "div", 2, 0), - frame => AssertFrame.Text(frame, "hi", 1)); - } - - [Fact] - public void Render_AttributeChildContent_NoArgTemplate() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderChildContentComponent); - - var component = CompileToComponent(@" -@{ RenderFragment template = @
@(""HI"".ToLowerInvariant())
; } -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 2), - frame => AssertFrame.Attribute(frame, "ChildContent", 3), - frame => AssertFrame.Element(frame, "div", 2, 0), - frame => AssertFrame.Text(frame, "hi", 1)); - } - - [Fact] - public void Render_AttributeChildContent_IgnoresEmptyBody() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderChildContentComponent); - - var component = CompileToComponent(@" -@{ RenderFragment template = (context) => @
@context.ToLowerInvariant()
; } -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 2), - frame => AssertFrame.Attribute(frame, "ChildContent", 3), - frame => AssertFrame.Element(frame, "div", 2, 0), - frame => AssertFrame.Text(frame, "hi", 1)); - } - - [Fact] - public void Render_AttributeChildContent_IgnoresWhitespaceBody() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderChildContentComponent); - - var component = CompileToComponent(@" -@{ RenderFragment template = (context) => @
@context.ToLowerInvariant()
; } - - -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 2), - frame => AssertFrame.Attribute(frame, "ChildContent", 3), - frame => AssertFrame.Element(frame, "div", 2, 0), - frame => AssertFrame.Text(frame, "hi", 1)); - } - - [Fact] - public void Render_MultipleChildContent() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderMultipleChildContent); - - var component = CompileToComponent(@" -@{ RenderFragment header = context => @
@context.ToLowerInvariant()
; } - - Some @context.ToLowerInvariant() Content -
Bye!
-
"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderMultipleChildContent", 6, 2), - frame => AssertFrame.Attribute(frame, "Name", "billg", 3), - frame => AssertFrame.Attribute(frame, "Header", typeof(RenderFragment), 4), - frame => AssertFrame.Attribute(frame, "Value", "HI", 5), - frame => AssertFrame.Attribute(frame, "ChildContent", typeof(RenderFragment), 6), - frame => AssertFrame.Attribute(frame, "Footer", typeof(RenderFragment), 10), - frame => AssertFrame.Element(frame, "div", 2, 0), - frame => AssertFrame.Text(frame, "billg", 1), - frame => AssertFrame.Text(frame, "Some ", 7), - frame => AssertFrame.Text(frame, "hi", 8), - frame => AssertFrame.Text(frame, " Content", 9), - frame => AssertFrame.Text(frame, "Bye!", 11)); - } - - [Fact] - public void Render_MultipleChildContent_ContextParameterOnComponent() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderMultipleChildContent); - - var component = CompileToComponent(@" - -
@item.ToLowerInvariant()
- Some @Context.ToLowerInvariant() Content -
Bye!
-
"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderMultipleChildContent", 6, 0), - frame => AssertFrame.Attribute(frame, "Name", "billg", 1), - frame => AssertFrame.Attribute(frame, "Value", "HI", 2), - frame => AssertFrame.Attribute(frame, "Header", typeof(RenderFragment), 3), - frame => AssertFrame.Attribute(frame, "ChildContent", typeof(RenderFragment), 6), - frame => AssertFrame.Attribute(frame, "Footer", typeof(RenderFragment), 10), - frame => AssertFrame.Element(frame, "div", 2, 4), - frame => AssertFrame.Text(frame, "billg", 5), - frame => AssertFrame.Text(frame, "Some ", 7), - frame => AssertFrame.Text(frame, "hi", 8), - frame => AssertFrame.Text(frame, " Content", 9), - frame => AssertFrame.Text(frame, "Bye!", 11)); - } - - // Verifies that our check for reuse of parameter names isn't too aggressive. - [Fact] - public void Render_MultipleChildContent_ContextParameterOnComponent_SetsSameName() - { - // Arrange - AdditionalSyntaxTrees.Add(RenderMultipleChildContent); - - var component = CompileToComponent(@" - - -
@item.ToLowerInvariant()
- Some @item.ToLowerInvariant() Content -
Bye!
-
"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.RenderMultipleChildContent", 6, 0), - frame => AssertFrame.Attribute(frame, "Name", "billg", 1), - frame => AssertFrame.Attribute(frame, "Value", "HI", 2), - frame => AssertFrame.Attribute(frame, "Header", typeof(RenderFragment), 3), - frame => AssertFrame.Attribute(frame, "ChildContent", typeof(RenderFragment), 6), - frame => AssertFrame.Attribute(frame, "Footer", typeof(RenderFragment), 10), - frame => AssertFrame.Element(frame, "div", 2, 4), - frame => AssertFrame.Text(frame, "billg", 5), - frame => AssertFrame.Text(frame, "Some ", 7), - frame => AssertFrame.Text(frame, "hi", 8), - frame => AssertFrame.Text(frame, " Content", 9), - frame => AssertFrame.Text(frame, "Bye!", 11)); - } - } -} diff --git a/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs b/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs deleted file mode 100644 index d15cf4f584..0000000000 --- a/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs +++ /dev/null @@ -1,616 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Linq; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.RenderTree; -using Microsoft.AspNetCore.Components.Test.Helpers; -using Microsoft.AspNetCore.Components.Web; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.AspNetCore.Blazor.Build.Test -{ - public class ComponentRenderingRazorIntegrationTest : RazorIntegrationTestBase - { - public ComponentRenderingRazorIntegrationTest(ITestOutputHelper output) - : base(output) - { - } - - internal override bool UseTwoPhaseCompilation => true; - - [Fact] - public void Render_ChildComponent_Simple() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase - { - } -} -")); - - var component = CompileToComponent(@" -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 1, 0)); - } - - [Fact] - public void Render_ChildComponent_WithParameters() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class SomeType - { - } - - public class MyComponent : ComponentBase - { - [Parameter] public int IntProperty { get; set; } - [Parameter] public bool BoolProperty { get; set; } - [Parameter] public string StringProperty { get; set; } - [Parameter] public SomeType ObjectProperty { get; set; } - } -} -")); - - var component = CompileToComponent(@" -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 5, 0), - frame => AssertFrame.Attribute(frame, "IntProperty", 123, 1), - frame => AssertFrame.Attribute(frame, "BoolProperty", true, 2), - frame => AssertFrame.Attribute(frame, "StringProperty", "My string", 3), - frame => - { - AssertFrame.Attribute(frame, "ObjectProperty", 4); - Assert.Equal("Test.SomeType", frame.AttributeValue.GetType().FullName); - }); - } - - [Fact] - public void Render_ChildComponent_TriesToSetNonParamter() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase - { - public int IntProperty { get; set; } - } -} -")); - - var component = CompileToComponent(@" -"); - - // Act - var ex = Assert.Throws(() => GetRenderTree(component)); - - // Assert - Assert.Equal( - "Object of type 'Test.MyComponent' has a property matching the name 'IntProperty', " + - "but it does not have [ParameterAttribute] or [CascadingParameterAttribute] applied.", - ex.Message); - } - - [Fact] - public void Render_ChildComponent_WithExplicitStringParameter() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase - { - [Parameter] - public string StringProperty { get; set; } - } -} -")); - - var component = CompileToComponent(@" -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 0), - frame => AssertFrame.Attribute(frame, "StringProperty", "42", 1)); - } - - [Fact] - public void Render_ChildComponent_WithNonPropertyAttributes() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using System.Threading.Tasks; -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase, IComponent - { - Task IComponent.SetParametersAsync(ParameterView parameters) - { - return Task.CompletedTask; - } - } -} -")); - - var component = CompileToComponent(@" -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0), - frame => AssertFrame.Attribute(frame, "some-attribute", "foo", 1), - frame => AssertFrame.Attribute(frame, "another-attribute", "42", 2)); - } - - - [Theory] - [InlineData("e => Increment(e)")] - [InlineData("(e) => Increment(e)")] - [InlineData("@(e => Increment(e))")] - [InlineData("@(e => { Increment(e); })")] - [InlineData("Increment")] - [InlineData("@Increment")] - [InlineData("@(Increment)")] - public void Render_ChildComponent_WithEventHandler(string expression) - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using System; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; - -namespace Test -{ - public class MyComponent : ComponentBase - { - [Parameter] - public Action OnClick { get; set; } - } -} -")); - - var component = CompileToComponent($@" -@using Microsoft.AspNetCore.Components.Web - - -@code {{ - private int counter; - private void Increment(MouseEventArgs e) {{ - counter++; - }} -}}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 0), - frame => - { - AssertFrame.Attribute(frame, "OnClick", 1); - - // The handler will have been assigned to a lambda - var handler = Assert.IsType>(frame.AttributeValue); - Assert.Equal("Test.TestComponent", handler.Target.GetType().FullName); - }); - } - - [Fact] - public void Render_ChildComponent_WithExplicitEventHandler() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using System; -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase - { - [Parameter] - public Action OnClick { get; set; } - } -} -")); - - var component = CompileToComponent(@" - - -@code { - private int counter; - private void Increment(EventArgs e) { - counter++; - } -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 0), - frame => - { - AssertFrame.Attribute(frame, "OnClick", 1); - - // The handler will have been assigned to a lambda - var handler = Assert.IsType>(frame.AttributeValue); - Assert.Equal("Test.TestComponent", handler.Target.GetType().FullName); - Assert.Equal("Increment", handler.Method.Name); - }); - } - - [Fact] - public void Render_ChildComponent_WithMinimizedBoolAttribute() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase - { - [Parameter] - public bool BoolProperty { get; set; } - } -}")); - - var component = CompileToComponent(@" -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 0), - frame => AssertFrame.Attribute(frame, "BoolProperty", true, 1)); - } - - [Fact] - public void Render_ChildComponent_WithChildContent() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using Microsoft.AspNetCore.Components; -namespace Test -{ - public class MyComponent : ComponentBase - { - [Parameter] - public string MyAttr { get; set; } - - [Parameter] - public RenderFragment ChildContent { get; set; } - } -} -")); - - var component = CompileToComponent(@" -Some textNested text @(""Hello"")"); - - // Act - var frames = GetRenderTree(component); - - // Assert: component frames are correct - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 3, 0), - frame => AssertFrame.Attribute(frame, "MyAttr", "abc", 1), - frame => AssertFrame.Attribute(frame, "ChildContent", 2)); - - // Assert: Captured ChildContent frames are correct - var childFrames = GetFrames((RenderFragment)frames[2].AttributeValue); - Assert.Collection( - childFrames.AsEnumerable(), - frame => AssertFrame.Text(frame, "Some text", 3), - frame => AssertFrame.Element(frame, "some-child", 4, 4), - frame => AssertFrame.Attribute(frame, "a", "1", 5), - frame => AssertFrame.Text(frame, "Nested text ", 6), - frame => AssertFrame.Text(frame, "Hello", 7)); - } - - [Fact] - public void Render_ChildComponent_Nested() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class MyComponent : ComponentBase - { - [Parameter] - public RenderFragment ChildContent { get; set; } - } -} -")); - - var component = CompileToComponent(@" -Some text"); - - // Act - var frames = GetRenderTree(component); - - // Assert: outer component frames are correct - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 0), - frame => AssertFrame.Attribute(frame, "ChildContent", 1)); - - // Assert: first level of ChildContent is correct - // Note that we don't really need the sequence numbers to continue on from the - // sequence numbers at the parent level. All that really matters is that they are - // correct relative to each other (i.e., incrementing) within the nesting level. - // As an implementation detail, it happens that they do follow on from the parent - // level, but we could change that part of the implementation if we wanted. - var innerFrames = GetFrames((RenderFragment)frames[1].AttributeValue).AsEnumerable().ToArray(); - Assert.Collection( - innerFrames, - frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 2), - frame => AssertFrame.Attribute(frame, "ChildContent", 3)); - - // Assert: second level of ChildContent is correct - Assert.Collection( - GetFrames((RenderFragment)innerFrames[1].AttributeValue).AsEnumerable(), - frame => AssertFrame.Text(frame, "Some text", 4)); - } - - [Fact] // https://github.com/aspnet/Blazor/issues/773 - public void Regression_773() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using Microsoft.AspNetCore.Components; - -namespace Test -{ - public class SurveyPrompt : ComponentBase - { - [Parameter] public string Title { get; set; } - } -} -")); - - var component = CompileToComponent(@" -@page ""/"" - -Test!
"" /> -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.SurveyPrompt", 2, 0), - frame => AssertFrame.Attribute(frame, "Title", "
Test!
", 1)); - } - - - [Fact] - public void Regression_784() - { - // Arrange - - // Act - var component = CompileToComponent(@" -@using Microsoft.AspNetCore.Components.Web -

-@code { - public string ParentBgColor { get; set; } = ""#FFFFFF""; - - public void OnComponentHover(MouseEventArgs e) - { - } -} -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "p", 3, 0), - frame => AssertFrame.Attribute(frame, "onmouseover", 1), - frame => AssertFrame.Attribute(frame, "style", "background: #FFFFFF;", 2)); - } - - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/6185")] - public void Render_Component_HtmlEncoded() - { - // Arrange - var component = CompileToComponent(@"<span>Hi</span>"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Text(frame, "Hi")); - } - - [Fact] - public void Render_Component_HtmlBlockEncoded() - { - // Arrange - var component = CompileToComponent(@"

<span>Hi</span>
"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Markup(frame, "
<span>Hi</span>
")); - } - - // Integration test for HTML block rewriting - [Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/6183")] - public void Render_HtmlBlock_Integration() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using Microsoft.AspNetCore.Components; -namespace Test -{ - public class MyComponent : ComponentBase - { - [Parameter] - public RenderFragment ChildContent { get; set; } - } -} -")); - - var component = CompileToComponent(@" - - - - -
-
@(""hi"")
-
-
-
@(""hi"")
-
-
- -"); - - // Act - var frames = GetRenderTree(component); - - // Assert: component frames are correct - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "html", 9, 0), - frame => AssertFrame.MarkupWhitespace(frame, 1), - frame => AssertFrame.Markup(frame, "\n ", 2), - frame => AssertFrame.Element(frame, "body", 5, 3), - frame => AssertFrame.MarkupWhitespace(frame, 4), - frame => AssertFrame.Component(frame, "Test.MyComponent", 2, 5), - frame => AssertFrame.Attribute(frame, "ChildContent", 6), - frame => AssertFrame.MarkupWhitespace(frame, 16), - frame => AssertFrame.MarkupWhitespace(frame, 17)); - - // Assert: Captured ChildContent frames are correct - var childFrames = GetFrames((RenderFragment)frames[6].AttributeValue); - Assert.Collection( - childFrames.AsEnumerable(), - frame => AssertFrame.MarkupWhitespace(frame, 7), - frame => AssertFrame.Markup(frame, "
\n ", 8), - frame => AssertFrame.Element(frame, "div", 2, 9), - frame => AssertFrame.Text(frame, "hi", 10), - frame => AssertFrame.MarkupWhitespace(frame, 11), - frame => AssertFrame.Markup(frame, "
\n
\n ", 12), - frame => AssertFrame.Element(frame, "div", 2, 13), - frame => AssertFrame.Text(frame, "hi", 14), - frame => AssertFrame.Markup(frame, "\n
\n ", 15)); - } - - [Fact] - public void RazorTemplate_CanBeUsedFromComponent() - { - // Arrange - AdditionalSyntaxTrees.Add(Parse(@" -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Rendering; - -namespace Test -{ - public class Repeater : ComponentBase - { - [Parameter] public int Count { get; set; } - [Parameter] public RenderFragment Template { get; set; } - [Parameter] public string Value { get; set; } - - protected override void BuildRenderTree(RenderTreeBuilder builder) - { - for (var i = 0; i < Count; i++) - { - builder.AddContent(i, Template, Value); - } - } - } -} -")); - - var component = CompileToComponent(@" -@{ RenderFragment template = (context) => @
@context.ToLower()
; } - -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, "Test.Repeater", 4, 2), - frame => AssertFrame.Attribute(frame, "Count", typeof(int), 3), - frame => AssertFrame.Attribute(frame, "Value", typeof(string), 4), - frame => AssertFrame.Attribute(frame, "Template", typeof(RenderFragment), 5), - frame => AssertFrame.Element(frame, "div", 2, 0), - frame => AssertFrame.Text(frame, "hello, world!", 1), - frame => AssertFrame.Element(frame, "div", 2, 0), - frame => AssertFrame.Text(frame, "hello, world!", 1), - frame => AssertFrame.Element(frame, "div", 2, 0), - frame => AssertFrame.Text(frame, "hello, world!", 1)); - } - } -} diff --git a/src/Components/Blazor/Build/test/DirectiveRazorIntegrationTest.cs b/src/Components/Blazor/Build/test/DirectiveRazorIntegrationTest.cs deleted file mode 100644 index ef46dd1d19..0000000000 --- a/src/Components/Blazor/Build/test/DirectiveRazorIntegrationTest.cs +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Test.Helpers; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.AspNetCore.Blazor.Build.Test -{ - // Integration tests for Blazor's directives - public class DirectiveRazorIntegrationTest : RazorIntegrationTestBase - { - public DirectiveRazorIntegrationTest(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void ComponentsDoNotHaveLayoutAttributeByDefault() - { - // Arrange/Act - var component = CompileToComponent($"Hello"); - - // Assert - Assert.Null(component.GetType().GetCustomAttribute()); - } - - [Fact] - public void SupportsLayoutDeclarations() - { - // Arrange/Act - var testComponentTypeName = FullTypeName(); - var component = CompileToComponent( - $"@layout {testComponentTypeName}\n" + - $"Hello"); - var frames = GetRenderTree(component); - - // Assert - var layoutAttribute = component.GetType().GetCustomAttribute(); - Assert.NotNull(layoutAttribute); - Assert.Equal(typeof(TestLayout), layoutAttribute.LayoutType); - Assert.Collection(frames, - frame => AssertFrame.Text(frame, "Hello")); - } - - [Fact] - public void SupportsImplementsDeclarations() - { - // Arrange/Act - var testInterfaceTypeName = FullTypeName(); - var component = CompileToComponent( - $"@implements {testInterfaceTypeName}\n" + - $"Hello"); - var frames = GetRenderTree(component); - - // Assert - Assert.IsAssignableFrom(component); - Assert.Collection(frames, - frame => AssertFrame.Text(frame, "Hello")); - } - - [Fact] - public void SupportsMultipleImplementsDeclarations() - { - // Arrange/Act - var testInterfaceTypeName = FullTypeName(); - var testInterfaceTypeName2 = FullTypeName(); - var component = CompileToComponent( - $"@implements {testInterfaceTypeName}\n" + - $"@implements {testInterfaceTypeName2}\n" + - $"Hello"); - var frames = GetRenderTree(component); - - // Assert - Assert.IsAssignableFrom(component); - Assert.IsAssignableFrom(component); - Assert.Collection(frames, - frame => AssertFrame.Text(frame, "Hello")); - } - - [Fact] - public void SupportsInheritsDirective() - { - // Arrange/Act - var testBaseClassTypeName = FullTypeName(); - var component = CompileToComponent( - $"@inherits {testBaseClassTypeName}" + Environment.NewLine + - $"Hello"); - var frames = GetRenderTree(component); - - // Assert - Assert.IsAssignableFrom(component); - Assert.Collection(frames, - frame => AssertFrame.Text(frame, "Hello")); - } - - [Fact] - public void SupportsInjectDirective() - { - // Arrange/Act 1: Compilation - var componentType = CompileToComponent( - $"@inject {FullTypeName()} MyService1\n" + - $"@inject {FullTypeName()} MyService2\n" + - $"Hello from @MyService1 and @MyService2").GetType(); - - // Assert 1: Compiled type has correct properties - var propertyFlags = BindingFlags.Instance | BindingFlags.NonPublic; - var injectableProperties = componentType.GetProperties(propertyFlags) - .Where(p => p.GetCustomAttribute() != null); - Assert.Collection(injectableProperties.OrderBy(p => p.Name), - property => - { - Assert.Equal("MyService1", property.Name); - Assert.Equal(typeof(IMyService1), property.PropertyType); - Assert.False(property.GetMethod.IsPublic); - Assert.False(property.SetMethod.IsPublic); - }, - property => - { - Assert.Equal("MyService2", property.Name); - Assert.Equal(typeof(IMyService2), property.PropertyType); - Assert.False(property.GetMethod.IsPublic); - Assert.False(property.SetMethod.IsPublic); - }); - - // Arrange/Act 2: DI-supplied component has correct behavior - var serviceProvider = new TestServiceProvider(); - serviceProvider.AddService(new MyService1Impl()); - serviceProvider.AddService(new MyService2Impl()); - var componentFactory = new ComponentFactory(); - var component = componentFactory.InstantiateComponent(serviceProvider, componentType); - var frames = GetRenderTree(component); - - // Assert 2: Rendered component behaves correctly - Assert.Collection(frames, - frame => AssertFrame.Text(frame, "Hello from "), - frame => AssertFrame.Text(frame, typeof(MyService1Impl).FullName), - frame => AssertFrame.Text(frame, " and "), - frame => AssertFrame.Text(frame, typeof(MyService2Impl).FullName)); - } - - public class TestLayout : IComponent - { - [Parameter] - public RenderFragment Body { get; set; } - - public void Attach(RenderHandle renderHandle) - { - } - - public Task SetParametersAsync(ParameterView parameters) - { - return Task.CompletedTask; - } - } - - public interface ITestInterface { } - - public interface ITestInterface2 { } - - public class TestBaseClass : ComponentBase { } - - public interface IMyService1 { } - public interface IMyService2 { } - public class MyService1Impl : IMyService1 { } - public class MyService2Impl : IMyService2 { } - } -} diff --git a/src/Components/Blazor/Build/test/GenericComponentRazorIntegrationTest.cs b/src/Components/Blazor/Build/test/GenericComponentRazorIntegrationTest.cs deleted file mode 100644 index 7527e83535..0000000000 --- a/src/Components/Blazor/Build/test/GenericComponentRazorIntegrationTest.cs +++ /dev/null @@ -1,314 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Test.Helpers; -using Microsoft.CodeAnalysis.CSharp; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.AspNetCore.Blazor.Build.Test -{ - public class GenericComponentRazorIntegrationTest : RazorIntegrationTestBase - { - private readonly CSharpSyntaxTree GenericContextComponent = Parse(@" -using System; -using System.Collections.Generic; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Rendering; -namespace Test -{ - public class GenericContext : ComponentBase - { - protected override void BuildRenderTree(RenderTreeBuilder builder) - { - var items = (IReadOnlyList)Items ?? Array.Empty(); - for (var i = 0; i < items.Count; i++) - { - if (ChildContent == null) - { - builder.AddContent(i, Items[i]); - } - else - { - builder.AddContent(i, ChildContent, new Context() { Index = i, Item = items[i], }); - } - } - } - - [Parameter] - public List Items { get; set; } - - [Parameter] - public RenderFragment ChildContent { get; set; } - - public class Context - { - public int Index { get; set; } - public TItem Item { get; set; } - } - } -} -"); - - private readonly CSharpSyntaxTree MultipleGenericParameterComponent = Parse(@" -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Rendering; -namespace Test -{ - public class MultipleGenericParameter : ComponentBase - { - protected override void BuildRenderTree(RenderTreeBuilder builder) - { - builder.AddContent(0, Item1); - builder.AddContent(1, Item2); - builder.AddContent(2, Item3); - } - - [Parameter] - public TItem1 Item1 { get; set; } - - [Parameter] - public TItem2 Item2 { get; set; } - - [Parameter] - public TItem3 Item3 { get; set; } - } -} -"); - - public GenericComponentRazorIntegrationTest(ITestOutputHelper output) - : base(output) - { - } - - internal override bool UseTwoPhaseCompilation => true; - - [Fact] - public void Render_GenericComponent_WithoutChildContent() - { - // Arrange - AdditionalSyntaxTrees.Add(GenericContextComponent); - - var component = CompileToComponent(@" -() { 1, 2, })"" />"); - - // Act - var frames = GetRenderTree(component); - - // Assert - var genericComponentType = component.GetType().Assembly.DefinedTypes - .Where(t => t.Name == "GenericContext`1") - .Single() - .MakeGenericType(typeof(int)); - - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, genericComponentType.FullName, 2, 0), - frame => AssertFrame.Attribute(frame, "Items", typeof(List), 1), - frame => AssertFrame.Text(frame, "1", 0), - frame => AssertFrame.Text(frame, "2", 1)); - } - - [Fact] - public void Render_GenericComponent_WithRef() - { - // Arrange - AdditionalSyntaxTrees.Add(GenericContextComponent); - - var component = CompileToComponent(@" -() { 1, 2, })"" @ref=""_my"" /> - -@code { - GenericContext _my; - void Foo() { GC.KeepAlive(_my); } -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - var genericComponentType = component.GetType().Assembly.DefinedTypes - .Where(t => t.Name == "GenericContext`1") - .Single() - .MakeGenericType(typeof(int)); - - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, genericComponentType.FullName, 3, 0), - frame => AssertFrame.Attribute(frame, "Items", typeof(List), 1), - frame => AssertFrame.ComponentReferenceCapture(frame, 2), - frame => AssertFrame.Text(frame, "1", 0), - frame => AssertFrame.Text(frame, "2", 1)); - } - - [Fact] - public void Render_GenericComponent_WithChildContent() - { - // Arrange - AdditionalSyntaxTrees.Add(GenericContextComponent); - - var component = CompileToComponent(@" -() { 1, 2, })""> -
@(context.Item * context.Index)
-
"); - - // Act - var frames = GetRenderTree(component); - - // Assert - var genericComponentType = component.GetType().Assembly.DefinedTypes - .Where(t => t.Name == "GenericContext`1") - .Single() - .MakeGenericType(typeof(int)); - - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, genericComponentType.FullName, 3, 0), - frame => AssertFrame.Attribute(frame, "Items", typeof(List), 1), - frame => AssertFrame.Attribute(frame, "ChildContent", 2), - frame => AssertFrame.MarkupWhitespace(frame, 3), - frame => AssertFrame.Element(frame, "div", 2, 4), - frame => AssertFrame.Text(frame, "0", 5), - frame => AssertFrame.MarkupWhitespace(frame, 6), - frame => AssertFrame.MarkupWhitespace(frame, 3), - frame => AssertFrame.Element(frame, "div", 2, 4), - frame => AssertFrame.Text(frame, "2", 5), - frame => AssertFrame.MarkupWhitespace(frame, 6)); - } - - [Fact] - public void Render_GenericComponent_TypeInference_WithRef() - { - // Arrange - AdditionalSyntaxTrees.Add(GenericContextComponent); - - var component = CompileToComponent(@" -() { 1, 2, })"" @ref=""_my"" /> - -@code { - GenericContext _my; - void Foo() { GC.KeepAlive(_my); } -}"); - - // Act - var frames = GetRenderTree(component); - - // Assert - var genericComponentType = component.GetType().Assembly.DefinedTypes - .Where(t => t.Name == "GenericContext`1") - .Single() - .MakeGenericType(typeof(int)); - - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, genericComponentType.FullName, 3, 0), - frame => AssertFrame.Attribute(frame, "Items", typeof(List), 1), - frame => AssertFrame.ComponentReferenceCapture(frame, 2), - frame => AssertFrame.Text(frame, "1", 0), - frame => AssertFrame.Text(frame, "2", 1)); - } - - [Fact] - public void Render_GenericComponent_TypeInference_WithRef_Recursive() - { - // Arrange - AdditionalSyntaxTrees.Add(GenericContextComponent); - - var assembly = CompileToAssembly("Test.cshtml", @" -@typeparam TItem - - -@code { - [Parameter] public List MyItems { get; set; } - GenericContext _my; - void Foo() { GC.KeepAlive(_my); } -}"); - - var componentType = assembly.Assembly.DefinedTypes - .Where(t => t.Name == "Test`1") - .Single() - .MakeGenericType(typeof(int)); - var component = (IComponent)Activator.CreateInstance(componentType); - - // Act - var frames = GetRenderTree(component); - - // Assert - var genericComponentType = assembly.Assembly.DefinedTypes - .Where(t => t.Name == "GenericContext`1") - .Single() - .MakeGenericType(typeof(int)); - - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, genericComponentType.FullName, 3, 0), - frame => AssertFrame.Attribute(frame, "Items", 1), - frame => AssertFrame.ComponentReferenceCapture(frame, 2)); - } - - [Fact] - public void Render_GenericComponent_TypeInference_WithoutChildContent() - { - // Arrange - AdditionalSyntaxTrees.Add(GenericContextComponent); - - var component = CompileToComponent(@" -() { 1, 2, })"" />"); - - // Act - var frames = GetRenderTree(component); - - // Assert - var genericComponentType = component.GetType().Assembly.DefinedTypes - .Where(t => t.Name == "GenericContext`1") - .Single() - .MakeGenericType(typeof(int)); - - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, genericComponentType.FullName, 2, 0), - frame => AssertFrame.Attribute(frame, "Items", typeof(List), 1), - frame => AssertFrame.Text(frame, "1", 0), - frame => AssertFrame.Text(frame, "2", 1)); - } - - [Fact] - public void Render_GenericComponent_MultipleParameters_WithChildContent() - { - // Arrange - AdditionalSyntaxTrees.Add(MultipleGenericParameterComponent); - - var component = CompileToComponent(@" -"); - - // Act - var frames = GetRenderTree(component); - - // Assert - var genericComponentType = component.GetType().Assembly.DefinedTypes - .Where(t => t.Name == "MultipleGenericParameter`3") - .Single() - .MakeGenericType(typeof(int), typeof(string), typeof(long)); - - Assert.Collection( - frames, - frame => AssertFrame.Component(frame, genericComponentType.FullName, 4, 0), - frame => AssertFrame.Attribute(frame, "Item1", 3, 1), - frame => AssertFrame.Attribute(frame, "Item2", "FOO", 2), - frame => AssertFrame.Attribute(frame, "Item3", 39L, 3), - frame => AssertFrame.Text(frame, "3", 0), - frame => AssertFrame.Text(frame, "FOO", 1), - frame => AssertFrame.Text(frame, "39", 2)); - } - } -} diff --git a/src/Components/Blazor/Build/test/Microsoft.AspNetCore.Blazor.Build.Tests.csproj b/src/Components/Blazor/Build/test/Microsoft.AspNetCore.Blazor.Build.Tests.csproj deleted file mode 100644 index eee74d8755..0000000000 --- a/src/Components/Blazor/Build/test/Microsoft.AspNetCore.Blazor.Build.Tests.csproj +++ /dev/null @@ -1,54 +0,0 @@ - - - - $(DefaultNetCoreTargetFramework) - - - $(DefaultItemExcludes);TestFiles\**\* - - false - - - - - - - - - GENERATE_BASELINES;$(DefineConstants) - - - - TRACE - - - - - - - - - - - - - - - - - - - - - - - <_BclDirectory Include="$(MonoBaseClassLibraryPath)" /> - <_BclDirectory Include="$(MonoBaseClassLibraryFacadesPath)" /> - <_BclDirectory Include="$(MonoWasmFrameworkPath)" /> - - - - - - - diff --git a/src/Components/Blazor/Build/test/Razor/NotFoundProjectItem.cs b/src/Components/Blazor/Build/test/Razor/NotFoundProjectItem.cs deleted file mode 100644 index ec5359db65..0000000000 --- a/src/Components/Blazor/Build/test/Razor/NotFoundProjectItem.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; - -namespace Microsoft.AspNetCore.Razor.Language -{ - /// - /// A that does not exist. - /// - internal class NotFoundProjectItem : RazorProjectItem - { - /// - /// Initializes a new instance of . - /// - /// The base path. - /// The path. - public NotFoundProjectItem(string basePath, string path) - { - BasePath = basePath; - FilePath = path; - } - - /// - public override string BasePath { get; } - - /// - public override string FilePath { get; } - - /// - public override bool Exists => false; - - /// - public override string PhysicalPath => throw new NotSupportedException(); - - /// - public override Stream Read() => throw new NotSupportedException(); - } -} \ No newline at end of file diff --git a/src/Components/Blazor/Build/test/Razor/TestFile.cs b/src/Components/Blazor/Build/test/Razor/TestFile.cs deleted file mode 100644 index 70d5cacd70..0000000000 --- a/src/Components/Blazor/Build/test/Razor/TestFile.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Reflection; -using Xunit; - -namespace Microsoft.AspNetCore.Razor.Language -{ - public class TestFile - { - private TestFile(string resourceName, Assembly assembly) - { - Assembly = assembly; - ResourceName = Assembly.GetName().Name + "." + resourceName.Replace('/', '.').Replace('\\', '.'); - } - - public Assembly Assembly { get; } - - public string ResourceName { get; } - - public static TestFile Create(string resourceName, Type type) - { - return new TestFile(resourceName, type.GetTypeInfo().Assembly); - } - - public static TestFile Create(string resourceName, Assembly assembly) - { - return new TestFile(resourceName, assembly); - } - - public Stream OpenRead() - { - var stream = Assembly.GetManifestResourceStream(ResourceName); - if (stream == null) - { - Assert.True(false, string.Format("Manifest resource: {0} not found", ResourceName)); - } - - return stream; - } - - public bool Exists() - { - var resourceNames = Assembly.GetManifestResourceNames(); - foreach (var resourceName in resourceNames) - { - // Resource names are case-sensitive. - if (string.Equals(ResourceName, resourceName, StringComparison.Ordinal)) - { - return true; - } - } - - return false; - } - - public string ReadAllText() - { - using (var reader = new StreamReader(OpenRead())) - { - // The .Replace() calls normalize line endings, in case you get \n instead of \r\n - // since all the unit tests rely on the assumption that the files will have \r\n endings. - return reader.ReadToEnd().Replace("\r", "").Replace("\n", "\r\n"); - } - } - - /// - /// Saves the file to the specified path. - /// - public void Save(string filePath) - { - var directory = Path.GetDirectoryName(filePath); - if (!Directory.Exists(directory)) - { - Directory.CreateDirectory(directory); - } - - using (var outStream = File.Create(filePath)) - { - using (var inStream = OpenRead()) - { - inStream.CopyTo(outStream); - } - } - } - } -} diff --git a/src/Components/Blazor/Build/test/Razor/TestProject.cs b/src/Components/Blazor/Build/test/Razor/TestProject.cs deleted file mode 100644 index 5f14ef4bed..0000000000 --- a/src/Components/Blazor/Build/test/Razor/TestProject.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; - -namespace Microsoft.AspNetCore.Razor.Language -{ - public static class TestProject - { - public static string GetProjectDirectory(Type type) - { - var solutionDir = GetSolutionRootDirectory("Components"); - - var assemblyName = type.Assembly.GetName().Name; - - var projectDirectory = Path.Combine(solutionDir, "test", assemblyName); - if (!Directory.Exists(projectDirectory)) - { - throw new InvalidOperationException( -$@"Could not locate project directory for type {type.FullName}. -Directory probe path: {projectDirectory}."); - } - - return projectDirectory; - } - - public static string GetSolutionRootDirectory(string solution) - { - var applicationBasePath = AppContext.BaseDirectory; - var directoryInfo = new DirectoryInfo(applicationBasePath); - - do - { - var projectFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, $"{solution}.sln")); - if (projectFileInfo.Exists) - { - return projectFileInfo.DirectoryName; - } - - directoryInfo = directoryInfo.Parent; - } - while (directoryInfo.Parent != null); - - throw new Exception($"Solution file {solution}.sln could not be found in {applicationBasePath} or its parent directories."); - } - } -} diff --git a/src/Components/Blazor/Build/test/Razor/VirtualProjectFileSystem.cs b/src/Components/Blazor/Build/test/Razor/VirtualProjectFileSystem.cs deleted file mode 100644 index 3d694a82d0..0000000000 --- a/src/Components/Blazor/Build/test/Razor/VirtualProjectFileSystem.cs +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; - -namespace Microsoft.AspNetCore.Razor.Language -{ - internal class VirtualRazorProjectFileSystem : RazorProjectFileSystem - { - private readonly DirectoryNode _root = new DirectoryNode("/"); - - public override IEnumerable EnumerateItems(string basePath) - { - basePath = NormalizeAndEnsureValidPath(basePath); - var directory = _root.GetDirectory(basePath); - return directory?.EnumerateItems() ?? Enumerable.Empty(); - } - - [Obsolete("Use GetItem(string path, string fileKind)] instead")] - public override RazorProjectItem GetItem(string path) - { - return GetItem(path, fileKind: null); - } - - public override RazorProjectItem GetItem(string path, string fileKind) - { - // We ignore fileKind here because the _root is pre-filled with project items that already have fileKinds defined. This is - // a unique circumstance where the RazorProjectFileSystem is actually pre-filled with all of its project items on construction. - - path = NormalizeAndEnsureValidPath(path); - return _root.GetItem(path) ?? new NotFoundProjectItem(string.Empty, path); - } - - public void Add(RazorProjectItem projectItem) - { - if (projectItem == null) - { - throw new ArgumentNullException(nameof(projectItem)); - } - - var filePath = NormalizeAndEnsureValidPath(projectItem.FilePath); - _root.AddFile(new FileNode(filePath, projectItem)); - } - - // Internal for testing - [DebuggerDisplay("{Path}")] - internal class DirectoryNode - { - public DirectoryNode(string path) - { - Path = path; - } - - public string Path { get; } - - public List Directories { get; } = new List(); - - public List Files { get; } = new List(); - - public void AddFile(FileNode fileNode) - { - var filePath = fileNode.Path; - if (!filePath.StartsWith(Path, StringComparison.OrdinalIgnoreCase)) - { - var message = "Error"; - throw new InvalidOperationException(message); - } - - // Look for the first / that appears in the path after the current directory path. - var directoryPath = GetDirectoryPath(filePath); - var directory = GetOrAddDirectory(this, directoryPath, createIfNotExists: true); - Debug.Assert(directory != null); - directory.Files.Add(fileNode); - } - - public DirectoryNode GetDirectory(string path) - { - if (!path.StartsWith(Path, StringComparison.OrdinalIgnoreCase)) - { - var message = "Error"; - throw new InvalidOperationException(message); - } - - return GetOrAddDirectory(this, path); - } - - public IEnumerable EnumerateItems() - { - foreach (var file in Files) - { - yield return file.ProjectItem; - } - - foreach (var directory in Directories) - { - foreach (var file in directory.EnumerateItems()) - { - yield return file; - } - } - } - - public RazorProjectItem GetItem(string path) - { - if (!path.StartsWith(Path, StringComparison.OrdinalIgnoreCase)) - { - throw new InvalidOperationException("Error"); - } - - var directoryPath = GetDirectoryPath(path); - var directory = GetOrAddDirectory(this, directoryPath); - if (directory == null) - { - return null; - } - - foreach (var file in directory.Files) - { - var filePath = file.Path; - var directoryLength = directory.Path.Length; - - // path, filePath -> /Views/Home/Index.cshtml - // directory.Path -> /Views/Home/ - // We only need to match the file name portion since we've already matched the directory segment. - if (string.Compare(path, directoryLength, filePath, directoryLength, path.Length - directoryLength, StringComparison.OrdinalIgnoreCase) == 0) - { - return file.ProjectItem; - } - } - - return null; - } - - private static string GetDirectoryPath(string path) - { - // /dir1/dir2/file.cshtml -> /dir1/dir2/ - var fileNameIndex = path.LastIndexOf('/'); - if (fileNameIndex == -1) - { - return path; - } - - return path.Substring(0, fileNameIndex + 1); - } - - private static DirectoryNode GetOrAddDirectory( - DirectoryNode directory, - string path, - bool createIfNotExists = false) - { - Debug.Assert(!string.IsNullOrEmpty(path)); - if (path[path.Length - 1] != '/') - { - path += '/'; - } - - int index; - while ((index = path.IndexOf('/', directory.Path.Length)) != -1 && index != path.Length) - { - var subDirectory = FindSubDirectory(directory, path); - - if (subDirectory == null) - { - if (createIfNotExists) - { - var directoryPath = path.Substring(0, index + 1); // + 1 to include trailing slash - subDirectory = new DirectoryNode(directoryPath); - directory.Directories.Add(subDirectory); - } - else - { - return null; - } - } - - directory = subDirectory; - } - - return directory; - } - - private static DirectoryNode FindSubDirectory(DirectoryNode parentDirectory, string path) - { - for (var i = 0; i < parentDirectory.Directories.Count; i++) - { - // ParentDirectory.Path -> /Views/Home/ - // CurrentDirectory.Path -> /Views/Home/SubDir/ - // Path -> /Views/Home/SubDir/MorePath/File.cshtml - // Each invocation of FindSubDirectory returns the immediate subdirectory along the path to the file. - - var currentDirectory = parentDirectory.Directories[i]; - var directoryPath = currentDirectory.Path; - var startIndex = parentDirectory.Path.Length; - var directoryNameLength = directoryPath.Length - startIndex; - - if (string.Compare(path, startIndex, directoryPath, startIndex, directoryPath.Length - startIndex, StringComparison.OrdinalIgnoreCase) == 0) - { - return currentDirectory; - } - } - - return null; - } - } - - // Internal for testing - [DebuggerDisplay("{Path}")] - internal struct FileNode - { - public FileNode(string path, RazorProjectItem projectItem) - { - Path = path; - ProjectItem = projectItem; - } - - public string Path { get; } - - public RazorProjectItem ProjectItem { get; } - } - } -} diff --git a/src/Components/Blazor/Build/test/Razor/VirtualProjectItem.cs b/src/Components/Blazor/Build/test/Razor/VirtualProjectItem.cs deleted file mode 100644 index 68c135d715..0000000000 --- a/src/Components/Blazor/Build/test/Razor/VirtualProjectItem.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.IO; - -namespace Microsoft.AspNetCore.Razor.Language -{ - internal class VirtualProjectItem : RazorProjectItem - { - private readonly byte[] _content; - - public VirtualProjectItem( - string basePath, - string filePath, - string physicalPath, - string relativePhysicalPath, - string fileKind, - byte[] content) - { - BasePath = basePath; - FilePath = filePath; - PhysicalPath = physicalPath; - RelativePhysicalPath = relativePhysicalPath; - _content = content; - - // Base class will detect based on file-extension. - FileKind = fileKind ?? base.FileKind; - } - - public override string BasePath { get; } - - public override string RelativePhysicalPath { get; } - - public override string FileKind { get; } - - public override string FilePath { get; } - - public override string PhysicalPath { get; } - - public override bool Exists => true; - - public override Stream Read() - { - return new MemoryStream(_content); - } - } -} diff --git a/src/Components/Blazor/Build/test/RazorIntegrationTestBase.cs b/src/Components/Blazor/Build/test/RazorIntegrationTestBase.cs deleted file mode 100644 index 943a658a36..0000000000 --- a/src/Components/Blazor/Build/test/RazorIntegrationTestBase.cs +++ /dev/null @@ -1,542 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Rendering; -using Microsoft.AspNetCore.Components.RenderTree; -using Microsoft.AspNetCore.Components.Test.Helpers; -using Microsoft.AspNetCore.Razor.Language; -using Microsoft.AspNetCore.Razor.Language.CodeGeneration; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Razor; -using Microsoft.Extensions.Logging.Abstractions; -using Xunit; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.AspNetCore.Blazor.Build.Test -{ - public class RazorIntegrationTestBase - { - private static readonly AsyncLocal _output = new AsyncLocal(); - - internal const string ArbitraryWindowsPath = "x:\\dir\\subdir\\Test"; - internal const string ArbitraryMacLinuxPath = "/dir/subdir/Test"; - - // Creating the initial compilation + reading references is on the order of 250ms without caching - // so making sure it doesn't happen for each test. - private static readonly CSharpCompilation BaseCompilation; - - private static CSharpParseOptions CSharpParseOptions { get; } - - static RazorIntegrationTestBase() - { - var referenceAssemblyRoots = new[] - { - typeof(System.Runtime.AssemblyTargetedPatchBandAttribute).Assembly, // System.Runtime - typeof(ComponentBase).Assembly, - typeof(RazorIntegrationTestBase).Assembly, // Reference this assembly, so that we can refer to test component types - }; - - var referenceAssemblies = referenceAssemblyRoots - .SelectMany(assembly => assembly.GetReferencedAssemblies().Concat(new[] { assembly.GetName() })) - .Distinct() - .Select(Assembly.Load) - .Select(assembly => MetadataReference.CreateFromFile(assembly.Location)) - .ToList(); - BaseCompilation = CSharpCompilation.Create( - "TestAssembly", - Array.Empty(), - referenceAssemblies, - new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - - CSharpParseOptions = new CSharpParseOptions(LanguageVersion.Preview); - } - - public RazorIntegrationTestBase(ITestOutputHelper output) - { - _output.Value = output; - - AdditionalSyntaxTrees = new List(); - AdditionalRazorItems = new List(); - - Configuration = RazorConfiguration.Create(RazorLanguageVersion.Latest, "MVC-3.0", Array.Empty()); - FileKind = FileKinds.Component; // Treat input files as components by default. - FileSystem = new VirtualRazorProjectFileSystem(); - PathSeparator = Path.DirectorySeparatorChar.ToString(); - WorkingDirectory = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ArbitraryWindowsPath : ArbitraryMacLinuxPath; - - // Many of the rendering tests include line endings in the output. - LineEnding = "\n"; - NormalizeSourceLineEndings = true; - - DefaultRootNamespace = "Test"; // Matches the default working directory - DefaultFileName = "TestComponent.cshtml"; - } - - internal List AdditionalRazorItems { get; } - - internal List AdditionalSyntaxTrees { get; } - - internal virtual RazorConfiguration Configuration { get; } - - internal virtual string DefaultRootNamespace { get; } - - internal virtual string DefaultFileName { get; } - - internal virtual bool DesignTime { get; } - - internal virtual string FileKind { get; } - - internal virtual VirtualRazorProjectFileSystem FileSystem { get; } - - // Used to force a specific style of line-endings for testing. This matters - // for the baseline tests that exercise line mappings. Even though we normalize - // newlines for testing, the difference between platforms affects the data through - // the *count* of characters written. - internal virtual string LineEnding { get; } - - internal virtual string PathSeparator { get; } - - internal virtual bool NormalizeSourceLineEndings { get; } - - internal virtual bool UseTwoPhaseCompilation { get; } - - internal virtual string WorkingDirectory { get; } - - // Intentionally private, we don't want tests messing with this because it's fragile. - private RazorProjectEngine CreateProjectEngine(MetadataReference[] references) - { - return RazorProjectEngine.Create(Configuration, FileSystem, b => - { - b.SetRootNamespace(DefaultRootNamespace); - - // Turn off checksums, we're testing code generation. - b.Features.Add(new SuppressChecksum()); - - if (LineEnding != null) - { - b.Phases.Insert(0, new ForceLineEndingPhase(LineEnding)); - } - - // Including MVC here so that we can find any issues that arise from mixed MVC + Components. - Microsoft.AspNetCore.Mvc.Razor.Extensions.RazorExtensions.Register(b); - - // Features that use Roslyn are mandatory for components - Microsoft.CodeAnalysis.Razor.CompilerFeatures.Register(b); - - b.Features.Add(new CompilationTagHelperFeature()); - b.Features.Add(new DefaultMetadataReferenceFeature() - { - References = references, - }); - }); - } - - internal RazorProjectItem CreateProjectItem(string cshtmlRelativePath, string cshtmlContent) - { - var fullPath = WorkingDirectory + PathSeparator + cshtmlRelativePath; - - // FilePaths in Razor are **always** are of the form '/a/b/c.cshtml' - var filePath = cshtmlRelativePath.Replace('\\', '/'); - if (!filePath.StartsWith('/')) - { - filePath = '/' + filePath; - } - - if (NormalizeSourceLineEndings) - { - cshtmlContent = cshtmlContent.Replace("\r", "").Replace("\n", LineEnding); - } - - return new VirtualProjectItem( - WorkingDirectory, - filePath, - fullPath, - cshtmlRelativePath, - FileKind, - Encoding.UTF8.GetBytes(cshtmlContent.TrimStart())); - } - - protected CompileToCSharpResult CompileToCSharp(string cshtmlContent) - { - return CompileToCSharp(DefaultFileName, cshtmlContent); - } - - protected CompileToCSharpResult CompileToCSharp(string cshtmlRelativePath, string cshtmlContent) - { - if (UseTwoPhaseCompilation) - { - // The first phase won't include any metadata references for component discovery. This mirrors - // what the build does. - var projectEngine = CreateProjectEngine(Array.Empty()); - - RazorCodeDocument codeDocument; - foreach (var item in AdditionalRazorItems) - { - // Result of generating declarations - codeDocument = projectEngine.ProcessDeclarationOnly(item); - Assert.Empty(codeDocument.GetCSharpDocument().Diagnostics); - - var syntaxTree = Parse(codeDocument.GetCSharpDocument().GeneratedCode, path: item.FilePath); - AdditionalSyntaxTrees.Add(syntaxTree); - } - - // Result of generating declarations - var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent); - codeDocument = projectEngine.ProcessDeclarationOnly(projectItem); - var declaration = new CompileToCSharpResult - { - BaseCompilation = BaseCompilation.AddSyntaxTrees(AdditionalSyntaxTrees), - CodeDocument = codeDocument, - Code = codeDocument.GetCSharpDocument().GeneratedCode, - Diagnostics = codeDocument.GetCSharpDocument().Diagnostics, - }; - - // Result of doing 'temp' compilation - var tempAssembly = CompileToAssembly(declaration); - - // Add the 'temp' compilation as a metadata reference - var references = BaseCompilation.References.Concat(new[] { tempAssembly.Compilation.ToMetadataReference() }).ToArray(); - projectEngine = CreateProjectEngine(references); - - // Now update the any additional files - foreach (var item in AdditionalRazorItems) - { - // Result of generating declarations - codeDocument = DesignTime ? projectEngine.ProcessDesignTime(item) : projectEngine.Process(item); - Assert.Empty(codeDocument.GetCSharpDocument().Diagnostics); - - // Replace the 'declaration' syntax tree - var syntaxTree = Parse(codeDocument.GetCSharpDocument().GeneratedCode, path: item.FilePath); - AdditionalSyntaxTrees.RemoveAll(st => st.FilePath == item.FilePath); - AdditionalSyntaxTrees.Add(syntaxTree); - } - - // Result of real code generation for the document under test - codeDocument = DesignTime ? projectEngine.ProcessDesignTime(projectItem) : projectEngine.Process(projectItem); - - _output.Value.WriteLine("Use this output when opening an issue"); - _output.Value.WriteLine(string.Empty); - - _output.Value.WriteLine($"## Main source file ({projectItem.FileKind}):"); - _output.Value.WriteLine("```"); - _output.Value.WriteLine(ReadProjectItem(projectItem)); - _output.Value.WriteLine("```"); - _output.Value.WriteLine(string.Empty); - - foreach (var item in AdditionalRazorItems) - { - _output.Value.WriteLine($"### Additional source file ({item.FileKind}):"); - _output.Value.WriteLine("```"); - _output.Value.WriteLine(ReadProjectItem(item)); - _output.Value.WriteLine("```"); - _output.Value.WriteLine(string.Empty); - } - - _output.Value.WriteLine("## Generated C#:"); - _output.Value.WriteLine("```C#"); - _output.Value.WriteLine(codeDocument.GetCSharpDocument().GeneratedCode); - _output.Value.WriteLine("```"); - - return new CompileToCSharpResult - { - BaseCompilation = BaseCompilation.AddSyntaxTrees(AdditionalSyntaxTrees), - CodeDocument = codeDocument, - Code = codeDocument.GetCSharpDocument().GeneratedCode, - Diagnostics = codeDocument.GetCSharpDocument().Diagnostics, - }; - } - else - { - // For single phase compilation tests just use the base compilation's references. - // This will include the built-in Blazor components. - var projectEngine = CreateProjectEngine(BaseCompilation.References.ToArray()); - - var projectItem = CreateProjectItem(cshtmlRelativePath, cshtmlContent); - var codeDocument = DesignTime ? projectEngine.ProcessDesignTime(projectItem) : projectEngine.Process(projectItem); - - // Log the generated code for test results. - _output.Value.WriteLine("Use this output when opening an issue"); - _output.Value.WriteLine(string.Empty); - - _output.Value.WriteLine($"## Main source file ({projectItem.FileKind}):"); - _output.Value.WriteLine("```"); - _output.Value.WriteLine(ReadProjectItem(projectItem)); - _output.Value.WriteLine("```"); - _output.Value.WriteLine(string.Empty); - - _output.Value.WriteLine("## Generated C#:"); - _output.Value.WriteLine("```C#"); - _output.Value.WriteLine(codeDocument.GetCSharpDocument().GeneratedCode); - _output.Value.WriteLine("```"); - - return new CompileToCSharpResult - { - BaseCompilation = BaseCompilation.AddSyntaxTrees(AdditionalSyntaxTrees), - CodeDocument = codeDocument, - Code = codeDocument.GetCSharpDocument().GeneratedCode, - Diagnostics = codeDocument.GetCSharpDocument().Diagnostics, - }; - } - } - - protected CompileToAssemblyResult CompileToAssembly(string cshtmlRelativePath, string cshtmlContent) - { - var cSharpResult = CompileToCSharp(cshtmlRelativePath, cshtmlContent); - return CompileToAssembly(cSharpResult); - } - - protected CompileToAssemblyResult CompileToAssembly(CompileToCSharpResult cSharpResult, bool throwOnFailure = true) - { - if (cSharpResult.Diagnostics.Any()) - { - var diagnosticsLog = string.Join(Environment.NewLine, cSharpResult.Diagnostics.Select(d => d.ToString()).ToArray()); - throw new InvalidOperationException($"Aborting compilation to assembly because RazorCompiler returned nonempty diagnostics: {diagnosticsLog}"); - } - - var syntaxTrees = new[] - { - Parse(cSharpResult.Code), - }; - - var compilation = cSharpResult.BaseCompilation.AddSyntaxTrees(syntaxTrees); - - var diagnostics = compilation - .GetDiagnostics() - .Where(d => d.Severity != DiagnosticSeverity.Hidden); - - if (diagnostics.Any() && throwOnFailure) - { - throw new CompilationFailedException(compilation); - } - else if (diagnostics.Any()) - { - return new CompileToAssemblyResult - { - Compilation = compilation, - Diagnostics = diagnostics, - }; - } - - using (var peStream = new MemoryStream()) - { - compilation.Emit(peStream); - - return new CompileToAssemblyResult - { - Compilation = compilation, - Diagnostics = diagnostics, - Assembly = diagnostics.Any() ? null : Assembly.Load(peStream.ToArray()) - }; - } - } - - protected IComponent CompileToComponent(string cshtmlSource) - { - var assemblyResult = CompileToAssembly(DefaultFileName, cshtmlSource); - - var componentFullTypeName = $"{DefaultRootNamespace}.{Path.GetFileNameWithoutExtension(DefaultFileName)}"; - return CompileToComponent(assemblyResult, componentFullTypeName); - } - - protected IComponent CompileToComponent(CompileToCSharpResult cSharpResult, string fullTypeName) - { - return CompileToComponent(CompileToAssembly(cSharpResult), fullTypeName); - } - - protected IComponent CompileToComponent(CompileToAssemblyResult assemblyResult, string fullTypeName) - { - var componentType = assemblyResult.Assembly.GetType(fullTypeName); - if (componentType == null) - { - throw new XunitException( - $"Failed to find component type '{fullTypeName}'. Found types:" + Environment.NewLine + - string.Join(Environment.NewLine, assemblyResult.Assembly.ExportedTypes.Select(t => t.FullName))); - } - - return (IComponent)Activator.CreateInstance(componentType); - } - - protected static CSharpSyntaxTree Parse(string text, string path = null) - { - return (CSharpSyntaxTree)CSharpSyntaxTree.ParseText(text, CSharpParseOptions, path: path); - } - - protected static string FullTypeName() => typeof(T).FullName.Replace('+', '.'); - - protected RenderTreeFrame[] GetRenderTree(IComponent component) - { - var renderer = new TestRenderer(); - return GetRenderTree(renderer, component); - } - - protected private RenderTreeFrame[] GetRenderTree(TestRenderer renderer, IComponent component) - { - renderer.AttachComponent(component); - var task = renderer.Dispatcher.InvokeAsync(() => component.SetParametersAsync(ParameterView.Empty)); - // we will have to change this method if we add a test that does actual async work. - Assert.True(task.Status.HasFlag(TaskStatus.RanToCompletion) || task.Status.HasFlag(TaskStatus.Faulted)); - if (task.IsFaulted) - { - ExceptionDispatchInfo.Capture(task.Exception.InnerException).Throw(); - } - return renderer.LatestBatchReferenceFrames; - } - - protected ArrayRange GetFrames(RenderFragment fragment) - { - var builder = new RenderTreeBuilder(); - fragment(builder); - return builder.GetFrames(); - } - - protected static void AssertSourceEquals(string expected, CompileToCSharpResult generated) - { - // Normalize the paths inside the expected result to match the OS paths - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - var windowsPath = Path.Combine(ArbitraryWindowsPath, generated.CodeDocument.Source.RelativePath).Replace('/', '\\'); - expected = expected.Replace(windowsPath, generated.CodeDocument.Source.FilePath); - } - - expected = expected.Trim(); - Assert.Equal(expected, generated.Code.Trim(), ignoreLineEndingDifferences: true); - } - - private static string ReadProjectItem(RazorProjectItem item) - { - using (var reader = new StreamReader(item.Read())) - { - return reader.ReadToEnd(); - } - } - - protected class CompileToCSharpResult - { - // A compilation that can be used *with* this code to compile an assembly - public Compilation BaseCompilation { get; set; } - public RazorCodeDocument CodeDocument { get; set; } - public string Code { get; set; } - public IEnumerable Diagnostics { get; set; } - } - - protected class CompileToAssemblyResult - { - public Assembly Assembly { get; set; } - public Compilation Compilation { get; set; } - public string VerboseLog { get; set; } - public IEnumerable Diagnostics { get; set; } - } - - protected class TestRenderer : Renderer - { - public TestRenderer() : base(new TestServiceProvider(), NullLoggerFactory.Instance) - { - } - - public override Dispatcher Dispatcher { get; } = Dispatcher.CreateDefault(); - - public RenderTreeFrame[] LatestBatchReferenceFrames { get; private set; } - - public void AttachComponent(IComponent component) - => AssignRootComponentId(component); - - protected override void HandleException(Exception exception) - { - ExceptionDispatchInfo.Capture(exception).Throw(); - } - - protected override Task UpdateDisplayAsync(in RenderBatch renderBatch) - { - LatestBatchReferenceFrames = renderBatch.ReferenceFrames.AsEnumerable().ToArray(); - return Task.CompletedTask; - } - } - - private class CompilationFailedException : XunitException - { - public CompilationFailedException(Compilation compilation) - { - Compilation = compilation; - } - - public Compilation Compilation { get; } - - public override string Message - { - get - { - var builder = new StringBuilder(); - builder.AppendLine("Compilation failed: "); - - var diagnostics = Compilation.GetDiagnostics(); - var syntaxTreesWithErrors = new HashSet(); - foreach (var diagnostic in diagnostics) - { - builder.AppendLine(diagnostic.ToString()); - - if (diagnostic.Location.IsInSource) - { - syntaxTreesWithErrors.Add(diagnostic.Location.SourceTree); - } - } - - if (syntaxTreesWithErrors.Any()) - { - builder.AppendLine(); - builder.AppendLine(); - - foreach (var syntaxTree in syntaxTreesWithErrors) - { - builder.AppendLine($"File {syntaxTree.FilePath ?? "unknown"}:"); - builder.AppendLine(syntaxTree.GetText().ToString()); - } - } - - return builder.ToString(); - } - } - } - - private class SuppressChecksum : IConfigureRazorCodeGenerationOptionsFeature - { - public int Order => 0; - - public RazorEngine Engine { get; set; } - - public void Configure(RazorCodeGenerationOptionsBuilder options) - { - options.SuppressChecksum = true; - } - } - - private class ForceLineEndingPhase : RazorEnginePhaseBase - { - public ForceLineEndingPhase(string lineEnding) - { - LineEnding = lineEnding; - } - - public string LineEnding { get; } - - protected override void ExecuteCore(RazorCodeDocument codeDocument) - { - var field = typeof(CodeRenderingContext).GetField("NewLineString", BindingFlags.Static | BindingFlags.NonPublic); - var key = field.GetValue(null); - codeDocument.Items[key] = LineEnding; - } - } - } -} diff --git a/src/Components/Blazor/Build/test/RenderingRazorIntegrationTest.cs b/src/Components/Blazor/Build/test/RenderingRazorIntegrationTest.cs deleted file mode 100644 index 3f380cbc79..0000000000 --- a/src/Components/Blazor/Build/test/RenderingRazorIntegrationTest.cs +++ /dev/null @@ -1,744 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.RenderTree; -using Microsoft.AspNetCore.Components.Test.Helpers; -using Microsoft.AspNetCore.Components.Web; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.AspNetCore.Blazor.Build.Test -{ - // Integration tests for the end-to-end of successful Razor compilation of component definitions - // Includes running the component code to verify the output. - public class RenderingRazorIntegrationTest : RazorIntegrationTestBase - { - public RenderingRazorIntegrationTest(ITestOutputHelper output) - : base(output) - { - } - - [Fact] - public void SupportsPlainText() - { - // Arrange/Act - var component = CompileToComponent("Some plain text"); - var frames = GetRenderTree(component); - - // Assert - Assert.Collection(frames, - frame => AssertFrame.Text(frame, "Some plain text", 0)); - } - - [Fact] - public void SupportsCSharpExpressions() - { - // Arrange/Act - var component = CompileToComponent(@" - @(""Hello"") - @((object)null) - @(123) - @(new object()) - "); - - // Assert - var frames = GetRenderTree(component); - Assert.Collection(frames, - frame => AssertFrame.Text(frame, "Hello", 0), - frame => AssertFrame.MarkupWhitespace(frame, 1), - frame => AssertFrame.TextWhitespace(frame, 2), // @((object)null) - frame => AssertFrame.MarkupWhitespace(frame, 3), - frame => AssertFrame.Text(frame, "123", 4), - frame => AssertFrame.MarkupWhitespace(frame, 5), - frame => AssertFrame.Text(frame, new object().ToString(), 6)); - } - - [Fact] - public void SupportsCSharpFunctionsBlock() - { - // Arrange/Act - var component = CompileToComponent(@" - @foreach(var item in items) { - @item - } - @code { - string[] items = new[] { ""First"", ""Second"", ""Third"" }; - } - "); - - // Assert - var frames = GetRenderTree(component); - Assert.Collection(frames, - frame => AssertFrame.Text(frame, "First", 0), - frame => AssertFrame.Text(frame, "Second", 0), - frame => AssertFrame.Text(frame, "Third", 0)); - } - - [Fact] - public void SupportsElementsWithDynamicContent() - { - // Arrange/Act - var component = CompileToComponent("Hello @(\"there\")"); - - // Assert - Assert.Collection(GetRenderTree(component), - frame => AssertFrame.Element(frame, "myelem", 3, 0), - frame => AssertFrame.Text(frame, "Hello ", 1), - frame => AssertFrame.Text(frame, "there", 2)); - } - - [Fact] - public void SupportsElementsAsStaticBlock() - { - // Arrange/Act - var component = CompileToComponent("Hello"); - - // Assert - Assert.Collection(GetRenderTree(component), - frame => AssertFrame.Markup(frame, "Hello", 0)); - } - - [Fact] - public void CreatesSeparateMarkupFrameForEachTopLevelStaticElement() - { - // The JavaScript-side rendering code does not rely on this behavior. It supports - // inserting markup frames with arbitrary markup (e.g., multiple top-level elements - // or none). This test exists only as an observation of the current behavior rather - // than a promise that we never want to change it. - - // Arrange/Act - var component = CompileToComponent( - "@(\"Hi\") a b "); - - // Assert - var frames = GetRenderTree(component); - Assert.Collection( - frames, - frame => AssertFrame.Element(frame, "root", 5, 0), - frame => AssertFrame.Text(frame, "Hi", 1), - frame => AssertFrame.Text(frame, " ", 2), - frame => AssertFrame.Markup(frame, "a ", 3), - frame => AssertFrame.Markup(frame, "b ", 4)); - } - - [Fact] - public void RendersMarkupStringAsMarkupFrame() - { - // Arrange/Act - var component = CompileToComponent( - "@{ var someMarkup = new MarkupString(\"
Hello
\"); }" - + "

@someMarkup

"); - - // Assert - Assert.Collection(GetRenderTree(component), - frame => AssertFrame.Element(frame, "p", 2, 0), - frame => AssertFrame.Markup(frame, "
Hello
", 1)); - } - - [Fact] - public void SupportsSelfClosingElementsWithDynamicContent() - { - // Arrange/Act - var component = CompileToComponent("Some text so elem isn't at position 0 "); - - // Assert - Assert.Collection(GetRenderTree(component), - frame => AssertFrame.Text(frame, "Some text so elem isn't at position 0 ", 0), - frame => AssertFrame.Element(frame, "myelem", 2, 1), - frame => AssertFrame.Attribute(frame, "myattr", "val", 2)); - } - - [Fact] - public void SupportsSelfClosingElementsAsStaticBlock() - { - // Arrange/Act - var component = CompileToComponent("Some text so elem isn't at position 0 "); - - // Assert - Assert.Collection( - GetRenderTree(component), - frame => AssertFrame.Markup(frame, "Some text so elem isn't at position 0 ", 0)); - } - - [Fact] - public void SupportsVoidHtmlElements() - { - // Arrange/Act - var component = CompileToComponent("Some text so elem isn't at position 0 "); - - // Assert - Assert.Collection( - GetRenderTree(component), - frame => AssertFrame.Markup(frame, "Some text so elem isn't at position 0 ", 0)); - } - - [Fact] - public void SupportsComments() - { - // Arrange/Act - var component = CompileToComponent("StartEnd"); - var frames = GetRenderTree(component); - - // Assert - Assert.Collection( - frames, - frame => AssertFrame.Markup(frame, "StartEnd", 0)); - } - - [Fact] - public void SupportsAttributesWithLiteralValues() - { - // Arrange/Act - var component = CompileToComponent("@(\"Hello\")"); - - // Assert - Assert.Collection(GetRenderTree(component), - frame => AssertFrame.Element(frame, "elem", 4, 0), - frame => AssertFrame.Attribute(frame, "attrib-one", "Value 1", 1), - frame => AssertFrame.Attribute(frame, "a2", "v2", 2), - frame => AssertFrame.Text(frame, "Hello", 3)); - } - - [Fact] - public void SupportsAttributesWithStringExpressionValues() - { - // Arrange/Act - var component = CompileToComponent( - "@{ var myValue = \"My string\"; }" - + ""); - - // Assert - Assert.Collection(GetRenderTree(component), - frame => AssertFrame.Element(frame, "elem", 2, 0), - frame => AssertFrame.Attribute(frame, "attr", "My string", 1)); - } - - [Fact] - public void SupportsAttributesWithNonStringExpressionValues() - { - // Arrange/Act - var component = CompileToComponent( - "@{ var myValue = 123; }" - + ""); - - // Assert - Assert.Collection(GetRenderTree(component), - frame => AssertFrame.Element(frame, "elem", 2, 0), - frame => AssertFrame.Attribute(frame, "attr", "123", 1)); - } - - [Fact] - public void SupportsAttributesWithInterpolatedStringExpressionValues() - { - // Arrange/Act - var component = CompileToComponent( - "@{ var myValue = \"world\"; var myNum=123; }" - + ""); - - // Assert - Assert.Collection(GetRenderTree(component), - frame => AssertFrame.Element(frame, "elem", 2, 0), - frame => AssertFrame.Attribute(frame, "attr", "Hello, WORLD with number 246!", 1)); - } - - [Fact] - public void SupportsAttributesWithInterpolatedTernaryExpressionValues() - { - // Arrange/Act - var component = CompileToComponent( - "@{ var myValue = \"world\"; }" - + ""); - - // Assert - Assert.Collection(GetRenderTree(component), - frame => AssertFrame.Element(frame, "elem", 2, 0), - frame => AssertFrame.Attribute(frame, "attr", "Hello, world!", 1)); - } - - [Fact] - public void SupportsHyphenedAttributesWithCSharpExpressionValues() - { - // Arrange/Act - var component = CompileToComponent( - "@{ var myValue = \"My string\"; }" - + ""); - - // Assert - Assert.Collection(GetRenderTree(component), - frame => AssertFrame.Element(frame, "elem", 2, 0), - frame => AssertFrame.Attribute(frame, "abc-def", "My string", 1)); - } - - [Fact] - public void SupportsDataDashAttributes() - { - // Arrange/Act - var component = CompileToComponent(@" -@{ - var myValue = ""Expression value""; -} -"); - - // Assert - Assert.Collection( - GetRenderTree(component), - frame => AssertFrame.Element(frame, "elem", 3, 0), - frame => AssertFrame.Attribute(frame, "data-abc", "Literal value", 1), - frame => AssertFrame.Attribute(frame, "data-def", "Expression value", 2)); - } - - [Fact] - public void SupportsUsingStatements() - { - // Arrange/Act - var component = CompileToComponent( - @"@using System.Collections.Generic - @(typeof(List).FullName)"); - var frames = GetRenderTree(component); - - // Assert - Assert.Collection(frames, - frame => AssertFrame.Text(frame, typeof(List).FullName, 0)); - } - - [Fact] - public async Task SupportsTwoWayBindingForTextboxes() - { - // Arrange/Act - var component = CompileToComponent(@" -@using Microsoft.AspNetCore.Components.Web - -@code { - public string MyValue { get; set; } = ""Initial value""; -}"); - var myValueProperty = component.GetType().GetProperty("MyValue"); - - var renderer = new TestRenderer(); - - // Assert - EventCallback setter = default; - var frames = GetRenderTree(renderer, component); - Assert.Collection(frames, - frame => AssertFrame.Element(frame, "input", 3, 0), - frame => AssertFrame.Attribute(frame, "value", "Initial value", 1), - frame => - { - AssertFrame.Attribute(frame, "onchange", 2); - setter = Assert.IsType(frame.AttributeValue); - }); - - // Trigger the change event to show it updates the property - // - // This should always complete synchronously. - var task = renderer.Dispatcher.InvokeAsync(() => setter.InvokeAsync(new ChangeEventArgs { Value = "Modified value", })); - Assert.Equal(TaskStatus.RanToCompletion, task.Status); - await task; - - Assert.Equal("Modified value", myValueProperty.GetValue(component)); - } - - [Fact] - public async Task SupportsTwoWayBindingForTextareas() - { - // Arrange/Act - var component = CompileToComponent(@" -@using Microsoft.AspNetCore.Components.Web - -@code { - public string MyValue { get; set; } = ""Initial value""; -}"); - var myValueProperty = component.GetType().GetProperty("MyValue"); - - var renderer = new TestRenderer(); - - // Assert - EventCallback setter = default; - var frames = GetRenderTree(renderer, component); - Assert.Collection(frames, - frame => AssertFrame.Element(frame, "textarea", 3, 0), - frame => AssertFrame.Attribute(frame, "value", "Initial value", 1), - frame => - { - AssertFrame.Attribute(frame, "onchange", 2); - setter = Assert.IsType(frame.AttributeValue); - }); - - // Trigger the change event to show it updates the property - // - // This should always complete synchronously. - var task = renderer.Dispatcher.InvokeAsync(() => setter.InvokeAsync(new ChangeEventArgs { Value = "Modified value", })); - Assert.Equal(TaskStatus.RanToCompletion, task.Status); - await task; - - Assert.Equal("Modified value", myValueProperty.GetValue(component)); - } - - [Fact] - public async Task SupportsTwoWayBindingForDateValues() - { - // Arrange/Act - var component = CompileToComponent(@" -@using Microsoft.AspNetCore.Components.Web - -@code { - public DateTime MyDate { get; set; } = new DateTime(2018, 3, 4, 1, 2, 3); -}"); - var myDateProperty = component.GetType().GetProperty("MyDate"); - - var renderer = new TestRenderer(); - - // Assert - EventCallback setter = default; - var frames = GetRenderTree(renderer, component); - Assert.Collection(frames, - frame => AssertFrame.Element(frame, "input", 3, 0), - frame => AssertFrame.Attribute(frame, "value", new DateTime(2018, 3, 4, 1, 2, 3).ToString(), 1), - frame => - { - AssertFrame.Attribute(frame, "onchange", 2); - setter = Assert.IsType(frame.AttributeValue); - }); - - // Trigger the change event to show it updates the property - // Trigger the change event to show it updates the property - // - // This should always complete synchronously. - var newDateValue = new DateTime(2018, 3, 5, 4, 5, 6); - var task = renderer.Dispatcher.InvokeAsync(() => setter.InvokeAsync(new ChangeEventArgs { Value = newDateValue.ToString(), })); - Assert.Equal(TaskStatus.RanToCompletion, task.Status); - await task; - - Assert.Equal(newDateValue, myDateProperty.GetValue(component)); - } - - [Fact] - public async Task SupportsTwoWayBindingForDateValuesWithFormatString() - { - // Arrange/Act - var testDateFormat = "ddd yyyy-MM-dd"; - var component = CompileToComponent($@" -@using Microsoft.AspNetCore.Components.Web - -@code {{ - public DateTime MyDate {{ get; set; }} = new DateTime(2018, 3, 4); -}}"); - var myDateProperty = component.GetType().GetProperty("MyDate"); - - var renderer = new TestRenderer(); - - // Assert - EventCallback setter = default; - var frames = GetRenderTree(renderer, component); - Assert.Collection(frames, - frame => AssertFrame.Element(frame, "input", 3, 0), - frame => AssertFrame.Attribute(frame, "value", new DateTime(2018, 3, 4).ToString(testDateFormat), 1), - frame => - { - AssertFrame.Attribute(frame, "onchange", 2); - setter = Assert.IsType(frame.AttributeValue); - }); - - // Trigger the change event to show it updates the property - // - // This should always complete synchronously. - var task = renderer.Dispatcher.InvokeAsync(() => setter.InvokeAsync(new ChangeEventArgs { Value = new DateTime(2018, 3, 5).ToString(testDateFormat), })); - Assert.Equal(TaskStatus.RanToCompletion, task.Status); - await task; - - Assert.Equal(new DateTime(2018, 3, 5), myDateProperty.GetValue(component)); - } - - [Fact] // In this case, onclick is just a normal HTML attribute - public void SupportsEventHandlerWithString() - { - // Arrange - var component = CompileToComponent(@" -", 0)); - } - - [Fact] - public void SupportsEventHandlerWithLambda() - { - // Arrange - var component = CompileToComponent(@" -@using Microsoft.AspNetCore.Components.Web -