Clean up and include routing unit tests
This commit is contained in:
parent
87fc15cc23
commit
7073429cd5
|
|
@ -66,6 +66,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AngleSharpBuilder", "src\an
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Blazor.Razor.Extensions", "src\Microsoft.AspNetCore.Blazor.Razor.Extensions\Microsoft.AspNetCore.Blazor.Razor.Extensions.csproj", "{D652A019-B765-4922-B7B8-3AB1C58338D7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.Blazor.Browser.Test", "test\Microsoft.AspNetCore.Blazor.Browser.Test\Microsoft.AspNetCore.Blazor.Browser.Test.csproj", "{EC2A38BF-6E77-4A8E-A731-15929544F29C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -160,6 +162,10 @@ Global
|
|||
{D652A019-B765-4922-B7B8-3AB1C58338D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D652A019-B765-4922-B7B8-3AB1C58338D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D652A019-B765-4922-B7B8-3AB1C58338D7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EC2A38BF-6E77-4A8E-A731-15929544F29C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EC2A38BF-6E77-4A8E-A731-15929544F29C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EC2A38BF-6E77-4A8E-A731-15929544F29C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EC2A38BF-6E77-4A8E-A731-15929544F29C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -192,6 +198,7 @@ Global
|
|||
{4E3BD19A-6159-4548-A88F-700443E6D934} = {B867E038-B3CE-43E3-9292-61568C46CDEB}
|
||||
{36706AC2-C851-4038-B161-9C1E44B668C8} = {4E3BD19A-6159-4548-A88F-700443E6D934}
|
||||
{D652A019-B765-4922-B7B8-3AB1C58338D7} = {B867E038-B3CE-43E3-9292-61568C46CDEB}
|
||||
{EC2A38BF-6E77-4A8E-A731-15929544F29C} = {ADA3AE29-F6DE-49F6-8C7C-B321508CAE8E}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {504DA352-6788-4DC0-8705-82167E72A4D3}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Blazor.Browser.Test")]
|
||||
|
|
@ -10,18 +10,35 @@ using Microsoft.AspNetCore.Blazor.RenderTree;
|
|||
|
||||
namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// A component that displays whichever other component corresponds to the
|
||||
/// browser's changing navigation state.
|
||||
/// </summary>
|
||||
public class BrowserRouter : IComponent, IDisposable
|
||||
{
|
||||
RenderHandle _renderHandle;
|
||||
string _baseUriPrefix;
|
||||
string _locationAbsolute;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the assembly that should be searched, along with its referenced
|
||||
/// assemblies, for components matching the URI.
|
||||
/// </summary>
|
||||
public Assembly AppAssembly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the namespace prefix that should be prepended when searching
|
||||
/// for matching components.
|
||||
/// </summary>
|
||||
public string PagesNamespace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the component name that will be used if the URI ends with
|
||||
/// a slash.
|
||||
/// </summary>
|
||||
public string DefaultComponentName { get; set; } = "Index";
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Init(RenderHandle renderHandle)
|
||||
{
|
||||
_renderHandle = renderHandle;
|
||||
|
|
@ -32,12 +49,14 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
|||
_locationAbsolute = UriHelper.GetAbsoluteUri();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetParameters(ParameterCollection parameters)
|
||||
{
|
||||
parameters.AssignToProperties(this);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
UriHelper.OnLocationChanged -= OnLocationChanged;
|
||||
|
|
|
|||
|
|
@ -6,29 +6,59 @@ using System;
|
|||
|
||||
namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
||||
{
|
||||
// TODO: Make this not static, and wrap it in an interface that can be injected through DI.
|
||||
// We can make EnableNavigationInteception private, and call it automatically when the any
|
||||
// concrete instance is instantiated.
|
||||
|
||||
/// <summary>
|
||||
/// Helpers for working with URIs and navigation state.
|
||||
/// </summary>
|
||||
public static class UriHelper
|
||||
{
|
||||
static readonly string _functionPrefix = typeof(UriHelper).FullName;
|
||||
|
||||
/// <summary>
|
||||
/// An event that fires when the navigation location has changed.
|
||||
/// </summary>
|
||||
public static event EventHandler<string> OnLocationChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Prevents default navigation on all links whose href is inside the base URI space,
|
||||
/// causing clicks on those links to trigger <see cref="OnLocationChanged"/> instead.
|
||||
/// </summary>
|
||||
public static void EnableNavigationInteception()
|
||||
=> RegisteredFunction.InvokeUnmarshalled<object>(
|
||||
$"{_functionPrefix}.enableNavigationInteception");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URI prefix that can be prepended before URI paths to produce an absolute URI.
|
||||
/// Typically this corresponds to the 'href' attribute on the document's <base> element.
|
||||
/// </summary>
|
||||
/// <returns>The URI prefix.</returns>
|
||||
public static string GetBaseUriPrefix()
|
||||
{
|
||||
var baseUri = RegisteredFunction.InvokeUnmarshalled<string>(
|
||||
$"{_functionPrefix}.getBaseURI");
|
||||
return ToBaseURIPrefix(baseUri);
|
||||
return ToBaseUriPrefix(baseUri);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the browser's current absolute URI.
|
||||
/// </summary>
|
||||
/// <returns>The browser's current absolute URI.</returns>
|
||||
public static string GetAbsoluteUri()
|
||||
{
|
||||
return RegisteredFunction.InvokeUnmarshalled<string>(
|
||||
$"{_functionPrefix}.getLocationHref");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Given a base URI prefix (e.g., one previously returned by <see cref="GetBaseUriPrefix"/>),
|
||||
/// converts an absolute URI into one relative to the base URI prefix.
|
||||
/// </summary>
|
||||
/// <param name="baseUriPrefix">The base URI prefix (e.g., previously returned by <see cref="GetBaseUriPrefix"/>).</param>
|
||||
/// <param name="absoluteUri">An absolute URI that is within the space of the base URI prefix.</param>
|
||||
/// <returns>A relative URI path.</returns>
|
||||
public static string ToBaseRelativePath(string baseUriPrefix, string absoluteUri)
|
||||
{
|
||||
// The absolute URI must be of the form "{baseUriPrefix}/something",
|
||||
|
|
@ -49,13 +79,14 @@ namespace Microsoft.AspNetCore.Blazor.Browser.Routing
|
|||
=> OnLocationChanged?.Invoke(null, newAbsoluteUri);
|
||||
|
||||
/// <summary>
|
||||
/// Given the href value from the document's <base> element, returns the URI
|
||||
/// prefix that can be prepended to URI paths to produce an absolute URI.
|
||||
/// Given the document's document.baseURI value, returns the URI prefix
|
||||
/// that can be prepended to URI paths to produce an absolute URI.
|
||||
/// This is computed by removing the final slash and any following characters.
|
||||
/// Internal for tests.
|
||||
/// </summary>
|
||||
/// <param name="baseUri">The href value from a document's <base> element.</param>
|
||||
/// <param name="baseUri">The page's document.baseURI value.</param>
|
||||
/// <returns>The URI prefix</returns>
|
||||
private static string ToBaseURIPrefix(string baseUri)
|
||||
internal static string ToBaseUriPrefix(string baseUri)
|
||||
{
|
||||
if (baseUri != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Blazor.Test")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Blazor.Browser.Test")]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Blazor.Browser\Microsoft.AspNetCore.Blazor.Browser.csproj" />
|
||||
|
||||
<!-- Shared sources -->
|
||||
<Compile Include="..\shared\**\*.cs" Link="Helpers\%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// 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.Blazor.Browser.Routing;
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.Browser.Test
|
||||
{
|
||||
public class UriHelperTest
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("scheme://host/", "scheme://host")]
|
||||
[InlineData("scheme://host:123/", "scheme://host:123")]
|
||||
[InlineData("scheme://host/path", "scheme://host")]
|
||||
[InlineData("scheme://host/path/", "scheme://host/path")]
|
||||
[InlineData("scheme://host/path/page?query=string&another=here", "scheme://host/path")]
|
||||
public void ComputesCorrectBaseUriPrefix(string baseUri, string expectedResult)
|
||||
{
|
||||
var actualResult = UriHelper.ToBaseUriPrefix(baseUri);
|
||||
Assert.Equal(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("scheme://host", "scheme://host/", "/")]
|
||||
[InlineData("scheme://host", "scheme://host/path", "/path")]
|
||||
[InlineData("scheme://host/path", "scheme://host/path/", "/")]
|
||||
[InlineData("scheme://host/path", "scheme://host/path/more", "/more")]
|
||||
public void ComputesCorrectValidBaseRelativePaths(string baseUriPrefix, string absoluteUri, string expectedResult)
|
||||
{
|
||||
var actualResult = UriHelper.ToBaseRelativePath(baseUriPrefix, absoluteUri);
|
||||
Assert.Equal(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("scheme://host", "otherscheme://host/")] // Mismatched prefix is error
|
||||
[InlineData("scheme://host", "scheme://otherhost/")] // Mismatched prefix is error
|
||||
[InlineData("scheme://host/path", "scheme://host/path")] // URI isn't within base URI space
|
||||
public void ThrowsForInvalidBaseRelativePaths(string baseUriPrefix, string absoluteUri)
|
||||
{
|
||||
var ex = Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
UriHelper.ToBaseRelativePath(baseUriPrefix, absoluteUri);
|
||||
});
|
||||
|
||||
Assert.Equal(
|
||||
$"The URI '{absoluteUri}' is not contained by the base URI '{baseUriPrefix}'.",
|
||||
ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Blazor\Microsoft.AspNetCore.Blazor.csproj" />
|
||||
|
||||
<!-- Shared sources -->
|
||||
<Compile Include="..\shared\AssertFrame.cs" Link="Helpers\AssertFrame.cs" />
|
||||
<Compile Include="..\shared\**\*.cs" Link="Helpers\%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Blazor.RenderTree;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.Test
|
||||
namespace Microsoft.AspNetCore.Blazor.Test.Helpers
|
||||
{
|
||||
public class CapturedBatch
|
||||
{
|
||||
Loading…
Reference in New Issue