diff --git a/.github/workflows/verification-dotnet-nightly.yml b/.github/workflows/verification-dotnet-nightly.yml deleted file mode 100644 index 49da31b50..000000000 --- a/.github/workflows/verification-dotnet-nightly.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: verification-dotnet-nightly - -on: - schedule: - - cron: "0 0 * * *" - workflow_dispatch: - -jobs: - verify-bunit: - name: ๐Ÿ‘Œ Verify bUnit - runs-on: ubuntu-latest - container: - image: mcr.microsoft.com/dotnet/nightly/sdk:7.0 - - steps: - - name: ๐ŸŒ› Show dotnet version - run: | - dotnet --info - - - name: ๐Ÿ›’ Checkout repository - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: ๐ŸŽจ Setup color - run: | - echo "DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION=1" >> $GITHUB_ENV - echo "TERM=xterm" >> $GITHUB_ENV - - - name: ๐Ÿ“ฆ Setup nuget nightly builds - run: | - dotnet restore --verbosity normal -s https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json -s https://api.nuget.org/v3/index.json - - - name: ๐Ÿงช Run unit tests - run: | - dotnet test ./tests/bunit.core.tests/bunit.core.tests.csproj -c release --no-restore -f net7.0 --logger:"console;verbosity=normal" --blame-hang-timeout 15s --blame-hang-dump-type full --blame-crash-dump-type full - dotnet test ./tests/bunit.web.tests/bunit.web.tests.csproj -c release --no-restore -f net7.0 --logger:"console;verbosity=normal" --blame-hang-timeout 15s --blame-hang-dump-type full --blame-crash-dump-type full - dotnet test ./tests/AngleSharpWrappers.Tests/AngleSharpWrappers.Tests.csproj -c release --no-restore -f net7.0 --logger:"console;verbosity=normal" --blame-hang-timeout 15s --blame-hang-dump-type full --blame-crash-dump-type full - - - name: ๐Ÿ“› Upload hang- and crash-dumps on test failure - if: failure() - uses: actions/upload-artifact@v3 - with: - if-no-files-found: ignore - name: test-dumps - path: | - **/*hangdump.dmp - **/*crashdump.dmp - - - name: ๐Ÿงพ Collect dotnet information - if: failure() - run: | - echo "DOTNET_VERSION=$(dotnet --version)" >> $GITHUB_ENV - echo $DOTNET_VERSION - - - name: โšก Create issue if failed - if: failure() - uses: JasonEtco/create-an-issue@v2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - ADJECTIVE: DOTNET_VERSION - with: - filename: .github/nightly-failed.md - update_existing: true diff --git a/CHANGELOG.md b/CHANGELOG.md index a1aaffd9f..28ee4e258 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ All notable changes to **bUnit** will be documented in this file. The project ad ## [Unreleased] +### Added +- Added the `StateFromJson` method to the `NavigationHistory` type, to make it easy to deserialize navigation state stored as JSON during a call to `NavigationManager.NavigateTo`, e.g. as seen with the new `InteractiveRequestOptions` type available in .NET 7. By [@linkdotnet](https://github.com/linkdotnet) and [@egil](https://github.com/egil). + ## [1.10.14] - 2022-09-16 ### Added diff --git a/Directory.Build.props b/Directory.Build.props index fe29a2151..60b5f6fdc 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -48,7 +48,7 @@ - + (); + +ActionToTriggerTheNavigationManager(); + +// This helper method retrieves the InteractiveRequestOptions object +var requestOptions = navigationManager.History.Last().StateFromJson(); +Asser.NotNull(requestOptions); +Assert.Equal(requestOptions.Interaction, InteractionType.SignIn); +options.TryGetAdditionalParameter("prompt", out string prompt); +Assert.Equal(prompt, "login"); ``` \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 74f317d57..4f3431aa3 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -43,7 +43,7 @@ - + diff --git a/src/bunit.core/ComponentParameterCollectionBuilder.cs b/src/bunit.core/ComponentParameterCollectionBuilder.cs index edfb05897..013241b21 100644 --- a/src/bunit.core/ComponentParameterCollectionBuilder.cs +++ b/src/bunit.core/ComponentParameterCollectionBuilder.cs @@ -72,7 +72,7 @@ public ComponentParameterCollectionBuilder Add(Expr /// A lambda function that selects the parameter. /// The markup string to pass to the . /// This . - public ComponentParameterCollectionBuilder Add(Expression> parameterSelector, string markup) + public ComponentParameterCollectionBuilder Add(Expression> parameterSelector, [StringSyntax("Html")]string markup) => Add(parameterSelector, markup.ToMarkupRenderFragment()); /// @@ -260,7 +260,7 @@ public ComponentParameterCollectionBuilder AddChildContent(RenderFra /// /// The markup string to pass the ChildContent parameter wrapped in a . /// This . - public ComponentParameterCollectionBuilder AddChildContent(string markup) + public ComponentParameterCollectionBuilder AddChildContent([StringSyntax("Html")]string markup) => AddChildContent(markup.ToMarkupRenderFragment()); /// diff --git a/src/bunit.core/ComponentParameterFactory.cs b/src/bunit.core/ComponentParameterFactory.cs index 9488dfe5c..668a8c65f 100644 --- a/src/bunit.core/ComponentParameterFactory.cs +++ b/src/bunit.core/ComponentParameterFactory.cs @@ -137,7 +137,7 @@ public static ComponentParameter CascadingValue(object value) /// /// Markup to pass to the child content parameter. /// The . - public static ComponentParameter ChildContent(string markup) + public static ComponentParameter ChildContent([StringSyntax("Html")]string markup) { return RenderFragment(nameof(ChildContent), markup); } @@ -173,7 +173,7 @@ public static ComponentParameter ChildContent(RenderFragment renderFragment) /// Parameter name. /// Markup to pass to the render fragment parameter. /// The . - public static ComponentParameter RenderFragment(string name, string markup) + public static ComponentParameter RenderFragment(string name, [StringSyntax("Html")]string markup) { return ComponentParameter.CreateParameter(name, markup.ToMarkupRenderFragment()); } diff --git a/src/bunit.core/Extensions/BlazorExtensions.cs b/src/bunit.core/Extensions/BlazorExtensions.cs index 0f4cc45f5..daba2f7cf 100644 --- a/src/bunit.core/Extensions/BlazorExtensions.cs +++ b/src/bunit.core/Extensions/BlazorExtensions.cs @@ -10,7 +10,7 @@ public static class BlazorExtensions /// /// Markup to render. /// The . - public static RenderFragment ToMarkupRenderFragment(this string? markup) + public static RenderFragment ToMarkupRenderFragment([StringSyntax("Html")]this string? markup) { if (string.IsNullOrEmpty(markup)) return _ => { }; diff --git a/src/bunit.core/Extensions/WaitForHelpers/WaitForHelper.cs b/src/bunit.core/Extensions/WaitForHelpers/WaitForHelper.cs index 9bcd8a277..e32dd7d73 100644 --- a/src/bunit.core/Extensions/WaitForHelpers/WaitForHelper.cs +++ b/src/bunit.core/Extensions/WaitForHelpers/WaitForHelper.cs @@ -9,6 +9,7 @@ namespace Bunit.Extensions.WaitForHelpers; /// public abstract class WaitForHelper : IDisposable { + private readonly Timer timer; private readonly TaskCompletionSource checkPassedCompletionSource; private readonly Func<(bool CheckPassed, T Content)> completeChecker; private readonly IRenderedFragmentBase renderedFragment; @@ -51,7 +52,13 @@ protected WaitForHelper( logger = renderedFragment.Services.CreateLogger>(); checkPassedCompletionSource = new TaskCompletionSource(); - WaitTask = CreateWaitTask(renderedFragment, timeout); + timer = new Timer(_ => + { + logger.LogWaiterTimedOut(renderedFragment.ComponentId); + checkPassedCompletionSource.TrySetException(new WaitForFailedException(TimeoutErrorMessage, capturedException)); + }); + WaitTask = CreateWaitTask(renderedFragment); + timer.Change(GetRuntimeTimeout(timeout), Timeout.InfiniteTimeSpan); InitializeWaiting(); } @@ -80,6 +87,7 @@ protected virtual void Dispose(bool disposing) return; isDisposed = true; + timer.Dispose(); checkPassedCompletionSource.TrySetCanceled(); renderedFragment.OnAfterRender -= OnAfterRender; logger.LogWaiterDisposed(renderedFragment.ComponentId); @@ -105,9 +113,11 @@ private void InitializeWaiting() } } - private Task CreateWaitTask(IRenderedFragmentBase renderedFragment, TimeSpan? timeout) + private Task CreateWaitTask(IRenderedFragmentBase renderedFragment) { - var renderer = renderedFragment.Services.GetRequiredService(); + var renderer = renderedFragment + .Services + .GetRequiredService(); // Two to failure conditions, that the renderer captures an unhandled // exception from a component or itself, or that the timeout is reached, @@ -115,31 +125,18 @@ private Task CreateWaitTask(IRenderedFragmentBase renderedFragment, TimeSpan? // and the continuations does not happen at the same time. var failureTask = renderer.Dispatcher.InvokeAsync(() => { - var taskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); - - var renderException = renderer + return renderer .UnhandledException .ContinueWith( x => Task.FromException(x.Result), CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously, - taskScheduler); - - var timeoutTask = Task.Delay(GetRuntimeTimeout(timeout)) - .ContinueWith( - x => - { - logger.LogWaiterTimedOut(renderedFragment.ComponentId); - return Task.FromException(new WaitForFailedException(TimeoutErrorMessage, capturedException)); - }, - CancellationToken.None, - TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously, - taskScheduler); - - return Task.WhenAny(renderException, timeoutTask).Unwrap(); + TaskScheduler.FromCurrentSynchronizationContext()); }).Unwrap(); - return Task.WhenAny(failureTask, checkPassedCompletionSource.Task).Unwrap(); + return Task + .WhenAny(checkPassedCompletionSource.Task, failureTask) + .Unwrap(); } private void OnAfterRender(object? sender, EventArgs args) @@ -170,7 +167,8 @@ private void OnAfterRender(object? sender, EventArgs args) if (StopWaitingOnCheckException) { - checkPassedCompletionSource.TrySetException(new WaitForFailedException(CheckThrowErrorMessage, capturedException)); + checkPassedCompletionSource.TrySetException( + new WaitForFailedException(CheckThrowErrorMessage, capturedException)); Dispose(); } } diff --git a/src/bunit.core/StringSyntaxAttribute.cs b/src/bunit.core/StringSyntaxAttribute.cs new file mode 100644 index 000000000..8817b14fd --- /dev/null +++ b/src/bunit.core/StringSyntaxAttribute.cs @@ -0,0 +1,25 @@ +#if !NET7_0_OR_GREATER +namespace System.Diagnostics.CodeAnalysis; + +/// Fake version of the StringSyntaxAttribute, which was introduced in .NET 7 +[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] +public sealed class StringSyntaxAttribute : Attribute +{ + /// + /// Initializes the with the identifier of the syntax used. + /// + public StringSyntaxAttribute(string syntax) + { + } + + /// + /// Initializes the with the identifier of the syntax used. + /// + public StringSyntaxAttribute(string syntax, params object?[] arguments) + { + } + + /// The syntax identifier for strings containing URIs. + public const string Uri = nameof(Uri); +} +#endif diff --git a/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs b/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs index 3474c61ef..4d7c2fe5e 100644 --- a/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs +++ b/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs @@ -20,7 +20,7 @@ public static class MarkupMatchesAssertExtensions /// The expected markup fragment. /// A custom user message to display in case the verification fails. [AssertionMethod] - public static void MarkupMatches(this string actual, string expected, string? userMessage = null) + public static void MarkupMatches([StringSyntax("Html")]this string actual, [StringSyntax("Html")]string expected, string? userMessage = null) { if (actual is null) throw new ArgumentNullException(nameof(actual)); @@ -42,7 +42,7 @@ public static void MarkupMatches(this string actual, string expected, string? us /// The expected . /// A custom user message to display in case the verification fails. [AssertionMethod] - public static void MarkupMatches(this string actual, IRenderedFragment expected, string? userMessage = null) + public static void MarkupMatches([StringSyntax("Html")]this string actual, IRenderedFragment expected, string? userMessage = null) { if (actual is null) throw new ArgumentNullException(nameof(actual)); @@ -62,7 +62,7 @@ public static void MarkupMatches(this string actual, IRenderedFragment expected, /// The expected . /// A custom user message to display in case the verification fails. [AssertionMethod] - public static void MarkupMatches(this string actual, INodeList expected, string? userMessage = null) + public static void MarkupMatches([StringSyntax("Html")]this string actual, INodeList expected, string? userMessage = null) { if (actual is null) throw new ArgumentNullException(nameof(actual)); @@ -82,7 +82,7 @@ public static void MarkupMatches(this string actual, INodeList expected, string? /// The expected . /// A custom user message to display in case the verification fails. [AssertionMethod] - public static void MarkupMatches(this string actual, INode expected, string? userMessage = null) + public static void MarkupMatches([StringSyntax("Html")]this string actual, INode expected, string? userMessage = null) { if (actual is null) throw new ArgumentNullException(nameof(actual)); @@ -102,7 +102,7 @@ public static void MarkupMatches(this string actual, INode expected, string? use /// The expected markup. /// A custom user message to display in case the verification fails. [AssertionMethod] - public static void MarkupMatches(this IRenderedFragment actual, string expected, string? userMessage = null) + public static void MarkupMatches(this IRenderedFragment actual, [StringSyntax("Html")]string expected, string? userMessage = null) { if (actual is null) throw new ArgumentNullException(nameof(actual)); @@ -182,7 +182,7 @@ public static void MarkupMatches(this INode actual, IRenderedFragment expected, /// The expected markup. /// A custom user message to display in case the verification fails. [AssertionMethod] - public static void MarkupMatches(this INode actual, string expected, string? userMessage = null) + public static void MarkupMatches(this INode actual, [StringSyntax("Html")]string expected, string? userMessage = null) { if (actual is null) throw new ArgumentNullException(nameof(actual)); @@ -203,7 +203,7 @@ public static void MarkupMatches(this INode actual, string expected, string? use /// The expected markup. /// A custom user message to display in case the verification fails. [AssertionMethod] - public static void MarkupMatches(this INodeList actual, string expected, string? userMessage = null) + public static void MarkupMatches(this INodeList actual, [StringSyntax("Html")]string expected, string? userMessage = null) { if (actual is null) throw new ArgumentNullException(nameof(actual)); @@ -351,11 +351,11 @@ public static void MarkupMatches(this INodeList actual, RenderFragment expected, /// the markup fragment, using the type. /// /// Thrown when the markup does not match the markup. - /// A enumerable of IElements to verifiy. + /// A enumerable of IElements to verify. /// The expected markup fragment. /// A custom user message to display in case the verification fails. [AssertionMethod] - public static void MarkupMatches(this IEnumerable actual, string expected, string? userMessage = null) + public static void MarkupMatches(this IEnumerable actual, [StringSyntax("Html")]string expected, string? userMessage = null) { if (actual is null) throw new ArgumentNullException(nameof(actual)); @@ -370,7 +370,7 @@ public static void MarkupMatches(this IEnumerable actual, string expec /// the fragments, using the type. /// /// Thrown when the element does not match the fragments. - /// An IElement to verifiy. + /// An IElement to verify. /// The expected markup fragments. /// A custom user message to display in case the verification fails. [AssertionMethod] @@ -412,7 +412,7 @@ public static void MarkupMatches(this IElement actual, IEnumerable exp /// the fragment, using the type. /// /// Thrown when the elements does not match the fragment. - /// A list of elements to verifiy. + /// A list of elements to verify. /// The expected markup fragment. /// A custom user message to display in case the verification fails. [AssertionMethod] @@ -473,9 +473,7 @@ private static INodeList ToNodeList(this IEnumerable elements, BunitHt using var parser = new BunitHtmlParser(); return nodesStr.ToNodeList(parser); } - else - { - return nodesStr.ToNodeList(htmlParser); - } + + return nodesStr.ToNodeList(htmlParser); } } diff --git a/src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs b/src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs index 01da2102a..011c82464 100644 --- a/src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs +++ b/src/bunit.web/Extensions/StubComponentFactoryCollectionExtensions.cs @@ -39,7 +39,7 @@ static Predicate CreatePredicate(Type componentTypeToStub) /// The bUnit to configure. /// Markup that will be used as render output instead of the stubbed out component. /// A . - public static ComponentFactoryCollection AddStub(this ComponentFactoryCollection factories, string replacementMarkup) where TComponent : IComponent + public static ComponentFactoryCollection AddStub(this ComponentFactoryCollection factories, [StringSyntax("Html")]string replacementMarkup) where TComponent : IComponent => AddStub(factories, b => b.AddMarkupContent(0, replacementMarkup)); /// diff --git a/src/bunit.web/Rendering/BunitHtmlParser.cs b/src/bunit.web/Rendering/BunitHtmlParser.cs index 07a7f42c1..c6edf2971 100644 --- a/src/bunit.web/Rendering/BunitHtmlParser.cs +++ b/src/bunit.web/Rendering/BunitHtmlParser.cs @@ -57,7 +57,7 @@ private BunitHtmlParser(IConfiguration angleSharpConfiguration) /// /// The markup to parse. /// The . - public INodeList Parse(string markup) + public INodeList Parse([StringSyntax("Html")]string markup) { if (markup is null) throw new ArgumentNullException(nameof(markup)); @@ -187,4 +187,4 @@ public IEnumerator GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } -} \ No newline at end of file +} diff --git a/src/bunit.web/TestDoubles/NavigationManager/NavigationHistory.cs b/src/bunit.web/TestDoubles/NavigationManager/NavigationHistory.cs index e6b86e73c..9422f7a58 100644 --- a/src/bunit.web/TestDoubles/NavigationManager/NavigationHistory.cs +++ b/src/bunit.web/TestDoubles/NavigationManager/NavigationHistory.cs @@ -1,4 +1,8 @@ +#if NET7_0_OR_GREATER +using System.Text.Json; using Microsoft.AspNetCore.Components.Routing; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; +#endif namespace Bunit.TestDoubles; @@ -45,7 +49,7 @@ public sealed class NavigationHistory : IEquatable /// /// [SuppressMessage("Design", "CA1054:URI-like parameters should not be strings", Justification = "Using string to align with NavigationManager")] - public NavigationHistory(string uri, Bunit.TestDoubles.NavigationOptions options) + public NavigationHistory([StringSyntax(StringSyntaxAttribute.Uri)]string uri, Bunit.TestDoubles.NavigationOptions options) { Uri = uri; Options = options; @@ -58,7 +62,7 @@ public NavigationHistory(string uri, Bunit.TestDoubles.NavigationOptions options /// /// [SuppressMessage("Design", "CA1054:URI-like parameters should not be strings", Justification = "Using string to align with NavigationManager")] - public NavigationHistory(string uri, NavigationOptions options) + public NavigationHistory([StringSyntax(StringSyntaxAttribute.Uri)]string uri, NavigationOptions options) { Uri = uri; Options = options; @@ -74,13 +78,37 @@ public NavigationHistory(string uri, NavigationOptions options) /// /// [SuppressMessage("Design", "CA1054:URI-like parameters should not be strings", Justification = "Using string to align with NavigationManager")] - public NavigationHistory(string uri, NavigationOptions options, NavigationState navigationState, Exception? exception = null) + public NavigationHistory( + [StringSyntax(StringSyntaxAttribute.Uri)]string uri, + NavigationOptions options, + NavigationState navigationState, + Exception? exception = null) { Uri = uri; Options = options; State = navigationState; Exception = exception; } + + /// + /// Deserialize the content of . + /// into if it is not null. + /// + /// The type to deserialize the content of . to. + /// The used when deserializing. If not provided, is used. + /// The target type of the JSON value. + /// When . is null. + public T? StateFromJson(JsonSerializerOptions? options = null) + { + if (Options.HistoryEntryState is null) + { + throw new InvalidOperationException($"No {nameof(Options.HistoryEntryState)} has been set."); + } + + return JsonSerializer.Deserialize( + Options.HistoryEntryState, + options ?? JsonSerializerOptions.Default); + } #endif /// @@ -88,13 +116,22 @@ public NavigationHistory(string uri, NavigationOptions options, NavigationState public bool Equals(NavigationHistory? other) => other is not null && string.Equals(Uri, other.Uri, StringComparison.Ordinal) && Options.Equals(other.Options); #endif -#if NET6_0_OR_GREATER +#if NET6_0 public bool Equals(NavigationHistory? other) => other is not null && string.Equals(Uri, other.Uri, StringComparison.Ordinal) && Options.ForceLoad == other.Options.ForceLoad && Options.ReplaceHistoryEntry == other.Options.ReplaceHistoryEntry; #endif +#if NET7_0_OR_GREATER + public bool Equals(NavigationHistory? other) + => other is not null + && string.Equals(Uri, other.Uri, StringComparison.Ordinal) + && Options.ForceLoad == other.Options.ForceLoad + && Options.ReplaceHistoryEntry == other.Options.ReplaceHistoryEntry + && State == other.State + && Exception == other.Exception; +#endif /// public override bool Equals(object? obj) => obj is NavigationHistory other && Equals(other); diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props index 9ed6290d0..143b11772 100644 --- a/tests/Directory.Build.props +++ b/tests/Directory.Build.props @@ -16,11 +16,11 @@ - + - + diff --git a/tests/bunit.web.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs b/tests/bunit.web.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs index 3709497c0..68549436d 100644 --- a/tests/bunit.web.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs +++ b/tests/bunit.web.tests/TestDoubles/NavigationManager/FakeNavigationManagerTest.cs @@ -1,3 +1,6 @@ +using System.Text.Json; +using Microsoft.AspNetCore.Components.WebAssembly.Authentication; + namespace Bunit.TestDoubles; using static Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers; @@ -219,6 +222,47 @@ public void Test012() entry.State.ShouldBe(NavigationState.Faulted); } + [Fact(DisplayName = "StateFromJson deserialize InteractiveRequestOptions")] + public void Test013() + { + var fakeNavigationManager = CreateFakeNavigationManager(); + var requestOptions = new InteractiveRequestOptions + { + ReturnUrl = "return", Interaction = InteractionType.SignIn, + }; + requestOptions.TryAddAdditionalParameter("library", "bunit"); + + fakeNavigationManager.NavigateToLogin("/some-url", requestOptions); + + var options = fakeNavigationManager.History.Last().StateFromJson(); + options.ShouldNotBeNull(); + options.Interaction.ShouldBe(InteractionType.SignIn); + options.ReturnUrl.ShouldBe("return"); + options.TryGetAdditionalParameter("library", out string libraryName).ShouldBeTrue(); + libraryName.ShouldBe("bunit"); + } + + [Fact(DisplayName = "Given no content in state then StateFromJson throws")] + public void Test014() + { + var fakeNavigationManager = CreateFakeNavigationManager(); + fakeNavigationManager.NavigateTo("/some-url"); + + Should.Throw( + () => fakeNavigationManager.History.Last().StateFromJson()); + } + + [Fact(DisplayName = "StateFromJson with invalid json throws")] + public void Test015() + { + var fakeNavigationManager = CreateFakeNavigationManager(); + + fakeNavigationManager.NavigateTo("/login", new NavigationOptions { HistoryEntryState = "" }); + + Should.Throw( + () => fakeNavigationManager.History.Last().StateFromJson()); + } + private class InterceptNavigateToCounterComponent : ComponentBase { protected override void BuildRenderTree(RenderTreeBuilder builder) @@ -251,7 +295,6 @@ private void InterceptNavigation(LocationChangingContext context) public class GotoExternalResourceComponent : ComponentBase { -#pragma warning disable 1998 protected override void BuildRenderTree(RenderTreeBuilder builder) { builder.OpenElement(0, "button"); diff --git a/tests/run-tests.ps1 b/tests/run-tests.ps1 index 51e7f05a4..3b8fe0688 100644 --- a/tests/run-tests.ps1 +++ b/tests/run-tests.ps1 @@ -10,14 +10,10 @@ for ($num = 1 ; $num -le $maxRuns ; $num++) if($filter) { - dotnet test .\bunit.core.tests\bunit.core.tests.csproj -c $mode --no-restore --no-build --blame-hang --blame-hang-timeout 100s --nologo --filter $filter --logger:"console;verbosity=normal" - dotnet test .\bunit.web.tests\bunit.web.tests.csproj -c $mode --no-restore --no-build --blame-hang --blame-hang-timeout 100s --nologo --filter $filter --logger:"console;verbosity=normal" - dotnet test .\bunit.web.testcomponents.tests\bunit.web.testcomponents.teststests.csproj -c $mode --no-restore --no-build --blame-hang --blame-hang-timeout 100s --nologo --filter $filter --logger:"console;verbosity=normal" + dotnet test ..\bunit.sln -c $mode --no-restore --no-build --blame --nologo --filter $filter } else { - dotnet test .\bunit.core.tests\bunit.core.tests.csproj -c $mode --no-restore --no-build --blame-hang --blame-hang-timeout 100s --nologo - dotnet test .\bunit.web.tests\bunit.web.tests.csproj -c $mode --no-restore --no-build --blame-hang --blame-hang-timeout 100s --nologo - dotnet test .\bunit.web.testcomponents.tests\bunit.web.testcomponents.tests.csproj -c $mode --no-restore --no-build --blame-hang --blame-hang-timeout 100s --nologo + dotnet test ..\bunit.sln -c $mode --no-restore --no-build --blame --nologo } } diff --git a/version.json b/version.json index 35c5358b2..cce110611 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.10", + "version": "1.11", "assemblyVersion": { "precision": "revision" },